diff --git a/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/controller/CafeController.kt b/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/controller/CafeController.kt index 21b2f2f..8f12999 100644 --- a/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/controller/CafeController.kt +++ b/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/controller/CafeController.kt @@ -1,8 +1,9 @@ package io.beaniejoy.dongnecafe.domain.cafe.controller -import io.beaniejoy.dongnecafe.domain.cafe.dto.cafe.CafeInfoResponseDto -import io.beaniejoy.dongnecafe.domain.cafe.dto.cafe.CafeSearchResponseDto -import io.beaniejoy.dongnecafe.domain.cafe.dto.request.CafeInfoRequestDto +import io.beaniejoy.dongnecafe.domain.cafe.model.request.CafeRegisterRequest +import io.beaniejoy.dongnecafe.domain.cafe.model.request.CafeUpdateRequest +import io.beaniejoy.dongnecafe.domain.cafe.model.response.CafeDetailedInfo +import io.beaniejoy.dongnecafe.domain.cafe.model.response.CafeSearchInfo import io.beaniejoy.dongnecafe.domain.cafe.service.CafeService import org.springframework.data.domain.Page import org.springframework.data.domain.Pageable @@ -15,9 +16,12 @@ import org.springframework.web.bind.annotation.* class CafeController( private val cafeService: CafeService ) { + /** + * 신규 카페 생성 + */ @PostMapping - fun createCafe(@RequestBody resource: CafeInfoRequestDto): Long { - return cafeService.createCafe( + fun createNewCafe(@RequestBody resource: CafeRegisterRequest): Long { + return cafeService.createNew( name = resource.name!!, address = resource.address!!, phoneNumber = resource.phoneNumber!!, @@ -26,25 +30,34 @@ class CafeController( ) } + /** + * 카페 리스트 조회(검색 기능) + */ @GetMapping - fun searchCafe( + fun searchCafeList( @PageableDefault(sort = ["name"], direction = Sort.Direction.ASC, page = 0, size = 10) pageable: Pageable - ): Page { - return cafeService.getCafeList(pageable) + ): Page { + return cafeService.searchCafeList(pageable) } + /** + * 단일 카페 상세 조회 + */ @GetMapping("/{id}") - fun getCafeDetailedInfo(@PathVariable("id") id: Long): CafeInfoResponseDto { - return cafeService.getCafeInfoByCafeId(id) + fun getDetailedInfo(@PathVariable("id") id: Long): CafeDetailedInfo { + return cafeService.getDetailedInfoByCafeId(id) } - // TODO spring boot validation 적용 필요 - @PutMapping("/{id}") - fun updateCafeInfo( + /** + * 단일 카페에 대한 정보 변경 + * - Cafe 기본 정보 데이터 변경 + */ + @PatchMapping("/{id}") + fun updateInfo( @PathVariable("id") id: Long, - @RequestBody resource: CafeInfoRequestDto + @RequestBody resource: CafeUpdateRequest ): String { - cafeService.updateCafe( + cafeService.updateInfo( id = id, name = resource.name!!, address = resource.address!!, diff --git a/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/controller/CafeMenuController.kt b/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/controller/CafeMenuController.kt index 1c700ae..7603af0 100644 --- a/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/controller/CafeMenuController.kt +++ b/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/controller/CafeMenuController.kt @@ -1,23 +1,83 @@ package io.beaniejoy.dongnecafe.domain.cafe.controller -import io.beaniejoy.dongnecafe.domain.cafe.dto.menu.CafeMenuDetailResponseDto +import io.beaniejoy.dongnecafe.domain.cafe.model.request.CafeMenuBulkDeleteRequest +import io.beaniejoy.dongnecafe.domain.cafe.model.request.CafeMenuUpdateRequest +import io.beaniejoy.dongnecafe.domain.cafe.model.response.CafeMenuDetailedInfo import io.beaniejoy.dongnecafe.domain.cafe.service.CafeMenuService +import org.springframework.web.bind.annotation.DeleteMapping import org.springframework.web.bind.annotation.GetMapping +import org.springframework.web.bind.annotation.PatchMapping import org.springframework.web.bind.annotation.PathVariable +import org.springframework.web.bind.annotation.RequestBody +import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RestController @RestController +@RequestMapping("/cafes/{cafeId}/menus") class CafeMenuController( private val cafeMenuService: CafeMenuService ) { - @GetMapping("/cafes/{cafeId}/menus/{menuId}") - fun getCafeMenuDetailedInfo( + /** + * 단일 카페 메뉴 상세 조회 + */ + @GetMapping("/{menuId}") + fun getDetailedInfo( @PathVariable("cafeId") cafeId: Long, @PathVariable("menuId") menuId: Long - ): CafeMenuDetailResponseDto { - return cafeMenuService.getCafeMenuInfoByCafeIdAndMenuId( + ): CafeMenuDetailedInfo { + return cafeMenuService.getDetailedInfoByMenuId( menuId = menuId, cafeId = cafeId ) } + + /** + * 단일 카페 메뉴에 대한 정보 변경 + * - CafeMenu 기본 정보 데이터 변경 + * - MenuOption List bulkUpdate (삭제, 변경) + * - OptionDetail List bulkUpdate (삭제, 변경) + */ + @PatchMapping("/{menuId}") + fun updateInfoAndBulkUpdateOptions( + @PathVariable("cafeId") cafeId: Long, + @PathVariable("menuId") menuId: Long, + @RequestBody cafeMenuUpdateRequest: CafeMenuUpdateRequest + ): String { + cafeMenuService.updateInfoAndBulkUpdate( + menuId = menuId, + cafeId = cafeId, + resource = cafeMenuUpdateRequest + ) + + return "Success Update Cafe[$cafeId]'s CafeMenu[$menuId]" + } + + /** + * 단일 카페 메뉴 삭제 + */ + @DeleteMapping("/{menuId}") + fun delete( + @PathVariable("cafeId") cafeId: Long, + @PathVariable("menuId") menuId: Long + ): String { + cafeMenuService.deleteByCafeMenuId( + menuId = menuId, + cafeId = cafeId + ) + + return "Success Delete Cafe[$cafeId]'s CafeMenu[$menuId]" + } + + /** + * 여러 카페 메뉴에 대한 bulk 삭제 + */ + @DeleteMapping("") + fun bulkDelete( + @PathVariable("cafeId") cafeId: Long, + @RequestBody resource: CafeMenuBulkDeleteRequest + ): String { + cafeMenuService.bulkDelete(cafeId, resource.cafeMenuIdList) + + return "Success Delete Cafe[$cafeId]'s CafeMenu List" + } } \ No newline at end of file diff --git a/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/dto/cafe/CafeImageResponseDto.kt b/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/dto/cafe/CafeImageResponseDto.kt deleted file mode 100644 index 0fdaaa5..0000000 --- a/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/dto/cafe/CafeImageResponseDto.kt +++ /dev/null @@ -1,13 +0,0 @@ -package io.beaniejoy.dongnecafe.domain.cafe.dto.cafe - -import io.beaniejoy.dongnecafe.domain.cafe.entity.CafeImage - -data class CafeImageResponseDto( - val imgUrl: String? = null -) { - companion object { - fun of(cafeImage: CafeImage): CafeImageResponseDto { - return CafeImageResponseDto(cafeImage.imgUrl) - } - } -} \ No newline at end of file diff --git a/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/dto/cafe/CafeInfoResponseDto.kt b/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/dto/cafe/CafeInfoResponseDto.kt deleted file mode 100644 index dda6c08..0000000 --- a/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/dto/cafe/CafeInfoResponseDto.kt +++ /dev/null @@ -1,30 +0,0 @@ -package io.beaniejoy.dongnecafe.domain.cafe.dto.cafe - -import io.beaniejoy.dongnecafe.domain.cafe.entity.Cafe -import io.beaniejoy.dongnecafe.domain.cafe.dto.menu.CafeMenuResponseDto - -data class CafeInfoResponseDto( - val id: Long? = null, - val name: String? = null, - val address: String? = null, - val phoneNumber: String? = null, - val totalRate: Double? = null, - val description: String? = null, - val menuList: List = emptyList(), - val imageList: List = emptyList() -) { - companion object { - fun of(cafe: Cafe): CafeInfoResponseDto { - return CafeInfoResponseDto( - id = cafe.id, - name = cafe.name, - address = cafe.address, - phoneNumber = cafe.phoneNumber, - totalRate = cafe.totalRate, - description = cafe.description, - menuList = cafe.cafeMenuList.map { CafeMenuResponseDto.of(it) }, - imageList = cafe.cafeImageList.map { CafeImageResponseDto.of(it) } - ) - } - } -} \ No newline at end of file diff --git a/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/dto/cafe/CafeSearchResponseDto.kt b/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/dto/cafe/CafeSearchResponseDto.kt deleted file mode 100644 index a943bfd..0000000 --- a/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/dto/cafe/CafeSearchResponseDto.kt +++ /dev/null @@ -1,23 +0,0 @@ -package io.beaniejoy.dongnecafe.domain.cafe.dto.cafe - -import io.beaniejoy.dongnecafe.domain.cafe.entity.Cafe - -data class CafeSearchResponseDto( - val id: Long = 0L, - val name: String? = null, - val address: String? = null, - val totalRate: Double? = null, - val imageList: List = emptyList() -) { - companion object { - fun of(cafe: Cafe): CafeSearchResponseDto { - return CafeSearchResponseDto( - id = cafe.id, - name = cafe.name, - address = cafe.address, - totalRate = cafe.totalRate, - imageList = cafe.cafeImageList.map { CafeImageResponseDto.of(it) } - ) - } - } -} \ No newline at end of file diff --git a/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/dto/menu/MenuOptionResponseDto.kt b/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/dto/menu/MenuOptionResponseDto.kt deleted file mode 100644 index 3c7b6d4..0000000 --- a/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/dto/menu/MenuOptionResponseDto.kt +++ /dev/null @@ -1,19 +0,0 @@ -package io.beaniejoy.dongnecafe.domain.cafe.dto.menu - -import io.beaniejoy.dongnecafe.domain.cafe.entity.MenuOption - -data class MenuOptionResponseDto( - val id: Long = 0L, - val title: String? = null, - val optionDetailList: List = emptyList() -) { - companion object { - fun of(menuOption: MenuOption): MenuOptionResponseDto { - return MenuOptionResponseDto( - id = menuOption.id, - title = menuOption.title, - optionDetailList = menuOption.optionDetailList.map { OptionDetailResponseDto.of(it) } - ) - } - } -} \ No newline at end of file diff --git a/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/dto/request/CafeInfoRequestDto.kt b/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/dto/request/CafeInfoRequestDto.kt deleted file mode 100644 index 70fa918..0000000 --- a/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/dto/request/CafeInfoRequestDto.kt +++ /dev/null @@ -1,9 +0,0 @@ -package io.beaniejoy.dongnecafe.domain.cafe.dto.request - -data class CafeInfoRequestDto( - val name: String? = null, - val address: String? = null, - val phoneNumber: String? = null, - val description: String? = null, - val cafeMenuList: List = arrayListOf() -) \ No newline at end of file diff --git a/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/dto/request/CafeMenuInfoRequestDto.kt b/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/dto/request/CafeMenuInfoRequestDto.kt deleted file mode 100644 index 1621c4e..0000000 --- a/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/dto/request/CafeMenuInfoRequestDto.kt +++ /dev/null @@ -1,9 +0,0 @@ -package io.beaniejoy.dongnecafe.domain.cafe.dto.request - -import java.math.BigDecimal - -data class CafeMenuInfoRequestDto( - val name: String? = null, - val price: BigDecimal = BigDecimal.ZERO, - val menuOptionList: List -) diff --git a/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/dto/request/MenuOptionInfoRequestDto.kt b/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/dto/request/MenuOptionInfoRequestDto.kt deleted file mode 100644 index f38d6d5..0000000 --- a/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/dto/request/MenuOptionInfoRequestDto.kt +++ /dev/null @@ -1,13 +0,0 @@ -package io.beaniejoy.dongnecafe.domain.cafe.dto.request - -import java.math.BigDecimal - -data class MenuOptionInfoRequestDto( - val title: String, - val optionDetailList: List -) - -data class OptionDetailInfoRequestDto( - val name: String, - val extraPrice: BigDecimal -) \ No newline at end of file diff --git a/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/entity/Cafe.kt b/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/entity/Cafe.kt index e43505b..c3a11b2 100644 --- a/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/entity/Cafe.kt +++ b/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/entity/Cafe.kt @@ -1,7 +1,7 @@ package io.beaniejoy.dongnecafe.domain.cafe.entity import io.beaniejoy.dongnecafe.common.entity.BaseTimeEntity -import io.beaniejoy.dongnecafe.domain.cafe.dto.request.CafeMenuInfoRequestDto +import io.beaniejoy.dongnecafe.domain.cafe.model.request.CafeMenuRegisterRequest import javax.persistence.* @Entity @@ -48,7 +48,7 @@ class Cafe protected constructor( address: String, phoneNumber: String, description: String, - cafeMenuRequestList: List, + cafeMenuRequestList: List, ): Cafe { val cafeMenuEntityList = cafeMenuRequestList.map { cafeMenuRequestDto -> CafeMenu.createCafeMenu( diff --git a/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/entity/CafeMenu.kt b/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/entity/CafeMenu.kt index fe4bfec..92b8299 100644 --- a/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/entity/CafeMenu.kt +++ b/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/entity/CafeMenu.kt @@ -1,7 +1,7 @@ package io.beaniejoy.dongnecafe.domain.cafe.entity import io.beaniejoy.dongnecafe.common.entity.BaseTimeEntity -import io.beaniejoy.dongnecafe.domain.cafe.dto.request.MenuOptionInfoRequestDto +import io.beaniejoy.dongnecafe.domain.cafe.model.request.MenuOptionRegisterRequest import java.math.BigDecimal import javax.persistence.* @@ -17,10 +17,12 @@ class CafeMenu protected constructor( val id: Long = 0L @Column(name = "name", nullable = false) - val name: String = name + var name: String = name + protected set @Column(name = "price", nullable = false) - val price: BigDecimal = price + var price: BigDecimal = price + protected set @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "cafe_id", nullable = false) @@ -31,7 +33,7 @@ class CafeMenu protected constructor( val menuOptionList: MutableList = arrayListOf() companion object { - fun createCafeMenu(name: String, price: BigDecimal, menuOptionRequestList: List): CafeMenu { + fun createCafeMenu(name: String, price: BigDecimal, menuOptionRequestList: List): CafeMenu { val menuOptionEntityList = menuOptionRequestList.map { menuOptionRequestDto -> MenuOption.createMenuOption( title = menuOptionRequestDto.title, @@ -56,4 +58,12 @@ class CafeMenu protected constructor( this.menuOptionList.add(menuOption) menuOption.updateCafeMenu(this) } + + fun updateInfo( + name: String, + price: BigDecimal + ) { + this.name = name + this.price = price + } } \ No newline at end of file diff --git a/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/entity/MenuOption.kt b/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/entity/MenuOption.kt index 08dc7d3..e63795a 100644 --- a/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/entity/MenuOption.kt +++ b/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/entity/MenuOption.kt @@ -1,7 +1,7 @@ package io.beaniejoy.dongnecafe.domain.cafe.entity import io.beaniejoy.dongnecafe.common.entity.BaseTimeEntity -import io.beaniejoy.dongnecafe.domain.cafe.dto.request.OptionDetailInfoRequestDto +import io.beaniejoy.dongnecafe.domain.cafe.model.request.OptionDetailRegisterRequest import javax.persistence.* @Entity @@ -15,7 +15,8 @@ class MenuOption protected constructor( val id: Long = 0L @Column(name = "title", nullable = false) - val title: String = title + var title: String = title + protected set @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "cafe_menu_id", nullable = false) @@ -26,7 +27,7 @@ class MenuOption protected constructor( val optionDetailList: MutableList = arrayListOf() companion object { - fun createMenuOption(title: String, optionDetailRequestList: List): MenuOption { + fun createMenuOption(title: String, optionDetailRequestList: List): MenuOption { val optionDetailEntityList = optionDetailRequestList.map { optionDetailRequestDto -> OptionDetail.createOptionDetail( name = optionDetailRequestDto.name, @@ -50,4 +51,8 @@ class MenuOption protected constructor( this.optionDetailList.add(optionDetail) optionDetail.updateMenuOption(this) } + + fun updateInfo(title: String) { + this.title = title + } } \ No newline at end of file diff --git a/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/entity/OptionDetail.kt b/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/entity/OptionDetail.kt index d19ba16..6bf8b70 100644 --- a/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/entity/OptionDetail.kt +++ b/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/entity/OptionDetail.kt @@ -16,10 +16,12 @@ class OptionDetail protected constructor( val id: Long = 0L @Column(name = "name", nullable = false) - val name: String = name + var name: String = name + protected set @Column(name = "extra_price", nullable = false) - val extraPrice: BigDecimal = extraPrice + var extraPrice: BigDecimal = extraPrice + protected set @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "menu_option_id", nullable = false) @@ -38,4 +40,9 @@ class OptionDetail protected constructor( fun updateMenuOption(menuOption: MenuOption) { this.menuOption = menuOption } + + fun updateInfo(name: String, extraPrice: BigDecimal) { + this.name = name + this.extraPrice = extraPrice + } } \ No newline at end of file diff --git a/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/error/CafeExceptionHandler.kt b/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/error/CafeExceptionHandler.kt index d9657d6..7b1f1fd 100644 --- a/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/error/CafeExceptionHandler.kt +++ b/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/error/CafeExceptionHandler.kt @@ -6,6 +6,7 @@ import org.springframework.web.bind.annotation.RestControllerAdvice @RestControllerAdvice class CafeExceptionHandler { + // TODO: error 규격화 @ExceptionHandler(CafeNotFoundException::class) fun handleNotFound(exception: CafeNotFoundException): ResponseEntity { return ResponseEntity.badRequest().body(exception.message) diff --git a/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/error/CafeExistedException.kt b/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/error/CafeExistedException.kt index 3775d57..ac08e0d 100644 --- a/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/error/CafeExistedException.kt +++ b/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/error/CafeExistedException.kt @@ -1,3 +1,3 @@ package io.beaniejoy.dongnecafe.domain.cafe.error -class CafeExistedException(name: String): RuntimeException("Cafe[$name] is already existed") \ No newline at end of file +class CafeExistedException(name: String) : RuntimeException("Cafe[$name] is already existed") \ No newline at end of file diff --git a/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/error/MenuOptionNotFoundException.kt b/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/error/MenuOptionNotFoundException.kt new file mode 100644 index 0000000..228fd9d --- /dev/null +++ b/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/error/MenuOptionNotFoundException.kt @@ -0,0 +1,3 @@ +package io.beaniejoy.dongnecafe.domain.cafe.error + +class MenuOptionNotFoundException(menuOptionId: Long) : RuntimeException("MenuOption[$menuOptionId] is not found") \ No newline at end of file diff --git a/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/error/OptionDetailNotFoundException.kt b/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/error/OptionDetailNotFoundException.kt new file mode 100644 index 0000000..59b5a88 --- /dev/null +++ b/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/error/OptionDetailNotFoundException.kt @@ -0,0 +1,3 @@ +package io.beaniejoy.dongnecafe.domain.cafe.error + +class OptionDetailNotFoundException(optionDetailId: Long) : RuntimeException("OptionDetail[$optionDetailId] is not found") \ No newline at end of file diff --git a/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/model/request/CafeMenuBulkDeleteRequest.kt b/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/model/request/CafeMenuBulkDeleteRequest.kt new file mode 100644 index 0000000..ca21012 --- /dev/null +++ b/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/model/request/CafeMenuBulkDeleteRequest.kt @@ -0,0 +1,5 @@ +package io.beaniejoy.dongnecafe.domain.cafe.model.request + +data class CafeMenuBulkDeleteRequest( + val cafeMenuIdList: List +) \ No newline at end of file diff --git a/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/model/request/CafeMenuRegisterRequest.kt b/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/model/request/CafeMenuRegisterRequest.kt new file mode 100644 index 0000000..156f8eb --- /dev/null +++ b/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/model/request/CafeMenuRegisterRequest.kt @@ -0,0 +1,9 @@ +package io.beaniejoy.dongnecafe.domain.cafe.model.request + +import java.math.BigDecimal + +data class CafeMenuRegisterRequest( + val name: String? = null, + val price: BigDecimal = BigDecimal.ZERO, + val menuOptionList: List = arrayListOf() +) diff --git a/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/model/request/CafeMenuUpdateRequest.kt b/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/model/request/CafeMenuUpdateRequest.kt new file mode 100644 index 0000000..9a58650 --- /dev/null +++ b/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/model/request/CafeMenuUpdateRequest.kt @@ -0,0 +1,9 @@ +package io.beaniejoy.dongnecafe.domain.cafe.model.request + +import java.math.BigDecimal + +data class CafeMenuUpdateRequest( + val name: String? = null, + val price: BigDecimal = BigDecimal.ZERO, + val menuOptionList: List = arrayListOf() +) \ No newline at end of file diff --git a/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/model/request/CafeRegisterRequest.kt b/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/model/request/CafeRegisterRequest.kt new file mode 100644 index 0000000..bdc026b --- /dev/null +++ b/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/model/request/CafeRegisterRequest.kt @@ -0,0 +1,9 @@ +package io.beaniejoy.dongnecafe.domain.cafe.model.request + +data class CafeRegisterRequest( + val name: String? = null, + val address: String? = null, + val phoneNumber: String? = null, + val description: String? = null, + val cafeMenuList: List = arrayListOf() +) \ No newline at end of file diff --git a/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/model/request/CafeUpdateRequest.kt b/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/model/request/CafeUpdateRequest.kt new file mode 100644 index 0000000..0b18d04 --- /dev/null +++ b/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/model/request/CafeUpdateRequest.kt @@ -0,0 +1,8 @@ +package io.beaniejoy.dongnecafe.domain.cafe.model.request + +data class CafeUpdateRequest( + val name: String? = null, + val address: String? = null, + val phoneNumber: String? = null, + val description: String? = null +) \ No newline at end of file diff --git a/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/model/request/MenuOptionRegisterRequest.kt b/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/model/request/MenuOptionRegisterRequest.kt new file mode 100644 index 0000000..7b70287 --- /dev/null +++ b/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/model/request/MenuOptionRegisterRequest.kt @@ -0,0 +1,13 @@ +package io.beaniejoy.dongnecafe.domain.cafe.model.request + +import java.math.BigDecimal + +data class MenuOptionRegisterRequest( + val title: String, + val optionDetailList: List = arrayListOf() +) + +data class OptionDetailRegisterRequest( + val name: String, + val extraPrice: BigDecimal +) \ No newline at end of file diff --git a/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/model/request/MenuOptionUpdateRequest.kt b/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/model/request/MenuOptionUpdateRequest.kt new file mode 100644 index 0000000..9e9208b --- /dev/null +++ b/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/model/request/MenuOptionUpdateRequest.kt @@ -0,0 +1,17 @@ +package io.beaniejoy.dongnecafe.domain.cafe.model.request + +import java.math.BigDecimal + +data class MenuOptionUpdateRequest( + val menuOptionId: Long, + val title: String, + val isDelete: Boolean = false, + val optionDetailList: List = arrayListOf() +) + +data class OptionDetailUpdateRequest( + val optionDetailId: Long, + val name: String, + val extraPrice: BigDecimal, + val isDelete: Boolean = false +) \ No newline at end of file diff --git a/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/model/response/CafeDetailedInfo.kt b/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/model/response/CafeDetailedInfo.kt new file mode 100644 index 0000000..1854540 --- /dev/null +++ b/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/model/response/CafeDetailedInfo.kt @@ -0,0 +1,29 @@ +package io.beaniejoy.dongnecafe.domain.cafe.model.response + +import io.beaniejoy.dongnecafe.domain.cafe.entity.Cafe + +data class CafeDetailedInfo( + val cafeId: Long = 0L, + val name: String? = null, + val address: String? = null, + val phoneNumber: String? = null, + val totalRate: Double? = null, + val description: String? = null, + val menuList: List = emptyList(), + val imageList: List = emptyList() +) { + companion object { + fun of(cafe: Cafe): CafeDetailedInfo { + return CafeDetailedInfo( + cafeId = cafe.id, + name = cafe.name, + address = cafe.address, + phoneNumber = cafe.phoneNumber, + totalRate = cafe.totalRate, + description = cafe.description, + menuList = cafe.cafeMenuList.map { CafeMenuInfo.of(it) }, + imageList = cafe.cafeImageList.map { CafeImageInfo.of(it) } + ) + } + } +} \ No newline at end of file diff --git a/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/model/response/CafeImageInfo.kt b/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/model/response/CafeImageInfo.kt new file mode 100644 index 0000000..b5a6bde --- /dev/null +++ b/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/model/response/CafeImageInfo.kt @@ -0,0 +1,14 @@ +package io.beaniejoy.dongnecafe.domain.cafe.model.response + +import io.beaniejoy.dongnecafe.domain.cafe.entity.CafeImage + +data class CafeImageInfo( + val cafeImageId: Long = 0L, + val imgUrl: String? = null +) { + companion object { + fun of(cafeImage: CafeImage): CafeImageInfo { + return CafeImageInfo(cafeImage.id, cafeImage.imgUrl) + } + } +} \ No newline at end of file diff --git a/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/dto/menu/CafeMenuDetailResponseDto.kt b/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/model/response/CafeMenuDetailedInfo.kt similarity index 51% rename from src/main/java/io/beaniejoy/dongnecafe/domain/cafe/dto/menu/CafeMenuDetailResponseDto.kt rename to src/main/java/io/beaniejoy/dongnecafe/domain/cafe/model/response/CafeMenuDetailedInfo.kt index dbaa76d..03e5625 100644 --- a/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/dto/menu/CafeMenuDetailResponseDto.kt +++ b/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/model/response/CafeMenuDetailedInfo.kt @@ -1,19 +1,21 @@ -package io.beaniejoy.dongnecafe.domain.cafe.dto.menu +package io.beaniejoy.dongnecafe.domain.cafe.model.response import io.beaniejoy.dongnecafe.domain.cafe.entity.CafeMenu import java.math.BigDecimal -data class CafeMenuDetailResponseDto( +data class CafeMenuDetailedInfo( + val cafeMenuId: Long = 0L, val name: String? = null, val price: BigDecimal = BigDecimal.ZERO, - val optionList: List = emptyList() + val optionList: List = emptyList() ) { companion object { - fun of(cafeMenu: CafeMenu): CafeMenuDetailResponseDto { - return CafeMenuDetailResponseDto( + fun of(cafeMenu: CafeMenu): CafeMenuDetailedInfo { + return CafeMenuDetailedInfo( + cafeMenuId = cafeMenu.id, name = cafeMenu.name, price = cafeMenu.price, - optionList = cafeMenu.menuOptionList.map { MenuOptionResponseDto.of(it) } + optionList = cafeMenu.menuOptionList.map { MenuOptionInfo.of(it) } ) } } diff --git a/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/dto/menu/CafeMenuResponseDto.kt b/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/model/response/CafeMenuInfo.kt similarity index 55% rename from src/main/java/io/beaniejoy/dongnecafe/domain/cafe/dto/menu/CafeMenuResponseDto.kt rename to src/main/java/io/beaniejoy/dongnecafe/domain/cafe/model/response/CafeMenuInfo.kt index 6236478..f24e5ef 100644 --- a/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/dto/menu/CafeMenuResponseDto.kt +++ b/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/model/response/CafeMenuInfo.kt @@ -1,17 +1,17 @@ -package io.beaniejoy.dongnecafe.domain.cafe.dto.menu +package io.beaniejoy.dongnecafe.domain.cafe.model.response import io.beaniejoy.dongnecafe.domain.cafe.entity.CafeMenu import java.math.BigDecimal -data class CafeMenuResponseDto( - val id: Long = 0L, +data class CafeMenuInfo( + val cafeMenuId: Long = 0L, val name: String? = null, val price: BigDecimal = BigDecimal.ZERO, ) { companion object { - fun of(cafeMenu: CafeMenu): CafeMenuResponseDto { - return CafeMenuResponseDto( - id = cafeMenu.id, + fun of(cafeMenu: CafeMenu): CafeMenuInfo { + return CafeMenuInfo( + cafeMenuId = cafeMenu.id, name = cafeMenu.name, price = cafeMenu.price ) diff --git a/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/model/response/CafeSearchInfo.kt b/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/model/response/CafeSearchInfo.kt new file mode 100644 index 0000000..520191f --- /dev/null +++ b/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/model/response/CafeSearchInfo.kt @@ -0,0 +1,23 @@ +package io.beaniejoy.dongnecafe.domain.cafe.model.response + +import io.beaniejoy.dongnecafe.domain.cafe.entity.Cafe + +data class CafeSearchInfo( + val cafeId: Long = 0L, + val name: String? = null, + val address: String? = null, + val totalRate: Double? = null, + val imageList: List = emptyList() +) { + companion object { + fun of(cafe: Cafe): CafeSearchInfo { + return CafeSearchInfo( + cafeId = cafe.id, + name = cafe.name, + address = cafe.address, + totalRate = cafe.totalRate, + imageList = cafe.cafeImageList.map { CafeImageInfo.of(it) } + ) + } + } +} \ No newline at end of file diff --git a/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/model/response/MenuOptionInfo.kt b/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/model/response/MenuOptionInfo.kt new file mode 100644 index 0000000..4970b08 --- /dev/null +++ b/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/model/response/MenuOptionInfo.kt @@ -0,0 +1,19 @@ +package io.beaniejoy.dongnecafe.domain.cafe.model.response + +import io.beaniejoy.dongnecafe.domain.cafe.entity.MenuOption + +data class MenuOptionInfo( + val menuOptionId: Long = 0L, + val title: String? = null, + val optionDetailList: List = emptyList() +) { + companion object { + fun of(menuOption: MenuOption): MenuOptionInfo { + return MenuOptionInfo( + menuOptionId = menuOption.id, + title = menuOption.title, + optionDetailList = menuOption.optionDetailList.map { OptionDetailInfo.of(it) } + ) + } + } +} \ No newline at end of file diff --git a/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/dto/menu/OptionDetailResponseDto.kt b/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/model/response/OptionDetailInfo.kt similarity index 53% rename from src/main/java/io/beaniejoy/dongnecafe/domain/cafe/dto/menu/OptionDetailResponseDto.kt rename to src/main/java/io/beaniejoy/dongnecafe/domain/cafe/model/response/OptionDetailInfo.kt index 756db31..b782f18 100644 --- a/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/dto/menu/OptionDetailResponseDto.kt +++ b/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/model/response/OptionDetailInfo.kt @@ -1,17 +1,17 @@ -package io.beaniejoy.dongnecafe.domain.cafe.dto.menu +package io.beaniejoy.dongnecafe.domain.cafe.model.response import io.beaniejoy.dongnecafe.domain.cafe.entity.OptionDetail import java.math.BigDecimal -data class OptionDetailResponseDto( - val id: Long = 0L, +data class OptionDetailInfo( + val optionDetailId: Long = 0L, val name: String? = null, val extra: BigDecimal = BigDecimal.ZERO ) { companion object { - fun of(optionDetail: OptionDetail): OptionDetailResponseDto { - return OptionDetailResponseDto( - id = optionDetail.id, + fun of(optionDetail: OptionDetail): OptionDetailInfo { + return OptionDetailInfo( + optionDetailId = optionDetail.id, name = optionDetail.name, extra = optionDetail.extraPrice ) diff --git a/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/repository/MenuOptionRepository.kt b/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/repository/MenuOptionRepository.kt new file mode 100644 index 0000000..eac2d35 --- /dev/null +++ b/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/repository/MenuOptionRepository.kt @@ -0,0 +1,6 @@ +package io.beaniejoy.dongnecafe.domain.cafe.repository + +import io.beaniejoy.dongnecafe.domain.cafe.entity.MenuOption +import org.springframework.data.jpa.repository.JpaRepository + +interface MenuOptionRepository : JpaRepository \ No newline at end of file diff --git a/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/repository/OptionDetailRepository.kt b/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/repository/OptionDetailRepository.kt new file mode 100644 index 0000000..27fcd2c --- /dev/null +++ b/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/repository/OptionDetailRepository.kt @@ -0,0 +1,6 @@ +package io.beaniejoy.dongnecafe.domain.cafe.repository + +import io.beaniejoy.dongnecafe.domain.cafe.entity.OptionDetail +import org.springframework.data.jpa.repository.JpaRepository + +interface OptionDetailRepository : JpaRepository \ No newline at end of file diff --git a/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/service/CafeMenuService.kt b/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/service/CafeMenuService.kt index e77555d..bf40940 100644 --- a/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/service/CafeMenuService.kt +++ b/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/service/CafeMenuService.kt @@ -1,21 +1,49 @@ package io.beaniejoy.dongnecafe.domain.cafe.service -import io.beaniejoy.dongnecafe.domain.cafe.dto.menu.CafeMenuDetailResponseDto +import io.beaniejoy.dongnecafe.domain.cafe.model.response.CafeMenuDetailedInfo import io.beaniejoy.dongnecafe.domain.cafe.error.CafeMenuNotFoundException +import io.beaniejoy.dongnecafe.domain.cafe.model.request.CafeMenuUpdateRequest import io.beaniejoy.dongnecafe.domain.cafe.repository.CafeMenuRepository import org.springframework.data.repository.findByIdOrNull import org.springframework.stereotype.Service import org.springframework.transaction.annotation.Transactional +// TODO +// - cafeMenu에 대한 생성, 수정, 삭제를 단일 카페 상세 페이지 내에서 한꺼번에 수행할지 고민 +// - front 개발 후에 CafeMenu에 대한 전체적인 로직 수정이 필요해 보임 @Service +@Transactional class CafeMenuService( - private val cafeMenuRepository: CafeMenuRepository + private val cafeMenuRepository: CafeMenuRepository, + private val menuOptionService: MenuOptionService ) { @Transactional(readOnly = true) - fun getCafeMenuInfoByCafeIdAndMenuId(menuId: Long, cafeId: Long): CafeMenuDetailResponseDto { + fun getDetailedInfoByMenuId(menuId: Long, cafeId: Long): CafeMenuDetailedInfo { val cafeMenu = cafeMenuRepository.findByIdOrNull(menuId) - ?: throw CafeMenuNotFoundException(menuId, cafeId) + ?: throw CafeMenuNotFoundException(menuId = menuId, cafeId = cafeId) - return CafeMenuDetailResponseDto.of(cafeMenu) + return CafeMenuDetailedInfo.of(cafeMenu) + } + + fun updateInfoAndBulkUpdate(menuId: Long, cafeId: Long, resource: CafeMenuUpdateRequest) { + val cafeMenu = cafeMenuRepository.findByIdOrNull(menuId) + ?: throw CafeMenuNotFoundException(menuId = menuId, cafeId = cafeId) + + cafeMenu.updateInfo(name = resource.name!!, price = resource.price) + + menuOptionService.bulkUpdate(resource.menuOptionList) + } + + fun deleteByCafeMenuId(menuId: Long, cafeId: Long) { + val cafeMenu = cafeMenuRepository.findByIdOrNull(menuId) + ?: throw CafeMenuNotFoundException(menuId = menuId, cafeId = cafeId) + + cafeMenuRepository.delete(cafeMenu) + } + + fun bulkDelete(cafeId: Long, cafeMenuIdList: List) { + cafeMenuIdList.forEach { + deleteByCafeMenuId(menuId = it, cafeId = cafeId) + } } } \ No newline at end of file diff --git a/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/service/CafeService.kt b/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/service/CafeService.kt index c3563df..9452130 100644 --- a/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/service/CafeService.kt +++ b/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/service/CafeService.kt @@ -1,12 +1,9 @@ package io.beaniejoy.dongnecafe.domain.cafe.service -import io.beaniejoy.dongnecafe.domain.cafe.dto.cafe.CafeInfoResponseDto -import io.beaniejoy.dongnecafe.domain.cafe.dto.cafe.CafeSearchResponseDto -import io.beaniejoy.dongnecafe.domain.cafe.dto.request.CafeMenuInfoRequestDto +import io.beaniejoy.dongnecafe.domain.cafe.model.response.CafeDetailedInfo +import io.beaniejoy.dongnecafe.domain.cafe.model.response.CafeSearchInfo +import io.beaniejoy.dongnecafe.domain.cafe.model.request.CafeMenuRegisterRequest import io.beaniejoy.dongnecafe.domain.cafe.entity.Cafe -import io.beaniejoy.dongnecafe.domain.cafe.entity.CafeMenu -import io.beaniejoy.dongnecafe.domain.cafe.entity.MenuOption -import io.beaniejoy.dongnecafe.domain.cafe.entity.OptionDetail import io.beaniejoy.dongnecafe.domain.cafe.error.CafeExistedException import io.beaniejoy.dongnecafe.domain.cafe.error.CafeNotFoundException import io.beaniejoy.dongnecafe.domain.cafe.repository.CafeRepository @@ -33,12 +30,12 @@ class CafeService( * - 옵션 상세 (상세 이름, 추가 금액 /ex. [(medium, 0), (large, 200), (venti, 700)]) */ @Transactional - fun createCafe( + fun createNew( name: String, address: String, phoneNumber: String, description: String, - cafeMenuRequestList: List, + cafeMenuRequestList: List, ): Long { checkCafeExistedByName(name) @@ -62,17 +59,17 @@ class CafeService( } } - fun getCafeList(pageable: Pageable): Page { + fun searchCafeList(pageable: Pageable): Page { val cafeList: Page = cafeRepository.findAll(pageable) - return cafeList.map { CafeSearchResponseDto.of(it) } + return cafeList.map { CafeSearchInfo.of(it) } } - fun getCafeInfoByCafeId(id: Long): CafeInfoResponseDto { + fun getDetailedInfoByCafeId(id: Long): CafeDetailedInfo { val cafe = cafeRepository.findByIdOrNull(id) ?: throw CafeNotFoundException(id) - return CafeInfoResponseDto.of(cafe) + return CafeDetailedInfo.of(cafe) } /** @@ -80,7 +77,7 @@ class CafeService( * - 카페 정보만 수정 (하위 엔티티에 대해서는 각 도메인 영역에서 수정) */ @Transactional - fun updateCafe( + fun updateInfo( id: Long, name: String, address: String, diff --git a/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/service/MenuOptionService.kt b/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/service/MenuOptionService.kt new file mode 100644 index 0000000..06236d8 --- /dev/null +++ b/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/service/MenuOptionService.kt @@ -0,0 +1,31 @@ +package io.beaniejoy.dongnecafe.domain.cafe.service + +import io.beaniejoy.dongnecafe.domain.cafe.error.MenuOptionNotFoundException +import io.beaniejoy.dongnecafe.domain.cafe.model.request.MenuOptionUpdateRequest +import io.beaniejoy.dongnecafe.domain.cafe.repository.MenuOptionRepository +import org.springframework.data.repository.findByIdOrNull +import org.springframework.stereotype.Service +import org.springframework.transaction.annotation.Transactional + +@Service +@Transactional +class MenuOptionService( + private val menuOptionRepository: MenuOptionRepository, + private val optionDetailService: OptionDetailService +) { + fun bulkUpdate(resources: List) { + resources.forEach { + val menuOption = menuOptionRepository.findByIdOrNull(it.menuOptionId) + ?: throw MenuOptionNotFoundException(it.menuOptionId) + + if (it.isDelete) { + menuOptionRepository.delete(menuOption) + return@forEach + } + + menuOption.updateInfo(it.title) + + optionDetailService.bulkUpdate(it.optionDetailList) + } + } +} \ No newline at end of file diff --git a/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/service/OptionDetailService.kt b/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/service/OptionDetailService.kt new file mode 100644 index 0000000..4cbe0b7 --- /dev/null +++ b/src/main/java/io/beaniejoy/dongnecafe/domain/cafe/service/OptionDetailService.kt @@ -0,0 +1,28 @@ +package io.beaniejoy.dongnecafe.domain.cafe.service + +import io.beaniejoy.dongnecafe.domain.cafe.error.OptionDetailNotFoundException +import io.beaniejoy.dongnecafe.domain.cafe.model.request.OptionDetailUpdateRequest +import io.beaniejoy.dongnecafe.domain.cafe.repository.OptionDetailRepository +import org.springframework.data.repository.findByIdOrNull +import org.springframework.stereotype.Service +import org.springframework.transaction.annotation.Transactional + +@Service +@Transactional +class OptionDetailService( + private val optionDetailRepository: OptionDetailRepository +) { + fun bulkUpdate(resources: List) { + resources.forEach { + val optionDetail = optionDetailRepository.findByIdOrNull(it.optionDetailId) + ?: throw OptionDetailNotFoundException(it.optionDetailId) + + if (it.isDelete) { + optionDetailRepository.delete(optionDetail) + return@forEach + } + + optionDetail.updateInfo(it.name, it.extraPrice) + } + } +} \ No newline at end of file diff --git a/src/main/resources/db/seed/R__Insert_Seed_cafe_image.sql b/src/main/resources/db/seed/R__Insert_Seed_cafe_image.sql index 460b7e2..c970c1c 100644 --- a/src/main/resources/db/seed/R__Insert_Seed_cafe_image.sql +++ b/src/main/resources/db/seed/R__Insert_Seed_cafe_image.sql @@ -6,18 +6,23 @@ BEGIN DECLARE i INT DEFAULT 0; DECLARE j INT; DECLARE idx_img INT DEFAULT 1; - DECLARE var_cafe_id binary(16); + DECLARE var_cafe_id INT; DECLARE count_cafe INT; + SET count_cafe = (SELECT COUNT(*) FROM `cafe`); - WHILE(i <= count_cafe) DO + + WHILE(i < count_cafe) DO SET j = 1; SET var_cafe_id = (SELECT cafe_id FROM `cafe` LIMIT i, 1); + WHILE(j <= 3) DO INSERT IGNORE INTO `cafe_image` (img_url, created_at, created_by, updated_at, updated_by, cafe_id) VALUES (CONCAT('test_img_url_', idx_img), now(), 'system', null, null, var_cafe_id); + SET j = j + 1; SET idx_img = idx_img + 1; END WHILE; + SET i = i + 1; END WHILE; END$$ diff --git a/src/main/resources/db/seed/R__Insert_Seed_cafe_menu.sql b/src/main/resources/db/seed/R__Insert_Seed_cafe_menu.sql index e5ee900..e3b3eea 100644 --- a/src/main/resources/db/seed/R__Insert_Seed_cafe_menu.sql +++ b/src/main/resources/db/seed/R__Insert_Seed_cafe_menu.sql @@ -5,15 +5,20 @@ CREATE PROCEDURE insertCafeMenus() BEGIN DECLARE i INT DEFAULT 0; DECLARE j INT; - DECLARE var_cafe_id binary(16); - WHILE(i <= 4) DO + DECLARE var_cafe_id INT; + + WHILE(i < 5) DO SET j = 1; - SET var_cafe_id = (SELECT cafe_id FROM `cafe` LIMIT i, 1); + SET var_cafe_id = (SELECT cafe_id + FROM `cafe` + LIMIT i, 1); + WHILE(j <= 10) DO INSERT IGNORE INTO `cafe_menu` (name, price, created_at, created_by, updated_at, updated_by, cafe_id) VALUES (CONCAT('커피', j), FLOOR(RAND() * 10 + 1) * 1000, now(), 'system', null, null, var_cafe_id); SET j = j + 1; END WHILE; + SET i = i + 1; END WHILE; END$$ diff --git a/src/main/resources/db/seed/R__Insert_Seed_menu_option.sql b/src/main/resources/db/seed/R__Insert_Seed_menu_option.sql new file mode 100644 index 0000000..6f254d1 --- /dev/null +++ b/src/main/resources/db/seed/R__Insert_Seed_menu_option.sql @@ -0,0 +1,25 @@ +DROP PROCEDURE IF EXISTS insertMenuOptions; + +DELIMITER $$ +CREATE PROCEDURE insertMenuOptions() +BEGIN + DECLARE i INT DEFAULT 0; + DECLARE var_cafe_menu_id INT; + DECLARE count_cafe_menu INT; + + SET count_cafe_menu = (SELECT COUNT(*) FROM `cafe_menu`); + + WHILE(i < count_cafe_menu) DO + SET var_cafe_menu_id = (SELECT cafe_menu_id + FROM `cafe_menu` + LIMIT i, 1); + + INSERT IGNORE INTO `menu_option` (title, created_at, created_by, updated_at, updated_by, cafe_menu_id) + VALUES ('SIZE', now(), 'system', null, null, var_cafe_menu_id); + + SET i = i + 1; + END WHILE; +END$$ +DELIMITER ; + +CALL insertMenuOptions(); \ No newline at end of file diff --git a/src/main/resources/db/seed/R__Insert_Seed_option_detail.sql b/src/main/resources/db/seed/R__Insert_Seed_option_detail.sql new file mode 100644 index 0000000..b8d7f5b --- /dev/null +++ b/src/main/resources/db/seed/R__Insert_Seed_option_detail.sql @@ -0,0 +1,29 @@ +DROP PROCEDURE IF EXISTS insertOptionDetails; + +DELIMITER $$ +CREATE PROCEDURE insertOptionDetails() +BEGIN + DECLARE i INT DEFAULT 0; + DECLARE var_menu_option_id INT; + DECLARE count_menu_option INT; + + SET count_menu_option = (SELECT COUNT(*) FROM `menu_option`); + + WHILE(i < count_menu_option) DO + SET var_menu_option_id = (SELECT menu_option_id + FROM `menu_option` + LIMIT i, 1); + + INSERT IGNORE INTO `option_detail` (name, extra_price, created_at, created_by, updated_at, updated_by, menu_option_id) + VALUES ('MEDIUM', FLOOR(RAND() * 3 + 1) * 1000, now(), 'system', null, null, var_menu_option_id); + INSERT IGNORE INTO `option_detail` (name, extra_price, created_at, created_by, updated_at, updated_by, menu_option_id) + VALUES ('LARGE', FLOOR(RAND() * 3 + 1) * 1000, now(), 'system', null, null, var_menu_option_id); + INSERT IGNORE INTO `option_detail` (name, extra_price, created_at, created_by, updated_at, updated_by, menu_option_id) + VALUES ('VENTI', FLOOR(RAND() * 3 + 1) * 1000, now(), 'system', null, null, var_menu_option_id); + + SET i = i + 1; + END WHILE; +END$$ +DELIMITER ; + +CALL insertOptionDetails(); \ No newline at end of file diff --git a/src/test/java/io/beaniejoy/dongnecafe/domain/cafe/entity/CafeTest.kt b/src/test/java/io/beaniejoy/dongnecafe/domain/cafe/entity/CafeTest.kt index f3d6628..39b9228 100644 --- a/src/test/java/io/beaniejoy/dongnecafe/domain/cafe/entity/CafeTest.kt +++ b/src/test/java/io/beaniejoy/dongnecafe/domain/cafe/entity/CafeTest.kt @@ -6,7 +6,7 @@ import org.junit.jupiter.api.Test internal class CafeTest { @Test fun create_cafe_test() { - val cafeRequestDto = CafeTestUtils.createCafeRequestDto() + val cafeRequestDto = CafeTestUtils.createCafeRegisterRequest() val cafe = Cafe.createCafe( name = cafeRequestDto.name!!, diff --git a/src/test/java/io/beaniejoy/dongnecafe/domain/cafe/repository/CafeRepositoryTest.kt b/src/test/java/io/beaniejoy/dongnecafe/domain/cafe/repository/CafeRepositoryTest.kt index 8e085fd..b1c90b2 100644 --- a/src/test/java/io/beaniejoy/dongnecafe/domain/cafe/repository/CafeRepositoryTest.kt +++ b/src/test/java/io/beaniejoy/dongnecafe/domain/cafe/repository/CafeRepositoryTest.kt @@ -4,6 +4,7 @@ import io.beaniejoy.dongnecafe.common.config.AuditingConfig import io.beaniejoy.dongnecafe.common.entity.BaseEntityAuditorAware import io.beaniejoy.dongnecafe.domain.cafe.entity.Cafe import io.beaniejoy.dongnecafe.domain.cafe.utils.CafeTestUtils +import mu.KLogging import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.DisplayName import org.junit.jupiter.api.Test @@ -20,13 +21,15 @@ import org.springframework.data.repository.findByIdOrNull ] ) internal class CafeRepositoryTest { + companion object : KLogging() + @Autowired lateinit var cafeRepository: CafeRepository @Test @DisplayName("[JPA] 신규 Cafe save 테스트") fun save_cafe_test() { - val cafeRequestDto = CafeTestUtils.createCafeRequestDto() + val cafeRequestDto = CafeTestUtils.createCafeRegisterRequest() val cafe = cafeRequestDto.let { Cafe.createCafe( name = it.name!!, @@ -47,7 +50,7 @@ internal class CafeRepositoryTest { @DisplayName("[JPA] 기존 Cafe 정보 update 테스트") fun update_cafe_test() { // TODO 테스트용 카페 데이터 주입 구성하기 - val cafeRequestDto = CafeTestUtils.createCafeRequestDto() + val cafeRequestDto = CafeTestUtils.createCafeRegisterRequest() val cafe = cafeRequestDto.let { Cafe.createCafe( name = it.name!!, @@ -81,4 +84,12 @@ internal class CafeRepositoryTest { assertEquals(updatedPhoneNumber, updatedCafe.phoneNumber) assertEquals(updatedDescription, updatedCafe.description) } + + @Test + fun select_cafe_test_data() { + val cafes = cafeRepository.findAll() + cafes.forEach { + logger.info { "cafe id=[${it.id}], name=[${it.name}]" } + } + } } \ No newline at end of file diff --git a/src/test/java/io/beaniejoy/dongnecafe/domain/cafe/service/CafeMenuServiceIntegratedTest.kt b/src/test/java/io/beaniejoy/dongnecafe/domain/cafe/service/CafeMenuServiceIntegratedTest.kt new file mode 100644 index 0000000..59b9b89 --- /dev/null +++ b/src/test/java/io/beaniejoy/dongnecafe/domain/cafe/service/CafeMenuServiceIntegratedTest.kt @@ -0,0 +1,62 @@ +package io.beaniejoy.dongnecafe.domain.cafe.service + +import io.beaniejoy.dongnecafe.domain.cafe.model.request.* +import io.beaniejoy.dongnecafe.domain.cafe.utils.CafeTestUtils +import org.junit.jupiter.api.Test +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.boot.test.context.SpringBootTest +import java.math.BigDecimal + +@SpringBootTest +class CafeMenuServiceIntegratedTest { + @Autowired + lateinit var cafeService: CafeService + + @Autowired + lateinit var cafeMenuService: CafeMenuService + + @Test + fun update_info_and_bulk_update_menu_options() { + val cafeRegisterRequest = CafeTestUtils.createCafeRegisterRequest() + + val savedCafeId = cafeService.createNew( + name = cafeRegisterRequest.name!!, + address = cafeRegisterRequest.address!!, + phoneNumber = cafeRegisterRequest.phoneNumber!!, + description = cafeRegisterRequest.description!!, + cafeMenuRequestList = cafeRegisterRequest.cafeMenuList + ) + + val cafeDetailedInfo = cafeService.getDetailedInfoByCafeId(savedCafeId) + + val cafeMenuUpdateRequest = cafeMenuService.getDetailedInfoByMenuId( + menuId = cafeDetailedInfo.menuList[0].cafeMenuId, + cafeId = cafeDetailedInfo.cafeId + ).let { + CafeMenuUpdateRequest( + name = "menu2 update", + price = it.price, + menuOptionList = listOf(it.optionList[1].let { menuOption -> + MenuOptionUpdateRequest( + menuOptionId = menuOption.menuOptionId, + title = "샷 update", + optionDetailList = menuOption.optionDetailList.mapIndexed { index, optionDetail -> + OptionDetailUpdateRequest( + optionDetailId = optionDetail.optionDetailId, + name = optionDetail.name!!, + extraPrice = BigDecimal("${index}000"), + isDelete = index == 0 + ) + } + ) + }) + ) + } + + cafeMenuService.updateInfoAndBulkUpdate( + menuId = cafeDetailedInfo.menuList[1].cafeMenuId, + cafeId = cafeDetailedInfo.cafeId, + resource = cafeMenuUpdateRequest + ) + } +} \ No newline at end of file diff --git a/src/test/java/io/beaniejoy/dongnecafe/domain/cafe/service/CafeMenuServiceTest.kt b/src/test/java/io/beaniejoy/dongnecafe/domain/cafe/service/CafeMenuServiceTest.kt new file mode 100644 index 0000000..361267a --- /dev/null +++ b/src/test/java/io/beaniejoy/dongnecafe/domain/cafe/service/CafeMenuServiceTest.kt @@ -0,0 +1,93 @@ +package io.beaniejoy.dongnecafe.domain.cafe.service + +import io.beaniejoy.dongnecafe.domain.cafe.entity.CafeMenu +import io.beaniejoy.dongnecafe.domain.cafe.error.CafeMenuNotFoundException +import io.beaniejoy.dongnecafe.domain.cafe.repository.CafeMenuRepository +import io.beaniejoy.dongnecafe.domain.cafe.repository.MenuOptionRepository +import io.beaniejoy.dongnecafe.domain.cafe.repository.OptionDetailRepository +import io.beaniejoy.dongnecafe.domain.cafe.utils.CafeMenuTestUtils +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.DisplayName +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertThrows +import org.junit.jupiter.api.extension.ExtendWith +import org.mockito.InjectMocks +import org.mockito.Mock +import org.mockito.Mockito.verify +import org.mockito.Mockito.`when` +import org.mockito.junit.jupiter.MockitoExtension +import java.util.* + +@ExtendWith(MockitoExtension::class) +internal class CafeMenuServiceTest { + @Mock + lateinit var mockCafeMenuRepository: CafeMenuRepository + + @Mock + lateinit var mockMenuOptionRepository: MenuOptionRepository + + @Mock + lateinit var mockOptionDetailRepository: OptionDetailRepository + + @Mock + lateinit var mockOptionDetailService: OptionDetailService + + @Mock + lateinit var mockMenuOptionService: MenuOptionService + + @InjectMocks + lateinit var mockCafeMenuService: CafeMenuService + + @Test + @DisplayName("카페 메뉴 ID를 통한 카페 메뉴 상세 조회") + fun find_cafe_menu_by_cafe_menu_id() { + // given + val (name, price, menuOptionList) = CafeMenuTestUtils.createCafeMenuRegisterRequest() + val cafeMenu = CafeMenu.createCafeMenu( + name = name!!, + price = price, + menuOptionRequestList = menuOptionList + ) + + val findCafeId = 100L + val findCafeMenuId = 1001L + + `when`(mockCafeMenuRepository.findById(findCafeMenuId)) + .thenReturn(Optional.of(cafeMenu.apply { + // cafe_menu_id Reflection 주입 + CafeMenuTestUtils.injectCafeMenuId(this, findCafeMenuId) + })) + + // when + val cafeMenuDetailedInfo = mockCafeMenuService.getDetailedInfoByMenuId(findCafeMenuId, findCafeId) + + // then + verify(mockCafeMenuRepository).findById(findCafeMenuId) + + cafeMenuDetailedInfo.also { + assertEquals(findCafeMenuId, it.cafeMenuId) + assertEquals(name, it.name) + assertEquals(price, it.price) + // TODO: MenuOption list도 비교 검증해야되는지 + } + } + + @Test + @DisplayName("존재하지 않는 카페 조회에 대한 예외 발생 테스트") + fun find_cafe_menu_by_cafe_menu_id_when_not_existed() { + // given + val findCafeId = 100L + val findCafeMenuId = 1001L + `when`(mockCafeMenuRepository.findById(findCafeMenuId)).thenReturn(Optional.empty()) + + // then + val exception = assertThrows { + // when + mockCafeMenuService.getDetailedInfoByMenuId(findCafeMenuId, findCafeId) + } + + assertEquals("Cafe[${findCafeId}]의 Menu[${findCafeMenuId}]는 존재하지 않는 메뉴입니다.", exception.message) + + verify(mockCafeMenuRepository).findById(findCafeMenuId) + } +} diff --git a/src/test/java/io/beaniejoy/dongnecafe/domain/cafe/service/CafeServiceTest.kt b/src/test/java/io/beaniejoy/dongnecafe/domain/cafe/service/CafeServiceTest.kt index 9cb91c7..6855a8c 100644 --- a/src/test/java/io/beaniejoy/dongnecafe/domain/cafe/service/CafeServiceTest.kt +++ b/src/test/java/io/beaniejoy/dongnecafe/domain/cafe/service/CafeServiceTest.kt @@ -13,8 +13,8 @@ import org.mockito.Mock import org.mockito.Mockito.* import org.mockito.junit.jupiter.MockitoExtension import java.util.* -import javax.persistence.GeneratedValue +// TODO: BDD 스타일로 리팩토링 해볼 것(추후 mockK도 사용해보자) @ExtendWith(MockitoExtension::class) @TestMethodOrder(MethodOrderer.DisplayName::class) internal class CafeServiceTest { @@ -28,25 +28,25 @@ internal class CafeServiceTest { @DisplayName("카페 신규 생성 테스트") fun create_cafe_test() { // given - val cafeRequestDto = CafeTestUtils.createCafeRequestDto() + val (name, address, phoneNumber, description, cafeMenuList) = CafeTestUtils.createCafeRegisterRequest() val savedMockCafeId = 100L - `when`(mockCafeRepository.findByName(cafeRequestDto.name!!)).thenReturn(null) + `when`(mockCafeRepository.findByName(name!!)).thenReturn(null) `when`(mockCafeRepository.save(any(Cafe::class.java))).thenAnswer { - injectCafeId(it.getArgument(0), savedMockCafeId) + CafeTestUtils.injectCafeId(it.getArgument(0), savedMockCafeId) } // when - val savedCafeId = mockCafeService.createCafe( - name = cafeRequestDto.name!!, - address = cafeRequestDto.address!!, - phoneNumber = cafeRequestDto.phoneNumber!!, - description = cafeRequestDto.description!!, - cafeMenuRequestList = cafeRequestDto.cafeMenuList + val savedCafeId = mockCafeService.createNew( + name = name, + address = address!!, + phoneNumber = phoneNumber!!, + description = description!!, + cafeMenuRequestList = cafeMenuList ) // then - verify(mockCafeRepository).findByName(cafeRequestDto.name!!) // TODO eq 에러 발생 이유 + verify(mockCafeRepository).findByName(name) // TODO eq 에러 발생 이유 verify(mockCafeRepository).save(any(Cafe::class.java)) assertEquals(savedCafeId, savedMockCafeId) @@ -56,61 +56,74 @@ internal class CafeServiceTest { @DisplayName("카페 신규 생성시 이미 존재하는 카페 예외 발생 테스트") fun fail_create_cafe_when_existed() { // given - val cafeRequestDto = CafeTestUtils.createCafeRequestDto() + val (name, address, phoneNumber, description, cafeMenuList) = CafeTestUtils.createCafeRegisterRequest() val cafe = Cafe.createCafe( - name = cafeRequestDto.name!!, - address = cafeRequestDto.address!!, - phoneNumber = cafeRequestDto.phoneNumber!!, - description = cafeRequestDto.description!!, - cafeMenuRequestList = cafeRequestDto.cafeMenuList + name = name!!, + address = address!!, + phoneNumber = phoneNumber!!, + description = description!!, + cafeMenuRequestList = cafeMenuList ) - `when`(mockCafeRepository.findByName(cafeRequestDto.name!!)).thenReturn(cafe) + `when`(mockCafeRepository.findByName(name)).thenReturn(cafe) // then assertThrows { // when - mockCafeService.createCafe( - name = cafeRequestDto.name!!, - address = cafeRequestDto.address!!, - phoneNumber = cafeRequestDto.phoneNumber!!, - description = cafeRequestDto.description!!, - cafeMenuRequestList = cafeRequestDto.cafeMenuList + mockCafeService.createNew( + name = name, + address = address, + phoneNumber = phoneNumber, + description = description, + cafeMenuRequestList = cafeMenuList ) } - verify(mockCafeRepository).findByName(cafeRequestDto.name!!) + verify(mockCafeRepository).findByName(name) } @Test @DisplayName("카페 정보 변경 테스트") fun update_cafe_test() { // given - val cafeRequestDto = CafeTestUtils.createCafeRequestDto() + val (name, address, phoneNumber, description, cafeMenuList) = CafeTestUtils.createCafeRegisterRequest() val cafe = Cafe.createCafe( - name = cafeRequestDto.name!!, - address = cafeRequestDto.address!!, - phoneNumber = cafeRequestDto.phoneNumber!!, - description = cafeRequestDto.description!!, - cafeMenuRequestList = cafeRequestDto.cafeMenuList + name = name!!, + address = address!!, + phoneNumber = phoneNumber!!, + description = description!!, + cafeMenuRequestList = cafeMenuList ) val cafeId = 50L - // TODO findByIdOrNull은 kotlin test 라이브러리 필요한 듯 - `when`(mockCafeRepository.findById(cafeId)).thenReturn(Optional.of(cafe)) + // TODO 'findByIdOrNull'은 kotlin test 라이브러리 필요한 듯 + val mockCafe = mock(Cafe::class.java) + doReturn(Optional.of(cafe)).`when`(mockCafeRepository.findById(eq(cafeId))) - // then - mockCafeService.updateCafe( - id = cafeId, - name = "", - address = "", - phoneNumber = "", - description = "", + doNothing().`when`(mockCafe).updateInfo( + name = anyString(), + address = anyString(), + phoneNumber = anyString(), + description = anyString() ) - verify(mockCafeRepository).findById(eq(cafeId)) + // when + mockCafeService.updateInfo( + id = eq(cafeId), + name = "updated_name", + address = "updated_address", + phoneNumber = "updated_phoneNumber", + description = "updated_desc" + ) - // TODO update TEST 방법? + // then + verify(mockCafeRepository).findById(eq(cafeId)) + verify(mockCafe).updateInfo( + name = "updated_name", + address = "updated_address", + phoneNumber = "updated_phoneNumber", + description = "updated_desc" + ) } @Test @@ -122,7 +135,7 @@ internal class CafeServiceTest { `when`(mockCafeRepository.findById(cafeId)).thenReturn(Optional.empty()) assertThrows { - mockCafeService.updateCafe( + mockCafeService.updateInfo( id = cafeId, name = "", address = "", @@ -131,19 +144,4 @@ internal class CafeServiceTest { ) } } - - private fun injectCafeId( - cafe: Cafe, - newCafeId: Long, - ): Cafe { - val idField = cafe.javaClass.declaredFields - .find { f -> - f.getAnnotation(GeneratedValue::class.java) != null - } ?: return cafe - - idField.isAccessible = true - idField.set(cafe, newCafeId) - - return cafe - } } \ No newline at end of file diff --git a/src/test/java/io/beaniejoy/dongnecafe/domain/cafe/utils/CafeMenuTestUtils.kt b/src/test/java/io/beaniejoy/dongnecafe/domain/cafe/utils/CafeMenuTestUtils.kt new file mode 100644 index 0000000..a700fde --- /dev/null +++ b/src/test/java/io/beaniejoy/dongnecafe/domain/cafe/utils/CafeMenuTestUtils.kt @@ -0,0 +1,108 @@ +package io.beaniejoy.dongnecafe.domain.cafe.utils + +import io.beaniejoy.dongnecafe.domain.cafe.entity.CafeMenu +import io.beaniejoy.dongnecafe.domain.cafe.entity.MenuOption +import io.beaniejoy.dongnecafe.domain.cafe.entity.OptionDetail +import io.beaniejoy.dongnecafe.domain.cafe.model.request.CafeMenuRegisterRequest +import io.beaniejoy.dongnecafe.domain.cafe.model.request.MenuOptionRegisterRequest +import io.beaniejoy.dongnecafe.domain.cafe.model.request.OptionDetailRegisterRequest +import org.junit.jupiter.api.Assertions +import java.math.BigDecimal +import javax.persistence.GeneratedValue + +class CafeMenuTestUtils { + companion object { + fun createCafeMenuRegisterRequest(): CafeMenuRegisterRequest { + return createCafeMenuRegisterRequestList()[0] + } + + fun createCafeMenuRegisterRequestList(): List { + val sizeOptionDetailList = listOf( + OptionDetailRegisterRequest(name = "medium", extraPrice = BigDecimal.ZERO), + OptionDetailRegisterRequest(name = "large", extraPrice = BigDecimal("200")), + OptionDetailRegisterRequest(name = "venti", extraPrice = BigDecimal("700")) + ) + val shotOptionDetailList = listOf( + OptionDetailRegisterRequest(name = "기본", extraPrice = BigDecimal.ZERO), + OptionDetailRegisterRequest(name = "샷 1 추가", extraPrice = BigDecimal("500")), + OptionDetailRegisterRequest(name = "샷 2 추가", extraPrice = BigDecimal("1000")), + ) + + val sizeMenuOption = MenuOptionRegisterRequest( + title = "사이즈", + optionDetailList = sizeOptionDetailList + ) + val shotMenuOption = MenuOptionRegisterRequest( + title = "샷", + optionDetailList = shotOptionDetailList + ) + + return listOf( + CafeMenuRegisterRequest( + name = "menu1", + price = BigDecimal("2800"), + menuOptionList = listOf(sizeMenuOption, shotMenuOption) + ), + CafeMenuRegisterRequest( + name = "menu2", + price = BigDecimal("3500"), + menuOptionList = listOf(sizeMenuOption) + ), + ) + } + + fun assertCafeMenuListEquals( + cafeMenuRequestList: List, + cafeMenuList: List, + ) { + for (index in cafeMenuRequestList.indices) { + Assertions.assertEquals(cafeMenuRequestList[index].name, cafeMenuList[index].name) + Assertions.assertEquals(cafeMenuRequestList[index].price, cafeMenuList[index].price) + + assertMenuOptionListEquals( + cafeMenuRequestList[index].menuOptionList, + cafeMenuList[index].menuOptionList + ) + } + } + + private fun assertMenuOptionListEquals( + menuOptionRequestList: List, + menuOptionList: List, + ) { + for (index in menuOptionRequestList.indices) { + Assertions.assertEquals(menuOptionRequestList[index].title, menuOptionList[index].title) + + assertOptionDetailListEquals( + menuOptionRequestList[index].optionDetailList, + menuOptionList[index].optionDetailList + ) + } + } + + private fun assertOptionDetailListEquals( + optionDetailRequestList: List, + optionDetailList: MutableList, + ) { + for (index in optionDetailRequestList.indices) { + Assertions.assertEquals(optionDetailRequestList[index].name, optionDetailList[index].name) + Assertions.assertEquals(optionDetailRequestList[index].extraPrice, optionDetailList[index].extraPrice) + } + } + + fun injectCafeMenuId( + cafeMenu: CafeMenu, + newCafeMenuId: Long, + ): CafeMenu { + val idField = cafeMenu.javaClass.declaredFields + .find { f -> + f.getAnnotation(GeneratedValue::class.java) != null + } ?: return cafeMenu + + idField.isAccessible = true + idField.set(cafeMenu, newCafeMenuId) + + return cafeMenu + } + } +} \ No newline at end of file diff --git a/src/test/java/io/beaniejoy/dongnecafe/domain/cafe/utils/CafeTestUtils.kt b/src/test/java/io/beaniejoy/dongnecafe/domain/cafe/utils/CafeTestUtils.kt index f16125a..66d3d2a 100644 --- a/src/test/java/io/beaniejoy/dongnecafe/domain/cafe/utils/CafeTestUtils.kt +++ b/src/test/java/io/beaniejoy/dongnecafe/domain/cafe/utils/CafeTestUtils.kt @@ -1,102 +1,56 @@ package io.beaniejoy.dongnecafe.domain.cafe.utils -import io.beaniejoy.dongnecafe.domain.cafe.dto.request.CafeInfoRequestDto -import io.beaniejoy.dongnecafe.domain.cafe.dto.request.CafeMenuInfoRequestDto -import io.beaniejoy.dongnecafe.domain.cafe.dto.request.MenuOptionInfoRequestDto -import io.beaniejoy.dongnecafe.domain.cafe.dto.request.OptionDetailInfoRequestDto +import io.beaniejoy.dongnecafe.domain.cafe.model.request.CafeRegisterRequest +import io.beaniejoy.dongnecafe.domain.cafe.model.request.CafeMenuRegisterRequest +import io.beaniejoy.dongnecafe.domain.cafe.model.request.MenuOptionRegisterRequest +import io.beaniejoy.dongnecafe.domain.cafe.model.request.OptionDetailRegisterRequest import io.beaniejoy.dongnecafe.domain.cafe.entity.Cafe import io.beaniejoy.dongnecafe.domain.cafe.entity.CafeMenu import io.beaniejoy.dongnecafe.domain.cafe.entity.MenuOption import io.beaniejoy.dongnecafe.domain.cafe.entity.OptionDetail import org.junit.jupiter.api.Assertions.* import java.math.BigDecimal +import javax.persistence.GeneratedValue class CafeTestUtils { companion object { - fun assertCafeEquals(request: CafeInfoRequestDto, entity: Cafe) { + fun assertCafeEquals(request: CafeRegisterRequest, entity: Cafe) { assertEquals(request.name, entity.name) assertEquals(request.address, entity.address) assertEquals(request.phoneNumber, entity.phoneNumber) assertEquals(request.description, entity.description) - assertCafeMenuListEquals(request.cafeMenuList, entity.cafeMenuList) + CafeMenuTestUtils.assertCafeMenuListEquals(request.cafeMenuList, entity.cafeMenuList) } - private fun assertCafeMenuListEquals( - cafeMenuRequestList: List, - cafeMenuList: List, - ) { - for (index in cafeMenuRequestList.indices) { - assertEquals(cafeMenuRequestList[index].name, cafeMenuList[index].name) - assertEquals(cafeMenuRequestList[index].price, cafeMenuList[index].price) - - assertMenuOptionListEquals( - cafeMenuRequestList[index].menuOptionList, - cafeMenuList[index].menuOptionList - ) - } - } - - private fun assertMenuOptionListEquals( - menuOptionRequestList: List, - menuOptionList: List, - ) { - for (index in menuOptionRequestList.indices) { - assertEquals(menuOptionRequestList[index].title, menuOptionList[index].title) - - assertOptionDetailListEquals( - menuOptionRequestList[index].optionDetailList, - menuOptionList[index].optionDetailList - ) - } - } - - private fun assertOptionDetailListEquals( - optionDetailRequestList: List, - optionDetailList: MutableList, - ) { - for (index in optionDetailRequestList.indices) { - assertEquals(optionDetailRequestList[index].name, optionDetailList[index].name) - assertEquals(optionDetailRequestList[index].extraPrice, optionDetailList[index].extraPrice) - } - } - - fun createCafeRequestDto(): CafeInfoRequestDto { + fun createCafeRegisterRequest(): CafeRegisterRequest { val cafeName = "beanie_cafe" val cafeAddress = "beanie_cafe_address" val phoneNumber = "01012345678" val description = "beanie_cafe_description" - val sizeOptionDetailList = listOf( - OptionDetailInfoRequestDto(name = "medium", extraPrice = BigDecimal.ZERO), - OptionDetailInfoRequestDto(name = "large", extraPrice = BigDecimal.valueOf(200L)), - OptionDetailInfoRequestDto(name = "venti", extraPrice = BigDecimal.valueOf(700L)) - ) - val sizeMenuOption = MenuOptionInfoRequestDto( - title = "size", - optionDetailList = sizeOptionDetailList - ) - - val cafeMenuList = listOf( - CafeMenuInfoRequestDto( - name = "menu1", - price = BigDecimal.valueOf(2_800L), - menuOptionList = listOf(sizeMenuOption) - ), - CafeMenuInfoRequestDto( - name = "menu2", - price = BigDecimal.valueOf(3_500L), - menuOptionList = listOf(sizeMenuOption) - ), - ) - - return CafeInfoRequestDto( + return CafeRegisterRequest( name = cafeName, address = cafeAddress, phoneNumber = phoneNumber, description = description, - cafeMenuList = cafeMenuList + cafeMenuList = CafeMenuTestUtils.createCafeMenuRegisterRequestList() ) } + + fun injectCafeId( + cafe: Cafe, + newCafeId: Long, + ): Cafe { + val idField = cafe.javaClass.declaredFields + .find { f -> + f.getAnnotation(GeneratedValue::class.java) != null + } ?: return cafe + + idField.isAccessible = true + idField.set(cafe, newCafeId) + + return cafe + } } } \ No newline at end of file