From 1c4fada9760dbd40b814cfa0a4109983d2cf8027 Mon Sep 17 00:00:00 2001 From: sungHeeLee <70899677+hee9841@users.noreply.github.com> Date: Tue, 29 Oct 2024 16:44:28 +0900 Subject: [PATCH] =?UTF-8?q?Fix:=20=EB=82=98=EC=9D=98=20=EA=B8=B0=EB=A1=9D?= =?UTF-8?q?=20=EB=B1=83=EC=A7=80=20=EC=A1=B0=ED=9A=8C=EB=A5=BC=20=EC=B5=9C?= =?UTF-8?q?=EC=8B=A0=20=EA=B8=B0=EC=A4=80=EC=9C=BC=EB=A1=9C=20=EC=B5=9C?= =?UTF-8?q?=EB=8C=80=203=EA=B0=9C=20=EB=A6=AC=ED=84=B4=ED=95=98=EB=8F=84?= =?UTF-8?q?=EB=A1=9D=20=EC=88=98=EC=A0=95=20(#288)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fix: 나의 뱃지 조회를 획득한 날짜 최신 순으로 최대 3개만 가져오도록 repository 함수 수정 * Fix: 뱃지 조회 repository 함수 명을 명확하게 변경, limit 인자 추가 - findByMemberIdWithBadge에서 findByMemberIdWithBadgeOrderByAchievedAtLimit으로 변경 * Test: 나의 기록의 뱃지 조회 findByMemberIdWithBadgeOrderByAchievedAtLimit 함수 테스트 코드 추가 --- .../runus/application/badge/BadgeService.java | 15 ++-- .../badge/BadgeAchievementRepository.java | 2 +- .../badge/BadgeAchievementRepositoryImpl.java | 4 +- .../badge/JooqBadgeAchievementRepository.java | 4 +- .../application/badge/BadgeServiceTest.java | 5 +- .../BadgeAchievementRepositoryImplTest.java | 68 +++++++++++++++++++ 6 files changed, 85 insertions(+), 13 deletions(-) diff --git a/src/main/java/com/dnd/runus/application/badge/BadgeService.java b/src/main/java/com/dnd/runus/application/badge/BadgeService.java index 5f64fe4c..d8a81e66 100644 --- a/src/main/java/com/dnd/runus/application/badge/BadgeService.java +++ b/src/main/java/com/dnd/runus/application/badge/BadgeService.java @@ -39,13 +39,14 @@ public void achieveBadge(Member member, BadgeType badgeType, int value) { } public AchievedBadgesResponse getAchievedBadges(long memberId) { - return new AchievedBadgesResponse(badgeAchievementRepository.findByMemberIdWithBadge(memberId).stream() - .map(badgeAchievement -> new AchievedBadgesResponse.AchievedBadge( - badgeAchievement.badge().badgeId(), - badgeAchievement.badge().name(), - badgeAchievement.badge().imageUrl(), - badgeAchievement.createdAt().toLocalDateTime())) - .toList()); + return new AchievedBadgesResponse( + badgeAchievementRepository.findByMemberIdWithBadgeOrderByAchievedAtLimit(memberId, 3).stream() + .map(badgeAchievement -> new AchievedBadgesResponse.AchievedBadge( + badgeAchievement.badge().badgeId(), + badgeAchievement.badge().name(), + badgeAchievement.badge().imageUrl(), + badgeAchievement.createdAt().toLocalDateTime())) + .toList()); } @Transactional(readOnly = true) diff --git a/src/main/java/com/dnd/runus/domain/badge/BadgeAchievementRepository.java b/src/main/java/com/dnd/runus/domain/badge/BadgeAchievementRepository.java index 08cdd0d1..ee738d17 100644 --- a/src/main/java/com/dnd/runus/domain/badge/BadgeAchievementRepository.java +++ b/src/main/java/com/dnd/runus/domain/badge/BadgeAchievementRepository.java @@ -7,7 +7,7 @@ public interface BadgeAchievementRepository { Optional findById(long id); - List findByMemberIdWithBadge(long memberId); + List findByMemberIdWithBadgeOrderByAchievedAtLimit(long memberId, int limit); BadgeAchievement save(BadgeAchievement badgeAchievement); diff --git a/src/main/java/com/dnd/runus/infrastructure/persistence/domain/badge/BadgeAchievementRepositoryImpl.java b/src/main/java/com/dnd/runus/infrastructure/persistence/domain/badge/BadgeAchievementRepositoryImpl.java index 66e4d555..91805710 100644 --- a/src/main/java/com/dnd/runus/infrastructure/persistence/domain/badge/BadgeAchievementRepositoryImpl.java +++ b/src/main/java/com/dnd/runus/infrastructure/persistence/domain/badge/BadgeAchievementRepositoryImpl.java @@ -24,8 +24,8 @@ public Optional findById(long id) { } @Override - public List findByMemberIdWithBadge(long memberId) { - return jooqBadgeAchievementRepository.findByMemberIdWithBadge(memberId); + public List findByMemberIdWithBadgeOrderByAchievedAtLimit(long memberId, int limit) { + return jooqBadgeAchievementRepository.findByMemberIdWithBadgeOrderByAchievedAtLimit(memberId, limit); } @Override diff --git a/src/main/java/com/dnd/runus/infrastructure/persistence/jooq/badge/JooqBadgeAchievementRepository.java b/src/main/java/com/dnd/runus/infrastructure/persistence/jooq/badge/JooqBadgeAchievementRepository.java index b43685a2..f45a468e 100644 --- a/src/main/java/com/dnd/runus/infrastructure/persistence/jooq/badge/JooqBadgeAchievementRepository.java +++ b/src/main/java/com/dnd/runus/infrastructure/persistence/jooq/badge/JooqBadgeAchievementRepository.java @@ -16,12 +16,14 @@ public class JooqBadgeAchievementRepository { private final DSLContext dsl; - public List findByMemberIdWithBadge(long memberId) { + public List findByMemberIdWithBadgeOrderByAchievedAtLimit(long memberId, int limit) { return dsl.select() .from(BADGE_ACHIEVEMENT) .join(BADGE) .on(BADGE_ACHIEVEMENT.BADGE_ID.eq(BADGE.ID)) .where(BADGE_ACHIEVEMENT.MEMBER_ID.eq(memberId)) + .orderBy(BADGE_ACHIEVEMENT.CREATED_AT.desc()) + .limit(limit) .fetch(badge -> new BadgeAchievement.OnlyBadge( badge.get(BADGE_ACHIEVEMENT.ID), new JooqBadgeMapper().map(badge), diff --git a/src/test/java/com/dnd/runus/application/badge/BadgeServiceTest.java b/src/test/java/com/dnd/runus/application/badge/BadgeServiceTest.java index ee5632e9..41a4f16c 100644 --- a/src/test/java/com/dnd/runus/application/badge/BadgeServiceTest.java +++ b/src/test/java/com/dnd/runus/application/badge/BadgeServiceTest.java @@ -46,7 +46,7 @@ void getAchievedBadges() { Badge badge1 = new Badge(1L, "badge1", "description", "imageUrl1", BadgeType.STREAK, 100); Badge badge2 = new Badge(2L, "badge2", "description", "imageUrl2", BadgeType.DISTANCE_METER, 1000); - given(badgeAchievementRepository.findByMemberIdWithBadge(1L)) + given(badgeAchievementRepository.findByMemberIdWithBadgeOrderByAchievedAtLimit(1L, 3)) .willReturn(List.of( new BadgeAchievement.OnlyBadge(1, badge1, OffsetDateTime.now(), OffsetDateTime.now()), new BadgeAchievement.OnlyBadge(2, badge2, OffsetDateTime.now(), OffsetDateTime.now()))); @@ -68,7 +68,8 @@ void getAchievedBadges() { @DisplayName("자신이 획득한 뱃지가 없다면, 뱃지가 없는 응답을 반환한다.") void getAchievedBadges_Empty() { // given - given(badgeAchievementRepository.findByMemberIdWithBadge(1L)).willReturn(List.of()); + given(badgeAchievementRepository.findByMemberIdWithBadgeOrderByAchievedAtLimit(1L, 3)) + .willReturn(List.of()); // when AchievedBadgesResponse achievedBadgesResponse = badgeService.getAchievedBadges(1L); diff --git a/src/test/java/com/dnd/runus/infrastructure/persistence/domain/badge/BadgeAchievementRepositoryImplTest.java b/src/test/java/com/dnd/runus/infrastructure/persistence/domain/badge/BadgeAchievementRepositoryImplTest.java index 7afc5d96..d9e84442 100644 --- a/src/test/java/com/dnd/runus/infrastructure/persistence/domain/badge/BadgeAchievementRepositoryImplTest.java +++ b/src/test/java/com/dnd/runus/infrastructure/persistence/domain/badge/BadgeAchievementRepositoryImplTest.java @@ -2,6 +2,7 @@ import com.dnd.runus.domain.badge.Badge; import com.dnd.runus.domain.badge.BadgeAchievement; +import com.dnd.runus.domain.badge.BadgeAchievement.OnlyBadge; import com.dnd.runus.domain.badge.BadgeAchievementRepository; import com.dnd.runus.domain.member.Member; import com.dnd.runus.domain.member.MemberRepository; @@ -14,6 +15,7 @@ import org.junit.jupiter.api.*; import org.springframework.beans.factory.annotation.Autowired; +import java.time.OffsetDateTime; import java.util.List; import static org.junit.jupiter.api.Assertions.*; @@ -51,6 +53,72 @@ public void deleteByMember() { .isPresent()); } + @Nested + @DisplayName("BadeAchievement 조회 테스트") + class BadgeAchievementFindTest { + @Autowired + private EntityManager entityManager; + + private Badge badge1; + private Badge badge2; + private Badge badge3; + private Badge badge4; + + @BeforeEach + void beforeEach() { + BadgeEntity badgeEntity1 = + BadgeEntity.from(new Badge(0L, "testBadge1", "testBadge1", "tesUrl1", BadgeType.DISTANCE_METER, 0)); + BadgeEntity badgeEntity2 = + BadgeEntity.from(new Badge(0L, "testBadge2", "testBadge2", "tesUrl2", BadgeType.DISTANCE_METER, 2)); + + BadgeEntity badgeEntity3 = + BadgeEntity.from(new Badge(0L, "testBadge3", "testBadge3", "tesUrl3", BadgeType.DISTANCE_METER, 3)); + + BadgeEntity badgeEntity4 = + BadgeEntity.from(new Badge(0L, "testBadge4", "testBadge4", "tesUrl4", BadgeType.DISTANCE_METER, 4)); + + entityManager.persist(badgeEntity1); + entityManager.persist(badgeEntity2); + entityManager.persist(badgeEntity3); + entityManager.persist(badgeEntity4); + + badge1 = badgeEntity1.toDomain(); + badge2 = badgeEntity2.toDomain(); + badge3 = badgeEntity3.toDomain(); + badge4 = badgeEntity4.toDomain(); + } + + @AfterEach + void afterEach() { + entityManager.createQuery("delete from badge_achievement").executeUpdate(); + entityManager.createQuery("delete from badge").executeUpdate(); + } + + @Test + @DisplayName("획득한 뱃지를 조회한다: 획득한 최신 순, 최대 3개의 데이터를 리턴한다.") + void findByMemberIdWithBadgeOrderByAchievedAtLimit() { + // given + badgeAchievementRepository.save(new BadgeAchievement(badge1, savedMember)); + badgeAchievementRepository.save(new BadgeAchievement(badge2, savedMember)); + badgeAchievementRepository.save(new BadgeAchievement(badge3, savedMember)); + badgeAchievementRepository.save(new BadgeAchievement(badge4, savedMember)); + + // when + List byMemberIdWithBadgeList = + badgeAchievementRepository.findByMemberIdWithBadgeOrderByAchievedAtLimit(savedMember.memberId(), 3); + + // then + assertEquals(3, byMemberIdWithBadgeList.size()); + + OffsetDateTime achievedAt1 = byMemberIdWithBadgeList.get(0).createdAt(); + OffsetDateTime achievedAt2 = byMemberIdWithBadgeList.get(1).createdAt(); + OffsetDateTime achievedAt3 = byMemberIdWithBadgeList.get(2).createdAt(); + + assertTrue(achievedAt1.isAfter(achievedAt2)); + assertTrue(achievedAt2.isAfter(achievedAt3)); + } + } + @Nested @DisplayName("BadgeAchievement 저장 테스트") class BadgeAchievementSaveTest {