From 7a59f4a8c70cb600819344fb0af656937230db45 Mon Sep 17 00:00:00 2001 From: vectorch Date: Fri, 22 Dec 2023 15:53:39 +0900 Subject: [PATCH 1/2] =?UTF-8?q?test:=20=EB=82=B4=20=ED=80=98=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=A1=B0=ED=9A=8C=20=EC=84=9C=EB=B9=84=EC=8A=A4?= =?UTF-8?q?=EB=A5=BC=20=ED=85=8C=EC=8A=A4=ED=8A=B8=ED=95=9C=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../application/GetQuestsServiceTest.java | 47 +++++++++++++++++++ .../support/fixture/QuestFixtures.java | 6 +++ 2 files changed, 53 insertions(+) create mode 100644 src/test/java/daybyquest/participant/application/GetQuestsServiceTest.java diff --git a/src/test/java/daybyquest/participant/application/GetQuestsServiceTest.java b/src/test/java/daybyquest/participant/application/GetQuestsServiceTest.java new file mode 100644 index 0000000..1a15d5d --- /dev/null +++ b/src/test/java/daybyquest/participant/application/GetQuestsServiceTest.java @@ -0,0 +1,47 @@ +package daybyquest.participant.application; + +import static daybyquest.participant.domain.ParticipantState.DOING; +import static daybyquest.support.fixture.BadgeFixtures.BADGE_1; +import static daybyquest.support.fixture.BadgeFixtures.BADGE_2; +import static daybyquest.support.fixture.BadgeFixtures.BADGE_3; +import static daybyquest.support.fixture.QuestFixtures.QUEST_1; +import static org.assertj.core.api.Assertions.assertThat; + +import daybyquest.quest.dto.response.MultipleQuestsResponse; +import daybyquest.quest.dto.response.QuestResponse; +import daybyquest.support.test.ServiceTest; +import java.util.List; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; + +public class GetQuestsServiceTest extends ServiceTest { + + @Autowired + private GetQuestsService getQuestsService; + + @Test + void 수행_중인_퀘스트를_조회한다() { + // given + final Long aliceId = ALICE를_저장한다(); + + final Long badge1Id = badges.save(BADGE_1.생성()).getId(); + final Long badge2Id = badges.save(BADGE_2.생성()).getId(); + final Long badge3Id = badges.save(BADGE_3.생성()).getId(); + + final Long quest1Id = quests.save(QUEST_1.세부사항이_설정된_일반_퀘스트_생성(badge1Id)).getId(); + final Long quest2Id = quests.save(QUEST_1.세부사항이_설정된_일반_퀘스트_생성(badge2Id)).getId(); + final Long quest3Id = quests.save(QUEST_1.세부사항이_설정된_일반_퀘스트_생성(badge3Id)).getId(); + + participants.saveWithUserIdAndQuestId(aliceId, quest1Id); + participants.saveWithUserIdAndQuestId(aliceId, quest2Id); + + final List expected = List.of(quest1Id, quest2Id); + + // when + final MultipleQuestsResponse response = getQuestsService.invoke(aliceId, DOING); + final List actual = response.quests().stream().map(QuestResponse::id).toList(); + + // then + assertThat(actual).containsExactlyInAnyOrderElementsOf(expected); + } +} diff --git a/src/test/java/daybyquest/support/fixture/QuestFixtures.java b/src/test/java/daybyquest/support/fixture/QuestFixtures.java index 4d032dc..54ba5a1 100644 --- a/src/test/java/daybyquest/support/fixture/QuestFixtures.java +++ b/src/test/java/daybyquest/support/fixture/QuestFixtures.java @@ -73,6 +73,12 @@ public enum QuestFixtures { return Quest.createNormalQuest(badge.getId(), imageDescription, 사진_목록(), badge.getImage()); } + public Quest 세부사항이_설정된_일반_퀘스트_생성(final Long badgeId) { + final Quest quest = 일반_퀘스트_생성(null, badgeId); + 세부사항을_설정한다(quest); + return quest; + } + public Quest 그룹_퀘스트_생성(final Long id, final Long groupId) { final Quest quest = Quest.createGroupQuest(groupId, imageDescription, 사진_목록(), 사진()); ReflectionTestUtils.setField(quest, "id", id); From a840c900eaff231558f7cb4b29dbdcf763bde037 Mon Sep 17 00:00:00 2001 From: vectorch Date: Tue, 26 Dec 2023 14:42:36 +0900 Subject: [PATCH 2/2] =?UTF-8?q?test:=20=ED=80=98=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=B0=B8=EC=97=AC=20=EB=8F=84=EB=A9=94=EC=9D=B8=20=EC=84=9C?= =?UTF-8?q?=EB=B9=84=EC=8A=A4=20=ED=85=8C=EC=8A=A4=ED=8A=B8=EB=A5=BC=20?= =?UTF-8?q?=EC=9E=91=EC=84=B1=ED=95=9C=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../participant/domain/Participants.java | 2 + .../application/ContinueQuestServiceTest.java | 73 ++++++++++++++++++ .../DeleteParticipantServiceTest.java | 47 ++++++++++++ .../application/FinishQuestServiceTest.java | 76 +++++++++++++++++++ .../SaveParticipantServiceTest.java | 27 +++++++ .../application/TakeRewardServiceTest.java | 69 +++++++++++++++++ .../daybyquest/support/test/ServiceTest.java | 10 +++ 7 files changed, 304 insertions(+) create mode 100644 src/test/java/daybyquest/participant/application/ContinueQuestServiceTest.java create mode 100644 src/test/java/daybyquest/participant/application/DeleteParticipantServiceTest.java create mode 100644 src/test/java/daybyquest/participant/application/FinishQuestServiceTest.java create mode 100644 src/test/java/daybyquest/participant/application/SaveParticipantServiceTest.java create mode 100644 src/test/java/daybyquest/participant/application/TakeRewardServiceTest.java diff --git a/src/main/java/daybyquest/participant/domain/Participants.java b/src/main/java/daybyquest/participant/domain/Participants.java index e3ad78f..00b5b3f 100644 --- a/src/main/java/daybyquest/participant/domain/Participants.java +++ b/src/main/java/daybyquest/participant/domain/Participants.java @@ -13,6 +13,7 @@ import daybyquest.user.domain.User; import daybyquest.user.domain.Users; import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; @Component public class Participants { @@ -85,6 +86,7 @@ public void validateCountByUserId(final Long userId) { } } + @Transactional public void increaseLinkedCount(final Long userId, final Long questId) { final Participant participant = getByUserIdAndQuestId(userId, questId); participant.increaseLinkedCount(); diff --git a/src/test/java/daybyquest/participant/application/ContinueQuestServiceTest.java b/src/test/java/daybyquest/participant/application/ContinueQuestServiceTest.java new file mode 100644 index 0000000..05e8505 --- /dev/null +++ b/src/test/java/daybyquest/participant/application/ContinueQuestServiceTest.java @@ -0,0 +1,73 @@ +package daybyquest.participant.application; + +import static daybyquest.global.error.ExceptionCode.NOT_CONTINUABLE_QUEST; +import static daybyquest.participant.domain.ParticipantState.CONTINUE; +import static daybyquest.support.fixture.BadgeFixtures.BADGE_1; +import static daybyquest.support.fixture.QuestFixtures.QUEST_1; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import daybyquest.global.error.exception.InvalidDomainException; +import daybyquest.participant.domain.Participant; +import daybyquest.support.test.ServiceTest; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; + +public class ContinueQuestServiceTest extends ServiceTest { + + @Autowired + private TakeRewardService takeRewardService; + + @Autowired + private ContinueQuestService continueQuestService; + + @Test + void 퀘스트를_계속한다() { + // given + final Long aliceId = ALICE를_저장한다(); + final Long badgeId = badges.save(BADGE_1.생성()).getId(); + final Long questId = quests.save(QUEST_1.세부사항이_설정된_일반_퀘스트_생성(badgeId)).getId(); + participants.saveWithUserIdAndQuestId(aliceId, questId); + 퀘스트를_수행한다(aliceId, questId, QUEST_1.rewardCount); + takeRewardService.invoke(aliceId, questId); + + // when + continueQuestService.invoke(aliceId, questId); + final Participant actual = participants.getByUserIdAndQuestId(aliceId, questId); + + // then + assertThat(actual.getState()).isEqualTo(CONTINUE); + } + + @Test + void 이미_계속_수행_중인_퀘스트를_계속할_수_없다() { + // given + final Long aliceId = ALICE를_저장한다(); + final Long badgeId = badges.save(BADGE_1.생성()).getId(); + final Long questId = quests.save(QUEST_1.세부사항이_설정된_일반_퀘스트_생성(badgeId)).getId(); + participants.saveWithUserIdAndQuestId(aliceId, questId); + 퀘스트를_수행한다(aliceId, questId, QUEST_1.rewardCount); + takeRewardService.invoke(aliceId, questId); + continueQuestService.invoke(aliceId, questId); + + // when & then + assertThatThrownBy(() -> continueQuestService.invoke(aliceId, questId)) + .isInstanceOf(InvalidDomainException.class) + .hasMessageContaining(NOT_CONTINUABLE_QUEST.getMessage()); + } + + @Test + void 보상을_받지_않은_퀘스트를_계속_할_수_없다() { + // given + final Long aliceId = ALICE를_저장한다(); + final Long badgeId = badges.save(BADGE_1.생성()).getId(); + final Long questId = quests.save(QUEST_1.세부사항이_설정된_일반_퀘스트_생성(badgeId)).getId(); + participants.saveWithUserIdAndQuestId(aliceId, questId); + 퀘스트를_수행한다(aliceId, questId, QUEST_1.rewardCount); + + // when & then + assertThatThrownBy(() -> continueQuestService.invoke(aliceId, questId)) + .isInstanceOf(InvalidDomainException.class) + .hasMessageContaining(NOT_CONTINUABLE_QUEST.getMessage()); + } +} diff --git a/src/test/java/daybyquest/participant/application/DeleteParticipantServiceTest.java b/src/test/java/daybyquest/participant/application/DeleteParticipantServiceTest.java new file mode 100644 index 0000000..5e1ab03 --- /dev/null +++ b/src/test/java/daybyquest/participant/application/DeleteParticipantServiceTest.java @@ -0,0 +1,47 @@ +package daybyquest.participant.application; + +import static daybyquest.global.error.ExceptionCode.NOT_ACCEPTED_QUEST; +import static daybyquest.support.fixture.BadgeFixtures.BADGE_1; +import static daybyquest.support.fixture.QuestFixtures.QUEST_1; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import daybyquest.global.error.exception.InvalidDomainException; +import daybyquest.support.test.ServiceTest; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; + +public class DeleteParticipantServiceTest extends ServiceTest { + + @Autowired + private DeleteParticipantService deleteParticipantService; + + @Test + void 퀘스트를_삭제한다() { + // given + final Long aliceId = ALICE를_저장한다(); + final Long badgeId = badges.save(BADGE_1.생성()).getId(); + final Long questId = quests.save(QUEST_1.세부사항이_설정된_일반_퀘스트_생성(badgeId)).getId(); + participants.saveWithUserIdAndQuestId(aliceId, questId); + + // when + deleteParticipantService.invoke(aliceId, questId); + + // then + assertThatThrownBy(() -> participants.getByUserIdAndQuestId(aliceId, questId)) + .isInstanceOf(InvalidDomainException.class) + .hasMessageContaining(NOT_ACCEPTED_QUEST.getMessage()); + } + + @Test + void 수락한_적이_없는_퀘스트는_삭제할_수_없다() { + // given + final Long aliceId = ALICE를_저장한다(); + final Long badgeId = badges.save(BADGE_1.생성()).getId(); + final Long questId = quests.save(QUEST_1.세부사항이_설정된_일반_퀘스트_생성(badgeId)).getId(); + + // when & then + assertThatThrownBy(() -> deleteParticipantService.invoke(aliceId, questId)) + .isInstanceOf(InvalidDomainException.class) + .hasMessageContaining(NOT_ACCEPTED_QUEST.getMessage()); + } +} diff --git a/src/test/java/daybyquest/participant/application/FinishQuestServiceTest.java b/src/test/java/daybyquest/participant/application/FinishQuestServiceTest.java new file mode 100644 index 0000000..7c6739d --- /dev/null +++ b/src/test/java/daybyquest/participant/application/FinishQuestServiceTest.java @@ -0,0 +1,76 @@ +package daybyquest.participant.application; + +import static daybyquest.global.error.ExceptionCode.NOT_FINISHABLE_QUEST; +import static daybyquest.participant.domain.ParticipantState.FINISHED; +import static daybyquest.support.fixture.BadgeFixtures.BADGE_1; +import static daybyquest.support.fixture.QuestFixtures.QUEST_1; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import daybyquest.global.error.exception.InvalidDomainException; +import daybyquest.participant.domain.Participant; +import daybyquest.support.test.ServiceTest; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; + +public class FinishQuestServiceTest extends ServiceTest { + + @Autowired + private FinishQuestService finishQuestService; + + @Autowired + private TakeRewardService takeRewardService; + + @Autowired + private ContinueQuestService continueQuestService; + + @Test + void 퀘스트를_끝낸다() { + // given + final Long aliceId = ALICE를_저장한다(); + final Long badgeId = badges.save(BADGE_1.생성()).getId(); + final Long questId = quests.save(QUEST_1.세부사항이_설정된_일반_퀘스트_생성(badgeId)).getId(); + participants.saveWithUserIdAndQuestId(aliceId, questId); + 퀘스트를_수행한다(aliceId, questId, QUEST_1.rewardCount); + takeRewardService.invoke(aliceId, questId); + continueQuestService.invoke(aliceId, questId); + + // when + finishQuestService.invoke(aliceId, questId); + final Participant actual = participants.getByUserIdAndQuestId(aliceId, questId); + + // then + assertThat(actual.getState()).isEqualTo(FINISHED); + } + + @Test + void 이미_끝낸_퀘스트를_끝낼_수_없다() { + // given + final Long aliceId = ALICE를_저장한다(); + final Long badgeId = badges.save(BADGE_1.생성()).getId(); + final Long questId = quests.save(QUEST_1.세부사항이_설정된_일반_퀘스트_생성(badgeId)).getId(); + participants.saveWithUserIdAndQuestId(aliceId, questId); + 퀘스트를_수행한다(aliceId, questId, QUEST_1.rewardCount); + takeRewardService.invoke(aliceId, questId); + + // when & then + assertThatThrownBy(() -> finishQuestService.invoke(aliceId, questId)) + .isInstanceOf(InvalidDomainException.class) + .hasMessageContaining(NOT_FINISHABLE_QUEST.getMessage()); + } + + @Test + void 보상을_받지_않은_퀘스트를_끝낼_수_없다() { + // given + final Long aliceId = ALICE를_저장한다(); + final Long badgeId = badges.save(BADGE_1.생성()).getId(); + final Long questId = quests.save(QUEST_1.세부사항이_설정된_일반_퀘스트_생성(badgeId)).getId(); + participants.saveWithUserIdAndQuestId(aliceId, questId); + 퀘스트를_수행한다(aliceId, questId, QUEST_1.rewardCount); + + // when & then + assertThatThrownBy(() -> finishQuestService.invoke(aliceId, questId)) + .isInstanceOf(InvalidDomainException.class) + .hasMessageContaining(NOT_FINISHABLE_QUEST.getMessage()); + } +} diff --git a/src/test/java/daybyquest/participant/application/SaveParticipantServiceTest.java b/src/test/java/daybyquest/participant/application/SaveParticipantServiceTest.java new file mode 100644 index 0000000..5e474a5 --- /dev/null +++ b/src/test/java/daybyquest/participant/application/SaveParticipantServiceTest.java @@ -0,0 +1,27 @@ +package daybyquest.participant.application; + +import static daybyquest.support.fixture.BadgeFixtures.BADGE_1; +import static daybyquest.support.fixture.QuestFixtures.QUEST_1; +import static org.assertj.core.api.Assertions.assertThatCode; + +import daybyquest.support.test.ServiceTest; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; + +public class SaveParticipantServiceTest extends ServiceTest { + + @Autowired + private SaveParticipantService saveParticipantService; + + @Test + void 퀘스트를_수락한다() { + // given + final Long aliceId = ALICE를_저장한다(); + final Long badgeId = badges.save(BADGE_1.생성()).getId(); + final Long questId = quests.save(QUEST_1.세부사항이_설정된_일반_퀘스트_생성(badgeId)).getId(); + + // when & then + assertThatCode(() -> saveParticipantService.invoke(aliceId, questId)) + .doesNotThrowAnyException(); + } +} diff --git a/src/test/java/daybyquest/participant/application/TakeRewardServiceTest.java b/src/test/java/daybyquest/participant/application/TakeRewardServiceTest.java new file mode 100644 index 0000000..a424b3d --- /dev/null +++ b/src/test/java/daybyquest/participant/application/TakeRewardServiceTest.java @@ -0,0 +1,69 @@ +package daybyquest.participant.application; + +import static daybyquest.global.error.ExceptionCode.ALREADY_REWARDED_QUEST; +import static daybyquest.global.error.ExceptionCode.NOT_FINISHABLE_QUEST; +import static daybyquest.participant.domain.ParticipantState.FINISHED; +import static daybyquest.support.fixture.BadgeFixtures.BADGE_1; +import static daybyquest.support.fixture.QuestFixtures.QUEST_1; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import daybyquest.global.error.exception.InvalidDomainException; +import daybyquest.participant.domain.Participant; +import daybyquest.support.test.ServiceTest; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; + +public class TakeRewardServiceTest extends ServiceTest { + + @Autowired + private TakeRewardService takeRewardService; + + @Test + void 퀘스트_보상을_받는다() { + // given + final Long aliceId = ALICE를_저장한다(); + final Long badgeId = badges.save(BADGE_1.생성()).getId(); + final Long questId = quests.save(QUEST_1.세부사항이_설정된_일반_퀘스트_생성(badgeId)).getId(); + participants.saveWithUserIdAndQuestId(aliceId, questId); + 퀘스트를_수행한다(aliceId, questId, QUEST_1.rewardCount); + + // when + takeRewardService.invoke(aliceId, questId); + final Participant actual = participants.getByUserIdAndQuestId(aliceId, questId); + + // then + assertThat(actual.getState()).isEqualTo(FINISHED); + } + + @Test + void 수행_횟수가_충분하지_않으면_보상을_받을_수_없다() { + // given + final Long aliceId = ALICE를_저장한다(); + final Long badgeId = badges.save(BADGE_1.생성()).getId(); + final Long questId = quests.save(QUEST_1.세부사항이_설정된_일반_퀘스트_생성(badgeId)).getId(); + participants.saveWithUserIdAndQuestId(aliceId, questId); + 퀘스트를_수행한다(aliceId, questId, QUEST_1.rewardCount - 1); + + // when & then + assertThatThrownBy(() -> takeRewardService.invoke(aliceId, questId)) + .isInstanceOf(InvalidDomainException.class) + .hasMessageContaining(NOT_FINISHABLE_QUEST.getMessage()); + } + + @Test + void 이미_보상을_받았다면_받을_수_없다() { + // given + final Long aliceId = ALICE를_저장한다(); + final Long badgeId = badges.save(BADGE_1.생성()).getId(); + final Long questId = quests.save(QUEST_1.세부사항이_설정된_일반_퀘스트_생성(badgeId)).getId(); + participants.saveWithUserIdAndQuestId(aliceId, questId); + 퀘스트를_수행한다(aliceId, questId, QUEST_1.rewardCount); + takeRewardService.invoke(aliceId, questId); + + // when & then + assertThatThrownBy(() -> takeRewardService.invoke(aliceId, questId)) + .isInstanceOf(InvalidDomainException.class) + .hasMessageContaining(ALREADY_REWARDED_QUEST.getMessage()); + } +} diff --git a/src/test/java/daybyquest/support/test/ServiceTest.java b/src/test/java/daybyquest/support/test/ServiceTest.java index 7054e18..b7ce0c4 100644 --- a/src/test/java/daybyquest/support/test/ServiceTest.java +++ b/src/test/java/daybyquest/support/test/ServiceTest.java @@ -7,6 +7,7 @@ import static daybyquest.support.fixture.UserFixtures.DAVID; import daybyquest.badge.domain.Badges; +import daybyquest.badge.domain.Ownings; import daybyquest.global.query.NoOffsetIdPage; import daybyquest.group.domain.GroupUsers; import daybyquest.group.domain.Groups; @@ -67,6 +68,9 @@ public class ServiceTest { @Autowired protected Follows follows; + @Autowired + protected Ownings ownings; + @MockBean protected DateTimeProvider dataTimeProvider; @@ -121,6 +125,12 @@ void cleanDatabase() { return users.save(DARTH.생성()).getId(); } + protected void 퀘스트를_수행한다(final Long userId, final Long qusetId, final Long count) { + for (int index = 1; index <= count; index++) { + participants.increaseLinkedCount(userId, qusetId); + } + } + protected NoOffsetIdPage 페이지() { return new NoOffsetIdPage(null, 5); }