diff --git a/src/main/kotlin/upbrella/be/config/event/EventConfiguration.kt b/src/main/kotlin/upbrella/be/config/event/EventConfiguration.kt new file mode 100644 index 00000000..2e2a2501 --- /dev/null +++ b/src/main/kotlin/upbrella/be/config/event/EventConfiguration.kt @@ -0,0 +1,18 @@ +package upbrella.be.config.event + +import org.springframework.beans.factory.InitializingBean +import org.springframework.context.ApplicationContext +import org.springframework.context.annotation.Bean +import org.springframework.context.annotation.Configuration +import upbrella.be.util.event.Events + +@Configuration +class EventsConfiguration( + private val applicationContext: ApplicationContext +) { + + @Bean + fun eventsInitializer(): InitializingBean { + return InitializingBean { Events.setPublisher(applicationContext) } + } +} diff --git a/src/main/kotlin/upbrella/be/rent/dto/response/ConditionReportResponse.kt b/src/main/kotlin/upbrella/be/rent/dto/response/ConditionReportResponse.kt index c67a0bbb..af629056 100644 --- a/src/main/kotlin/upbrella/be/rent/dto/response/ConditionReportResponse.kt +++ b/src/main/kotlin/upbrella/be/rent/dto/response/ConditionReportResponse.kt @@ -1,21 +1,8 @@ package upbrella.be.rent.dto.response -import upbrella.be.rent.entity.ConditionReport - data class ConditionReportResponse( val id: Long, val umbrellaUuid: Long, val content: String?, val etc: String? -) { - companion object { - fun fromConditionReport(conditionReport: ConditionReport): ConditionReportResponse { - return ConditionReportResponse( - id = conditionReport.history.id!!, - umbrellaUuid = conditionReport.history.umbrella.uuid, - content = conditionReport.content, - etc = conditionReport.etc - ) - } - } -} +) diff --git a/src/main/kotlin/upbrella/be/rent/dto/response/ImprovementReportResponse.kt b/src/main/kotlin/upbrella/be/rent/dto/response/ImprovementReportResponse.kt index d77258b9..4b753265 100644 --- a/src/main/kotlin/upbrella/be/rent/dto/response/ImprovementReportResponse.kt +++ b/src/main/kotlin/upbrella/be/rent/dto/response/ImprovementReportResponse.kt @@ -1,21 +1,8 @@ package upbrella.be.rent.dto.response -import upbrella.be.rent.entity.ImprovementReport - data class ImprovementReportResponse( val id: Long = 0, val umbrellaUuid: Long = 0, val content: String? = "", val etc: String? = "" -) { - companion object { - fun fromImprovementReport(improvementReport: ImprovementReport): ImprovementReportResponse { - return ImprovementReportResponse( - id = improvementReport.history.id ?: 0, - umbrellaUuid = improvementReport.history.umbrella.uuid, - content = improvementReport.content, - etc = improvementReport.etc - ) - } - } -} +) diff --git a/src/main/kotlin/upbrella/be/rent/entity/ConditionReport.kt b/src/main/kotlin/upbrella/be/rent/entity/ConditionReport.kt index aa8dba1b..bce0eef0 100644 --- a/src/main/kotlin/upbrella/be/rent/entity/ConditionReport.kt +++ b/src/main/kotlin/upbrella/be/rent/entity/ConditionReport.kt @@ -4,9 +4,7 @@ import javax.persistence.* @Entity class ConditionReport( - @OneToOne - @JoinColumn(name = "history_id") - val history: History, + val historyId: Long, val content: String? = null, val etc: String? = null, @Id diff --git a/src/main/kotlin/upbrella/be/rent/entity/ImprovementReport.kt b/src/main/kotlin/upbrella/be/rent/entity/ImprovementReport.kt index cd6ca6f1..114cab0b 100644 --- a/src/main/kotlin/upbrella/be/rent/entity/ImprovementReport.kt +++ b/src/main/kotlin/upbrella/be/rent/entity/ImprovementReport.kt @@ -4,9 +4,7 @@ import javax.persistence.* @Entity class ImprovementReport( - @OneToOne - @JoinColumn(name = "history_id") - val history: History, + val historyId: Long, val content: String? = null, val etc: String? = null, @Id diff --git a/src/main/kotlin/upbrella/be/rent/event/RentEventHandler.kt b/src/main/kotlin/upbrella/be/rent/event/RentEventHandler.kt new file mode 100644 index 00000000..b56c2ae3 --- /dev/null +++ b/src/main/kotlin/upbrella/be/rent/event/RentEventHandler.kt @@ -0,0 +1,88 @@ +package upbrella.be.rent.event + +import org.springframework.context.event.EventListener +import org.springframework.stereotype.Service +import upbrella.be.rent.entity.ConditionReport +import upbrella.be.rent.entity.ImprovementReport +import upbrella.be.rent.service.ConditionReportService +import upbrella.be.rent.service.ImprovementReportService +import upbrella.be.rent.service.RentService +import upbrella.be.slack.SlackAlarmService +import upbrella.be.slack.dto.service.input.NotifyConditionReportInput +import upbrella.be.slack.dto.service.input.NotifyImprovementReportInput +import upbrella.be.slack.dto.service.input.NotifyRentInput +import upbrella.be.slack.dto.service.input.NotifyReturnInput + +@Service +class RentEventHandler( + private val slackAlarmService: SlackAlarmService, + private val conditionReportService: ConditionReportService, + private val rentService: RentService, + private val improvementReportService: ImprovementReportService, +) { + + @EventListener(UmbrellaRentedEvent::class) + fun handleUmbrellaRentedEvent(event: UmbrellaRentedEvent) { + slackAlarmService.notifyRent( + NotifyRentInput( + userId = event.userId, + userName = event.userName, + rentStoreName = event.rentStoreName + ) + ) + + event.conditionReportContent + ?.takeIf { it.isNotBlank() } + ?.let { content -> + ConditionReport( + historyId = event.historyId, + content = content + ).also { conditionReport -> + conditionReportService.saveConditionReport(conditionReport) + slackAlarmService.notifyConditionReport( + NotifyConditionReportInput( + umbrellaId = event.umbrellaId, + rentStoreName = event.rentStoreName, + content = content + ) + ) + } + } + } + + @EventListener(UmbrellaReturnedEvent::class) + fun handleUmbrellaReturnedEvent(event: UmbrellaReturnedEvent) { + + val unrefundedRentCount = rentService.countUnrefundedRent() + slackAlarmService.notifyReturn( + NotifyReturnInput( + userId = event.rentUserId, + rentStoreName = event.rentStoreName, + rentedAt = event.rentedAt.toString(), + returnStoreName = event.returnStoreName, + returnedAt = event.returnedAt.toString(), + unrefundedCount = unrefundedRentCount + ) + ) + + event.improvementReportContent?.takeIf { it.isNotBlank() } + ?.let { content -> + ImprovementReport( + historyId = event.historyId, + content = content + ).also { improvementReport -> + improvementReportService.save(improvementReport) + slackAlarmService.notifyImprovementReport( + NotifyImprovementReportInput( + umbrellaId = event.returnedUmbrellaId, + rentStoreName = event.rentStoreName, + rentedAt = event.rentedAt.toString(), + returnStoreName = event.returnStoreName, + returnedAt = event.returnedAt.toString(), + content = content + ) + ) + } + } + } +} \ No newline at end of file diff --git a/src/main/kotlin/upbrella/be/rent/event/UmbrellaRentedEvent.kt b/src/main/kotlin/upbrella/be/rent/event/UmbrellaRentedEvent.kt new file mode 100644 index 00000000..3d3d4d26 --- /dev/null +++ b/src/main/kotlin/upbrella/be/rent/event/UmbrellaRentedEvent.kt @@ -0,0 +1,12 @@ +package upbrella.be.rent.event + +import upbrella.be.util.event.Event + +class UmbrellaRentedEvent( + val userId: Long, + val userName: String, + val rentStoreName: String, + val conditionReportContent: String? = null, + val umbrellaId: Long, + val historyId: Long, +) : Event() diff --git a/src/main/kotlin/upbrella/be/rent/event/UmbrellaReturnedEvent.kt b/src/main/kotlin/upbrella/be/rent/event/UmbrellaReturnedEvent.kt new file mode 100644 index 00000000..e3aaaded --- /dev/null +++ b/src/main/kotlin/upbrella/be/rent/event/UmbrellaReturnedEvent.kt @@ -0,0 +1,15 @@ +package upbrella.be.rent.event + +import upbrella.be.util.event.Event +import java.time.LocalDateTime + +class UmbrellaReturnedEvent( + val rentUserId: Long, + val rentStoreName: String, + val rentedAt: LocalDateTime, + val returnStoreName: String, + val returnedAt: LocalDateTime, + val historyId: Long, + val improvementReportContent: String? = null, + val returnedUmbrellaId: Long, +) : Event() diff --git a/src/main/kotlin/upbrella/be/rent/repository/CustomConditionReportRepository.kt b/src/main/kotlin/upbrella/be/rent/repository/CustomConditionReportRepository.kt new file mode 100644 index 00000000..9da517fc --- /dev/null +++ b/src/main/kotlin/upbrella/be/rent/repository/CustomConditionReportRepository.kt @@ -0,0 +1,29 @@ +package upbrella.be.rent.repository + +import com.querydsl.core.types.Projections +import com.querydsl.jpa.impl.JPAQueryFactory +import org.springframework.stereotype.Repository +import upbrella.be.rent.dto.response.ConditionReportResponse +import upbrella.be.rent.entity.QConditionReport.conditionReport +import upbrella.be.rent.entity.QHistory.history + +@Repository +class CustomConditionReportRepository( + private val queryFactory: JPAQueryFactory +) { + fun findAllConditionReport(): List { + return queryFactory + .select( + Projections.constructor( + ConditionReportResponse::class.java, + conditionReport.id, + history.umbrella.uuid, + conditionReport.content, + conditionReport.etc + ) + ) + .from(conditionReport) + .join(history) + .fetch() + } +} \ No newline at end of file diff --git a/src/main/kotlin/upbrella/be/rent/repository/CustomImprovementReportRepository.kt b/src/main/kotlin/upbrella/be/rent/repository/CustomImprovementReportRepository.kt new file mode 100644 index 00000000..09bed156 --- /dev/null +++ b/src/main/kotlin/upbrella/be/rent/repository/CustomImprovementReportRepository.kt @@ -0,0 +1,30 @@ +package upbrella.be.rent.repository + +import com.querydsl.core.types.Projections +import com.querydsl.jpa.impl.JPAQueryFactory +import org.springframework.stereotype.Repository +import upbrella.be.rent.dto.response.ImprovementReportResponse +import upbrella.be.rent.entity.QHistory.history +import upbrella.be.rent.entity.QImprovementReport.improvementReport + +@Repository +class CustomImprovementReportRepository( + private val queryFactory: JPAQueryFactory, +) { + fun findAllImprovementReport(): List { + return queryFactory + .select( + Projections.constructor( + ImprovementReportResponse::class.java, + improvementReport.id, + history.umbrella.uuid, + improvementReport.content, + improvementReport.etc + ) + ) + .from(improvementReport) + .join(history) + .fetchJoin() + .fetch() + } +} diff --git a/src/main/kotlin/upbrella/be/rent/service/ConditionReportService.kt b/src/main/kotlin/upbrella/be/rent/service/ConditionReportService.kt index c55d1567..c0bb7f7d 100644 --- a/src/main/kotlin/upbrella/be/rent/service/ConditionReportService.kt +++ b/src/main/kotlin/upbrella/be/rent/service/ConditionReportService.kt @@ -2,23 +2,20 @@ package upbrella.be.rent.service import org.springframework.stereotype.Service import upbrella.be.rent.dto.response.ConditionReportPageResponse -import upbrella.be.rent.dto.response.ConditionReportResponse import upbrella.be.rent.entity.ConditionReport import upbrella.be.rent.repository.ConditionReportRepository +import upbrella.be.rent.repository.CustomConditionReportRepository @Service class ConditionReportService( - private val conditionReportRepository: ConditionReportRepository + private val conditionReportRepository: ConditionReportRepository, + private val customConditionReportRepository: CustomConditionReportRepository, ) { fun findAll(): ConditionReportPageResponse = - ConditionReportPageResponse.of(findAllConditionReport()) + ConditionReportPageResponse.of(customConditionReportRepository.findAllConditionReport()) fun saveConditionReport(conditionReport: ConditionReport) { conditionReportRepository.save(conditionReport) } - - private fun findAllConditionReport(): List = - conditionReportRepository.findAll() - .map { ConditionReportResponse.fromConditionReport(it) } } diff --git a/src/main/kotlin/upbrella/be/rent/service/ImprovementReportService.kt b/src/main/kotlin/upbrella/be/rent/service/ImprovementReportService.kt index e991ec4d..5e24b7e5 100644 --- a/src/main/kotlin/upbrella/be/rent/service/ImprovementReportService.kt +++ b/src/main/kotlin/upbrella/be/rent/service/ImprovementReportService.kt @@ -2,24 +2,21 @@ package upbrella.be.rent.service import org.springframework.stereotype.Service import upbrella.be.rent.dto.response.ImprovementReportPageResponse -import upbrella.be.rent.dto.response.ImprovementReportResponse import upbrella.be.rent.entity.ImprovementReport +import upbrella.be.rent.repository.CustomImprovementReportRepository import upbrella.be.rent.repository.ImprovementReportRepository @Service class ImprovementReportService( - private val improvementReportRepository: ImprovementReportRepository + private val improvementReportRepository: ImprovementReportRepository, + private val customImprovementReportRepository: CustomImprovementReportRepository ) { fun findAll(): ImprovementReportPageResponse = - ImprovementReportPageResponse.of(findAllImprovementReport()) + ImprovementReportPageResponse.of(customImprovementReportRepository.findAllImprovementReport()) fun save(improvementReport: ImprovementReport) { improvementReportRepository.save(improvementReport) } - - private fun findAllImprovementReport(): List = - improvementReportRepository.findAll() - .map { ImprovementReportResponse.fromImprovementReport(it) } } diff --git a/src/main/kotlin/upbrella/be/rent/service/RentService.kt b/src/main/kotlin/upbrella/be/rent/service/RentService.kt index d38873bc..fc4e7570 100644 --- a/src/main/kotlin/upbrella/be/rent/service/RentService.kt +++ b/src/main/kotlin/upbrella/be/rent/service/RentService.kt @@ -7,16 +7,17 @@ import upbrella.be.rent.dto.request.HistoryFilterRequest import upbrella.be.rent.dto.request.RentUmbrellaByUserRequest import upbrella.be.rent.dto.request.ReturnUmbrellaByUserRequest import upbrella.be.rent.dto.response.* -import upbrella.be.rent.entity.ConditionReport import upbrella.be.rent.entity.History -import upbrella.be.rent.entity.ImprovementReport -import upbrella.be.rent.exception.* +import upbrella.be.rent.event.UmbrellaRentedEvent +import upbrella.be.rent.exception.CannotBeRentedException +import upbrella.be.rent.exception.ExistingUmbrellaForRentException +import upbrella.be.rent.exception.NonExistingHistoryException +import upbrella.be.rent.exception.NonExistingUmbrellaForRentException import upbrella.be.rent.repository.RentRepository import upbrella.be.slack.SlackAlarmService import upbrella.be.store.entity.StoreMeta import upbrella.be.store.repository.StoreMetaReader import upbrella.be.umbrella.entity.Umbrella -import upbrella.be.umbrella.exception.MissingUmbrellaException import upbrella.be.umbrella.exception.NonExistingBorrowedHistoryException import upbrella.be.umbrella.service.UmbrellaService import upbrella.be.user.dto.response.AllHistoryResponse @@ -25,6 +26,7 @@ import upbrella.be.user.dto.response.SingleHistoryResponse import upbrella.be.user.entity.User import upbrella.be.user.repository.UserReader import upbrella.be.user.service.BlackListService +import upbrella.be.util.event.Events import java.time.LocalDateTime import java.time.temporal.ChronoUnit @@ -35,8 +37,6 @@ class RentService( private val slackAlarmService: SlackAlarmService, private val improvementReportService: ImprovementReportService, private val rentRepository: RentRepository, - private val conditionReportService: ConditionReportService, - private val lockerService: LockerService, private val blackListService: BlackListService, private val userReader: UserReader, ) { @@ -66,30 +66,25 @@ class RentService( throw ExistingUmbrellaForRentException("[ERROR] 해당 유저가 대여 중인 우산이 있습니다.") } val umbrella = umbrellaService.findUmbrellaById(rentUmbrellaByUserRequest.umbrellaId) - if (umbrella.storeMeta.id != rentUmbrellaByUserRequest.storeId) { - throw UmbrellaStoreMissMatchException("[ERROR] 해당 우산은 해당 매장에 존재하지 않습니다.") - } - if (umbrella.missed) { - throw MissingUmbrellaException("[ERROR] 해당 우산은 분실되었습니다.") - } - if (!umbrella.rentable) { - throw NotAvailableUmbrellaException("[ERROR] 해당 우산은 대여중입니다.") - } - umbrella.rentUmbrella() + + umbrella.rentUmbrella(rentUmbrellaByUserRequest.storeId) + val rentalStore = storeMetaReader.findById(rentUmbrellaByUserRequest.storeId) val history = rentRepository.save( History.ofCreatedByNewRent(umbrella, userToRent, rentalStore) ) - slackAlarmService.notifyRent(userToRent, history) - - rentUmbrellaByUserRequest.conditionReport - ?.takeIf { it.isNotBlank() } - ?.let { content -> - ConditionReport(history = history, content = content).also { conditionReport -> - conditionReportService.saveConditionReport(conditionReport) - slackAlarmService.notifyConditionReport(conditionReport) - } - } + + // umbrellaRentedEvent + Events.raise( + UmbrellaRentedEvent( + userId = userToRent.id, + userName = userToRent.name, + rentStoreName = rentalStore.name, + conditionReportContent = rentUmbrellaByUserRequest.conditionReport, + umbrellaId = umbrella.id!!, + historyId = history.id!!, + ) + ) } @Transactional @@ -107,18 +102,7 @@ class RentService( val returnedUmbrella: Umbrella = history.umbrella returnedUmbrella.returnUmbrella(returnStore) - val unrefundedRentCount = countUnrefundedRent() - - slackAlarmService.notifyReturn(userToReturn, history, unrefundedRentCount) rentRepository.save(history) - - request.improvementReportContent?.takeIf { it.isNotBlank() } - ?.let { content -> - ImprovementReport(history = history, content = content).also { improvementReport -> - improvementReportService.save(improvementReport) - slackAlarmService.notifyImprovementReport(improvementReport) - } - } } @Transactional diff --git a/src/main/kotlin/upbrella/be/slack/SlackAlarmService.kt b/src/main/kotlin/upbrella/be/slack/SlackAlarmService.kt index b9466e8d..3a95dd33 100644 --- a/src/main/kotlin/upbrella/be/slack/SlackAlarmService.kt +++ b/src/main/kotlin/upbrella/be/slack/SlackAlarmService.kt @@ -5,10 +5,10 @@ import org.springframework.http.HttpMethod.POST import org.springframework.stereotype.Service import org.springframework.web.client.RestTemplate import upbrella.be.config.SlackBotConfig -import upbrella.be.rent.entity.ConditionReport -import upbrella.be.rent.entity.History -import upbrella.be.rent.entity.ImprovementReport -import upbrella.be.user.entity.User +import upbrella.be.slack.dto.service.input.NotifyConditionReportInput +import upbrella.be.slack.dto.service.input.NotifyImprovementReportInput +import upbrella.be.slack.dto.service.input.NotifyRentInput +import upbrella.be.slack.dto.service.input.NotifyReturnInput @Service class SlackAlarmService( @@ -16,57 +16,57 @@ class SlackAlarmService( private val restTemplate: RestTemplate ) { - fun notifyRent(user: User, history: History) { + fun notifyRent(input: NotifyRentInput) { val message = buildString { append("*우산 대여 알림: 입금을 확인해주세요.*\n\n") - append("사용자 ID : ${user.id}\n") - append("예금주 이름 : ${user.name}\n") - append("대여 지점 이름 : ${history.rentStoreMeta.name}\n") + append("사용자 ID : ${input.userId}\n") + append("예금주 이름 : ${input.userName}\n") + append("대여 지점 이름 : ${input.rentStoreName}\n") } send(message) } - fun notifyReturn(user: User, history: History, unrefundedCount: Long) { + fun notifyReturn(input: NotifyReturnInput) { val message = buildString { append("*우산 반납 알림: 보증금을 환급해주세요.*\n\n") - append("사용자 ID : ${user.id}\n") - append("대여 지점 이름 : ${history.rentStoreMeta.name}\n") - append("대여 시각: ${history.rentedAt}\n") - append("반납 지점 이름 : ${history.returnStoreMeta?.name}\n") - append("반납 시각: ${history.returnedAt}\n") - append("*잔여 환급 대기 건수* : $unrefundedCount") + append("사용자 ID : ${input.userId}\n") + append("대여 지점 이름 : ${input.rentStoreName}\n") + append("대여 시각: ${input.rentedAt}\n") + append("반납 지점 이름 : ${input.returnStoreName}\n") + append("반납 시각: ${input.returnedAt}\n") + append("*잔여 환급 대기 건수* : ${input.unrefundedCount}") } send(message) } - private fun send(message: String) { - val request = mutableMapOf( - "text" to message - ) - val entity = HttpEntity(request) - restTemplate.exchange(slackBotConfig.webHookUrl, POST, entity, String::class.java) - } - - fun notifyConditionReport(conditionReport: ConditionReport) { + fun notifyConditionReport(input: NotifyConditionReportInput) { val message = buildString { append("*우산 상태 신고 접수*\n\n") - append("우산 ID : ${conditionReport.history.umbrella.id}\n") - append("대여 지점 이름 : ${conditionReport.history.rentStoreMeta.name}\n") - append("신고 내용 : ${conditionReport.content}\n") + append("우산 ID : ${input.umbrellaId}\n") + append("대여 지점 이름 : ${input.rentStoreName}\n") + append("신고 내용 : ${input.content}\n") } send(message) } - fun notifyImprovementReport(improvementReport: ImprovementReport) { + fun notifyImprovementReport(input: NotifyImprovementReportInput) { val message = buildString { append("*우산 개선 사항 신고가 접수되었습니다.*\n\n") - append("우산 ID : ${improvementReport.history.umbrella.id}\n") - append("대여 지점 이름 : ${improvementReport.history.rentStoreMeta.name}\n") - append("대여 시각: ${improvementReport.history.rentedAt}\n") - append("반납 지점 이름 : ${improvementReport.history.returnStoreMeta?.name}\n") - append("반납 시각: ${improvementReport.history.returnedAt}\n") - append("신고 내용 : ${improvementReport.content}\n") + append("우산 ID : ${input.umbrellaId}\n") + append("대여 지점 이름 : ${input.rentStoreName}\n") + append("대여 시각: ${input.rentedAt}\n") + append("반납 지점 이름 : ${input.returnStoreName}\n") + append("반납 시각: ${input.returnedAt}\n") + append("신고 내용 : ${input.content}\n") } send(message) } + + private fun send(message: String) { + val request = mutableMapOf( + "text" to message + ) + val entity = HttpEntity(request) + restTemplate.exchange(slackBotConfig.webHookUrl, POST, entity, String::class.java) + } } diff --git a/src/main/kotlin/upbrella/be/slack/dto/service/input/SlackAlarmInput.kt b/src/main/kotlin/upbrella/be/slack/dto/service/input/SlackAlarmInput.kt new file mode 100644 index 00000000..4f66fd88 --- /dev/null +++ b/src/main/kotlin/upbrella/be/slack/dto/service/input/SlackAlarmInput.kt @@ -0,0 +1,31 @@ +package upbrella.be.slack.dto.service.input + +data class NotifyRentInput( + val userId: Long, + val userName: String, + val rentStoreName: String, +) + +data class NotifyConditionReportInput( + val umbrellaId: Long, + val rentStoreName: String, + val content: String, +) + +data class NotifyReturnInput( + val userId: Long, + val rentStoreName: String, + val rentedAt: String, + val returnStoreName: String, + val returnedAt: String?, + val unrefundedCount: Long, +) + +data class NotifyImprovementReportInput( + val umbrellaId: Long, + val rentStoreName: String, + val rentedAt: String, + val returnStoreName: String, + val returnedAt: String?, + val content: String, +) diff --git a/src/main/kotlin/upbrella/be/umbrella/entity/Umbrella.kt b/src/main/kotlin/upbrella/be/umbrella/entity/Umbrella.kt index ca906573..8a46ad8c 100644 --- a/src/main/kotlin/upbrella/be/umbrella/entity/Umbrella.kt +++ b/src/main/kotlin/upbrella/be/umbrella/entity/Umbrella.kt @@ -1,8 +1,11 @@ package upbrella.be.umbrella.entity +import upbrella.be.rent.exception.NotAvailableUmbrellaException +import upbrella.be.rent.exception.UmbrellaStoreMissMatchException import upbrella.be.store.entity.StoreMeta import upbrella.be.umbrella.dto.request.UmbrellaCreateRequest import upbrella.be.umbrella.dto.request.UmbrellaModifyRequest +import upbrella.be.umbrella.exception.MissingUmbrellaException import java.time.LocalDateTime import javax.persistence.* @@ -49,7 +52,16 @@ class Umbrella( this.missed = request.missed } - fun rentUmbrella() { + fun rentUmbrella(storeIdForRent: Long) { + if (this.storeMeta.id != storeIdForRent) { + throw UmbrellaStoreMissMatchException("[ERROR] 해당 우산은 해당 매장에 존재하지 않습니다.") + } + if (this.missed) { + throw MissingUmbrellaException("[ERROR] 해당 우산은 분실되었습니다.") + } + if (!this.rentable) { + throw NotAvailableUmbrellaException("[ERROR] 해당 우산은 대여중입니다.") + } this.rentable = false } diff --git a/src/main/kotlin/upbrella/be/util/event/Event.kt b/src/main/kotlin/upbrella/be/util/event/Event.kt new file mode 100644 index 00000000..4c5255bb --- /dev/null +++ b/src/main/kotlin/upbrella/be/util/event/Event.kt @@ -0,0 +1,5 @@ +package upbrella.be.util.event + +abstract class Event( + val timestamp: Long = System.currentTimeMillis(), +) diff --git a/src/main/kotlin/upbrella/be/util/event/Events.kt b/src/main/kotlin/upbrella/be/util/event/Events.kt new file mode 100644 index 00000000..975e4994 --- /dev/null +++ b/src/main/kotlin/upbrella/be/util/event/Events.kt @@ -0,0 +1,16 @@ +package upbrella.be.util.event + +import org.springframework.context.ApplicationEventPublisher + +object Events { + private var publisher: ApplicationEventPublisher? = null + + fun setPublisher(publisher: ApplicationEventPublisher) { + this.publisher = publisher + } + + fun raise(event: Any) { + publisher?.publishEvent(event) + ?: throw IllegalStateException("ApplicationEventPublisher가 설정되지 않았습니다.") + } +} diff --git a/src/test/kotlin/upbrella/be/config/event/NoOpPublisher.kt b/src/test/kotlin/upbrella/be/config/event/NoOpPublisher.kt new file mode 100644 index 00000000..9468da9e --- /dev/null +++ b/src/test/kotlin/upbrella/be/config/event/NoOpPublisher.kt @@ -0,0 +1,13 @@ +package upbrella.be.config.event + +import org.springframework.context.ApplicationEvent +import org.springframework.context.ApplicationEventPublisher + +/** + * 테스트 전용 No-Operation Publisher + * 실제로 아무 이벤트도 발행하지 않음 + */ +object NoOpPublisher : ApplicationEventPublisher { + override fun publishEvent(event: Any) { /* no-op */ } + override fun publishEvent(event: ApplicationEvent) { /* no-op */ } +} diff --git a/src/test/kotlin/upbrella/be/rent/service/ConditionReportServiceTest.kt b/src/test/kotlin/upbrella/be/rent/service/ConditionReportServiceTest.kt index abf5520a..63a720ea 100644 --- a/src/test/kotlin/upbrella/be/rent/service/ConditionReportServiceTest.kt +++ b/src/test/kotlin/upbrella/be/rent/service/ConditionReportServiceTest.kt @@ -18,6 +18,7 @@ import upbrella.be.rent.dto.response.ConditionReportResponse import upbrella.be.rent.entity.ConditionReport import upbrella.be.rent.entity.History import upbrella.be.rent.repository.ConditionReportRepository +import upbrella.be.rent.repository.CustomConditionReportRepository import upbrella.be.store.entity.StoreMeta import upbrella.be.umbrella.entity.Umbrella import upbrella.be.user.entity.User @@ -29,6 +30,9 @@ class ConditionReportServiceTest { @Mock private lateinit var conditionReportRepository: ConditionReportRepository + @Mock + private lateinit var customConditionReportRepository: CustomConditionReportRepository + @InjectMocks private lateinit var conditionReportService: ConditionReportService @@ -76,7 +80,7 @@ class ConditionReportServiceTest { conditionReport = ConditionReport( id = 1L, content = "content", - history = history, + historyId = history.id!!, etc = "etc", ) } @@ -100,8 +104,15 @@ class ConditionReportServiceTest { ) ) - given(conditionReportRepository.findAll()) - .willReturn(listOf(conditionReport)) + given(customConditionReportRepository.findAllConditionReport()) + .willReturn(listOf( + ConditionReportResponse( + id = 33L, + umbrellaUuid = 99L, + content = "content", + etc = "etc" + ) + )) // when val allConditionReports = conditionReportService.findAll() @@ -115,9 +126,6 @@ class ConditionReportServiceTest { }, { assertThat(allConditionReports.conditionReports.size).isEqualTo(1) - }, - { - then(conditionReportRepository).should(times(1)).findAll() } ) } diff --git a/src/test/kotlin/upbrella/be/rent/service/RentServiceTest.kt b/src/test/kotlin/upbrella/be/rent/service/RentServiceTest.kt index a6160974..5ed5e607 100644 --- a/src/test/kotlin/upbrella/be/rent/service/RentServiceTest.kt +++ b/src/test/kotlin/upbrella/be/rent/service/RentServiceTest.kt @@ -13,10 +13,14 @@ import org.mockito.InjectMocks import org.mockito.Mock import org.mockito.Mockito.times import org.mockito.junit.jupiter.MockitoExtension +import org.mockito.kotlin.mock +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.context.ApplicationEventPublisher import org.springframework.data.domain.PageRequest import org.springframework.data.domain.Pageable import upbrella.be.config.FixtureBuilderFactory import upbrella.be.config.FixtureFactory +import upbrella.be.config.event.NoOpPublisher import upbrella.be.rent.dto.request.HistoryFilterRequest import upbrella.be.rent.dto.request.RentUmbrellaByUserRequest import upbrella.be.rent.dto.response.HistoryInfoDto @@ -42,6 +46,7 @@ import upbrella.be.user.exception.NonExistingMemberException import upbrella.be.user.repository.UserReader import upbrella.be.user.service.BlackListService import upbrella.be.util.AesEncryptor +import upbrella.be.util.event.Events import java.time.LocalDateTime import java.util.* @@ -143,9 +148,11 @@ class RentServiceTest { conditionReport = ConditionReport( id = 1L, content = "상태 양호", - history = history, + historyId = history.id!!, etc = "etc", ) + + Events.setPublisher(NoOpPublisher) } @Nested @@ -159,8 +166,6 @@ class RentServiceTest { given(storeMetaReader.findById(25L)).willReturn(foundStoreMeta) given(umbrellaService.findUmbrellaById(99L)).willReturn(foundUmbrella) given(rentRepository.save(any(History::class.java) ?: history)).willReturn(history) - doNothing().`when`(conditionReportService) - .saveConditionReport(any(ConditionReport::class.java) ?: conditionReport) // when rentService.addRental(rentUmbrellaByUserRequest, userToRent) diff --git a/src/test/kotlin/upbrella/be/slack/service/SlackAlarmServiceTest.kt b/src/test/kotlin/upbrella/be/slack/service/SlackAlarmServiceTest.kt index bcd70bc2..a13b4d66 100644 --- a/src/test/kotlin/upbrella/be/slack/service/SlackAlarmServiceTest.kt +++ b/src/test/kotlin/upbrella/be/slack/service/SlackAlarmServiceTest.kt @@ -19,6 +19,7 @@ import upbrella.be.config.SlackBotConfig import upbrella.be.rent.dto.request.RentUmbrellaByUserRequest import upbrella.be.rent.entity.History import upbrella.be.slack.SlackAlarmService +import upbrella.be.slack.dto.service.input.NotifyReturnInput import upbrella.be.store.entity.StoreMeta import upbrella.be.umbrella.entity.Umbrella import upbrella.be.user.entity.User @@ -108,7 +109,16 @@ class SlackAlarmServiceTest { ).willReturn(null) // when - slackAlarmService.notifyReturn(userToRent, history, 1L) + slackAlarmService.notifyReturn( + NotifyReturnInput( + userId = userToRent.id!!, + rentStoreName = foundStoreMeta.name, + rentedAt = history.rentedAt.toString(), + returnStoreName = foundStoreMeta.name, + returnedAt = history.returnedAt.toString(), + unrefundedCount = 1L + ) + ) val requestEntityCaptor = ArgumentCaptor.forClass(HttpEntity::class.java)