From d76f3f86650fdfe1039f05e1df653ad359adf0a5 Mon Sep 17 00:00:00 2001 From: KimDoubleB Date: Sun, 30 Jun 2024 02:48:09 +0900 Subject: [PATCH 1/8] fix: TargetRoomId to TargetPlaceId --- .../com/piikii/application/domain/place/PlaceService.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/piikii-application/src/main/kotlin/com/piikii/application/domain/place/PlaceService.kt b/piikii-application/src/main/kotlin/com/piikii/application/domain/place/PlaceService.kt index 783b6138..262ac16a 100644 --- a/piikii-application/src/main/kotlin/com/piikii/application/domain/place/PlaceService.kt +++ b/piikii-application/src/main/kotlin/com/piikii/application/domain/place/PlaceService.kt @@ -37,12 +37,12 @@ class PlaceService( @Transactional override fun modify( - targetRoomId: Long, + targetPlaceId: Long, modifyPlaceRequest: ModifyPlaceRequest, ) { placeCommandPort.update( - targetPlaceId = targetRoomId, - place = modifyPlaceRequest.toDomain(targetRoomId), + targetPlaceId = targetPlaceId, + place = modifyPlaceRequest.toDomain(targetPlaceId), ) } From 19038889ebbfeb51ae5b6ea21a033da4420d02e7 Mon Sep 17 00:00:00 2001 From: KimDoubleB Date: Sun, 30 Jun 2024 03:09:30 +0900 Subject: [PATCH 2/8] feat: update retrieve to findBy --- .../kotlin/com/piikii/application/domain/place/Place.kt | 2 ++ .../com/piikii/application/domain/place/PlaceService.kt | 2 +- .../com/piikii/application/domain/room/RoomService.kt | 8 ++++---- .../com/piikii/application/port/input/PlaceUseCase.kt | 2 +- .../com/piikii/application/port/input/RoomUseCase.kt | 2 +- .../application/port/input/dto/response/RoomResponse.kt | 2 +- .../application/port/output/persistence/PlacePort.kt | 4 +++- .../application/port/output/persistence/RoomPort.kt | 2 +- .../kotlin/com/piikii/input/http/controller/PlaceApi.kt | 2 +- .../kotlin/com/piikii/input/http/controller/RoomApi.kt | 2 +- .../output/persistence/postgresql/adapter/PlaceAdapter.kt | 6 +++++- .../output/persistence/postgresql/adapter/RoomAdapter.kt | 2 +- .../postgresql/persistence/entity/PlaceEntity.kt | 1 + 13 files changed, 23 insertions(+), 14 deletions(-) diff --git a/piikii-application/src/main/kotlin/com/piikii/application/domain/place/Place.kt b/piikii-application/src/main/kotlin/com/piikii/application/domain/place/Place.kt index 6d043f8e..3f25d3ce 100644 --- a/piikii-application/src/main/kotlin/com/piikii/application/domain/place/Place.kt +++ b/piikii-application/src/main/kotlin/com/piikii/application/domain/place/Place.kt @@ -3,6 +3,7 @@ package com.piikii.application.domain.place import com.piikii.application.domain.generic.Source import com.piikii.application.domain.generic.ThumbnailLinks import com.piikii.application.domain.schedule.PlaceType +import java.util.UUID data class Place( val id: Long? = 0L, @@ -13,4 +14,5 @@ data class Place( val phoneNumber: String? = null, val starGrade: Float? = null, val source: Source, + val roomId: UUID, ) diff --git a/piikii-application/src/main/kotlin/com/piikii/application/domain/place/PlaceService.kt b/piikii-application/src/main/kotlin/com/piikii/application/domain/place/PlaceService.kt index 262ac16a..841f9822 100644 --- a/piikii-application/src/main/kotlin/com/piikii/application/domain/place/PlaceService.kt +++ b/piikii-application/src/main/kotlin/com/piikii/application/domain/place/PlaceService.kt @@ -31,7 +31,7 @@ class PlaceService( ) } - override fun retrieveAllByRoomId(roomId: UUID): List { + override fun findAllByRoomId(roomId: UUID): List { return groupingByPlaceType(placeQueryPort.retrieveAllByRoomId(roomId)) } diff --git a/piikii-application/src/main/kotlin/com/piikii/application/domain/room/RoomService.kt b/piikii-application/src/main/kotlin/com/piikii/application/domain/room/RoomService.kt index 5c7d89af..41f3c85c 100644 --- a/piikii-application/src/main/kotlin/com/piikii/application/domain/room/RoomService.kt +++ b/piikii-application/src/main/kotlin/com/piikii/application/domain/room/RoomService.kt @@ -30,9 +30,9 @@ class RoomService( roomCommandPort.delete(roomId) } - override fun search(roomId: UUID): RoomResponse { - val retrievedRoom = roomQueryPort.retrieve(roomId) - return RoomResponse.fromDomain(retrievedRoom) + override fun findById(roomId: UUID): RoomResponse { + val retrievedRoom = roomQueryPort.findById(roomId) + return RoomResponse.from(retrievedRoom) } override fun changeVoteDeadline( @@ -40,7 +40,7 @@ class RoomService( password: Password, voteDeadline: LocalDateTime, ) { - roomQueryPort.retrieve(roomId).let { room -> + roomQueryPort.findById(roomId).let { room -> verifyPassword(room, password) roomCommandPort.update(room.copy(voteDeadline = voteDeadline)) } diff --git a/piikii-application/src/main/kotlin/com/piikii/application/port/input/PlaceUseCase.kt b/piikii-application/src/main/kotlin/com/piikii/application/port/input/PlaceUseCase.kt index 340a3246..63bfca99 100644 --- a/piikii-application/src/main/kotlin/com/piikii/application/port/input/PlaceUseCase.kt +++ b/piikii-application/src/main/kotlin/com/piikii/application/port/input/PlaceUseCase.kt @@ -12,7 +12,7 @@ interface PlaceUseCase { addPlaceRequest: AddPlaceRequest, ): PlaceResponse - fun retrieveAllByRoomId(roomId: UUID): List + fun findAllByRoomId(roomId: UUID): List fun modify( targetPlaceId: Long, diff --git a/piikii-application/src/main/kotlin/com/piikii/application/port/input/RoomUseCase.kt b/piikii-application/src/main/kotlin/com/piikii/application/port/input/RoomUseCase.kt index 193c6e84..4bb10d4a 100644 --- a/piikii-application/src/main/kotlin/com/piikii/application/port/input/RoomUseCase.kt +++ b/piikii-application/src/main/kotlin/com/piikii/application/port/input/RoomUseCase.kt @@ -15,7 +15,7 @@ interface RoomUseCase { fun remove(roomId: UUID) - fun search(roomId: UUID): RoomResponse + fun findById(roomId: UUID): RoomResponse fun changeVoteDeadline( roomId: UUID, diff --git a/piikii-application/src/main/kotlin/com/piikii/application/port/input/dto/response/RoomResponse.kt b/piikii-application/src/main/kotlin/com/piikii/application/port/input/dto/response/RoomResponse.kt index da468bf4..5c59cf43 100644 --- a/piikii-application/src/main/kotlin/com/piikii/application/port/input/dto/response/RoomResponse.kt +++ b/piikii-application/src/main/kotlin/com/piikii/application/port/input/dto/response/RoomResponse.kt @@ -23,7 +23,7 @@ data class RoomResponse( val roomId: UUID, ) { companion object { - fun fromDomain(room: Room): RoomResponse { + fun from(room: Room): RoomResponse { return RoomResponse( meetingName = room.meetingName, message = room.message, diff --git a/piikii-application/src/main/kotlin/com/piikii/application/port/output/persistence/PlacePort.kt b/piikii-application/src/main/kotlin/com/piikii/application/port/output/persistence/PlacePort.kt index 96de4644..1fab576f 100644 --- a/piikii-application/src/main/kotlin/com/piikii/application/port/output/persistence/PlacePort.kt +++ b/piikii-application/src/main/kotlin/com/piikii/application/port/output/persistence/PlacePort.kt @@ -4,7 +4,9 @@ import com.piikii.application.domain.place.Place import java.util.UUID interface PlaceQueryPort { - fun retrieveByPlaceId(placeId: Long): Place? + fun findByPlaceId(placeId: Long): Place? + + fun findAllByPlaceIds(placeIds: List): List fun retrieveAllByRoomId(roomId: UUID): List } diff --git a/piikii-application/src/main/kotlin/com/piikii/application/port/output/persistence/RoomPort.kt b/piikii-application/src/main/kotlin/com/piikii/application/port/output/persistence/RoomPort.kt index 91804ac5..26d4d78c 100644 --- a/piikii-application/src/main/kotlin/com/piikii/application/port/output/persistence/RoomPort.kt +++ b/piikii-application/src/main/kotlin/com/piikii/application/port/output/persistence/RoomPort.kt @@ -4,7 +4,7 @@ import com.piikii.application.domain.room.Room import java.util.UUID interface RoomQueryPort { - fun retrieve(roomId: UUID): Room + fun findById(roomId: UUID): Room } interface RoomCommandPort { diff --git a/piikii-input-http/src/main/kotlin/com/piikii/input/http/controller/PlaceApi.kt b/piikii-input-http/src/main/kotlin/com/piikii/input/http/controller/PlaceApi.kt index 06f0d74f..6db958ac 100644 --- a/piikii-input-http/src/main/kotlin/com/piikii/input/http/controller/PlaceApi.kt +++ b/piikii-input-http/src/main/kotlin/com/piikii/input/http/controller/PlaceApi.kt @@ -44,7 +44,7 @@ class PlaceApi( @PathVariable roomId: UUID, ): ResponseForm> { return ResponseForm( - data = placeUseCase.retrieveAllByRoomId(roomId), + data = placeUseCase.findAllByRoomId(roomId), ) } diff --git a/piikii-input-http/src/main/kotlin/com/piikii/input/http/controller/RoomApi.kt b/piikii-input-http/src/main/kotlin/com/piikii/input/http/controller/RoomApi.kt index 18dacafb..477c1326 100644 --- a/piikii-input-http/src/main/kotlin/com/piikii/input/http/controller/RoomApi.kt +++ b/piikii-input-http/src/main/kotlin/com/piikii/input/http/controller/RoomApi.kt @@ -61,7 +61,7 @@ class RoomApi( @PathVariable roomId: UUID, ): ResponseForm { return ResponseForm( - data = roomUseCase.search(roomId), + data = roomUseCase.findById(roomId), ) } } diff --git a/piikii-output-persistence/postgresql/src/main/kotlin/com/piikii/output/persistence/postgresql/adapter/PlaceAdapter.kt b/piikii-output-persistence/postgresql/src/main/kotlin/com/piikii/output/persistence/postgresql/adapter/PlaceAdapter.kt index af6f1ed1..fb19bce7 100644 --- a/piikii-output-persistence/postgresql/src/main/kotlin/com/piikii/output/persistence/postgresql/adapter/PlaceAdapter.kt +++ b/piikii-output-persistence/postgresql/src/main/kotlin/com/piikii/output/persistence/postgresql/adapter/PlaceAdapter.kt @@ -52,13 +52,17 @@ class PlaceAdapter( placeRepository.deleteById(targetPlaceId) } - override fun retrieveByPlaceId(placeId: Long): Place { + override fun findByPlaceId(placeId: Long): Place { return placeRepository.findByIdOrNull(placeId)?.toDomain() ?: throw PiikiiException( exceptionCode = ExceptionCode.NOT_FOUNDED, detailMessage = "placeId : $placeId", ) } + override fun findAllByPlaceIds(placeIds: List): List { + return placeRepository.findAllById(placeIds).map { it.toDomain() } + } + override fun retrieveAllByRoomId(roomId: UUID): List { return placeRepository.findAllByRoomId(roomId).map { it.toDomain() } } diff --git a/piikii-output-persistence/postgresql/src/main/kotlin/com/piikii/output/persistence/postgresql/adapter/RoomAdapter.kt b/piikii-output-persistence/postgresql/src/main/kotlin/com/piikii/output/persistence/postgresql/adapter/RoomAdapter.kt index 1a6a4c2e..82e8750f 100644 --- a/piikii-output-persistence/postgresql/src/main/kotlin/com/piikii/output/persistence/postgresql/adapter/RoomAdapter.kt +++ b/piikii-output-persistence/postgresql/src/main/kotlin/com/piikii/output/persistence/postgresql/adapter/RoomAdapter.kt @@ -33,7 +33,7 @@ class RoomAdapter( roomRepository.deleteByRoomId(roomId) } - override fun retrieve(roomId: UUID): Room { + override fun findById(roomId: UUID): Room { return findByRoomId(roomId).toDomain() } diff --git a/piikii-output-persistence/postgresql/src/main/kotlin/com/piikii/output/persistence/postgresql/persistence/entity/PlaceEntity.kt b/piikii-output-persistence/postgresql/src/main/kotlin/com/piikii/output/persistence/postgresql/persistence/entity/PlaceEntity.kt index d4f9e24b..7f625287 100644 --- a/piikii-output-persistence/postgresql/src/main/kotlin/com/piikii/output/persistence/postgresql/persistence/entity/PlaceEntity.kt +++ b/piikii-output-persistence/postgresql/src/main/kotlin/com/piikii/output/persistence/postgresql/persistence/entity/PlaceEntity.kt @@ -40,6 +40,7 @@ class PlaceEntity( ) : BaseEntity() { fun toDomain(): Place { return Place( + roomId = roomId, id = id, url = url, thumbnailLinks = ThumbnailLinks(thumbnailLinks), From fbd7ac431274a336af7ed1611e57042483c7b261 Mon Sep 17 00:00:00 2001 From: KimDoubleB Date: Sun, 30 Jun 2024 03:11:02 +0900 Subject: [PATCH 3/8] feat: verify place id of room is valid --- .../com/piikii/application/domain/place/Place.kt | 2 +- .../application/domain/vote/VoteService.kt | 16 +++++++++++++--- .../com/piikii/common/exception/ExceptionCode.kt | 2 ++ 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/piikii-application/src/main/kotlin/com/piikii/application/domain/place/Place.kt b/piikii-application/src/main/kotlin/com/piikii/application/domain/place/Place.kt index 3f25d3ce..ab123547 100644 --- a/piikii-application/src/main/kotlin/com/piikii/application/domain/place/Place.kt +++ b/piikii-application/src/main/kotlin/com/piikii/application/domain/place/Place.kt @@ -14,5 +14,5 @@ data class Place( val phoneNumber: String? = null, val starGrade: Float? = null, val source: Source, - val roomId: UUID, + val roomId: UUID? = null, ) diff --git a/piikii-application/src/main/kotlin/com/piikii/application/domain/vote/VoteService.kt b/piikii-application/src/main/kotlin/com/piikii/application/domain/vote/VoteService.kt index 885c2a66..6a14e38e 100644 --- a/piikii-application/src/main/kotlin/com/piikii/application/domain/vote/VoteService.kt +++ b/piikii-application/src/main/kotlin/com/piikii/application/domain/vote/VoteService.kt @@ -1,6 +1,7 @@ package com.piikii.application.domain.vote import com.piikii.application.port.input.VoteUseCase +import com.piikii.application.port.output.persistence.PlaceQueryPort import com.piikii.application.port.output.persistence.RoomQueryPort import com.piikii.application.port.output.persistence.VoteCommandPort import com.piikii.common.exception.ExceptionCode @@ -13,24 +14,32 @@ import java.util.UUID class VoteService( private val voteCommandPort: VoteCommandPort, private val roomQueryPort: RoomQueryPort, + private val placeQueryPort: PlaceQueryPort, ) : VoteUseCase { override fun vote( roomId: UUID, votes: List, ) { - if (roomQueryPort.retrieve(roomId).isVoteUnavailable()) { + val room = roomQueryPort.findById(roomId) + require(!room.isVoteUnavailable()) { throw PiikiiException( exceptionCode = ExceptionCode.ACCESS_DENIED, detailMessage = VOTE_UNAVAILABLE, ) } - // TODO: votes.map { it.placeId } 존재여부 검증 필요 -> 도현이 작업 완료되면 붙일 예정 + + val placeIds = votes.map { it.placeId } + val placesOfRoom = placeQueryPort.findAllByPlaceIds(placeIds).filter { it.roomId == roomId } + require(placesOfRoom.count() == votes.size) { + throw PiikiiException(exceptionCode = ExceptionCode.VOTE_PLACE_ID_INVALID) + } + voteCommandPort.vote(votes) } override fun isVoteFinished(roomId: UUID): Boolean { val voteDeadline = - roomQueryPort.retrieve(roomId).voteDeadline + roomQueryPort.findById(roomId).voteDeadline ?: throw PiikiiException( exceptionCode = ExceptionCode.ACCESS_DENIED, detailMessage = VOTE_NOT_STARTED, @@ -39,6 +48,7 @@ class VoteService( } companion object { + const val VOTE_DATE_FAILURE = "투표 요청 데이터가 올바르지 않습니다." const val VOTE_UNAVAILABLE = "투표가 시작되지 않았거나, 마감되었습니다" const val VOTE_NOT_STARTED = "투표가 시작되지 않았습니다" } diff --git a/piikii-common/src/main/kotlin/com/piikii/common/exception/ExceptionCode.kt b/piikii-common/src/main/kotlin/com/piikii/common/exception/ExceptionCode.kt index 4cb4081c..5a1cd16c 100644 --- a/piikii-common/src/main/kotlin/com/piikii/common/exception/ExceptionCode.kt +++ b/piikii-common/src/main/kotlin/com/piikii/common/exception/ExceptionCode.kt @@ -6,6 +6,8 @@ enum class ExceptionCode( ) { // 400 ILLEGAL_ARGUMENT_EXCEPTION(400, "요청 값이 올바르지 않습니다."), + VOTE_PLACE_ID_INVALID(400, "투표 항목 데이터(Place Id)이 올바르지 않습니다."), + UNAUTHORIZED(401, "인증된 토큰으로부터의 요청이 아닙니다."), ROOM_PASSWORD_INVALID(401, "방 패스워드가 틀립니다."), ACCESS_DENIED(403, "해당 리소스에 접근할 수 없습니다."), From fbaecb24e3cc5340ec575a5f742c1e2ecdb2a4cc Mon Sep 17 00:00:00 2001 From: KimDoubleB Date: Sun, 30 Jun 2024 04:23:27 +0900 Subject: [PATCH 4/8] feat: PiikiiException send data to super class (RuntimeException) --- .../common/exception/PiikiiException.kt | 33 ++++++++++--------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/piikii-common/src/main/kotlin/com/piikii/common/exception/PiikiiException.kt b/piikii-common/src/main/kotlin/com/piikii/common/exception/PiikiiException.kt index 111ab96a..ed650a7d 100644 --- a/piikii-common/src/main/kotlin/com/piikii/common/exception/PiikiiException.kt +++ b/piikii-common/src/main/kotlin/com/piikii/common/exception/PiikiiException.kt @@ -1,19 +1,22 @@ package com.piikii.common.exception -class PiikiiException( - var statusCode: Int, - var defaultMessage: String, - var detailMessage: String?, -) : RuntimeException() { - constructor(exceptionCode: ExceptionCode, detailMessage: String) : this( - statusCode = exceptionCode.statusCode, - defaultMessage = exceptionCode.defaultMessage, - detailMessage = detailMessage, - ) +class PiikiiException : RuntimeException { + var statusCode: Int + var defaultMessage: String + var detailMessage: String? = null - constructor(exceptionCode: ExceptionCode) : this( - statusCode = exceptionCode.statusCode, - defaultMessage = exceptionCode.defaultMessage, - detailMessage = null, - ) + constructor( + exceptionCode: ExceptionCode, + detailMessage: String, + ) : super("[$exceptionCode] $detailMessage") { + this.statusCode = exceptionCode.statusCode + this.defaultMessage = exceptionCode.defaultMessage + this.detailMessage = detailMessage + } + + constructor(exceptionCode: ExceptionCode) : + super("[$exceptionCode] ${exceptionCode.defaultMessage}") { + this.statusCode = exceptionCode.statusCode + this.defaultMessage = exceptionCode.defaultMessage + } } From d4da65b2c3582c622c0be1f0f052e410c539aa31 Mon Sep 17 00:00:00 2001 From: KimDoubleB Date: Sun, 30 Jun 2024 04:23:36 +0900 Subject: [PATCH 5/8] feat: remove unused const --- .../kotlin/com/piikii/application/domain/vote/VoteService.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/piikii-application/src/main/kotlin/com/piikii/application/domain/vote/VoteService.kt b/piikii-application/src/main/kotlin/com/piikii/application/domain/vote/VoteService.kt index 6a14e38e..306a401d 100644 --- a/piikii-application/src/main/kotlin/com/piikii/application/domain/vote/VoteService.kt +++ b/piikii-application/src/main/kotlin/com/piikii/application/domain/vote/VoteService.kt @@ -48,7 +48,6 @@ class VoteService( } companion object { - const val VOTE_DATE_FAILURE = "투표 요청 데이터가 올바르지 않습니다." const val VOTE_UNAVAILABLE = "투표가 시작되지 않았거나, 마감되었습니다" const val VOTE_NOT_STARTED = "투표가 시작되지 않았습니다" } From 8051c0489e127c39a662d94536a57a6b06308004 Mon Sep 17 00:00:00 2001 From: KimDoubleB Date: Sun, 30 Jun 2024 04:23:43 +0900 Subject: [PATCH 6/8] test: added vote test --- .../domain/vote/VoteServiceTest.kt | 251 ++++++++++++++++++ 1 file changed, 251 insertions(+) create mode 100644 piikii-application/src/test/kotlin/com/piikii/application/domain/vote/VoteServiceTest.kt diff --git a/piikii-application/src/test/kotlin/com/piikii/application/domain/vote/VoteServiceTest.kt b/piikii-application/src/test/kotlin/com/piikii/application/domain/vote/VoteServiceTest.kt new file mode 100644 index 00000000..3c8d910f --- /dev/null +++ b/piikii-application/src/test/kotlin/com/piikii/application/domain/vote/VoteServiceTest.kt @@ -0,0 +1,251 @@ +package com.piikii.application.domain.vote + +import com.piikii.application.domain.generic.Source +import com.piikii.application.domain.generic.ThumbnailLinks +import com.piikii.application.domain.place.Place +import com.piikii.application.domain.room.Password +import com.piikii.application.domain.room.Room +import com.piikii.application.domain.schedule.PlaceType +import com.piikii.application.port.output.persistence.PlaceQueryPort +import com.piikii.application.port.output.persistence.RoomQueryPort +import com.piikii.application.port.output.persistence.VoteCommandPort +import com.piikii.common.exception.PiikiiException +import org.assertj.core.api.Assertions.assertThatThrownBy +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertDoesNotThrow +import org.junit.jupiter.api.extension.ExtendWith +import org.junit.jupiter.params.ParameterizedTest +import org.junit.jupiter.params.provider.MethodSource +import org.mockito.BDDMockito.given +import org.mockito.BDDMockito.verify +import org.mockito.InjectMocks +import org.mockito.Mock +import org.mockito.junit.jupiter.MockitoExtension +import java.time.LocalDate +import java.time.LocalDateTime +import java.util.UUID +import java.util.stream.Stream + +@ExtendWith(MockitoExtension::class) +class VoteServiceTest { + @InjectMocks + lateinit var voteService: VoteService + + @Mock + lateinit var voteCommandPort: VoteCommandPort + + @Mock + lateinit var roomQueryPort: RoomQueryPort + + @Mock + lateinit var placeQueryPort: PlaceQueryPort + + @MethodSource("voteUnavailableRoom") + @ParameterizedTest + fun `Room Vote가 불가능한 상황에서 vote 요청 시 Exception이 발생한다`(room: Room) { + // given, when + given(roomQueryPort.findById(room.roomId)) + .willReturn(room) + + // then + assertThatThrownBy { voteService.vote(room.roomId, emptyList()) } + .isExactlyInstanceOf(PiikiiException::class.java) + .hasMessageContaining("투표가 시작되지 않았거나, 마감되었습니다") + } + + @Test + fun `Vote Place Id가 존재하지 않으면 Exception이 발생한다`() { + // given + val userId = UUID.randomUUID() + val roomId = UUID.randomUUID() + + val room = + Room( + meetingName = "BB Kim", + message = null, + address = "gunpo si", + meetDay = LocalDate.now(), + thumbnailLink = "https://test", + password = Password("1234"), + voteDeadline = LocalDateTime.now().plusDays(1), + roomId = roomId, + ) + val votes = + listOf( + Vote(userId = userId, placeId = 1, result = VoteResult.O), + Vote(userId = userId, placeId = 2, result = VoteResult.X), + Vote(userId = userId, placeId = 3, result = VoteResult.O), + ) + val place = + Place( + id = null, + placeType = PlaceType.ARCADE, + url = null, + thumbnailLinks = ThumbnailLinks(contents = null), + address = null, + phoneNumber = null, + starGrade = null, + source = Source.MANUAL, + roomId = roomId, + ) + + // when + given(roomQueryPort.findById(room.roomId)) + .willReturn(room) + given(placeQueryPort.findAllByPlaceIds(votes.map { it.placeId })) + .willReturn(listOf(place)) + + // then + assertThatThrownBy { voteService.vote(room.roomId, votes) } + .isExactlyInstanceOf(PiikiiException::class.java) + .hasMessageContaining("투표 항목 데이터(Place Id)이 올바르지 않습니다") + } + + @Test + fun `Vote Place Id가 해당 Room에 속하지 않을 경우, Exception이 발생한다`() { + // given + val userId = UUID.randomUUID() + val roomId = UUID.randomUUID() + + val room = + Room( + meetingName = "BB Kim", + message = null, + address = "gunpo si", + meetDay = LocalDate.now(), + thumbnailLink = "https://test", + password = Password("1234"), + voteDeadline = LocalDateTime.now().plusDays(1), + roomId = roomId, + ) + val votes = + listOf( + Vote(userId = userId, placeId = 1, result = VoteResult.O), + Vote(userId = userId, placeId = 2, result = VoteResult.X), + ) + val places = + listOf( + Place( + id = null, + placeType = PlaceType.ARCADE, + url = null, + thumbnailLinks = ThumbnailLinks(contents = null), + address = null, + phoneNumber = null, + starGrade = null, + source = Source.MANUAL, + roomId = UUID.randomUUID(), + ), + Place( + id = null, + placeType = PlaceType.ARCADE, + url = null, + thumbnailLinks = ThumbnailLinks(contents = null), + address = null, + phoneNumber = null, + starGrade = null, + source = Source.MANUAL, + roomId = UUID.randomUUID(), + ), + ) + + // when + given(roomQueryPort.findById(room.roomId)) + .willReturn(room) + given(placeQueryPort.findAllByPlaceIds(votes.map { it.placeId })) + .willReturn(places) + + // then + assertThatThrownBy { voteService.vote(room.roomId, votes) } + .isExactlyInstanceOf(PiikiiException::class.java) + .hasMessageContaining("투표 항목 데이터(Place Id)이 올바르지 않습니다") + } + + @Test + fun `올바른 데이터에서 vote는 성공한다`() { + // given + val userId = UUID.randomUUID() + val roomId = UUID.randomUUID() + + val room = + Room( + meetingName = "BB Kim", + message = null, + address = "gunpo si", + meetDay = LocalDate.now(), + thumbnailLink = "https://test", + password = Password("1234"), + voteDeadline = LocalDateTime.now().plusDays(1), + roomId = roomId, + ) + val votes = + listOf( + Vote(userId = userId, placeId = 1, result = VoteResult.O), + Vote(userId = userId, placeId = 2, result = VoteResult.X), + ) + val places = + listOf( + Place( + id = null, + placeType = PlaceType.ARCADE, + url = null, + thumbnailLinks = ThumbnailLinks(contents = null), + address = null, + phoneNumber = null, + starGrade = null, + source = Source.MANUAL, + roomId = roomId, + ), + Place( + id = null, + placeType = PlaceType.ARCADE, + url = null, + thumbnailLinks = ThumbnailLinks(contents = null), + address = null, + phoneNumber = null, + starGrade = null, + source = Source.MANUAL, + roomId = roomId, + ), + ) + + // when + given(roomQueryPort.findById(roomId)) + .willReturn(room) + given(placeQueryPort.findAllByPlaceIds(votes.map { it.placeId })) + .willReturn(places) + + // then + assertDoesNotThrow { voteService.vote(roomId, votes) } + verify(voteCommandPort).vote(votes) + } + + companion object { + @JvmStatic + fun voteUnavailableRoom(): Stream { + val roomId = UUID.randomUUID() + return Stream.of( + Room( + meetingName = "BB Kim", + message = null, + address = "gunpo si", + meetDay = LocalDate.now(), + thumbnailLink = "https://test", + password = Password("1234"), + voteDeadline = null, + roomId = roomId, + ), + Room( + meetingName = "BB Kim", + message = null, + address = "gunpo si", + meetDay = LocalDate.now(), + thumbnailLink = "https://test", + password = Password("1234"), + voteDeadline = LocalDateTime.of(1995, 9, 25, 1, 1, 1), + roomId = roomId, + ), + ) + } + } +} From 77d8a9162127eff48ae56203ffa64860fed8500e Mon Sep 17 00:00:00 2001 From: KimDoubleB Date: Thu, 4 Jul 2024 01:50:38 +0900 Subject: [PATCH 7/8] feat: roomId of Place is not nullable --- .../com/piikii/application/domain/place/Place.kt | 2 +- .../piikii/application/domain/place/PlaceService.kt | 9 +++++---- .../com/piikii/application/port/input/PlaceUseCase.kt | 3 ++- .../application/port/input/dto/request/PlaceRequest.kt | 10 ++++++++-- .../com/piikii/input/http/controller/PlaceApi.kt | 2 +- 5 files changed, 17 insertions(+), 9 deletions(-) diff --git a/piikii-application/src/main/kotlin/com/piikii/application/domain/place/Place.kt b/piikii-application/src/main/kotlin/com/piikii/application/domain/place/Place.kt index ab123547..3f25d3ce 100644 --- a/piikii-application/src/main/kotlin/com/piikii/application/domain/place/Place.kt +++ b/piikii-application/src/main/kotlin/com/piikii/application/domain/place/Place.kt @@ -14,5 +14,5 @@ data class Place( val phoneNumber: String? = null, val starGrade: Float? = null, val source: Source, - val roomId: UUID? = null, + val roomId: UUID, ) diff --git a/piikii-application/src/main/kotlin/com/piikii/application/domain/place/PlaceService.kt b/piikii-application/src/main/kotlin/com/piikii/application/domain/place/PlaceService.kt index 841f9822..102f8937 100644 --- a/piikii-application/src/main/kotlin/com/piikii/application/domain/place/PlaceService.kt +++ b/piikii-application/src/main/kotlin/com/piikii/application/domain/place/PlaceService.kt @@ -20,13 +20,13 @@ class PlaceService( ) : PlaceUseCase { @Transactional override fun addPlace( - targetRoomId: UUID, + roomId: UUID, addPlaceRequest: AddPlaceRequest, ): PlaceResponse { return PlaceResponse( placeCommandPort.save( - targetRoomId = targetRoomId, - place = addPlaceRequest.toDomain(), + targetRoomId = roomId, + place = addPlaceRequest.toDomain(roomId), ), ) } @@ -37,12 +37,13 @@ class PlaceService( @Transactional override fun modify( + roomId: UUID, targetPlaceId: Long, modifyPlaceRequest: ModifyPlaceRequest, ) { placeCommandPort.update( targetPlaceId = targetPlaceId, - place = modifyPlaceRequest.toDomain(targetPlaceId), + place = modifyPlaceRequest.toDomain(roomId, targetPlaceId), ) } diff --git a/piikii-application/src/main/kotlin/com/piikii/application/port/input/PlaceUseCase.kt b/piikii-application/src/main/kotlin/com/piikii/application/port/input/PlaceUseCase.kt index 63bfca99..7bad17ae 100644 --- a/piikii-application/src/main/kotlin/com/piikii/application/port/input/PlaceUseCase.kt +++ b/piikii-application/src/main/kotlin/com/piikii/application/port/input/PlaceUseCase.kt @@ -8,13 +8,14 @@ import java.util.UUID interface PlaceUseCase { fun addPlace( - targetRoomId: UUID, + roomId: UUID, addPlaceRequest: AddPlaceRequest, ): PlaceResponse fun findAllByRoomId(roomId: UUID): List fun modify( + roomId: UUID, targetPlaceId: Long, modifyPlaceRequest: ModifyPlaceRequest, ) diff --git a/piikii-application/src/main/kotlin/com/piikii/application/port/input/dto/request/PlaceRequest.kt b/piikii-application/src/main/kotlin/com/piikii/application/port/input/dto/request/PlaceRequest.kt index 77dfafdc..91f4a8e6 100644 --- a/piikii-application/src/main/kotlin/com/piikii/application/port/input/dto/request/PlaceRequest.kt +++ b/piikii-application/src/main/kotlin/com/piikii/application/port/input/dto/request/PlaceRequest.kt @@ -4,6 +4,7 @@ import com.piikii.application.domain.generic.Source import com.piikii.application.domain.generic.ThumbnailLinks import com.piikii.application.domain.place.Place import com.piikii.application.domain.schedule.PlaceType +import java.util.UUID data class AddPlaceRequest( val url: String? = null, @@ -14,7 +15,7 @@ data class AddPlaceRequest( val source: Source, val placeType: PlaceType, ) { - fun toDomain(): Place { + fun toDomain(roomId: UUID): Place { return Place( id = null, url = url, @@ -24,6 +25,7 @@ data class AddPlaceRequest( starGrade = starGrade, source = source, placeType = placeType, + roomId = roomId, ) } } @@ -37,7 +39,10 @@ data class ModifyPlaceRequest( val source: Source, val placeType: PlaceType, ) { - fun toDomain(targetPlaceId: Long): Place { + fun toDomain( + roomId: UUID, + targetPlaceId: Long, + ): Place { return Place( id = targetPlaceId, url = url, @@ -47,6 +52,7 @@ data class ModifyPlaceRequest( starGrade = starGrade, source = source, placeType = placeType, + roomId = roomId, ) } } diff --git a/piikii-input-http/src/main/kotlin/com/piikii/input/http/controller/PlaceApi.kt b/piikii-input-http/src/main/kotlin/com/piikii/input/http/controller/PlaceApi.kt index 6db958ac..0161c54b 100644 --- a/piikii-input-http/src/main/kotlin/com/piikii/input/http/controller/PlaceApi.kt +++ b/piikii-input-http/src/main/kotlin/com/piikii/input/http/controller/PlaceApi.kt @@ -55,7 +55,7 @@ class PlaceApi( @RequestBody @Valid modifyPlaceRequest: ModifyPlaceRequest, ): ResponseForm { return ResponseForm( - data = placeUseCase.modify(targetPlaceId, modifyPlaceRequest), + data = placeUseCase.modify(roomId, targetPlaceId, modifyPlaceRequest), ) } From 5a9ea1f18f59487cae9ac799b3566559d99fc4ab Mon Sep 17 00:00:00 2001 From: KimDoubleB Date: Thu, 4 Jul 2024 01:51:08 +0900 Subject: [PATCH 8/8] test: fix test comments --- .../piikii/application/domain/vote/VoteServiceTest.kt | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/piikii-application/src/test/kotlin/com/piikii/application/domain/vote/VoteServiceTest.kt b/piikii-application/src/test/kotlin/com/piikii/application/domain/vote/VoteServiceTest.kt index 3c8d910f..57980cc7 100644 --- a/piikii-application/src/test/kotlin/com/piikii/application/domain/vote/VoteServiceTest.kt +++ b/piikii-application/src/test/kotlin/com/piikii/application/domain/vote/VoteServiceTest.kt @@ -89,13 +89,12 @@ class VoteServiceTest { roomId = roomId, ) - // when given(roomQueryPort.findById(room.roomId)) .willReturn(room) given(placeQueryPort.findAllByPlaceIds(votes.map { it.placeId })) .willReturn(listOf(place)) - // then + // when & then assertThatThrownBy { voteService.vote(room.roomId, votes) } .isExactlyInstanceOf(PiikiiException::class.java) .hasMessageContaining("투표 항목 데이터(Place Id)이 올바르지 않습니다") @@ -149,13 +148,12 @@ class VoteServiceTest { ), ) - // when given(roomQueryPort.findById(room.roomId)) .willReturn(room) given(placeQueryPort.findAllByPlaceIds(votes.map { it.placeId })) .willReturn(places) - // then + // when & then assertThatThrownBy { voteService.vote(room.roomId, votes) } .isExactlyInstanceOf(PiikiiException::class.java) .hasMessageContaining("투표 항목 데이터(Place Id)이 올바르지 않습니다") @@ -209,13 +207,12 @@ class VoteServiceTest { ), ) - // when given(roomQueryPort.findById(roomId)) .willReturn(room) given(placeQueryPort.findAllByPlaceIds(votes.map { it.placeId })) .willReturn(places) - // then + // when & then assertDoesNotThrow { voteService.vote(roomId, votes) } verify(voteCommandPort).vote(votes) }