From e43688ad212ee6f28d54aeb357ab8543d6fbd40e Mon Sep 17 00:00:00 2001 From: jaeyeonkim Date: Sat, 24 Aug 2024 22:19:08 +0900 Subject: [PATCH 01/16] =?UTF-8?q?refactor:=20=ED=83=88=ED=87=B4=20?= =?UTF-8?q?=EB=B0=8F=20=EC=9D=B4=EC=9A=A9=EC=A0=9C=ED=95=9C=20=EA=B1=B8?= =?UTF-8?q?=EB=A6=B0=20=EC=B9=9C=EA=B5=AC=EB=8A=94=20=ED=88=AC=ED=91=9C?= =?UTF-8?q?=EB=A5=BC=20=EB=B0=9B=EC=9D=84=20=EC=88=98=20=EC=97=86=EB=8F=84?= =?UTF-8?q?=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kotlin/com/wespot/vote/VoteController.kt | 6 +-- .../com/wespot/user/port/out/UserPort.kt | 2 +- ...veVoteResponse.kt => SavedVoteResponse.kt} | 2 +- .../wespot/vote/port/in/SavedVoteUseCase.kt | 4 +- .../wespot/vote/service/SavedVoteService.kt | 41 ++++++++++--------- .../vote/service/helper/VoteServiceHelper.kt | 4 ++ .../src/main/kotlin/com/wespot/user/User.kt | 7 +++- .../src/main/kotlin/com/wespot/vote/Vote.kt | 27 +++++++++++- .../user/adapter/UserPersistenceAdapter.kt | 5 ++- .../user/repository/UserJpaRepository.kt | 9 +++- 10 files changed, 74 insertions(+), 33 deletions(-) rename core/src/main/kotlin/com/wespot/vote/dto/response/{SaveVoteResponse.kt => SavedVoteResponse.kt} (65%) diff --git a/app/src/main/kotlin/com/wespot/vote/VoteController.kt b/app/src/main/kotlin/com/wespot/vote/VoteController.kt index 08cf1f97..64b16fab 100644 --- a/app/src/main/kotlin/com/wespot/vote/VoteController.kt +++ b/app/src/main/kotlin/com/wespot/vote/VoteController.kt @@ -1,7 +1,7 @@ package com.wespot.vote import com.wespot.vote.dto.request.VoteRequests -import com.wespot.vote.dto.response.SaveVoteResponse +import com.wespot.vote.dto.response.SavedVoteResponse import com.wespot.vote.dto.response.VoteItems import com.wespot.vote.dto.response.received.ReceivedVoteResponse import com.wespot.vote.dto.response.received.ReceivedVotesResponses @@ -41,8 +41,8 @@ class VoteController( @PostMapping fun createVote( @RequestBody requests: VoteRequests - ): ResponseEntity { - val savedId: SaveVoteResponse = savedVoteUseCase.saveVote(requests) + ): ResponseEntity { + val savedId: SavedVoteResponse = savedVoteUseCase.saveVote(requests) return ResponseEntity.status(HttpStatus.CREATED) .body(savedId) } diff --git a/core/src/main/kotlin/com/wespot/user/port/out/UserPort.kt b/core/src/main/kotlin/com/wespot/user/port/out/UserPort.kt index 31b8eb67..528d25b2 100644 --- a/core/src/main/kotlin/com/wespot/user/port/out/UserPort.kt +++ b/core/src/main/kotlin/com/wespot/user/port/out/UserPort.kt @@ -21,7 +21,7 @@ interface UserPort { classNumber: Int ): List - fun findIdsByIdIn(ids: List): List + fun findByIdIn(ids: List): List fun findByEmail(userEmail: String): User? diff --git a/core/src/main/kotlin/com/wespot/vote/dto/response/SaveVoteResponse.kt b/core/src/main/kotlin/com/wespot/vote/dto/response/SavedVoteResponse.kt similarity index 65% rename from core/src/main/kotlin/com/wespot/vote/dto/response/SaveVoteResponse.kt rename to core/src/main/kotlin/com/wespot/vote/dto/response/SavedVoteResponse.kt index d8c7f932..4c7aa4be 100644 --- a/core/src/main/kotlin/com/wespot/vote/dto/response/SaveVoteResponse.kt +++ b/core/src/main/kotlin/com/wespot/vote/dto/response/SavedVoteResponse.kt @@ -1,5 +1,5 @@ package com.wespot.vote.dto.response -data class SaveVoteResponse( +data class SavedVoteResponse( val id: Long ) diff --git a/core/src/main/kotlin/com/wespot/vote/port/in/SavedVoteUseCase.kt b/core/src/main/kotlin/com/wespot/vote/port/in/SavedVoteUseCase.kt index 341ca830..b767fd13 100644 --- a/core/src/main/kotlin/com/wespot/vote/port/in/SavedVoteUseCase.kt +++ b/core/src/main/kotlin/com/wespot/vote/port/in/SavedVoteUseCase.kt @@ -1,13 +1,13 @@ package com.wespot.vote.port.`in` import com.wespot.vote.dto.request.VoteRequests -import com.wespot.vote.dto.response.SaveVoteResponse +import com.wespot.vote.dto.response.SavedVoteResponse import com.wespot.vote.dto.response.VoteItems interface SavedVoteUseCase { fun getVoteOptions(): VoteItems - fun saveVote(requests: VoteRequests): SaveVoteResponse + fun saveVote(requests: VoteRequests): SavedVoteResponse } diff --git a/core/src/main/kotlin/com/wespot/vote/service/SavedVoteService.kt b/core/src/main/kotlin/com/wespot/vote/service/SavedVoteService.kt index 87c28e0c..b4713ee7 100644 --- a/core/src/main/kotlin/com/wespot/vote/service/SavedVoteService.kt +++ b/core/src/main/kotlin/com/wespot/vote/service/SavedVoteService.kt @@ -7,7 +7,7 @@ import com.wespot.user.port.out.UserPort import com.wespot.vote.Vote import com.wespot.vote.dto.request.VoteRequest import com.wespot.vote.dto.request.VoteRequests -import com.wespot.vote.dto.response.SaveVoteResponse +import com.wespot.vote.dto.response.SavedVoteResponse import com.wespot.vote.dto.response.VoteItems import com.wespot.vote.event.ReceivedVoteEvent import com.wespot.vote.event.RegisteredVoteEvent @@ -46,28 +46,34 @@ class SavedVoteService( @Transactional override fun saveVote( requests: VoteRequests - ): SaveVoteResponse { - validateRequestsSize(requests.votes.size) - validateUserIdsInRequests(requests.votes) + ): SavedVoteResponse { + val receivers = getVotedUsers(requests.votes) val user = VoteServiceHelper.findLoginUser(userPort) val voteTime = LocalDateTime.now() val vote: Vote = VoteServiceHelper.findVoteByUser(votePort, user, voteTime.toLocalDate()) requests.votes .stream() - .forEach { request -> addBallot(request, vote, user, voteTime) } + .forEach { request -> + addBallot( + request, + vote, + user, + receivers.find { it.id == request.userId } + ?: throw CustomException(HttpStatus.BAD_REQUEST, ExceptionView.DIALOG, "투표 대상을 찾을 수 없습니다."), + voteTime) + } eventPublisher.publishEvent(RegisteredVoteEvent(user, vote)) - return SaveVoteResponse(votePort.save(vote).id) + return SavedVoteResponse(votePort.save(vote).id) } private fun addBallot( request: VoteRequest, vote: Vote, user: User, + receiver: User, voteTime: LocalDateTime ) { - val receiver = VoteServiceHelper.findUser(userPort, request.userId) - eventPublisher.publishEvent(ReceivedVoteEvent(receiver)) vote.addBallot( voteOptionId = request.voteOptionId, sender = user, @@ -76,22 +82,19 @@ class SavedVoteService( ) } - private fun validateRequestsSize(requestsSize: Int) { - if (5 < requestsSize) { - throw CustomException(HttpStatus.BAD_REQUEST, ExceptionView.TOAST, "투표는 한번에 최대 5명에게 할 수 있습니다.") - } - } - - private fun validateUserIdsInRequests(requests: List) { + private fun getVotedUsers(requests: List): List { + validateRequestsSize(requests.size) val userIds: List = requests.stream() .map { it.userId } .toList() - val foundUserIds = userPort.findIdsByIdIn(userIds) - if (foundUserIds.size == userIds.size) { - return + return userPort.findByIdIn(userIds) + } + + private fun validateRequestsSize(requestsSize: Int) { + if (5 < requestsSize) { + throw CustomException(HttpStatus.BAD_REQUEST, ExceptionView.TOAST, "투표는 한번에 최대 5명에게 할 수 있습니다.") } - throw CustomException(HttpStatus.BAD_REQUEST, ExceptionView.TOAST, "투표하고자 하는 회원이 존재하지 않습니다.") } } diff --git a/core/src/main/kotlin/com/wespot/vote/service/helper/VoteServiceHelper.kt b/core/src/main/kotlin/com/wespot/vote/service/helper/VoteServiceHelper.kt index 2700f2ac..ca4e0d8b 100644 --- a/core/src/main/kotlin/com/wespot/vote/service/helper/VoteServiceHelper.kt +++ b/core/src/main/kotlin/com/wespot/vote/service/helper/VoteServiceHelper.kt @@ -72,4 +72,8 @@ object VoteServiceHelper { ) } + fun findUsersByIds(userPort: UserPort, ids: List): List { + return userPort.findByIdIn(ids) + } + } diff --git a/domain/src/main/kotlin/com/wespot/user/User.kt b/domain/src/main/kotlin/com/wespot/user/User.kt index 9055cb2f..8ee2dd71 100644 --- a/domain/src/main/kotlin/com/wespot/user/User.kt +++ b/domain/src/main/kotlin/com/wespot/user/User.kt @@ -148,7 +148,8 @@ data class User( companion object { private const val WITHDRAW_USER_NAME = "탈퇴한 유저입니다." - private const val INIT_PROFILE_ICON_URL = "https://wespot-test-data.s3.ap-northeast-2.amazonaws.com/wespot_init_profile.png" + private const val INIT_PROFILE_ICON_URL = + "https://wespot-test-data.s3.ap-northeast-2.amazonaws.com/wespot_init_profile.png" fun create( email: String, @@ -260,4 +261,8 @@ data class User( && this.grade == otherUser.grade && this.classNumber == otherUser.classNumber + fun isKeepRestrict(): Boolean { + return restriction.isKeepRestriction() + } + } diff --git a/domain/src/main/kotlin/com/wespot/vote/Vote.kt b/domain/src/main/kotlin/com/wespot/vote/Vote.kt index 42ae43c1..56f9a3fa 100644 --- a/domain/src/main/kotlin/com/wespot/vote/Vote.kt +++ b/domain/src/main/kotlin/com/wespot/vote/Vote.kt @@ -3,7 +3,9 @@ package com.wespot.vote import com.wespot.exception.CustomException import com.wespot.exception.ExceptionView import com.wespot.user.User +import com.wespot.vote.event.ReceivedVoteEvent import com.wespot.voteoption.VoteOption +import org.springframework.data.domain.AbstractAggregateRoot import org.springframework.http.HttpStatus import java.time.LocalDate import java.time.LocalDateTime @@ -15,7 +17,7 @@ data class Vote( val voteNumber: Int, val voteOptionsByVoteDate: VoteOptionsByVoteDate, val ballots: Ballots, -) { +) : AbstractAggregateRoot() { companion object { private const val NUMBER_OF_VOTE_USERS = 5 @@ -89,6 +91,7 @@ data class Vote( return classmates.stream() .filter { !alreadyVotedByUser.contains(it.id) && isNotMe(it, user) } + .filter { it.withdrawalStatus != WithdrawalStatus.WITHDRAW || it.isKeepRestrict() } .toList() .shuffled() .take(NUMBER_OF_VOTE_USERS) @@ -104,7 +107,9 @@ data class Vote( ) { voteOptionsByVoteDate.validateVoteOption(voteOptionId) validateClassmate(sender) - validateClassmate(receiver) + validateReceiver(receiver) + registerEvent(ReceivedVoteEvent(receiver)) + ballots.add( Ballot.of( voteId = this.id, @@ -128,6 +133,24 @@ data class Vote( } } + private fun validateReceiver(receiver: User) { + validateClassmate(receiver) + if (receiver.withdrawalStatus == WithdrawalStatus.WITHDRAW) { + throw CustomException( + HttpStatus.BAD_REQUEST, + ExceptionView.TOAST, + "탈퇴한 학생에게 투표할 수 없습니다." + ) + } + if (receiver.isKeepRestrict()) { + throw CustomException( + HttpStatus.BAD_REQUEST, + ExceptionView.TOAST, + "이용제한을 받은 학생에게 투표할 수 없습니다." + ) + } + } + fun getBallots(): List { return ballots.ballots .map { it.value } diff --git a/infrastructure/mysql/src/main/kotlin/com/wespot/user/adapter/UserPersistenceAdapter.kt b/infrastructure/mysql/src/main/kotlin/com/wespot/user/adapter/UserPersistenceAdapter.kt index 72d915c2..ecee2d84 100644 --- a/infrastructure/mysql/src/main/kotlin/com/wespot/user/adapter/UserPersistenceAdapter.kt +++ b/infrastructure/mysql/src/main/kotlin/com/wespot/user/adapter/UserPersistenceAdapter.kt @@ -102,8 +102,9 @@ class UserPersistenceAdapter( .toList() } - override fun findIdsByIdIn(ids: List): List { - return userJpaRepository.findIdsByIdIn(ids) + override fun findByIdIn(ids: List): List { + return userJpaRepository.findByIdIn(ids) + .map { UserMapper.mapToDomainEntity(it) } } override fun findAll(): List { diff --git a/infrastructure/mysql/src/main/kotlin/com/wespot/user/repository/UserJpaRepository.kt b/infrastructure/mysql/src/main/kotlin/com/wespot/user/repository/UserJpaRepository.kt index d0cb5209..0f4ce72c 100644 --- a/infrastructure/mysql/src/main/kotlin/com/wespot/user/repository/UserJpaRepository.kt +++ b/infrastructure/mysql/src/main/kotlin/com/wespot/user/repository/UserJpaRepository.kt @@ -18,8 +18,7 @@ interface UserJpaRepository : JpaRepository { classNumber: Int ): List - @Query("SELECT u.id FROM UserJpaEntity u WHERE u.id IN :ids") - fun findIdsByIdIn(@Param("ids") ids: List): List + fun findByIdIn(ids: List): List fun existsBySchoolIdAndGradeAndClassNumber( schoolId: Long, @@ -48,6 +47,9 @@ interface UserJpaRepository : JpaRepository { END = :cursorSchoolTypeOrder AND u.id > :cursorId) ) ) + AND u.withdrawalStatus != 'WITHDRAWN' + AND u.restriction.messageRestrictionType = 'NONE' + AND u.restriction.voteRestrictionType = 'NONE' ORDER BY u.name ASC, s.name ASC, CASE WHEN s.schoolType = 'MIDDLE' THEN 1 @@ -86,6 +88,9 @@ interface UserJpaRepository : JpaRepository { END = :cursorSchoolTypeOrder AND u.id > :cursorId) ) ) + AND u.withdrawalStatus != 'WITHDRAWN' + AND u.restriction.messageRestrictionType = 'NONE' + AND u.restriction.voteRestrictionType = 'NONE' """ ) fun countUsersAfterCursor( From ba6147c6884e2e3f26757c4a125885f48ee64565 Mon Sep 17 00:00:00 2001 From: jaeyeonkim Date: Sat, 24 Aug 2024 22:28:22 +0900 Subject: [PATCH 02/16] =?UTF-8?q?refactor:=20=EC=BF=BC=EB=A6=AC=20?= =?UTF-8?q?=EC=9D=BC=EB=B6=80=20=EC=B5=9C=EC=A0=81=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wespot/vote/service/SavedVoteService.kt | 22 ++----------------- .../vote/service/helper/VoteServiceHelper.kt | 4 ---- .../src/main/kotlin/com/wespot/user/User.kt | 4 ++++ .../src/main/kotlin/com/wespot/vote/Vote.kt | 4 ++-- .../user/repository/UserJpaRepository.kt | 12 ++++++++++ 5 files changed, 20 insertions(+), 26 deletions(-) diff --git a/core/src/main/kotlin/com/wespot/vote/service/SavedVoteService.kt b/core/src/main/kotlin/com/wespot/vote/service/SavedVoteService.kt index b4713ee7..d85b4f6f 100644 --- a/core/src/main/kotlin/com/wespot/vote/service/SavedVoteService.kt +++ b/core/src/main/kotlin/com/wespot/vote/service/SavedVoteService.kt @@ -9,7 +9,6 @@ import com.wespot.vote.dto.request.VoteRequest import com.wespot.vote.dto.request.VoteRequests import com.wespot.vote.dto.response.SavedVoteResponse import com.wespot.vote.dto.response.VoteItems -import com.wespot.vote.event.ReceivedVoteEvent import com.wespot.vote.event.RegisteredVoteEvent import com.wespot.vote.port.`in`.SavedVoteUseCase import com.wespot.vote.port.out.VotePort @@ -52,11 +51,9 @@ class SavedVoteService( val voteTime = LocalDateTime.now() val vote: Vote = VoteServiceHelper.findVoteByUser(votePort, user, voteTime.toLocalDate()) requests.votes - .stream() .forEach { request -> - addBallot( - request, - vote, + vote.addBallot( + request.voteOptionId, user, receivers.find { it.id == request.userId } ?: throw CustomException(HttpStatus.BAD_REQUEST, ExceptionView.DIALOG, "투표 대상을 찾을 수 없습니다."), @@ -67,21 +64,6 @@ class SavedVoteService( return SavedVoteResponse(votePort.save(vote).id) } - private fun addBallot( - request: VoteRequest, - vote: Vote, - user: User, - receiver: User, - voteTime: LocalDateTime - ) { - vote.addBallot( - voteOptionId = request.voteOptionId, - sender = user, - receiver = receiver, - voteTime = voteTime - ) - } - private fun getVotedUsers(requests: List): List { validateRequestsSize(requests.size) val userIds: List = requests.stream() diff --git a/core/src/main/kotlin/com/wespot/vote/service/helper/VoteServiceHelper.kt b/core/src/main/kotlin/com/wespot/vote/service/helper/VoteServiceHelper.kt index ca4e0d8b..2700f2ac 100644 --- a/core/src/main/kotlin/com/wespot/vote/service/helper/VoteServiceHelper.kt +++ b/core/src/main/kotlin/com/wespot/vote/service/helper/VoteServiceHelper.kt @@ -72,8 +72,4 @@ object VoteServiceHelper { ) } - fun findUsersByIds(userPort: UserPort, ids: List): List { - return userPort.findByIdIn(ids) - } - } diff --git a/domain/src/main/kotlin/com/wespot/user/User.kt b/domain/src/main/kotlin/com/wespot/user/User.kt index 8ee2dd71..d13e4a25 100644 --- a/domain/src/main/kotlin/com/wespot/user/User.kt +++ b/domain/src/main/kotlin/com/wespot/user/User.kt @@ -265,4 +265,8 @@ data class User( return restriction.isKeepRestriction() } + fun isWithDraw(): Boolean { + return withdrawalStatus == WithdrawalStatus.WITHDRAW + } + } diff --git a/domain/src/main/kotlin/com/wespot/vote/Vote.kt b/domain/src/main/kotlin/com/wespot/vote/Vote.kt index 56f9a3fa..3f67f643 100644 --- a/domain/src/main/kotlin/com/wespot/vote/Vote.kt +++ b/domain/src/main/kotlin/com/wespot/vote/Vote.kt @@ -91,7 +91,7 @@ data class Vote( return classmates.stream() .filter { !alreadyVotedByUser.contains(it.id) && isNotMe(it, user) } - .filter { it.withdrawalStatus != WithdrawalStatus.WITHDRAW || it.isKeepRestrict() } + .filter { it.isWithDraw() || it.isKeepRestrict() } .toList() .shuffled() .take(NUMBER_OF_VOTE_USERS) @@ -135,7 +135,7 @@ data class Vote( private fun validateReceiver(receiver: User) { validateClassmate(receiver) - if (receiver.withdrawalStatus == WithdrawalStatus.WITHDRAW) { + if (receiver.isWithDraw()) { throw CustomException( HttpStatus.BAD_REQUEST, ExceptionView.TOAST, diff --git a/infrastructure/mysql/src/main/kotlin/com/wespot/user/repository/UserJpaRepository.kt b/infrastructure/mysql/src/main/kotlin/com/wespot/user/repository/UserJpaRepository.kt index 0f4ce72c..98a6691a 100644 --- a/infrastructure/mysql/src/main/kotlin/com/wespot/user/repository/UserJpaRepository.kt +++ b/infrastructure/mysql/src/main/kotlin/com/wespot/user/repository/UserJpaRepository.kt @@ -12,6 +12,18 @@ interface UserJpaRepository : JpaRepository { fun findByEmail(email: String): UserJpaEntity? + @Query( + """ + SELECT u + FROM UserJpaEntity u + WHERE u.schoolId = :schoolId + AND u.grade = :grade + AND u.classNumber = :classNumber + AND u.withdrawalStatus != 'WITHDRAWN' + AND u.restriction.messageRestrictionType = 'NONE' + AND u.restriction.voteRestrictionType = 'NONE' + """ + ) fun findAllBySchoolIdAndGradeAndClassNumber( schoolId: Long, grade: Int, From 76fc2884224118520f0bab7aab84a0225f7f83b8 Mon Sep 17 00:00:00 2001 From: jaeyeonkim Date: Sat, 24 Aug 2024 22:39:02 +0900 Subject: [PATCH 03/16] =?UTF-8?q?refactor:=20=EA=B7=9C=EC=A0=9C=EB=A5=BC?= =?UTF-8?q?=20=EB=8B=B9=ED=95=9C=20=EC=9C=A0=EC=A0=80=EB=8A=94=20=ED=95=B4?= =?UTF-8?q?=EB=8B=B9=20=EC=84=9C=EB=B9=84=EC=8A=A4=20=EC=82=AC=EC=9A=A9?= =?UTF-8?q?=ED=95=A0=20=EC=88=98=20=EC=97=86=EB=8F=84=EB=A1=9D=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kotlin/com/wespot/vote/service/SavedVoteService.kt | 10 +++++++++- domain/src/main/kotlin/com/wespot/user/User.kt | 4 ++++ domain/src/main/kotlin/com/wespot/vote/Vote.kt | 5 +++-- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/core/src/main/kotlin/com/wespot/vote/service/SavedVoteService.kt b/core/src/main/kotlin/com/wespot/vote/service/SavedVoteService.kt index d85b4f6f..2367de0d 100644 --- a/core/src/main/kotlin/com/wespot/vote/service/SavedVoteService.kt +++ b/core/src/main/kotlin/com/wespot/vote/service/SavedVoteService.kt @@ -30,6 +30,7 @@ class SavedVoteService( @Transactional(readOnly = true) override fun getVoteOptions(): VoteItems { val user = VoteServiceHelper.findLoginUser(userPort) + validateLoginUserRegulation(user) val classmates = VoteServiceHelper.findClassmatesByUser(userPort, user) val today = LocalDate.now() @@ -42,12 +43,19 @@ class SavedVoteService( ) } + private fun validateLoginUserRegulation(user: User) { + if (user.isRegulation()) { + throw CustomException(HttpStatus.FORBIDDEN, ExceptionView.TOAST, "규제를 당한 유저는 해당 서비스를 사용할 수 없습니다.") + } + } + @Transactional override fun saveVote( requests: VoteRequests ): SavedVoteResponse { - val receivers = getVotedUsers(requests.votes) val user = VoteServiceHelper.findLoginUser(userPort) + validateLoginUserRegulation(user) + val receivers = getVotedUsers(requests.votes) val voteTime = LocalDateTime.now() val vote: Vote = VoteServiceHelper.findVoteByUser(votePort, user, voteTime.toLocalDate()) requests.votes diff --git a/domain/src/main/kotlin/com/wespot/user/User.kt b/domain/src/main/kotlin/com/wespot/user/User.kt index d13e4a25..1b8ab718 100644 --- a/domain/src/main/kotlin/com/wespot/user/User.kt +++ b/domain/src/main/kotlin/com/wespot/user/User.kt @@ -269,4 +269,8 @@ data class User( return withdrawalStatus == WithdrawalStatus.WITHDRAW } + fun isRegulation(): Boolean { + return isWithDraw() || isKeepRestrict() + } + } diff --git a/domain/src/main/kotlin/com/wespot/vote/Vote.kt b/domain/src/main/kotlin/com/wespot/vote/Vote.kt index 3f67f643..6a753567 100644 --- a/domain/src/main/kotlin/com/wespot/vote/Vote.kt +++ b/domain/src/main/kotlin/com/wespot/vote/Vote.kt @@ -91,7 +91,7 @@ data class Vote( return classmates.stream() .filter { !alreadyVotedByUser.contains(it.id) && isNotMe(it, user) } - .filter { it.isWithDraw() || it.isKeepRestrict() } + .filter { it.isRegulation() } .toList() .shuffled() .take(NUMBER_OF_VOTE_USERS) @@ -108,7 +108,6 @@ data class Vote( voteOptionsByVoteDate.validateVoteOption(voteOptionId) validateClassmate(sender) validateReceiver(receiver) - registerEvent(ReceivedVoteEvent(receiver)) ballots.add( Ballot.of( @@ -120,6 +119,8 @@ data class Vote( voteTime = voteTime ) ) + + registerEvent(ReceivedVoteEvent(receiver)) } private fun validateClassmate(user: User) { From 189268f12d3740c698306ae266b6bc38ebf234bf Mon Sep 17 00:00:00 2001 From: jaeyeonkim Date: Sat, 24 Aug 2024 22:43:34 +0900 Subject: [PATCH 04/16] =?UTF-8?q?refactor:=20=EC=A0=9C=EC=9E=AC=EB=A5=BC?= =?UTF-8?q?=20=EB=8B=B9=ED=95=9C=20=EC=9C=A0=EC=A0=80=EB=8A=94=20=EA=B2=80?= =?UTF-8?q?=EC=83=89=EC=9D=84=20=ED=95=A0=20=EC=88=98=20=EC=97=86=EB=8F=84?= =?UTF-8?q?=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kotlin/com/wespot/user/service/SearchUserService.kt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/core/src/main/kotlin/com/wespot/user/service/SearchUserService.kt b/core/src/main/kotlin/com/wespot/user/service/SearchUserService.kt index 0e66c51d..8f033534 100644 --- a/core/src/main/kotlin/com/wespot/user/service/SearchUserService.kt +++ b/core/src/main/kotlin/com/wespot/user/service/SearchUserService.kt @@ -1,5 +1,6 @@ package com.wespot.user.service +import com.wespot.auth.service.SecurityUtils import com.wespot.exception.CustomException import com.wespot.exception.ExceptionView import com.wespot.school.School @@ -27,6 +28,7 @@ class SearchUserService( keyword: String, cursorId: Long ): UserListResponse { + validateLoginUserRegulation() val pageable = PageRequest.of(0, 10, Sort.by("id")) if (cursorId == 0L) { @@ -54,6 +56,13 @@ class SearchUserService( return buildUserListResponse(users = users, pageable = pageable, totalCount = totalCount) } + private fun validateLoginUserRegulation() { + val loginUser = SecurityUtils.getLoginUser(userPort) + if (loginUser.isRegulation()) { + throw CustomException(HttpStatus.FORBIDDEN, ExceptionView.TOAST, "규제를 당한 유저는 해당 서비스를 사용할 수 없습니다.") + } + } + private fun fetchFirstPage( keyword: String, pageable: Pageable From 0bbd7e962779660a522535702960afc56617ceab Mon Sep 17 00:00:00 2001 From: jaeyeonkim Date: Sat, 24 Aug 2024 23:10:47 +0900 Subject: [PATCH 05/16] =?UTF-8?q?feat:=20Message=20=EA=B4=80=EB=A0=A8?= =?UTF-8?q?=ED=95=98=EC=97=AC=20=ED=83=88=ED=87=B4=20=ED=98=B9=EC=9D=80=20?= =?UTF-8?q?=EA=B7=9C=EC=A0=9C=EB=A5=BC=20=EB=8B=B9=ED=95=9C=20=EC=9C=A0?= =?UTF-8?q?=EC=A0=80=EA=B0=80=20=EC=84=9C=EB=B9=84=EC=8A=A4=EB=A5=BC=20?= =?UTF-8?q?=EC=82=AC=EC=9A=A9=ED=95=A0=20=EC=88=98=20=EC=97=86=EB=8F=84?= =?UTF-8?q?=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../message/schedule/MessageScheduler.kt | 1 + .../message/service/SendMessageService.kt | 4 +-- .../wespot/vote/service/SavedVoteService.kt | 8 ----- .../main/kotlin/com/wespot/message/Message.kt | 29 +++++++++++++++--- .../src/main/kotlin/com/wespot/vote/Vote.kt | 30 +++++++++---------- 5 files changed, 43 insertions(+), 29 deletions(-) diff --git a/app/src/main/kotlin/com/wespot/message/schedule/MessageScheduler.kt b/app/src/main/kotlin/com/wespot/message/schedule/MessageScheduler.kt index fb247656..7c0e6ae1 100644 --- a/app/src/main/kotlin/com/wespot/message/schedule/MessageScheduler.kt +++ b/app/src/main/kotlin/com/wespot/message/schedule/MessageScheduler.kt @@ -14,4 +14,5 @@ class MessageScheduler( fun scheduleMessageUpdate() { schedulerMessageUseCase.sendScheduledMessages() } + } diff --git a/core/src/main/kotlin/com/wespot/message/service/SendMessageService.kt b/core/src/main/kotlin/com/wespot/message/service/SendMessageService.kt index 6ee61c39..ec50768e 100644 --- a/core/src/main/kotlin/com/wespot/message/service/SendMessageService.kt +++ b/core/src/main/kotlin/com/wespot/message/service/SendMessageService.kt @@ -39,8 +39,8 @@ class SendMessageService( val sendMessage = Message.sendMessage( content = sendMessageRequest.content, - receiverId = receiver.id, - senderId = loginUser.id, + receiver = receiver, + sender = loginUser, senderName = sendMessageRequest.senderName, isAnonymous = sendMessageRequest.isAnonymous ) diff --git a/core/src/main/kotlin/com/wespot/vote/service/SavedVoteService.kt b/core/src/main/kotlin/com/wespot/vote/service/SavedVoteService.kt index 2367de0d..815a1f80 100644 --- a/core/src/main/kotlin/com/wespot/vote/service/SavedVoteService.kt +++ b/core/src/main/kotlin/com/wespot/vote/service/SavedVoteService.kt @@ -30,7 +30,6 @@ class SavedVoteService( @Transactional(readOnly = true) override fun getVoteOptions(): VoteItems { val user = VoteServiceHelper.findLoginUser(userPort) - validateLoginUserRegulation(user) val classmates = VoteServiceHelper.findClassmatesByUser(userPort, user) val today = LocalDate.now() @@ -43,18 +42,11 @@ class SavedVoteService( ) } - private fun validateLoginUserRegulation(user: User) { - if (user.isRegulation()) { - throw CustomException(HttpStatus.FORBIDDEN, ExceptionView.TOAST, "규제를 당한 유저는 해당 서비스를 사용할 수 없습니다.") - } - } - @Transactional override fun saveVote( requests: VoteRequests ): SavedVoteResponse { val user = VoteServiceHelper.findLoginUser(userPort) - validateLoginUserRegulation(user) val receivers = getVotedUsers(requests.votes) val voteTime = LocalDateTime.now() val vote: Vote = VoteServiceHelper.findVoteByUser(votePort, user, voteTime.toLocalDate()) diff --git a/domain/src/main/kotlin/com/wespot/message/Message.kt b/domain/src/main/kotlin/com/wespot/message/Message.kt index c8b5af52..b46dbd2d 100644 --- a/domain/src/main/kotlin/com/wespot/message/Message.kt +++ b/domain/src/main/kotlin/com/wespot/message/Message.kt @@ -36,6 +36,7 @@ data class Message( receiverId: Long, senderName: String ): Message { + validateRegulationUser(modifier) validateMessageOwner(modifier) require(senderId != receiverId) { throw CustomException( @@ -250,19 +251,21 @@ data class Message( fun sendMessage( content: String, - receiverId: Long, - senderId: Long, + receiver: User, + sender: User, senderName: String, isAnonymous: Boolean ): Message { + validateRegulationUser(sender) + validateRegulationUser(receiver) validateMessageSendTime() val message = Message( id = 0L, content = MessageContent.from(content), - senderId = senderId, + senderId = sender.id, senderName = senderName, messageType = MessageType.SENT, - receiverId = receiverId, + receiverId = receiver.id, isAnonymous = isAnonymous, isReceiverRead = false, readAt = null, @@ -309,5 +312,23 @@ data class Message( receiverDeletedAt = null ) } + + private fun validateRegulationUser(user: User) { + if (user.isWithDraw()) { + throw CustomException( + HttpStatus.BAD_REQUEST, + ExceptionView.TOAST, + "탈퇴한 학생은 해당 서비스를 이용할 수 없습니다." + ) + } + if (user.isKeepRestrict()) { + throw CustomException( + HttpStatus.BAD_REQUEST, + ExceptionView.TOAST, + "이용제한을 당한 학생은 해당 서비스를 이용할 수 없습니다." + ) + } + } + } } diff --git a/domain/src/main/kotlin/com/wespot/vote/Vote.kt b/domain/src/main/kotlin/com/wespot/vote/Vote.kt index 6a753567..33c14f3f 100644 --- a/domain/src/main/kotlin/com/wespot/vote/Vote.kt +++ b/domain/src/main/kotlin/com/wespot/vote/Vote.kt @@ -85,7 +85,7 @@ data class Vote( fun findUsersForVote(classmates: List, user: User): List { - validateClassmate(user) + validateUser(user) classmates.forEach { validateClassmate(it) } val alreadyVotedByUser: List = ballots.findUserIdsVotedByUser(user.id) @@ -106,8 +106,8 @@ data class Vote( voteTime: LocalDateTime ) { voteOptionsByVoteDate.validateVoteOption(voteOptionId) - validateClassmate(sender) - validateReceiver(receiver) + validateUser(sender) + validateUser(receiver) ballots.add( Ballot.of( @@ -123,31 +123,31 @@ data class Vote( registerEvent(ReceivedVoteEvent(receiver)) } - private fun validateClassmate(user: User) { - val userVoteIdentifier = VoteIdentifier.of(user, voteIdentifier.date) - require(voteIdentifier.isSameClass(userVoteIdentifier)) { + private fun validateUser(user: User) { + validateClassmate(user) + if (user.isWithDraw()) { throw CustomException( HttpStatus.BAD_REQUEST, ExceptionView.TOAST, - "다른 반의 학생이(을) 투표할 수 없습니다." + "탈퇴한 학생은 해당 서비스를 이용할 수 없습니다." ) } - } - - private fun validateReceiver(receiver: User) { - validateClassmate(receiver) - if (receiver.isWithDraw()) { + if (user.isKeepRestrict()) { throw CustomException( HttpStatus.BAD_REQUEST, ExceptionView.TOAST, - "탈퇴한 학생에게 투표할 수 없습니다." + "이용제한을 당한 학생은 해당 서비스를 이용할 수 없습니다." ) } - if (receiver.isKeepRestrict()) { + } + + private fun validateClassmate(user: User) { + val userVoteIdentifier = VoteIdentifier.of(user, voteIdentifier.date) + require(voteIdentifier.isSameClass(userVoteIdentifier)) { throw CustomException( HttpStatus.BAD_REQUEST, ExceptionView.TOAST, - "이용제한을 받은 학생에게 투표할 수 없습니다." + "다른 반 학생과 상호작용 할 수 없습니다." ) } } From 8561dc4ac009149d9a20c2121c819010e1e809bb Mon Sep 17 00:00:00 2001 From: jaeyeonkim Date: Tue, 27 Aug 2024 00:10:01 +0900 Subject: [PATCH 06/16] =?UTF-8?q?refactor:=20loginUserId=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/wespot/message/domain/MessageTest.kt | 9 +- .../wespot/message/fixture/MessageFixture.kt | 5 +- .../real/RealSendMessageServiceTest.kt | 4 +- .../listener/NotificationEventListenerTest.kt | 4 +- .../wespot/user/service/SearchServiceTest.kt | 45 +++++-- .../kotlin/com/wespot/vote/domain/VoteTest.kt | 8 +- .../vote/service/SavedVoteServiceTest.kt | 2 +- .../src/main/kotlin/com/wespot/EventUtils.kt | 24 ++++ .../com/wespot/user/port/out/UserPort.kt | 6 +- .../wespot/user/service/SearchUserService.kt | 23 ++-- .../src/main/kotlin/com/wespot/user/User.kt | 110 +++++++++--------- .../src/main/kotlin/com/wespot/vote/Vote.kt | 5 +- .../user/adapter/UserPersistenceAdapter.kt | 12 +- .../user/repository/UserJpaRepository.kt | 13 ++- 14 files changed, 167 insertions(+), 103 deletions(-) create mode 100644 common/src/main/kotlin/com/wespot/EventUtils.kt diff --git a/app/src/test/kotlin/com/wespot/message/domain/MessageTest.kt b/app/src/test/kotlin/com/wespot/message/domain/MessageTest.kt index 8ba32689..be69b413 100644 --- a/app/src/test/kotlin/com/wespot/message/domain/MessageTest.kt +++ b/app/src/test/kotlin/com/wespot/message/domain/MessageTest.kt @@ -4,6 +4,7 @@ import com.wespot.exception.CustomException import com.wespot.message.Message import com.wespot.message.MessageTimeValidator import com.wespot.message.fixture.MessageFixture +import com.wespot.user.fixture.UserFixture import io.kotest.assertions.throwables.shouldThrow import io.kotest.core.spec.style.BehaviorSpec import io.kotest.matchers.shouldBe @@ -63,8 +64,8 @@ class MessageTest : BehaviorSpec({ val shouldThrow = shouldThrow { Message.sendMessage( badWordsContent, - 1, - 2, + UserFixture.createWithId(1), + UserFixture.createWithId(2), "senderName", false ) @@ -77,8 +78,8 @@ class MessageTest : BehaviorSpec({ val shouldThrow = shouldThrow { Message.sendMessage( emptyContent, - 1, - 2, + UserFixture.createWithId(1), + UserFixture.createWithId(2), "senderName", false ) diff --git a/app/src/test/kotlin/com/wespot/message/fixture/MessageFixture.kt b/app/src/test/kotlin/com/wespot/message/fixture/MessageFixture.kt index 248edf13..5e52d8fb 100644 --- a/app/src/test/kotlin/com/wespot/message/fixture/MessageFixture.kt +++ b/app/src/test/kotlin/com/wespot/message/fixture/MessageFixture.kt @@ -3,6 +3,7 @@ package com.wespot.message.fixture import com.wespot.message.Message import com.wespot.message.MessageContent import com.wespot.message.MessageType +import com.wespot.user.fixture.UserFixture import java.time.LocalDateTime @@ -89,8 +90,8 @@ object MessageFixture { ): Message { return Message.sendMessage( content = content, - receiverId = receiverId, - senderId = senderId, + receiver = UserFixture.createWithId(receiverId), + sender = UserFixture.createWithId(senderId), senderName = senderName, isAnonymous = false, ) diff --git a/app/src/test/kotlin/com/wespot/message/service/real/RealSendMessageServiceTest.kt b/app/src/test/kotlin/com/wespot/message/service/real/RealSendMessageServiceTest.kt index cf4f3ae8..0d9b7cf1 100644 --- a/app/src/test/kotlin/com/wespot/message/service/real/RealSendMessageServiceTest.kt +++ b/app/src/test/kotlin/com/wespot/message/service/real/RealSendMessageServiceTest.kt @@ -38,8 +38,8 @@ class RealSendMessageServiceTest @Autowired constructor( val message = messagePort.save( Message.sendMessage( content = "content", - receiverId = receiver.id, - senderId = sender.id, + receiver = receiver, + sender = sender, senderName = "senderName", isAnonymous = false ) diff --git a/app/src/test/kotlin/com/wespot/notification/service/listener/NotificationEventListenerTest.kt b/app/src/test/kotlin/com/wespot/notification/service/listener/NotificationEventListenerTest.kt index 00ba00bd..cae0f2d4 100644 --- a/app/src/test/kotlin/com/wespot/notification/service/listener/NotificationEventListenerTest.kt +++ b/app/src/test/kotlin/com/wespot/notification/service/listener/NotificationEventListenerTest.kt @@ -40,8 +40,8 @@ class NotificationEventListenerTest @Autowired constructor( val message = messagePort.save( Message.sendMessage( content = "content", - receiverId = receiver.id, - senderId = sender.id, + receiver = receiver, + sender = sender, senderName = sender.name, isAnonymous = false ) diff --git a/app/src/test/kotlin/com/wespot/user/service/SearchServiceTest.kt b/app/src/test/kotlin/com/wespot/user/service/SearchServiceTest.kt index 30211fa6..bb7a63bf 100644 --- a/app/src/test/kotlin/com/wespot/user/service/SearchServiceTest.kt +++ b/app/src/test/kotlin/com/wespot/user/service/SearchServiceTest.kt @@ -1,5 +1,6 @@ package com.wespot.user.service +import com.wespot.auth.service.SecurityUtils import com.wespot.school.SchoolType import com.wespot.school.fixture.SchoolFixture import com.wespot.school.port.out.SchoolPort @@ -9,6 +10,8 @@ import io.kotest.core.spec.style.BehaviorSpec import io.kotest.matchers.shouldBe import io.mockk.every import io.mockk.mockk +import io.mockk.mockkStatic +import io.mockk.unmockkStatic import io.mockk.verify import org.springframework.data.domain.PageRequest import org.springframework.data.domain.Sort @@ -34,9 +37,12 @@ class SearchServiceTest : BehaviorSpec({ val school1 = SchoolFixture.createSchool(1L, "서울고등학교", SchoolType.HIGH, "서울", "서울시 강남구") val school2 = SchoolFixture.createSchool(2L, "부산고등학교", SchoolType.HIGH, "부산", "부산시 남구") val school3 = SchoolFixture.createSchool(3L, "광주고등학교", SchoolType.HIGH, "광주", "광주시 서구") + val loginUser = UserFixture.createWithId(1L) - every { userPort.searchUsers(keyword, null, null, null, null, pageable) } returns users - every { userPort.countUsersAfterCursor(keyword, null, null, null, null) } returns 0L + mockkStatic(SecurityUtils::class) + every { SecurityUtils.getLoginUser(userPort) } returns loginUser + every { userPort.searchUsers(keyword, null, null, null, null, pageable, loginUser.id) } returns users + every { userPort.countUsersAfterCursor(keyword, null, null, null, null, loginUser.id) } returns 0L every { schoolPort.findById(1L) } returns school1 every { schoolPort.findById(2L) } returns school2 every { schoolPort.findById(3L) } returns school3 @@ -44,10 +50,12 @@ class SearchServiceTest : BehaviorSpec({ val result = searchUserService.searchUsers(keyword, cursorId) then("첫 페이지의 사용자들을 반환한다") { - verify { userPort.searchUsers(keyword, null, null, null, null, pageable) } + verify { userPort.searchUsers(keyword, null, null, null, null, pageable, loginUser.id) } result.users.size shouldBe 3 result.hasNext shouldBe false } + + unmockkStatic(SecurityUtils::class) } } @@ -62,21 +70,26 @@ class SearchServiceTest : BehaviorSpec({ UserFixture.createUser(2L, "user2@example.com", "김경식", 2L), UserFixture.createUser(3L, "user3@example.com", "김경수", 3L) ) + val loginUser = UserFixture.createWithId(1L) + mockkStatic(SecurityUtils::class) + every { SecurityUtils.getLoginUser(userPort) } returns loginUser every { userPort.findById(cursorId) } returns cursorUser - every { userPort.countUsersAfterCursor("경", "김갑수", "서울고등학교", 2, 1) } returns 0L + every { userPort.countUsersAfterCursor("경", "김갑수", "서울고등학교", 2, 1, loginUser.id) } returns 0L every { schoolPort.findById(1L) } returns school - every { userPort.searchUsers(keyword, "김갑수", "서울고등학교", 2, cursorId, pageable) } returns users + every { userPort.searchUsers(keyword, "김갑수", "서울고등학교", 2, cursorId, pageable, loginUser.id) } returns users val result = searchUserService.searchUsers(keyword, cursorId) then("커서 기반의 사용자들을 반환한다") { verify { userPort.findById(cursorId) } verify { schoolPort.findById(1L) } - verify { userPort.searchUsers(keyword, "김갑수", "서울고등학교", 2, cursorId, pageable) } + verify { userPort.searchUsers(keyword, "김갑수", "서울고등학교", 2, cursorId, pageable, loginUser.id) } result.users.size shouldBe 2 result.hasNext shouldBe false } + + unmockkStatic(SecurityUtils::class) } } @@ -90,21 +103,26 @@ class SearchServiceTest : BehaviorSpec({ val users = listOf( UserFixture.createUser(3L, "user3@example.com", "김경수", 3L) ) + val loginUser = UserFixture.createWithId(1L) - every { userPort.countUsersAfterCursor("경", "김경식", "부산고등학교", 2, 2) } returns 0L + mockkStatic(SecurityUtils::class) + every { SecurityUtils.getLoginUser(userPort) } returns loginUser + every { userPort.countUsersAfterCursor("경", "김경식", "부산고등학교", 2, 2, loginUser.id) } returns 0L every { userPort.findById(cursorId) } returns cursorUser every { schoolPort.findById(2L) } returns school - every { userPort.searchUsers(keyword, "김경식", "부산고등학교", 2, cursorId, pageable) } returns users + every { userPort.searchUsers(keyword, "김경식", "부산고등학교", 2, cursorId, pageable, loginUser.id) } returns users val result = searchUserService.searchUsers(keyword, cursorId) then("다음 페이지의 사용자들을 반환한다") { verify { userPort.findById(cursorId) } verify { schoolPort.findById(2L) } - verify { userPort.searchUsers(keyword, "김경식", "부산고등학교", 2, cursorId, pageable) } + verify { userPort.searchUsers(keyword, "김경식", "부산고등학교", 2, cursorId, pageable, loginUser.id) } result.users.size shouldBe 1 result.hasNext shouldBe false } + + unmockkStatic(SecurityUtils::class) } } @@ -122,8 +140,11 @@ class SearchServiceTest : BehaviorSpec({ val school1 = SchoolFixture.createSchool(1L, "서울고등학교", SchoolType.HIGH, "서울", "서울시 강남구") val school2 = SchoolFixture.createSchool(2L, "부산고등학교", SchoolType.HIGH, "부산", "부산시 남구") val school3 = SchoolFixture.createSchool(3L, "광주고등학교", SchoolType.HIGH, "광주", "광주시 서구") + val loginUser = UserFixture.createWithId(1L) - every { userPort.searchUsers(keyword, null, null, null, null, pageable) } returns users + mockkStatic(SecurityUtils::class) + every { SecurityUtils.getLoginUser(userPort) } returns loginUser + every { userPort.searchUsers(keyword, null, null, null, null, pageable, loginUser.id) } returns users every { schoolPort.findById(1L) } returns school1 every { schoolPort.findById(2L) } returns school2 every { schoolPort.findById(3L) } returns school3 @@ -131,7 +152,7 @@ class SearchServiceTest : BehaviorSpec({ val result = searchUserService.searchUsers(keyword, cursorId) then("정렬된 사용자들을 반환한다") { - verify { userPort.searchUsers(keyword, null, null, null, null, pageable) } + verify { userPort.searchUsers(keyword, null, null, null, null, pageable, loginUser.id) } result.users.size shouldBe 3 result.hasNext shouldBe false @@ -139,6 +160,8 @@ class SearchServiceTest : BehaviorSpec({ result.users[1].name shouldBe "김경수" result.users[2].name shouldBe "김갑수" } + + unmockkStatic(SecurityUtils::class) } } }) diff --git a/app/src/test/kotlin/com/wespot/vote/domain/VoteTest.kt b/app/src/test/kotlin/com/wespot/vote/domain/VoteTest.kt index 4a51a525..4e378824 100644 --- a/app/src/test/kotlin/com/wespot/vote/domain/VoteTest.kt +++ b/app/src/test/kotlin/com/wespot/vote/domain/VoteTest.kt @@ -622,8 +622,8 @@ class VoteTest() : BehaviorSpec({ shouldThrow { vote.findUsersForVote(classmates, user) } then("예외가 발생한다.") { - shouldThrow1 shouldHaveMessage "다른 반의 학생이(을) 투표할 수 없습니다." - shouldThrow2 shouldHaveMessage "다른 반의 학생이(을) 투표할 수 없습니다." + shouldThrow1 shouldHaveMessage "다른 반 학생과 상호작용 할 수 없습니다." + shouldThrow2 shouldHaveMessage "다른 반 학생과 상호작용 할 수 없습니다." } } } @@ -640,8 +640,8 @@ class VoteTest() : BehaviorSpec({ val shouldThrow2 = shouldThrow { vote.addBallot(1, otherClassmate, user, LocalDateTime.now()) } then("예외가 발생한다.") { - shouldThrow1 shouldHaveMessage "다른 반의 학생이(을) 투표할 수 없습니다." - shouldThrow2 shouldHaveMessage "다른 반의 학생이(을) 투표할 수 없습니다." + shouldThrow1 shouldHaveMessage "다른 반 학생과 상호작용 할 수 없습니다." + shouldThrow2 shouldHaveMessage "다른 반 학생과 상호작용 할 수 없습니다." } } } diff --git a/app/src/test/kotlin/com/wespot/vote/service/SavedVoteServiceTest.kt b/app/src/test/kotlin/com/wespot/vote/service/SavedVoteServiceTest.kt index d5ebd390..50a19c17 100644 --- a/app/src/test/kotlin/com/wespot/vote/service/SavedVoteServiceTest.kt +++ b/app/src/test/kotlin/com/wespot/vote/service/SavedVoteServiceTest.kt @@ -93,7 +93,7 @@ class SavedVoteServiceTest @Autowired constructor( // then val shouldThrow = shouldThrow(throwingCallable) - shouldThrow shouldHaveMessage "투표하고자 하는 회원이 존재하지 않습니다." + shouldThrow shouldHaveMessage "투표 대상을 찾을 수 없습니다." } @Test diff --git a/common/src/main/kotlin/com/wespot/EventUtils.kt b/common/src/main/kotlin/com/wespot/EventUtils.kt new file mode 100644 index 00000000..cfe25295 --- /dev/null +++ b/common/src/main/kotlin/com/wespot/EventUtils.kt @@ -0,0 +1,24 @@ +package com.wespot + +import org.springframework.context.ApplicationEventPublisher + +class EventUtils(applicationEventPublisher: ApplicationEventPublisher) { + + init { + EventUtils.applicationEventPublisher = applicationEventPublisher + } + + companion object { + + private var applicationEventPublisher: ApplicationEventPublisher? = null + + fun publish(event: Any) { + if (applicationEventPublisher == null) { + return + } + applicationEventPublisher!!.publishEvent(event) + } + + } + +} diff --git a/core/src/main/kotlin/com/wespot/user/port/out/UserPort.kt b/core/src/main/kotlin/com/wespot/user/port/out/UserPort.kt index 528d25b2..104ed650 100644 --- a/core/src/main/kotlin/com/wespot/user/port/out/UserPort.kt +++ b/core/src/main/kotlin/com/wespot/user/port/out/UserPort.kt @@ -33,7 +33,8 @@ interface UserPort { cursorSchoolName: String?, cursorSchoolTypeOrder: Int?, cursorId: Long?, - pageable: Pageable + pageable: Pageable, + loginUserId: Long, ): List fun findAll(): List @@ -43,7 +44,8 @@ interface UserPort { cursorName: String?, cursorSchoolName: String?, cursorSchoolTypeOrder: Int?, - cursorId: Long? + cursorId: Long?, + loginUserId: Long, ): Long fun countBySchoolIdAndGradeAndClassNumber( diff --git a/core/src/main/kotlin/com/wespot/user/service/SearchUserService.kt b/core/src/main/kotlin/com/wespot/user/service/SearchUserService.kt index 8f033534..afbb31ee 100644 --- a/core/src/main/kotlin/com/wespot/user/service/SearchUserService.kt +++ b/core/src/main/kotlin/com/wespot/user/service/SearchUserService.kt @@ -28,11 +28,12 @@ class SearchUserService( keyword: String, cursorId: Long ): UserListResponse { - validateLoginUserRegulation() + val loginUser = SecurityUtils.getLoginUser(userPort) + validateLoginUserRegulation(loginUser) val pageable = PageRequest.of(0, 10, Sort.by("id")) if (cursorId == 0L) { - return fetchFirstPage(keyword = keyword, pageable = pageable) + return fetchFirstPage(keyword = keyword, pageable = pageable, loginUserId = loginUser.id) } val cursorData = fetchCursorData(cursorId) @@ -42,7 +43,8 @@ class SearchUserService( cursorSchoolName = cursorData.cursorSchoolName, cursorSchoolTypeOrder = cursorData.cursorSchoolTypeOrder, cursorId = cursorId, - pageable = pageable + pageable = pageable, + loginUserId = loginUser.id ) val totalCount = userPort.countUsersAfterCursor( @@ -50,14 +52,14 @@ class SearchUserService( cursorName = cursorData.cursorName, cursorSchoolName = cursorData.cursorSchoolName, cursorSchoolTypeOrder = cursorData.cursorSchoolTypeOrder, - cursorId = cursorId + cursorId = cursorId, + loginUserId = loginUser.id ) return buildUserListResponse(users = users, pageable = pageable, totalCount = totalCount) } - private fun validateLoginUserRegulation() { - val loginUser = SecurityUtils.getLoginUser(userPort) + private fun validateLoginUserRegulation(loginUser: User) { if (loginUser.isRegulation()) { throw CustomException(HttpStatus.FORBIDDEN, ExceptionView.TOAST, "규제를 당한 유저는 해당 서비스를 사용할 수 없습니다.") } @@ -65,7 +67,8 @@ class SearchUserService( private fun fetchFirstPage( keyword: String, - pageable: Pageable + pageable: Pageable, + loginUserId: Long, ): UserListResponse { val users = userPort.searchUsers( name = keyword, @@ -73,7 +76,8 @@ class SearchUserService( cursorSchoolName = null, cursorSchoolTypeOrder = null, cursorId = null, - pageable = pageable + pageable = pageable, + loginUserId = loginUserId ) val totalCount = userPort.countUsersAfterCursor( @@ -81,7 +85,8 @@ class SearchUserService( cursorName = null, cursorSchoolName = null, cursorSchoolTypeOrder = null, - cursorId = null + cursorId = null, + loginUserId = loginUserId ) return buildUserListResponse(users = users, pageable = pageable, totalCount = totalCount) diff --git a/domain/src/main/kotlin/com/wespot/user/User.kt b/domain/src/main/kotlin/com/wespot/user/User.kt index 1b8ab718..bff2920f 100644 --- a/domain/src/main/kotlin/com/wespot/user/User.kt +++ b/domain/src/main/kotlin/com/wespot/user/User.kt @@ -83,33 +83,33 @@ data class User( withdrawalCompleteAt = null ) - fun cancelWithdraw() : User{ - isWithdrawActive() - return User( - id = id, - email = email, - password = password, - name = name, - introduction = introduction, - gender = gender, - role = role, - schoolId = schoolId, - grade = grade, - classNumber = classNumber, - profile = profile, - fcm = fcm, - setting = setting, - social = social, - userConsent = userConsent, - createdAt = createdAt, - restriction = restriction, - updatedAt = LocalDateTime.now(), - withdrawalStatus = WithdrawalStatus.CANCELED, - withdrawalRequestAt = withdrawalRequestAt, - withdrawalCancelAt = LocalDateTime.now(), - withdrawalCompleteAt = null - ) - } + fun cancelWithdraw(): User { + isWithdrawActive() + return User( + id = id, + email = email, + password = password, + name = name, + introduction = introduction, + gender = gender, + role = role, + schoolId = schoolId, + grade = grade, + classNumber = classNumber, + profile = profile, + fcm = fcm, + setting = setting, + social = social, + userConsent = userConsent, + createdAt = createdAt, + restriction = restriction, + updatedAt = LocalDateTime.now(), + withdrawalStatus = WithdrawalStatus.CANCELED, + withdrawalRequestAt = withdrawalRequestAt, + withdrawalCancelAt = LocalDateTime.now(), + withdrawalCompleteAt = null + ) + } fun completeWithdraw( @@ -161,33 +161,33 @@ data class User( social: Social, gender: Gender, ) = User( - id = 0L, - email = email, - password = password, - name = name, - introduction = UserIntroduction.emptyUserIntroduction(), - gender = gender, - role = Role.USER, - schoolId = schoolId, - grade = grade, - classNumber = groupNumber, - profile = Profile.createInit(), - fcm = null, - setting = Setting(), - social = social, - userConsent = UserConsent.create( - consentType = ConsentType.MARKETING, - consentedAt = LocalDateTime.now(), - consentValue = false - ), - restriction = Restriction.createInitialState(), - createdAt = LocalDateTime.now(), - updatedAt = LocalDateTime.now(), - withdrawalStatus = WithdrawalStatus.NONE, - withdrawalRequestAt = null, - withdrawalCancelAt = null, - withdrawalCompleteAt = null - ) + id = 0L, + email = email, + password = password, + name = name, + introduction = UserIntroduction.emptyUserIntroduction(), + gender = gender, + role = Role.USER, + schoolId = schoolId, + grade = grade, + classNumber = groupNumber, + profile = Profile.createInit(), + fcm = null, + setting = Setting(), + social = social, + userConsent = UserConsent.create( + consentType = ConsentType.MARKETING, + consentedAt = LocalDateTime.now(), + consentValue = false + ), + restriction = Restriction.createInitialState(), + createdAt = LocalDateTime.now(), + updatedAt = LocalDateTime.now(), + withdrawalStatus = WithdrawalStatus.NONE, + withdrawalRequestAt = null, + withdrawalCancelAt = null, + withdrawalCompleteAt = null + ) fun update( user: User, @@ -266,7 +266,7 @@ data class User( } fun isWithDraw(): Boolean { - return withdrawalStatus == WithdrawalStatus.WITHDRAW + return withdrawalStatus == WithdrawalStatus.WITHDRAWN } fun isRegulation(): Boolean { diff --git a/domain/src/main/kotlin/com/wespot/vote/Vote.kt b/domain/src/main/kotlin/com/wespot/vote/Vote.kt index 33c14f3f..5f4ec02b 100644 --- a/domain/src/main/kotlin/com/wespot/vote/Vote.kt +++ b/domain/src/main/kotlin/com/wespot/vote/Vote.kt @@ -1,5 +1,6 @@ package com.wespot.vote +import com.wespot.EventUtils import com.wespot.exception.CustomException import com.wespot.exception.ExceptionView import com.wespot.user.User @@ -91,7 +92,7 @@ data class Vote( return classmates.stream() .filter { !alreadyVotedByUser.contains(it.id) && isNotMe(it, user) } - .filter { it.isRegulation() } + .filter { !it.isRegulation() } .toList() .shuffled() .take(NUMBER_OF_VOTE_USERS) @@ -120,7 +121,7 @@ data class Vote( ) ) - registerEvent(ReceivedVoteEvent(receiver)) + EventUtils.publish(ReceivedVoteEvent(receiver)) } private fun validateUser(user: User) { diff --git a/infrastructure/mysql/src/main/kotlin/com/wespot/user/adapter/UserPersistenceAdapter.kt b/infrastructure/mysql/src/main/kotlin/com/wespot/user/adapter/UserPersistenceAdapter.kt index ecee2d84..847b70ea 100644 --- a/infrastructure/mysql/src/main/kotlin/com/wespot/user/adapter/UserPersistenceAdapter.kt +++ b/infrastructure/mysql/src/main/kotlin/com/wespot/user/adapter/UserPersistenceAdapter.kt @@ -37,7 +37,8 @@ class UserPersistenceAdapter( cursorSchoolName: String?, cursorSchoolTypeOrder: Int?, cursorId: Long?, - pageable: Pageable + pageable: Pageable, + loginUserId: Long, ): List { return userJpaRepository.searchUsers( name = name, @@ -45,7 +46,8 @@ class UserPersistenceAdapter( cursorSchoolName = cursorSchoolName, cursorSchoolTypeOrder = cursorSchoolTypeOrder, cursorId = cursorId, - pageable = pageable + pageable = pageable, + loginUserId = loginUserId ).stream() .map { userJpaEntity -> UserMapper.mapToDomainEntity(userJpaEntity) } .toList() @@ -56,14 +58,16 @@ class UserPersistenceAdapter( cursorName: String?, cursorSchoolName: String?, cursorSchoolTypeOrder: Int?, - cursorId: Long? + cursorId: Long?, + loginUserId: Long, ): Long { return userJpaRepository.countUsersAfterCursor( name = name, cursorName = cursorName, cursorSchoolName = cursorSchoolName, cursorSchoolTypeOrder = cursorSchoolTypeOrder, - cursorId = cursorId + cursorId = cursorId, + loginUserId = loginUserId ) } diff --git a/infrastructure/mysql/src/main/kotlin/com/wespot/user/repository/UserJpaRepository.kt b/infrastructure/mysql/src/main/kotlin/com/wespot/user/repository/UserJpaRepository.kt index 98a6691a..b1fede77 100644 --- a/infrastructure/mysql/src/main/kotlin/com/wespot/user/repository/UserJpaRepository.kt +++ b/infrastructure/mysql/src/main/kotlin/com/wespot/user/repository/UserJpaRepository.kt @@ -43,6 +43,7 @@ interface UserJpaRepository : JpaRepository { SELECT u FROM UserJpaEntity u LEFT JOIN SchoolJpaEntity s ON u.schoolId = s.id WHERE LOWER(u.name) LIKE LOWER(CONCAT('%', :name, '%')) + AND u.id <> :loginUserId AND ( :cursorId IS NULL OR ( (:cursorName IS NULL OR u.name > :cursorName) OR @@ -75,14 +76,15 @@ interface UserJpaRepository : JpaRepository { @Param("cursorSchoolName") cursorSchoolName: String?, @Param("cursorSchoolTypeOrder") cursorSchoolTypeOrder: Int?, @Param("cursorId") cursorId: Long?, + @Param("loginUserId") loginUserId: Long, pageable: Pageable ): List - @Query( """ SELECT COUNT(u) FROM UserJpaEntity u LEFT JOIN SchoolJpaEntity s ON u.schoolId = s.id + AND u.id <> :loginUserId WHERE LOWER(u.name) LIKE LOWER(CONCAT('%', :name, '%')) AND ( :cursorId IS NULL OR ( @@ -100,9 +102,9 @@ interface UserJpaRepository : JpaRepository { END = :cursorSchoolTypeOrder AND u.id > :cursorId) ) ) - AND u.withdrawalStatus != 'WITHDRAWN' - AND u.restriction.messageRestrictionType = 'NONE' - AND u.restriction.voteRestrictionType = 'NONE' + AND u.withdrawalStatus != 'WITHDRAWN' + AND u.restriction.messageRestrictionType = 'NONE' + AND u.restriction.voteRestrictionType = 'NONE' """ ) fun countUsersAfterCursor( @@ -110,7 +112,8 @@ interface UserJpaRepository : JpaRepository { @Param("cursorName") cursorName: String?, @Param("cursorSchoolName") cursorSchoolName: String?, @Param("cursorSchoolTypeOrder") cursorSchoolTypeOrder: Int?, - @Param("cursorId") cursorId: Long? + @Param("cursorId") cursorId: Long?, + @Param("loginUserId") loginUserId: Long, ): Long fun countBySchoolIdAndGradeAndClassNumber( From 0973bd6a80978b605d3fc54056280be03c8c2a94 Mon Sep 17 00:00:00 2001 From: jaeyeonkim Date: Tue, 27 Aug 2024 00:10:51 +0900 Subject: [PATCH 07/16] =?UTF-8?q?style:=20=EC=82=AC=EC=9A=A9=ED=95=98?= =?UTF-8?q?=EC=A7=80=20=EC=95=8A=EB=8A=94=20import=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/listener/NotificationEventListenerTest.kt | 1 - .../test/kotlin/com/wespot/vote/service/SavedVoteServiceTest.kt | 1 - 2 files changed, 2 deletions(-) diff --git a/app/src/test/kotlin/com/wespot/notification/service/listener/NotificationEventListenerTest.kt b/app/src/test/kotlin/com/wespot/notification/service/listener/NotificationEventListenerTest.kt index cae0f2d4..59332bd3 100644 --- a/app/src/test/kotlin/com/wespot/notification/service/listener/NotificationEventListenerTest.kt +++ b/app/src/test/kotlin/com/wespot/notification/service/listener/NotificationEventListenerTest.kt @@ -4,7 +4,6 @@ import com.wespot.common.service.ServiceTest import com.wespot.message.Message import com.wespot.message.MessageTimeValidator import com.wespot.message.event.ReceivedMessageEvent -import com.wespot.message.fixture.MessageFixture import com.wespot.message.port.out.MessagePort import com.wespot.notification.NotificationType import com.wespot.notification.port.out.NotificationPort diff --git a/app/src/test/kotlin/com/wespot/vote/service/SavedVoteServiceTest.kt b/app/src/test/kotlin/com/wespot/vote/service/SavedVoteServiceTest.kt index 50a19c17..9fd3e7ac 100644 --- a/app/src/test/kotlin/com/wespot/vote/service/SavedVoteServiceTest.kt +++ b/app/src/test/kotlin/com/wespot/vote/service/SavedVoteServiceTest.kt @@ -1,6 +1,5 @@ package com.wespot.vote.service -import com.wespot.DatabaseCleanup import com.wespot.common.service.ServiceTest import com.wespot.exception.CustomException import com.wespot.notification.port.out.NotificationPort From 03e90851bb16dd9975300b0ea3b18055783afde0 Mon Sep 17 00:00:00 2001 From: jaeyeonkim Date: Tue, 27 Aug 2024 00:23:43 +0900 Subject: [PATCH 08/16] =?UTF-8?q?refactor:=20EventUtils=20=EC=84=A0?= =?UTF-8?q?=EC=96=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../VoteNotificationEventListenerTest.kt | 16 ++++++++-------- common/src/main/kotlin/com/wespot/EventUtils.kt | 6 ++++-- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/app/src/test/kotlin/com/wespot/notification/service/listener/VoteNotificationEventListenerTest.kt b/app/src/test/kotlin/com/wespot/notification/service/listener/VoteNotificationEventListenerTest.kt index 15c3fc3c..96f14119 100644 --- a/app/src/test/kotlin/com/wespot/notification/service/listener/VoteNotificationEventListenerTest.kt +++ b/app/src/test/kotlin/com/wespot/notification/service/listener/VoteNotificationEventListenerTest.kt @@ -65,14 +65,14 @@ class VoteNotificationEventListenerTest @Autowired constructor( val notifications = notificationPort.findAll() // then - notifications.size shouldBe 5 - notifications[0].userId shouldBe users[1].id - notifications[1].userId shouldBe users[2].id - notifications[2].userId shouldBe users[3].id - notifications[3].userId shouldBe users[4].id - notifications[0].type shouldBe NotificationType.VOTE_RESULT - notifications[0].targetId shouldBe 0 - notifications[0].date shouldBe LocalDate.now() + notifications.size shouldBe 10 + notifications[5].userId shouldBe users[1].id + notifications[6].userId shouldBe users[2].id + notifications[7].userId shouldBe users[3].id + notifications[8].userId shouldBe users[4].id + notifications[5].type shouldBe NotificationType.VOTE_RESULT + notifications[5].targetId shouldBe 0 + notifications[5].date shouldBe LocalDate.now() } @Test diff --git a/common/src/main/kotlin/com/wespot/EventUtils.kt b/common/src/main/kotlin/com/wespot/EventUtils.kt index cfe25295..f9af6a47 100644 --- a/common/src/main/kotlin/com/wespot/EventUtils.kt +++ b/common/src/main/kotlin/com/wespot/EventUtils.kt @@ -1,11 +1,13 @@ package com.wespot import org.springframework.context.ApplicationEventPublisher +import org.springframework.stereotype.Component -class EventUtils(applicationEventPublisher: ApplicationEventPublisher) { +@Component +class EventUtils private constructor(applicationEventPublisher: ApplicationEventPublisher) { init { - EventUtils.applicationEventPublisher = applicationEventPublisher + Companion.applicationEventPublisher = applicationEventPublisher } companion object { From 42aa2ed6cfa3004b34df5e28d11171c28b4f0c0a Mon Sep 17 00:00:00 2001 From: jaeyeonkim Date: Tue, 27 Aug 2024 00:36:42 +0900 Subject: [PATCH 09/16] =?UTF-8?q?refactor:=20ApplicationEventPublisher=20U?= =?UTF-8?q?tils=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/wespot/auth/service/AuthServiceTest.kt | 9 --------- .../message/service/ModifyMessageServiceTest.kt | 14 -------------- .../message/service/SendMessageServiceTest.kt | 7 ------- .../VoteNotificationEventListenerTest.kt | 1 - .../com/wespot/auth/service/AuthService.kt | 16 ++++++++-------- .../message/service/ModifyMessageService.kt | 5 ++--- .../service/ScheduledMessageSenderService.kt | 5 ++--- .../wespot/message/service/SendMessageService.kt | 5 ++--- .../wespot/vote/service/CreatedVoteService.kt | 5 ++--- .../com/wespot/vote/service/SavedVoteService.kt | 5 ++--- domain/src/main/kotlin/com/wespot/user/User.kt | 6 ++++-- 11 files changed, 22 insertions(+), 56 deletions(-) diff --git a/app/src/test/kotlin/com/wespot/auth/service/AuthServiceTest.kt b/app/src/test/kotlin/com/wespot/auth/service/AuthServiceTest.kt index 0eb4da80..a5578d69 100644 --- a/app/src/test/kotlin/com/wespot/auth/service/AuthServiceTest.kt +++ b/app/src/test/kotlin/com/wespot/auth/service/AuthServiceTest.kt @@ -17,9 +17,6 @@ import com.wespot.exception.CustomException import com.wespot.exception.ExceptionView import com.wespot.school.port.out.SchoolPort import com.wespot.user.SocialType -import com.wespot.user.event.CreatedVoteEvent -import com.wespot.user.event.SignUpUserEvent -import com.wespot.user.event.WelcomeMessageEvent import com.wespot.user.fixture.UserFixture import com.wespot.user.port.out.FCMPort import com.wespot.user.port.out.ProfilePort @@ -36,7 +33,6 @@ import io.mockk.every import io.mockk.just import io.mockk.mockk import io.mockk.spyk -import org.springframework.context.ApplicationEventPublisher import org.springframework.http.HttpStatus import org.springframework.security.authentication.AuthenticationManager import org.springframework.security.core.Authentication @@ -56,7 +52,6 @@ class AuthServiceTest : BehaviorSpec({ val authenticationManager = mockk() val passwordEncoder = mockk() val refreshTokenService = mockk() - val eventPublisher = mockk() val fcmPort = mockk() val restrictionPort = mockk() val personalInfoPort = mockk() @@ -77,7 +72,6 @@ class AuthServiceTest : BehaviorSpec({ authenticationManager = authenticationManager, passwordEncoder = passwordEncoder, refreshTokenService = refreshTokenService, - eventPublisher = eventPublisher, fcmPort = fcmPort, secretKey = secretKey, restrictionPort = restrictionPort, @@ -219,9 +213,6 @@ class AuthServiceTest : BehaviorSpec({ every { userPort.save(any()) } returns user every { authService.saveRelatedEntities(user, signUpRequest, authData.fcmToken) } just Runs every { authService.signIn(any()) } returns tokenAndUserDetailResponse - every { eventPublisher.publishEvent(SignUpUserEvent(user)) } returns Unit - every { eventPublisher.publishEvent(CreatedVoteEvent(user)) } returns Unit - every { eventPublisher.publishEvent(WelcomeMessageEvent(user)) } returns Unit `when`("사용자가 signUp을 호출할 때") { val response = authService.signUp(signUpRequest) diff --git a/app/src/test/kotlin/com/wespot/message/service/ModifyMessageServiceTest.kt b/app/src/test/kotlin/com/wespot/message/service/ModifyMessageServiceTest.kt index f9a9e710..deba9591 100644 --- a/app/src/test/kotlin/com/wespot/message/service/ModifyMessageServiceTest.kt +++ b/app/src/test/kotlin/com/wespot/message/service/ModifyMessageServiceTest.kt @@ -6,7 +6,6 @@ import com.wespot.message.MessageContent import com.wespot.message.MessageTimeValidator import com.wespot.message.dto.request.UpdateMessageRequest import com.wespot.message.dto.response.UpdateMessageResponse -import com.wespot.message.event.ReadMessageByReceiverEvent import com.wespot.message.fixture.MessageFixture import com.wespot.message.port.out.MessagePort import com.wespot.user.User @@ -18,7 +17,6 @@ import io.mockk.clearAllMocks import io.mockk.every import io.mockk.mockk import io.mockk.verify -import org.springframework.context.ApplicationEventPublisher import java.time.Clock import java.time.Instant import java.time.ZoneId @@ -27,11 +25,9 @@ class ModifyMessageServiceTest : BehaviorSpec({ val messagePort = mockk() val userPort = mockk() - val eventPublisher = mockk() val modifyMessageService = ModifyMessageService( messagePort = messagePort, userPort = userPort, - eventPublisher = eventPublisher ) lateinit var sender: User @@ -99,16 +95,6 @@ class ModifyMessageServiceTest : BehaviorSpec({ every { userPort.findById(1) } returns sender every { messagePort.findById(messageId) } returns receivedMessage every { messagePort.save(any()) } returns receivedMessage.copy(isReceiverRead = true) - every { - eventPublisher.publishEvent( - ReadMessageByReceiverEvent( - sender, - receiver, - messageId, - false - ) - ) - } returns Unit then("메시지가 읽은 상태로 업데이트되어야 한다") { modifyMessageService.readMessage(messageId) diff --git a/app/src/test/kotlin/com/wespot/message/service/SendMessageServiceTest.kt b/app/src/test/kotlin/com/wespot/message/service/SendMessageServiceTest.kt index 8090e460..887d4841 100644 --- a/app/src/test/kotlin/com/wespot/message/service/SendMessageServiceTest.kt +++ b/app/src/test/kotlin/com/wespot/message/service/SendMessageServiceTest.kt @@ -5,8 +5,6 @@ import com.wespot.message.Message import com.wespot.message.MessageTimeValidator import com.wespot.message.dto.request.SendMessageRequest import com.wespot.message.dto.response.SendMessageResponse -import com.wespot.message.event.MessageLimitEvent -import com.wespot.message.event.ReceivedMessageEvent import com.wespot.message.fixture.MessageFixture import com.wespot.message.port.out.MessagePort import com.wespot.user.User @@ -19,7 +17,6 @@ import io.mockk.clearAllMocks import io.mockk.every import io.mockk.mockk import io.mockk.verify -import org.springframework.context.ApplicationEventPublisher import java.time.Clock import java.time.Instant import java.time.ZoneId @@ -29,12 +26,10 @@ class SendMessageServiceTest : BehaviorSpec({ val messagePort = mockk() val userPort = mockk() val blockedUserPort = mockk() - val eventPublisher = mockk() val sendMessageService = SendMessageService( messagePort = messagePort, userPort = userPort, blockedUserPort = blockedUserPort, - eventPublisher = eventPublisher ) lateinit var sender: User @@ -75,8 +70,6 @@ class SendMessageServiceTest : BehaviorSpec({ every { messagePort.save(any()) } returns message every { messagePort.sendMessageCount(sender.id) } returns 0 every { messagePort.hasSentMessageToday(sender.id, receiver.id) } returns false - every { eventPublisher.publishEvent(MessageLimitEvent(sender.id, 0)) } returns Unit - every { eventPublisher.publishEvent(ReceivedMessageEvent(receiver, 0)) } returns Unit every { blockedUserPort.existsByBlockerIdAndBlockedId(1, 2) } returns false every { blockedUserPort.existsByBlockerIdAndBlockedId(2, 1) } returns false diff --git a/app/src/test/kotlin/com/wespot/notification/service/listener/VoteNotificationEventListenerTest.kt b/app/src/test/kotlin/com/wespot/notification/service/listener/VoteNotificationEventListenerTest.kt index 96f14119..b4b35c7d 100644 --- a/app/src/test/kotlin/com/wespot/notification/service/listener/VoteNotificationEventListenerTest.kt +++ b/app/src/test/kotlin/com/wespot/notification/service/listener/VoteNotificationEventListenerTest.kt @@ -18,7 +18,6 @@ import io.kotest.matchers.shouldBe import io.mockk.every import io.mockk.mockk import org.springframework.beans.factory.annotation.Autowired -import org.springframework.boot.test.context.SpringBootTest import java.time.LocalDate import java.time.LocalDateTime import kotlin.test.Test diff --git a/core/src/main/kotlin/com/wespot/auth/service/AuthService.kt b/core/src/main/kotlin/com/wespot/auth/service/AuthService.kt index dbb0acfe..e27579df 100644 --- a/core/src/main/kotlin/com/wespot/auth/service/AuthService.kt +++ b/core/src/main/kotlin/com/wespot/auth/service/AuthService.kt @@ -1,5 +1,6 @@ package com.wespot.auth.service +import com.wespot.EventUtils import com.wespot.auth.dto.AuthData import com.wespot.auth.dto.request.* import com.wespot.auth.dto.response.SettingResponse @@ -25,7 +26,6 @@ import com.wespot.user.port.out.UserConsentPort import com.wespot.user.port.out.UserPort import com.wespot.user.port.out.FCMPort import org.springframework.beans.factory.annotation.Value -import org.springframework.context.ApplicationEventPublisher import org.springframework.http.HttpStatus import org.springframework.security.authentication.AuthenticationManager import org.springframework.security.crypto.password.PasswordEncoder @@ -50,7 +50,6 @@ class AuthService( private val passwordEncoder: PasswordEncoder, private val refreshTokenService: RefreshTokenService, private val restrictionPort: RestrictionPort, - private val eventPublisher: ApplicationEventPublisher, private val fcmPort: FCMPort, private val personalInfoPort: PersonalInfoPort, @@ -98,15 +97,14 @@ class AuthService( } - override fun signUp(signUpRequest: SignUpRequest): TokenAndUserDetailResponse { val signUpToken = checkSignUpToken(signUpRequest.signUpToken) val user = createUser(signUpToken, signUpRequest) val savedUser = userPort.save(user) - eventPublisher.publishEvent(CreatedVoteEvent(savedUser)) - eventPublisher.publishEvent(SignUpUserEvent(savedUser)) - eventPublisher.publishEvent(WelcomeMessageEvent(savedUser)) + EventUtils.publish(CreatedVoteEvent(savedUser)) + EventUtils.publish(SignUpUserEvent(savedUser)) + EventUtils.publish(WelcomeMessageEvent(savedUser)) saveRelatedEntities(savedUser, signUpRequest, signUpToken.fcmToken) @@ -237,8 +235,10 @@ class AuthService( personalInfo?.let { restrictionPort.findById(it.restriction)?.let { restriction -> - val isPermBanMessage = restriction.messageRestriction.restrictionType == RestrictionType.PERMANENT_BAN_MESSAGE_REPORT - val isPermBanVote = restriction.voteRestriction.restrictionType == RestrictionType.PERMANENT_BAN_VOTE_REPORT + val isPermBanMessage = + restriction.messageRestriction.restrictionType == RestrictionType.PERMANENT_BAN_MESSAGE_REPORT + val isPermBanVote = + restriction.voteRestriction.restrictionType == RestrictionType.PERMANENT_BAN_VOTE_REPORT require(!(isPermBanMessage || isPermBanVote)) { "영구 제한된 계정입니다." } } diff --git a/core/src/main/kotlin/com/wespot/message/service/ModifyMessageService.kt b/core/src/main/kotlin/com/wespot/message/service/ModifyMessageService.kt index ac8e4cc2..366d4b71 100644 --- a/core/src/main/kotlin/com/wespot/message/service/ModifyMessageService.kt +++ b/core/src/main/kotlin/com/wespot/message/service/ModifyMessageService.kt @@ -1,5 +1,6 @@ package com.wespot.message.service +import com.wespot.EventUtils import com.wespot.auth.service.SecurityUtils.getLoginUser import com.wespot.message.dto.request.UpdateMessageRequest import com.wespot.message.dto.response.UpdateMessageResponse @@ -9,7 +10,6 @@ import com.wespot.message.port.out.MessagePort import com.wespot.message.service.MessageFinder.findMessageById import com.wespot.message.service.MessageFinder.findUserById import com.wespot.user.port.out.UserPort -import org.springframework.context.ApplicationEventPublisher import org.springframework.stereotype.Service import org.springframework.transaction.annotation.Transactional @@ -18,7 +18,6 @@ import org.springframework.transaction.annotation.Transactional class ModifyMessageService( private val messagePort: MessagePort, private val userPort: UserPort, - private val eventPublisher: ApplicationEventPublisher ) : ModifyMessageUseCase { override fun updateMessage( @@ -49,7 +48,7 @@ class ModifyMessageService( val readMessage = message.readMessage(loginUser) messagePort.save(readMessage) - eventPublisher.publishEvent( + EventUtils.publish( ReadMessageByReceiverEvent( sender, loginUser, diff --git a/core/src/main/kotlin/com/wespot/message/service/ScheduledMessageSenderService.kt b/core/src/main/kotlin/com/wespot/message/service/ScheduledMessageSenderService.kt index 028ca484..c2717bc8 100644 --- a/core/src/main/kotlin/com/wespot/message/service/ScheduledMessageSenderService.kt +++ b/core/src/main/kotlin/com/wespot/message/service/ScheduledMessageSenderService.kt @@ -1,5 +1,6 @@ package com.wespot.message.service +import com.wespot.EventUtils import com.wespot.exception.CustomException import com.wespot.exception.ExceptionView import com.wespot.message.Message @@ -8,7 +9,6 @@ import com.wespot.message.port.`in`.SchedulerMessageUseCase import com.wespot.message.port.out.MessagePort import com.wespot.user.port.out.UserPort import com.wespot.user.service.UserFinder -import org.springframework.context.ApplicationEventPublisher import org.springframework.http.HttpStatus import org.springframework.stereotype.Service import org.springframework.transaction.annotation.Propagation @@ -20,7 +20,6 @@ import java.time.LocalDateTime class ScheduledMessageSenderService( private val messagePort: MessagePort, private val userPort: UserPort, - private val eventPublisher: ApplicationEventPublisher, ) : SchedulerMessageUseCase { @Transactional @@ -43,7 +42,7 @@ class ScheduledMessageSenderService( id = receivedMessage.receiverId, userPort = userPort ) - eventPublisher.publishEvent( + EventUtils.publish( ReceivedMessageEvent( receiver = receiver, messageId = receivedMessage.id diff --git a/core/src/main/kotlin/com/wespot/message/service/SendMessageService.kt b/core/src/main/kotlin/com/wespot/message/service/SendMessageService.kt index ec50768e..ba18c678 100644 --- a/core/src/main/kotlin/com/wespot/message/service/SendMessageService.kt +++ b/core/src/main/kotlin/com/wespot/message/service/SendMessageService.kt @@ -1,5 +1,6 @@ package com.wespot.message.service +import com.wespot.EventUtils import com.wespot.auth.service.SecurityUtils.getLoginUser import com.wespot.message.Message import com.wespot.message.MessageTimeValidator.validateMessageSendTime @@ -14,7 +15,6 @@ import com.wespot.message.service.MessageSendValidator.validateSendMessageLimit import com.wespot.message.service.MessageSendValidator.validateUserBlockStatus import com.wespot.user.port.out.BlockedUserPort import com.wespot.user.port.out.UserPort -import org.springframework.context.ApplicationEventPublisher import org.springframework.stereotype.Service import org.springframework.transaction.annotation.Transactional @@ -24,7 +24,6 @@ class SendMessageService( private val messagePort: MessagePort, private val userPort: UserPort, private val blockedUserPort: BlockedUserPort, - private val eventPublisher: ApplicationEventPublisher ) : SendMessageUseCase { override fun send(sendMessageRequest: SendMessageRequest): SendMessageResponse { @@ -46,7 +45,7 @@ class SendMessageService( ) val saveMessage = messagePort.save(sendMessage) - eventPublisher.publishEvent( + EventUtils.publish( MessageLimitEvent( senderId = loginUser.id, messagePort.sendMessageCount(loginUser.id) diff --git a/core/src/main/kotlin/com/wespot/vote/service/CreatedVoteService.kt b/core/src/main/kotlin/com/wespot/vote/service/CreatedVoteService.kt index eba7de6c..8b60fc8f 100644 --- a/core/src/main/kotlin/com/wespot/vote/service/CreatedVoteService.kt +++ b/core/src/main/kotlin/com/wespot/vote/service/CreatedVoteService.kt @@ -1,5 +1,6 @@ package com.wespot.vote.service +import com.wespot.EventUtils import com.wespot.user.User import com.wespot.user.port.out.UserPort import com.wespot.vote.Vote @@ -10,7 +11,6 @@ import com.wespot.vote.port.out.VoteOptionPort import com.wespot.vote.port.out.VotePort import com.wespot.vote.service.helper.VoteServiceHelper import com.wespot.voteoption.VoteOption -import org.springframework.context.ApplicationEventPublisher import org.springframework.stereotype.Service import org.springframework.transaction.annotation.Transactional import java.time.LocalDate @@ -20,14 +20,13 @@ class CreatedVoteService( private val votePort: VotePort, private val userPort: UserPort, private val voteOptionPort: VoteOptionPort, - private val eventPublisher: ApplicationEventPublisher ) : CreatedVoteUseCase { @Transactional override fun createVotes() { val today = LocalDate.now() val allVoteOptions = voteOptionPort.findAll() - eventPublisher.publishEvent(EndVoteEvent()) + EventUtils.publish(EndVoteEvent()) userPort.findAll() .map { VoteIdentifier.of(it, today) } diff --git a/core/src/main/kotlin/com/wespot/vote/service/SavedVoteService.kt b/core/src/main/kotlin/com/wespot/vote/service/SavedVoteService.kt index 815a1f80..b6e819d1 100644 --- a/core/src/main/kotlin/com/wespot/vote/service/SavedVoteService.kt +++ b/core/src/main/kotlin/com/wespot/vote/service/SavedVoteService.kt @@ -1,5 +1,6 @@ package com.wespot.vote.service +import com.wespot.EventUtils import com.wespot.exception.CustomException import com.wespot.exception.ExceptionView import com.wespot.user.User @@ -13,7 +14,6 @@ import com.wespot.vote.event.RegisteredVoteEvent import com.wespot.vote.port.`in`.SavedVoteUseCase import com.wespot.vote.port.out.VotePort import com.wespot.vote.service.helper.VoteServiceHelper -import org.springframework.context.ApplicationEventPublisher import org.springframework.http.HttpStatus import org.springframework.stereotype.Service import org.springframework.transaction.annotation.Transactional @@ -24,7 +24,6 @@ import java.time.LocalDateTime class SavedVoteService( private val votePort: VotePort, private val userPort: UserPort, - private val eventPublisher: ApplicationEventPublisher, ) : SavedVoteUseCase { @Transactional(readOnly = true) @@ -59,7 +58,7 @@ class SavedVoteService( ?: throw CustomException(HttpStatus.BAD_REQUEST, ExceptionView.DIALOG, "투표 대상을 찾을 수 없습니다."), voteTime) } - eventPublisher.publishEvent(RegisteredVoteEvent(user, vote)) + EventUtils.publish(RegisteredVoteEvent(user, vote)) return SavedVoteResponse(votePort.save(vote).id) } diff --git a/domain/src/main/kotlin/com/wespot/user/User.kt b/domain/src/main/kotlin/com/wespot/user/User.kt index bff2920f..a6d5efe1 100644 --- a/domain/src/main/kotlin/com/wespot/user/User.kt +++ b/domain/src/main/kotlin/com/wespot/user/User.kt @@ -1,6 +1,9 @@ package com.wespot.user +import com.wespot.exception.CustomException +import com.wespot.exception.ExceptionView import com.wespot.user.restriction.Restriction +import org.springframework.http.HttpStatus import java.time.LocalDate import java.time.LocalDateTime @@ -223,10 +226,9 @@ data class User( } - private fun isWithdrawActive() { if (withdrawalStatus != WithdrawalStatus.ACTIVE) { - throw IllegalStateException("탈퇴가 진행 중이 아닙니다.") + throw CustomException(HttpStatus.BAD_REQUEST, ExceptionView.TOAST, "탈퇴가 진행 중이 아닙니다.") } } From 943c59dbb2807d09cccd188341db0c025c3f290e Mon Sep 17 00:00:00 2001 From: jaeyeonkim Date: Tue, 27 Aug 2024 23:58:06 +0900 Subject: [PATCH 10/16] =?UTF-8?q?test:=20=EC=AA=BD=EC=A7=80=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/wespot/message/domain/MessageTest.kt | 143 ++++++++++++++++++ .../com/wespot/user/fixture/UserFixture.kt | 44 ++++++ .../main/kotlin/com/wespot/message/Message.kt | 2 + 3 files changed, 189 insertions(+) diff --git a/app/src/test/kotlin/com/wespot/message/domain/MessageTest.kt b/app/src/test/kotlin/com/wespot/message/domain/MessageTest.kt index be69b413..bfa990e8 100644 --- a/app/src/test/kotlin/com/wespot/message/domain/MessageTest.kt +++ b/app/src/test/kotlin/com/wespot/message/domain/MessageTest.kt @@ -4,6 +4,8 @@ import com.wespot.exception.CustomException import com.wespot.message.Message import com.wespot.message.MessageTimeValidator import com.wespot.message.fixture.MessageFixture +import com.wespot.user.RestrictionType +import com.wespot.user.fixture.ProfileFixture import com.wespot.user.fixture.UserFixture import io.kotest.assertions.throwables.shouldThrow import io.kotest.core.spec.style.BehaviorSpec @@ -91,4 +93,145 @@ class MessageTest : BehaviorSpec({ unmockkStatic(LocalDateTime::class) } + given("쪽지를 수정할 때") { + val restrictionUser = + UserFixture.createUserWithIdAndRestrictionTypeAndRestrictDay( + 1, + listOf(Pair(RestrictionType.PERMANENT_BAN_MESSAGE_REPORT, Long.MAX_VALUE)) + ) + val withDrawUser = UserFixture.createWithId(2).withdraw().completeWithdraw(ProfileFixture.createWithId(1)) + val restrictionUserMessage = MessageFixture.createMessage("Hello", 2, 1, "senderName") + val withDrawUserMessage = MessageFixture.createMessage("Hello", 1, 2, "senderName") + `when`("수정하는 자가 탈퇴 혹은 이용제재를 당한 사용자라면") { + val shouldThrow1 = shouldThrow { + restrictionUserMessage.updateMessage( + "Hello1", + restrictionUser, + withDrawUser.id, + restrictionUser.name + ) + } + val shouldThrow2 = shouldThrow { + withDrawUserMessage.updateMessage( + "Hello2", + withDrawUser, + restrictionUser.id, + withDrawUser.name + ) + } + then("예외가 발생한다.") { + shouldThrow1 shouldHaveMessage "이용제한을 당한 학생은 해당 서비스를 이용할 수 없습니다." + shouldThrow2 shouldHaveMessage "탈퇴한 학생은 해당 서비스를 이용할 수 없습니다." + } + } + } + + given("쪽지를 보낼 때") { + val restrictionUser = + UserFixture.createUserWithIdAndRestrictionTypeAndRestrictDay( + 1, + listOf(Pair(RestrictionType.PERMANENT_BAN_MESSAGE_REPORT, Long.MAX_VALUE)) + ) + val withDrawUser = UserFixture.createWithId(2).withdraw().completeWithdraw(ProfileFixture.createWithId(1)) + `when`("송신자가 탈퇴 혹은 이용제재를 당한 사용자라면") { + val shouldThrow1 = shouldThrow { + Message.sendMessage( + "hello", + UserFixture.createWithId(3), + withDrawUser, + withDrawUser.name, + false, + ) + } + val shouldThrow2 = shouldThrow { + Message.sendMessage( + "hello", + UserFixture.createWithId(3), + restrictionUser, + restrictionUser.name, + false + ) + } + + then("예외가 발생한다.") { + shouldThrow1 shouldHaveMessage "탈퇴한 학생은 해당 서비스를 이용할 수 없습니다." + shouldThrow2 shouldHaveMessage "이용제한을 당한 학생은 해당 서비스를 이용할 수 없습니다." + } + } + + `when`("수신자가 탈퇴 혹은 이용제재를 당한 사용자라면") { + val shouldThrow1 = shouldThrow { + Message.sendMessage( + "hello", + withDrawUser, + UserFixture.createWithId(3), + "senderName", + false, + ) + } + val shouldThrow2 = shouldThrow { + Message.sendMessage( + "hello", + restrictionUser, + UserFixture.createWithId(3), + "senderName", + false + ) + } + + then("예외가 발생한다.") { + shouldThrow1 shouldHaveMessage "탈퇴한 학생은 해당 서비스를 이용할 수 없습니다." + shouldThrow2 shouldHaveMessage "이용제한을 당한 학생은 해당 서비스를 이용할 수 없습니다." + } + } + } + + given("받은 쪽지를 삭제할 때") { + val restrictionUser = + UserFixture.createUserWithIdAndRestrictionTypeAndRestrictDay( + 1, + listOf(Pair(RestrictionType.PERMANENT_BAN_MESSAGE_REPORT, Long.MAX_VALUE)) + ) + val withDrawUser = UserFixture.createWithId(2).withdraw().completeWithdraw(ProfileFixture.createWithId(1)) + val restrictionUserMessage = MessageFixture.createMessage("Hello", 2, 1, "senderName") + val withDrawUserMessage = MessageFixture.createMessage("Hello", 1, 2, "senderName") + `when`("수신자가 탈퇴 혹은 이용제재를 당한 사용자라면") { + val shouldThrow1 = shouldThrow { + withDrawUserMessage.receivedMessageSoftDelete(restrictionUser) + } + val shouldThrow2 = shouldThrow { + restrictionUserMessage.receivedMessageSoftDelete(withDrawUser) + } + + then("예외가 발생한다.") { + shouldThrow1 shouldHaveMessage "이용제한을 당한 학생은 해당 서비스를 이용할 수 없습니다." + shouldThrow2 shouldHaveMessage "탈퇴한 학생은 해당 서비스를 이용할 수 없습니다." + } + } + } + + given("보낸 쪽지를 삭제할 때") { + val restrictionUser = + UserFixture.createUserWithIdAndRestrictionTypeAndRestrictDay( + 1, + listOf(Pair(RestrictionType.PERMANENT_BAN_MESSAGE_REPORT, Long.MAX_VALUE)) + ) + val withDrawUser = UserFixture.createWithId(2).withdraw().completeWithdraw(ProfileFixture.createWithId(1)) + val restrictionUserMessage = MessageFixture.createMessage("Hello", 2, 1, "senderName") + val withDrawUserMessage = MessageFixture.createMessage("Hello", 1, 2, "senderName") + `when`("수신자가 탈퇴 혹은 이용제재를 당한 사용자라면") { + val shouldThrow1 = shouldThrow { + restrictionUserMessage.sendMessageSoftDelete(withDrawUser) + } + val shouldThrow2 = shouldThrow { + withDrawUserMessage.sendMessageSoftDelete(restrictionUser) + } + + then("예외가 발생한다.") { + shouldThrow1 shouldHaveMessage "탈퇴한 학생은 해당 서비스를 이용할 수 없습니다." + shouldThrow2 shouldHaveMessage "이용제한을 당한 학생은 해당 서비스를 이용할 수 없습니다." + } + } + } + }) diff --git a/app/src/test/kotlin/com/wespot/user/fixture/UserFixture.kt b/app/src/test/kotlin/com/wespot/user/fixture/UserFixture.kt index 4cb9d7f8..d546d3f3 100644 --- a/app/src/test/kotlin/com/wespot/user/fixture/UserFixture.kt +++ b/app/src/test/kotlin/com/wespot/user/fixture/UserFixture.kt @@ -392,4 +392,48 @@ object UserFixture { ) } + fun createUserWithIdAndRestrictionTypeAndRestrictDay( + id: Long, + restrictions: List> + ): User { + var restriction = Restriction.createInitialState() + for (eachRestriction in restrictions) { + restriction = restriction.addRestrict(eachRestriction.first, eachRestriction.second) + } + return User( + id = id, + email = "TestEmail@Kakako", + password = "TestPassword", + role = Role.USER, + name = "TestUser", + introduction = UserIntroduction.from("hello"), + gender = Gender.MALE, + schoolId = 1L, + grade = 1, + classNumber = 1, + setting = Setting(), + profile = Profile(0, "black", "image.png"), + fcm = FCM(0, "token", LocalDateTime.now()), + social = Social( + socialType = SocialType.KAKAO, + socialId = "1123123", + socialEmail = null, + socialRefreshToken = "refreshToken" + ), + userConsent = UserConsent( + id = 0, + consentType = ConsentType.MARKETING, + consentValue = true, + consentedAt = LocalDateTime.now() + ), + restriction = restriction, + createdAt = LocalDateTime.now(), + updatedAt = LocalDateTime.now(), + withdrawalStatus = WithdrawalStatus.NONE, + withdrawalRequestAt = null, + withdrawalCancelAt = null, + withdrawalCompleteAt = null + ) + } + } diff --git a/domain/src/main/kotlin/com/wespot/message/Message.kt b/domain/src/main/kotlin/com/wespot/message/Message.kt index b46dbd2d..3280b8cd 100644 --- a/domain/src/main/kotlin/com/wespot/message/Message.kt +++ b/domain/src/main/kotlin/com/wespot/message/Message.kt @@ -220,6 +220,7 @@ data class Message( fun sendMessageSoftDelete(loginUser: User): Message { validateDeleteSendMessage(loginUser) + validateRegulationUser(loginUser) return this.copy( isSenderDeleted = true, senderDeletedAt = LocalDateTime.now(), @@ -229,6 +230,7 @@ data class Message( fun receivedMessageSoftDelete(loginUser: User): Message { validateDeleteReceivedMessage(loginUser) + validateRegulationUser(loginUser) return this.copy( isReceiverDeleted = true, receiverDeletedAt = LocalDateTime.now(), From 3d9b864dd4cc2fbe8c0e6a0f5ad7efdfa4c6ceb6 Mon Sep 17 00:00:00 2001 From: jaeyeonkim Date: Tue, 27 Aug 2024 23:58:51 +0900 Subject: [PATCH 11/16] =?UTF-8?q?style:=20=EA=B0=9C=ED=96=89=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- domain/src/main/kotlin/com/wespot/vote/Vote.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/domain/src/main/kotlin/com/wespot/vote/Vote.kt b/domain/src/main/kotlin/com/wespot/vote/Vote.kt index 5f4ec02b..28800ae9 100644 --- a/domain/src/main/kotlin/com/wespot/vote/Vote.kt +++ b/domain/src/main/kotlin/com/wespot/vote/Vote.kt @@ -84,7 +84,6 @@ data class Vote( } } - fun findUsersForVote(classmates: List, user: User): List { validateUser(user) classmates.forEach { validateClassmate(it) } From b66a9e3fc9cc8e6b44c1fee43da097b5271e9d32 Mon Sep 17 00:00:00 2001 From: jaeyeonkim Date: Wed, 28 Aug 2024 00:14:32 +0900 Subject: [PATCH 12/16] =?UTF-8?q?test:=20VoteTest=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kotlin/com/wespot/vote/domain/VoteTest.kt | 84 +++++++++++++++++++ 1 file changed, 84 insertions(+) diff --git a/app/src/test/kotlin/com/wespot/vote/domain/VoteTest.kt b/app/src/test/kotlin/com/wespot/vote/domain/VoteTest.kt index 4e378824..c917e6ae 100644 --- a/app/src/test/kotlin/com/wespot/vote/domain/VoteTest.kt +++ b/app/src/test/kotlin/com/wespot/vote/domain/VoteTest.kt @@ -1,7 +1,9 @@ package com.wespot.vote.domain import com.wespot.exception.CustomException +import com.wespot.user.RestrictionType import com.wespot.user.User +import com.wespot.user.fixture.ProfileFixture import com.wespot.user.fixture.UserFixture import com.wespot.vote.RankCalculateService import com.wespot.vote.ReceivedVoteCalculateService @@ -14,6 +16,7 @@ import com.wespot.voteoption.fixture.VoteOptionFixture import io.kotest.assertions.throwables.shouldNotThrow import io.kotest.assertions.throwables.shouldThrow import io.kotest.core.spec.style.BehaviorSpec +import io.kotest.matchers.should import io.kotest.matchers.shouldBe import io.kotest.matchers.shouldNotBe import io.kotest.matchers.throwable.shouldHaveMessage @@ -98,6 +101,68 @@ class VoteTest() : BehaviorSpec({ } } + `when`("투표를 진행할 때, 송신자가 탈퇴 및 이용제재를 당한 상태라면") { + val vote = Vote.of(voteIdentifier, voteOptions, null) + val restrictionUser = + UserFixture.createUserWithIdAndRestrictionTypeAndRestrictDay( + 1, + listOf(Pair(RestrictionType.PERMANENT_BAN_MESSAGE_REPORT, Long.MAX_VALUE)) + ) + val withDrawUser = UserFixture.createWithId(2).withdraw().completeWithdraw(ProfileFixture.createWithId(1)) + val shouldThrow1 = shouldThrow { + vote.addBallot( + 1, + restrictionUser, + UserFixture.createWithId(3), + LocalDateTime.now() + ) + } + val shouldThrow2 = shouldThrow { + vote.addBallot( + 1, + withDrawUser, + UserFixture.createWithId(3), + LocalDateTime.now() + ) + } + + then("정상적으로 투표가 진행된다.") { + shouldThrow1 shouldHaveMessage "탈퇴한 학생은 해당 서비스를 이용할 수 없습니다." + shouldThrow2 shouldHaveMessage "이용제한을 당한 학생은 해당 서비스를 이용할 수 없습니다." + } + } + + `when`("투표를 진행할 때, 수신자가 탈퇴 및 이용제재를 당한 상태라면") { + val vote = Vote.of(voteIdentifier, voteOptions, null) + val restrictionUser = + UserFixture.createUserWithIdAndRestrictionTypeAndRestrictDay( + 1, + listOf(Pair(RestrictionType.PERMANENT_BAN_MESSAGE_REPORT, Long.MAX_VALUE)) + ) + val withDrawUser = UserFixture.createWithId(2).withdraw().completeWithdraw(ProfileFixture.createWithId(1)) + val shouldThrow1 = shouldThrow { + vote.addBallot( + 1, + UserFixture.createWithId(3), + restrictionUser, + LocalDateTime.now() + ) + } + val shouldThrow2 = shouldThrow { + vote.addBallot( + 1, + UserFixture.createWithId(3), + withDrawUser, + LocalDateTime.now() + ) + } + then("예외가 발생한다.") { + shouldThrow1 shouldHaveMessage "이용제한을 당한 학생은 해당 서비스를 이용할 수 없습니다." + shouldThrow2 shouldHaveMessage "탈퇴한 학생은 해당 서비스를 이용할 수 없습니다." + } + } + + `when`("중복되지 않은 투표를 하는 경우") { val vote = Vote.of(voteIdentifier, voteOptions, null) val users = listOf( @@ -171,6 +236,25 @@ class VoteTest() : BehaviorSpec({ } } + `when`("투표할 친구를 찾는 과정에서 탈퇴 및 제재를 당한 유저가 있다면") { + val users = createUserByCount(3).toMutableList() + users.add(UserFixture.createWithId(4).withdraw().completeWithdraw(ProfileFixture.createWithId(1))) + users.add( + UserFixture.createUserWithIdAndRestrictionTypeAndRestrictDay( + 5, + listOf(Pair(RestrictionType.PERMANENT_BAN_MESSAGE_REPORT, Long.MAX_VALUE)) + ) + ) + val vote = VoteFixture.createWithVoteNumberAndBallots(0, ballots) + val me = users[0] + val voteUsers = vote.findUsersForVote(users, me) + then("제외시킨다.") { + voteUsers.size shouldBe 2 + voteUsers.find { it.id == 2L } shouldBe null + voteUsers.find { it.id == 3L } shouldBe null + } + } + } given("투표 결과를 통해") { From 640d83cc0f3bd788920cc967ddf89ad735409641 Mon Sep 17 00:00:00 2001 From: jaeyeonkim Date: Wed, 28 Aug 2024 00:27:33 +0900 Subject: [PATCH 13/16] =?UTF-8?q?test:=20UserSearchTest=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/wespot/user/fixture/UserFixture.kt | 45 +++++++++++ .../mysql/UserJpaRepositoryTest.kt | 81 +++++++++++++++++++ 2 files changed, 126 insertions(+) create mode 100644 app/src/test/kotlin/com/wespot/user/infrastructure/mysql/UserJpaRepositoryTest.kt diff --git a/app/src/test/kotlin/com/wespot/user/fixture/UserFixture.kt b/app/src/test/kotlin/com/wespot/user/fixture/UserFixture.kt index d546d3f3..363a76c1 100644 --- a/app/src/test/kotlin/com/wespot/user/fixture/UserFixture.kt +++ b/app/src/test/kotlin/com/wespot/user/fixture/UserFixture.kt @@ -392,6 +392,51 @@ object UserFixture { ) } + fun createUserWithNameAndEmailAndRestrictionTypeAndRestrictDay( + name: String, + email: String, + restrictions: List> + ): User { + var restriction = Restriction.createInitialState() + for (eachRestriction in restrictions) { + restriction = restriction.addRestrict(eachRestriction.first, eachRestriction.second) + } + return User( + id = 0, + email = email, + password = "TestPassword", + role = Role.USER, + name = name, + introduction = UserIntroduction.from("hello"), + gender = Gender.MALE, + schoolId = 1L, + grade = 1, + classNumber = 1, + setting = Setting(), + profile = Profile(0, "black", "image.png"), + fcm = FCM(0, "token", LocalDateTime.now()), + social = Social( + socialType = SocialType.KAKAO, + socialId = "1123123", + socialEmail = null, + socialRefreshToken = "refreshToken" + ), + userConsent = UserConsent( + id = 0, + consentType = ConsentType.MARKETING, + consentValue = true, + consentedAt = LocalDateTime.now() + ), + restriction = restriction, + createdAt = LocalDateTime.now(), + updatedAt = LocalDateTime.now(), + withdrawalStatus = WithdrawalStatus.NONE, + withdrawalRequestAt = null, + withdrawalCancelAt = null, + withdrawalCompleteAt = null + ) + } + fun createUserWithIdAndRestrictionTypeAndRestrictDay( id: Long, restrictions: List> diff --git a/app/src/test/kotlin/com/wespot/user/infrastructure/mysql/UserJpaRepositoryTest.kt b/app/src/test/kotlin/com/wespot/user/infrastructure/mysql/UserJpaRepositoryTest.kt new file mode 100644 index 00000000..4ab3d8bf --- /dev/null +++ b/app/src/test/kotlin/com/wespot/user/infrastructure/mysql/UserJpaRepositoryTest.kt @@ -0,0 +1,81 @@ +package com.wespot.user.infrastructure.mysql + +import com.wespot.school.SchoolJpaRepository +import com.wespot.school.SchoolMapper +import com.wespot.school.fixture.SchoolFixture +import com.wespot.user.RestrictionType +import com.wespot.user.fixture.ProfileFixture +import com.wespot.user.fixture.UserFixture +import com.wespot.user.port.out.UserPort +import com.wespot.user.repository.UserJpaRepository +import io.kotest.matchers.shouldBe +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest +import org.springframework.data.domain.PageRequest +import kotlin.test.Test + +@DataJpaTest +class UserJpaRepositoryTest @Autowired constructor( + private val userPort: UserPort, + private val userJpaRepository: UserJpaRepository, + private val schoolJpaRepository: SchoolJpaRepository +) { + + @Test + fun `친구를 검색할 때, 탈퇴 및 이용제재에 걸려있는 친구와 본인은 조회하지 않는다`() { + // given + val school = SchoolFixture.createWithId(0) + val savedSchool = schoolJpaRepository.save(SchoolMapper.mapToJpaEntity(school)) + val user1 = userPort.save( + UserFixture.createUser( + 0, + "hello@kakao", + "hello", + savedSchool.id, + 1 + ) + ) + UserFixture.setSecurityContextUser(user1) + val user2 = userPort.save( + UserFixture.createUser( + 0, + "hello4@kakao", + "hello4", + savedSchool.id, + 1 + ) + ) + val restrictionUser = userPort.save( + UserFixture.createUserWithNameAndEmailAndRestrictionTypeAndRestrictDay( + "hell", + "hello1@kakao", + listOf(Pair(RestrictionType.TEMPORARY_BAN_MESSAGE_REPORT, 30)) + ) + ) + val withDrawUser = userPort.save( + UserFixture.createUser( + 0, + "hello1@kakao", + "helloo", + savedSchool.id, + 1 + ).withdraw().completeWithdraw(ProfileFixture.createWithId(1)) + ) + + // when + val searchUsers = userJpaRepository.searchUsers( + "he", + "hello", + "Test School", + 2, + 0, + 1, + PageRequest.of(0, 10), + ) + + // then + searchUsers.size shouldBe 1 + searchUsers[0].id shouldBe user2.id + } + +} From f269a970a315246bd02723a1f1026df9706f9e41 Mon Sep 17 00:00:00 2001 From: jaeyeonkim Date: Wed, 28 Aug 2024 00:31:46 +0900 Subject: [PATCH 14/16] =?UTF-8?q?test:=20classmate=20=EC=B0=BE=EB=8A=94=20?= =?UTF-8?q?jpa=20method=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/wespot/user/fixture/UserFixture.kt | 1 - .../mysql/UserJpaRepositoryTest.kt | 54 +++++++++++++++++++ .../kotlin/com/wespot/vote/domain/VoteTest.kt | 1 - 3 files changed, 54 insertions(+), 2 deletions(-) diff --git a/app/src/test/kotlin/com/wespot/user/fixture/UserFixture.kt b/app/src/test/kotlin/com/wespot/user/fixture/UserFixture.kt index 363a76c1..cf7e51c0 100644 --- a/app/src/test/kotlin/com/wespot/user/fixture/UserFixture.kt +++ b/app/src/test/kotlin/com/wespot/user/fixture/UserFixture.kt @@ -1,7 +1,6 @@ package com.wespot.user.fixture import com.wespot.auth.PrincipalDetails -import com.wespot.auth.dto.request.ProfileRequest import com.wespot.user.restriction.Restriction import com.wespot.user.Role import com.wespot.user.Setting diff --git a/app/src/test/kotlin/com/wespot/user/infrastructure/mysql/UserJpaRepositoryTest.kt b/app/src/test/kotlin/com/wespot/user/infrastructure/mysql/UserJpaRepositoryTest.kt index 4ab3d8bf..088b14d5 100644 --- a/app/src/test/kotlin/com/wespot/user/infrastructure/mysql/UserJpaRepositoryTest.kt +++ b/app/src/test/kotlin/com/wespot/user/infrastructure/mysql/UserJpaRepositoryTest.kt @@ -78,4 +78,58 @@ class UserJpaRepositoryTest @Autowired constructor( searchUsers[0].id shouldBe user2.id } + @Test + fun `탈퇴 및 이용제재가 아닌 유저만 반 친구로 조회한다`() { + // given + val school = SchoolFixture.createWithId(0) + val savedSchool = schoolJpaRepository.save(SchoolMapper.mapToJpaEntity(school)) + val user1 = userPort.save( + UserFixture.createUser( + 0, + "hello@kakao", + "hello", + savedSchool.id, + 1 + ) + ) + UserFixture.setSecurityContextUser(user1) + val user2 = userPort.save( + UserFixture.createUser( + 0, + "hello4@kakao", + "hello4", + savedSchool.id, + 1 + ) + ) + val restrictionUser = userPort.save( + UserFixture.createUserWithNameAndEmailAndRestrictionTypeAndRestrictDay( + "hell", + "hello1@kakao", + listOf(Pair(RestrictionType.TEMPORARY_BAN_MESSAGE_REPORT, 30)) + ) + ) + val withDrawUser = userPort.save( + UserFixture.createUser( + 0, + "hello1@kakao", + "helloo", + savedSchool.id, + 1 + ).withdraw().completeWithdraw(ProfileFixture.createWithId(1)) + ) + + // when + val classmateWithoutRegulationUser = userJpaRepository.findAllBySchoolIdAndGradeAndClassNumber( + savedSchool.id, + 1, + 1 + ) + + // then + classmateWithoutRegulationUser.size shouldBe 2 + classmateWithoutRegulationUser[0].id shouldBe user1.id + classmateWithoutRegulationUser[1].id shouldBe user2.id + } + } diff --git a/app/src/test/kotlin/com/wespot/vote/domain/VoteTest.kt b/app/src/test/kotlin/com/wespot/vote/domain/VoteTest.kt index c917e6ae..79f0d732 100644 --- a/app/src/test/kotlin/com/wespot/vote/domain/VoteTest.kt +++ b/app/src/test/kotlin/com/wespot/vote/domain/VoteTest.kt @@ -16,7 +16,6 @@ import com.wespot.voteoption.fixture.VoteOptionFixture import io.kotest.assertions.throwables.shouldNotThrow import io.kotest.assertions.throwables.shouldThrow import io.kotest.core.spec.style.BehaviorSpec -import io.kotest.matchers.should import io.kotest.matchers.shouldBe import io.kotest.matchers.shouldNotBe import io.kotest.matchers.throwable.shouldHaveMessage From 7d46fe4e7cef3748edd88a52e6dcbfe33769a296 Mon Sep 17 00:00:00 2001 From: jaeyeonkim Date: Wed, 28 Aug 2024 01:03:24 +0900 Subject: [PATCH 15/16] =?UTF-8?q?test:=20Test=20=EC=A0=84=EB=B6=80=20?= =?UTF-8?q?=ED=86=B5=EA=B3=BC=ED=95=98=EB=8F=84=EB=A1=9D=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/wespot/message/domain/MessageTest.kt | 10 +++---- .../mysql/UserJpaRepositoryTest.kt | 26 +++++++++---------- .../kotlin/com/wespot/vote/domain/VoteTest.kt | 9 +++---- 3 files changed, 21 insertions(+), 24 deletions(-) diff --git a/app/src/test/kotlin/com/wespot/message/domain/MessageTest.kt b/app/src/test/kotlin/com/wespot/message/domain/MessageTest.kt index bfa990e8..8a4d6452 100644 --- a/app/src/test/kotlin/com/wespot/message/domain/MessageTest.kt +++ b/app/src/test/kotlin/com/wespot/message/domain/MessageTest.kt @@ -219,17 +219,17 @@ class MessageTest : BehaviorSpec({ val withDrawUser = UserFixture.createWithId(2).withdraw().completeWithdraw(ProfileFixture.createWithId(1)) val restrictionUserMessage = MessageFixture.createMessage("Hello", 2, 1, "senderName") val withDrawUserMessage = MessageFixture.createMessage("Hello", 1, 2, "senderName") - `when`("수신자가 탈퇴 혹은 이용제재를 당한 사용자라면") { + `when`("송신자가 탈퇴 혹은 이용제재를 당한 사용자라면") { val shouldThrow1 = shouldThrow { - restrictionUserMessage.sendMessageSoftDelete(withDrawUser) + restrictionUserMessage.sendMessageSoftDelete(restrictionUser) } val shouldThrow2 = shouldThrow { - withDrawUserMessage.sendMessageSoftDelete(restrictionUser) + withDrawUserMessage.sendMessageSoftDelete(withDrawUser) } then("예외가 발생한다.") { - shouldThrow1 shouldHaveMessage "탈퇴한 학생은 해당 서비스를 이용할 수 없습니다." - shouldThrow2 shouldHaveMessage "이용제한을 당한 학생은 해당 서비스를 이용할 수 없습니다." + shouldThrow1 shouldHaveMessage "이용제한을 당한 학생은 해당 서비스를 이용할 수 없습니다." + shouldThrow2 shouldHaveMessage "탈퇴한 학생은 해당 서비스를 이용할 수 없습니다." } } } diff --git a/app/src/test/kotlin/com/wespot/user/infrastructure/mysql/UserJpaRepositoryTest.kt b/app/src/test/kotlin/com/wespot/user/infrastructure/mysql/UserJpaRepositoryTest.kt index 088b14d5..222c1dbe 100644 --- a/app/src/test/kotlin/com/wespot/user/infrastructure/mysql/UserJpaRepositoryTest.kt +++ b/app/src/test/kotlin/com/wespot/user/infrastructure/mysql/UserJpaRepositoryTest.kt @@ -1,5 +1,6 @@ package com.wespot.user.infrastructure.mysql +import com.wespot.common.service.ServiceTest import com.wespot.school.SchoolJpaRepository import com.wespot.school.SchoolMapper import com.wespot.school.fixture.SchoolFixture @@ -10,16 +11,14 @@ import com.wespot.user.port.out.UserPort import com.wespot.user.repository.UserJpaRepository import io.kotest.matchers.shouldBe import org.springframework.beans.factory.annotation.Autowired -import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest import org.springframework.data.domain.PageRequest import kotlin.test.Test -@DataJpaTest class UserJpaRepositoryTest @Autowired constructor( private val userPort: UserPort, private val userJpaRepository: UserJpaRepository, private val schoolJpaRepository: SchoolJpaRepository -) { +) : ServiceTest() { @Test fun `친구를 검색할 때, 탈퇴 및 이용제재에 걸려있는 친구와 본인은 조회하지 않는다`() { @@ -32,17 +31,16 @@ class UserJpaRepositoryTest @Autowired constructor( "hello@kakao", "hello", savedSchool.id, - 1 + 0 ) ) - UserFixture.setSecurityContextUser(user1) val user2 = userPort.save( UserFixture.createUser( 0, "hello4@kakao", "hello4", savedSchool.id, - 1 + 0 ) ) val restrictionUser = userPort.save( @@ -55,11 +53,11 @@ class UserJpaRepositoryTest @Autowired constructor( val withDrawUser = userPort.save( UserFixture.createUser( 0, - "hello1@kakao", + "hello2@kakao", "helloo", savedSchool.id, - 1 - ).withdraw().completeWithdraw(ProfileFixture.createWithId(1)) + 0 + ).withdraw().completeWithdraw(ProfileFixture.createWithId(0)) ) // when @@ -69,7 +67,7 @@ class UserJpaRepositoryTest @Autowired constructor( "Test School", 2, 0, - 1, + user1.id, PageRequest.of(0, 10), ) @@ -89,7 +87,7 @@ class UserJpaRepositoryTest @Autowired constructor( "hello@kakao", "hello", savedSchool.id, - 1 + 0 ) ) UserFixture.setSecurityContextUser(user1) @@ -99,7 +97,7 @@ class UserJpaRepositoryTest @Autowired constructor( "hello4@kakao", "hello4", savedSchool.id, - 1 + 0 ) ) val restrictionUser = userPort.save( @@ -115,8 +113,8 @@ class UserJpaRepositoryTest @Autowired constructor( "hello1@kakao", "helloo", savedSchool.id, - 1 - ).withdraw().completeWithdraw(ProfileFixture.createWithId(1)) + 0 + ).withdraw().completeWithdraw(ProfileFixture.createWithId(0)) ) // when diff --git a/app/src/test/kotlin/com/wespot/vote/domain/VoteTest.kt b/app/src/test/kotlin/com/wespot/vote/domain/VoteTest.kt index 79f0d732..cc47ca73 100644 --- a/app/src/test/kotlin/com/wespot/vote/domain/VoteTest.kt +++ b/app/src/test/kotlin/com/wespot/vote/domain/VoteTest.kt @@ -126,8 +126,8 @@ class VoteTest() : BehaviorSpec({ } then("정상적으로 투표가 진행된다.") { - shouldThrow1 shouldHaveMessage "탈퇴한 학생은 해당 서비스를 이용할 수 없습니다." - shouldThrow2 shouldHaveMessage "이용제한을 당한 학생은 해당 서비스를 이용할 수 없습니다." + shouldThrow1 shouldHaveMessage "이용제한을 당한 학생은 해당 서비스를 이용할 수 없습니다." + shouldThrow2 shouldHaveMessage "탈퇴한 학생은 해당 서비스를 이용할 수 없습니다." } } @@ -248,9 +248,8 @@ class VoteTest() : BehaviorSpec({ val me = users[0] val voteUsers = vote.findUsersForVote(users, me) then("제외시킨다.") { - voteUsers.size shouldBe 2 - voteUsers.find { it.id == 2L } shouldBe null - voteUsers.find { it.id == 3L } shouldBe null + voteUsers.size shouldBe 1 + voteUsers.find { it.id == 3L } shouldNotBe null } } From 7f035fdd01acacd550be3c38f46e0acfc7f54507 Mon Sep 17 00:00:00 2001 From: jaeyeonkim Date: Wed, 28 Aug 2024 01:23:59 +0900 Subject: [PATCH 16/16] =?UTF-8?q?test:=20Search=20User=20Service=20Test=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/wespot/user/fixture/UserFixture.kt | 7 +- .../mysql/UserJpaRepositoryTest.kt | 10 +- .../user/service/SearchUserServiceTest.kt | 122 ++++++++++++++++++ 3 files changed, 132 insertions(+), 7 deletions(-) create mode 100644 app/src/test/kotlin/com/wespot/user/service/SearchUserServiceTest.kt diff --git a/app/src/test/kotlin/com/wespot/user/fixture/UserFixture.kt b/app/src/test/kotlin/com/wespot/user/fixture/UserFixture.kt index cf7e51c0..25760d0c 100644 --- a/app/src/test/kotlin/com/wespot/user/fixture/UserFixture.kt +++ b/app/src/test/kotlin/com/wespot/user/fixture/UserFixture.kt @@ -391,10 +391,11 @@ object UserFixture { ) } - fun createUserWithNameAndEmailAndRestrictionTypeAndRestrictDay( + fun createUserWithNameAndEmailAndRestrictionTypeAndRestrictDayAndSchoolId( name: String, email: String, - restrictions: List> + restrictions: List>, + schoolId: Long, ): User { var restriction = Restriction.createInitialState() for (eachRestriction in restrictions) { @@ -408,7 +409,7 @@ object UserFixture { name = name, introduction = UserIntroduction.from("hello"), gender = Gender.MALE, - schoolId = 1L, + schoolId = schoolId, grade = 1, classNumber = 1, setting = Setting(), diff --git a/app/src/test/kotlin/com/wespot/user/infrastructure/mysql/UserJpaRepositoryTest.kt b/app/src/test/kotlin/com/wespot/user/infrastructure/mysql/UserJpaRepositoryTest.kt index 222c1dbe..6c682d59 100644 --- a/app/src/test/kotlin/com/wespot/user/infrastructure/mysql/UserJpaRepositoryTest.kt +++ b/app/src/test/kotlin/com/wespot/user/infrastructure/mysql/UserJpaRepositoryTest.kt @@ -44,10 +44,11 @@ class UserJpaRepositoryTest @Autowired constructor( ) ) val restrictionUser = userPort.save( - UserFixture.createUserWithNameAndEmailAndRestrictionTypeAndRestrictDay( + UserFixture.createUserWithNameAndEmailAndRestrictionTypeAndRestrictDayAndSchoolId( "hell", "hello1@kakao", - listOf(Pair(RestrictionType.TEMPORARY_BAN_MESSAGE_REPORT, 30)) + listOf(Pair(RestrictionType.TEMPORARY_BAN_MESSAGE_REPORT, 30)), + savedSchool.id ) ) val withDrawUser = userPort.save( @@ -101,10 +102,11 @@ class UserJpaRepositoryTest @Autowired constructor( ) ) val restrictionUser = userPort.save( - UserFixture.createUserWithNameAndEmailAndRestrictionTypeAndRestrictDay( + UserFixture.createUserWithNameAndEmailAndRestrictionTypeAndRestrictDayAndSchoolId( "hell", "hello1@kakao", - listOf(Pair(RestrictionType.TEMPORARY_BAN_MESSAGE_REPORT, 30)) + listOf(Pair(RestrictionType.TEMPORARY_BAN_MESSAGE_REPORT, 30)), + savedSchool.id ) ) val withDrawUser = userPort.save( diff --git a/app/src/test/kotlin/com/wespot/user/service/SearchUserServiceTest.kt b/app/src/test/kotlin/com/wespot/user/service/SearchUserServiceTest.kt new file mode 100644 index 00000000..400809c5 --- /dev/null +++ b/app/src/test/kotlin/com/wespot/user/service/SearchUserServiceTest.kt @@ -0,0 +1,122 @@ +package com.wespot.user.service + +import com.wespot.common.service.ServiceTest +import com.wespot.exception.CustomException +import com.wespot.school.SchoolJpaRepository +import com.wespot.school.SchoolMapper +import com.wespot.school.fixture.SchoolFixture +import com.wespot.user.RestrictionType +import com.wespot.user.fixture.ProfileFixture +import com.wespot.user.fixture.UserFixture +import com.wespot.user.port.out.UserPort +import io.kotest.assertions.throwables.shouldThrow +import io.kotest.matchers.shouldBe +import io.kotest.matchers.throwable.shouldHaveMessage +import org.springframework.beans.factory.annotation.Autowired +import kotlin.test.Test + +class SearchUserServiceTest @Autowired constructor( + private val searchUserService: SearchUserService, + private val schoolJpaRepository: SchoolJpaRepository, + private val userPort: UserPort, +) : ServiceTest() { + + @Test + fun `탈퇴 및 제재를 당한 유저가 검색을 하는 경우 예외가 발생한다`() { + // given + val school = SchoolFixture.createWithId(0) + val savedSchool = schoolJpaRepository.save(SchoolMapper.mapToJpaEntity(school)) + val restrictionUser = userPort.save( + UserFixture.createUserWithNameAndEmailAndRestrictionTypeAndRestrictDayAndSchoolId( + "hell", + "hello1@kakao", + listOf(Pair(RestrictionType.TEMPORARY_BAN_MESSAGE_REPORT, 30)), + savedSchool.id + ) + ) + val withDrawUser = userPort.save( + UserFixture.createUser( + 0, + "hello2@kakao", + "helloo", + savedSchool.id, + 0 + ).withdraw().completeWithdraw(ProfileFixture.createWithId(0)) + ) + + // when + UserFixture.setSecurityContextUser(restrictionUser) + val shouldThrow1 = shouldThrow { + searchUserService.searchUsers( + "he", + 0 + ) + } + UserFixture.setSecurityContextUser(withDrawUser) + val shouldThrow2 = shouldThrow { + searchUserService.searchUsers( + "he", + 0 + ) + } + + // then + shouldThrow1 shouldHaveMessage "규제를 당한 유저는 해당 서비스를 사용할 수 없습니다." + shouldThrow2 shouldHaveMessage "규제를 당한 유저는 해당 서비스를 사용할 수 없습니다." + } + + @Test + fun `탈퇴 및 제재를 당하지 않은 유저가 검색을 하는 경우 예외가 발생하지 않는다`() { + // given + val school = SchoolFixture.createWithId(0) + val savedSchool = schoolJpaRepository.save(SchoolMapper.mapToJpaEntity(school)) + val user1 = userPort.save( + UserFixture.createUser( + 0, + "hello@kakao", + "hello", + savedSchool.id, + 0 + ) + ) + val user2 = userPort.save( + UserFixture.createUser( + 0, + "hello2@kakao", + "hello2", + savedSchool.id, + 0 + ) + ) + val restrictionUser = userPort.save( + UserFixture.createUserWithNameAndEmailAndRestrictionTypeAndRestrictDayAndSchoolId( + "hell", + "hello1@kakao", + listOf(Pair(RestrictionType.TEMPORARY_BAN_MESSAGE_REPORT, 30)), + savedSchool.id + ) + ) + val withDrawUser = userPort.save( + UserFixture.createUser( + 0, + "hello2@kakao", + "helloo", + savedSchool.id, + 0 + ).withdraw().completeWithdraw(ProfileFixture.createWithId(0)) + ) + + // when + UserFixture.setSecurityContextUser(user1) + val searchUsers = searchUserService.searchUsers( + "he", + 0 + ) + + // then + searchUsers.users.size shouldBe 1 + searchUsers.hasNext shouldBe false + searchUsers.users[0].id shouldBe user2.id + } + +}