diff --git a/src/main/java/daybyquest/participant/domain/Participants.java b/src/main/java/daybyquest/participant/domain/Participants.java index d50a92d..e3ad78f 100644 --- a/src/main/java/daybyquest/participant/domain/Participants.java +++ b/src/main/java/daybyquest/participant/domain/Participants.java @@ -10,12 +10,15 @@ import daybyquest.group.domain.GroupUsers; import daybyquest.quest.domain.Quest; import daybyquest.quest.domain.Quests; +import daybyquest.user.domain.User; import daybyquest.user.domain.Users; import org.springframework.stereotype.Component; @Component public class Participants { + public static final int PROMOTE_THRESHOLD = 50; + private static final int MAX_DOING_COUNT = 15; private static final int MAX_CONTINUE_COUNT = 15; @@ -81,4 +84,13 @@ public void validateCountByUserId(final Long userId) { throw new InvalidDomainException(EXCEED_MAX_QUEST); } } + + public void increaseLinkedCount(final Long userId, final Long questId) { + final Participant participant = getByUserIdAndQuestId(userId, questId); + participant.increaseLinkedCount(); + if (participant.getLinkedCount() == PROMOTE_THRESHOLD) { + final User user = users.getById(userId); + user.promote(); + } + } } diff --git a/src/main/java/daybyquest/participant/listener/IncreaseLinkedCountListener.java b/src/main/java/daybyquest/participant/listener/IncreaseLinkedCountListener.java index 890a2b2..cb9e362 100644 --- a/src/main/java/daybyquest/participant/listener/IncreaseLinkedCountListener.java +++ b/src/main/java/daybyquest/participant/listener/IncreaseLinkedCountListener.java @@ -1,6 +1,5 @@ package daybyquest.participant.listener; -import daybyquest.participant.domain.Participant; import daybyquest.participant.domain.Participants; import daybyquest.post.domain.SuccessfullyPostLinkedEvent; import org.springframework.context.event.EventListener; @@ -19,8 +18,6 @@ public IncreaseLinkedCountListener(final Participants participants) { @Transactional @EventListener public void listenSuccessfullyPostLinkedEvent(final SuccessfullyPostLinkedEvent event) { - final Participant participant = participants.getByUserIdAndQuestId(event.getUserId(), - event.getQuestId()); - participant.increaseLinkedCount(); + participants.increaseLinkedCount(event.getUserId(), event.getQuestId()); } } diff --git a/src/main/java/daybyquest/user/domain/User.java b/src/main/java/daybyquest/user/domain/User.java index b5ec591..a0032fe 100644 --- a/src/main/java/daybyquest/user/domain/User.java +++ b/src/main/java/daybyquest/user/domain/User.java @@ -5,6 +5,9 @@ import static daybyquest.global.error.ExceptionCode.INVALID_USER_NAME; import static daybyquest.global.error.ExceptionCode.INVALID_USER_USERNAME; import static daybyquest.global.error.ExceptionCode.NOT_UPDATABLE_USER; +import static daybyquest.user.domain.UserState.ADMIN; +import static daybyquest.user.domain.UserState.MODERATOR; +import static daybyquest.user.domain.UserState.USER; import static jakarta.persistence.GenerationType.IDENTITY; import daybyquest.global.error.exception.InvalidDomainException; @@ -76,7 +79,7 @@ public User(String username, String email, String name, Image image) { this.email = email; this.name = name; this.image = image; - this.state = UserState.USER; + this.state = USER; this.visibility = UserVisibility.PUBLIC; this.interests = new ArrayList<>(); validate(); @@ -152,14 +155,20 @@ public void updateImage(Image image) { } public boolean isUser() { - return state == UserState.USER || state == UserState.MODERATOR; + return state == USER || state == MODERATOR; } public boolean isAdmin() { - return state == UserState.ADMIN; + return state == ADMIN; } public boolean isModerator() { - return state == UserState.MODERATOR; + return state == MODERATOR; + } + + public void promote() { + if (state == USER) { + this.state = MODERATOR; + } } } diff --git a/src/test/java/daybyquest/participant/domain/ParticipantsTest.java b/src/test/java/daybyquest/participant/domain/ParticipantsTest.java index 7cda571..6d8a1bb 100644 --- a/src/test/java/daybyquest/participant/domain/ParticipantsTest.java +++ b/src/test/java/daybyquest/participant/domain/ParticipantsTest.java @@ -3,6 +3,9 @@ import static daybyquest.participant.domain.ParticipantState.CONTINUE; import static daybyquest.participant.domain.ParticipantState.DOING; import static daybyquest.support.fixture.QuestFixtures.QUEST_1; +import static daybyquest.support.fixture.UserFixtures.BOB; +import static daybyquest.support.util.ParticipantUtils.게시물_연결_횟수를_지정한다; +import static daybyquest.user.domain.UserState.MODERATOR; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.junit.jupiter.api.Assertions.assertAll; @@ -14,6 +17,7 @@ import daybyquest.group.domain.GroupUsers; import daybyquest.quest.domain.Quest; import daybyquest.quest.domain.Quests; +import daybyquest.user.domain.User; import daybyquest.user.domain.Users; import java.util.Optional; import org.junit.jupiter.api.Test; @@ -228,4 +232,46 @@ public class ParticipantsTest { assertThatThrownBy(() -> participants.validateCountByUserId(userId)) .isInstanceOf(InvalidDomainException.class); } + + @Test + void 링크된_게시물_수를_증가시킨다() { + // given + final Long userId = 1L; + final Long questId = 2L; + final Quest quest = QUEST_1.일반_퀘스트_생성(questId, null); + QUEST_1.보상_없이_세부사항을_설정한다(quest); + final Participant participant = new Participant(userId, quest); + given(participantRepository.findByUserIdAndQuestId(userId, questId)) + .willReturn(Optional.of(participant)); + + // when + participants.increaseLinkedCount(userId, questId); + + // then + assertAll(() -> { + then(participantRepository).should().findByUserIdAndQuestId(userId, questId); + assertThat(participant.getLinkedCount()).isEqualTo(1L); + }); + } + + @Test + void 링크된_게시물_수가_50개가_되면_사용자를_승급시킨다() { + // given + final Long userId = 1L; + final Long questId = 2L; + final User user = BOB.생성(userId); + final Quest quest = QUEST_1.일반_퀘스트_생성(questId, null); + QUEST_1.보상_없이_세부사항을_설정한다(quest); + final Participant participant = new Participant(userId, quest); + 게시물_연결_횟수를_지정한다(participant, 49L); + given(participantRepository.findByUserIdAndQuestId(userId, questId)) + .willReturn(Optional.of(participant)); + given(users.getById(userId)).willReturn(user); + + // when + participants.increaseLinkedCount(userId, questId); + + // then + assertThat(user.getState()).isEqualTo(MODERATOR); + } }