Skip to content

Commit

Permalink
Merge pull request #169 from DayByQuest/test/participantService
Browse files Browse the repository at this point in the history
[Test] 퀘스트 참여 도메인 서비스 테스트를 작성한다
  • Loading branch information
vectorch9 authored Dec 26, 2023
2 parents c3257d4 + a840c90 commit 1a123f2
Show file tree
Hide file tree
Showing 9 changed files with 357 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/main/java/daybyquest/participant/domain/Participants.java
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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();
Expand Down
Original file line number Diff line number Diff line change
@@ -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());
}
}
Original file line number Diff line number Diff line change
@@ -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());
}
}
Original file line number Diff line number Diff line change
@@ -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());
}
}
Original file line number Diff line number Diff line change
@@ -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<Long> expected = List.of(quest1Id, quest2Id);

// when
final MultipleQuestsResponse response = getQuestsService.invoke(aliceId, DOING);
final List<Long> actual = response.quests().stream().map(QuestResponse::id).toList();

// then
assertThat(actual).containsExactlyInAnyOrderElementsOf(expected);
}
}
Original file line number Diff line number Diff line change
@@ -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();
}
}
Original file line number Diff line number Diff line change
@@ -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());
}
}
6 changes: 6 additions & 0 deletions src/test/java/daybyquest/support/fixture/QuestFixtures.java
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Loading

0 comments on commit 1a123f2

Please sign in to comment.