Merge pull request #10 from beaniejoy/feature/8

cafe 관련 기본 기능 추가 및 수정(기본 CRUD 구성) & 기본적인 테스트코드 구성
This commit is contained in:
Hanbin Lee
2022-08-13 01:17:29 +09:00
committed by GitHub
20 changed files with 649 additions and 61 deletions

2
.gitignore vendored
View File

@@ -33,4 +33,4 @@ out/
/.nb-gradle/
### VS Code ###
.vscode/
.vscode/

View File

@@ -11,16 +11,20 @@ import javax.persistence.MappedSuperclass
@MappedSuperclass
@EntityListeners(AuditingEntityListener::class)
class BaseTimeEntity(
abstract class BaseTimeEntity protected constructor() {
@CreatedDate
val createdAt: LocalDateTime = LocalDateTime.now(),
var createdAt: LocalDateTime = LocalDateTime.now()
protected set
@CreatedBy
val createdBy: String = "",
var createdBy: String = ""
protected set
@LastModifiedDate
val updatedAt: LocalDateTime? = null,
var updatedAt: LocalDateTime? = null
protected set
@LastModifiedBy
val updatedBy: String? = null
)
var updatedBy: String? = null
protected set
}

View File

@@ -2,7 +2,7 @@ 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.cafe.CafeUpdateRequestDto
import io.beaniejoy.dongnecafe.domain.cafe.dto.request.CafeInfoRequestDto
import io.beaniejoy.dongnecafe.domain.cafe.service.CafeService
import org.springframework.data.domain.Page
import org.springframework.data.domain.Pageable
@@ -15,8 +15,19 @@ import org.springframework.web.bind.annotation.*
class CafeController(
private val cafeService: CafeService
) {
@PostMapping
fun createCafe(@RequestBody resource: CafeInfoRequestDto): Long {
return cafeService.createCafe(
name = resource.name!!,
address = resource.address!!,
phoneNumber = resource.phoneNumber!!,
description = resource.description!!,
cafeMenuRequestList = resource.cafeMenuList
)
}
@GetMapping
fun searchCafeList(
fun searchCafe(
@PageableDefault(sort = ["name"], direction = Sort.Direction.ASC, page = 0, size = 10) pageable: Pageable
): Page<CafeSearchResponseDto> {
return cafeService.getCafeList(pageable)
@@ -31,7 +42,7 @@ class CafeController(
@PutMapping("/{id}")
fun updateCafeInfo(
@PathVariable("id") id: Long,
@RequestBody resource: CafeUpdateRequestDto
@RequestBody resource: CafeInfoRequestDto
): String {
cafeService.updateCafe(
id = id,

View File

@@ -1,8 +0,0 @@
package io.beaniejoy.dongnecafe.domain.cafe.dto.cafe
data class CafeUpdateRequestDto(
val name: String? = null,
val address: String? = null,
val phoneNumber: String? = null,
val description: String? = null
)

View File

@@ -0,0 +1,9 @@
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<CafeMenuInfoRequestDto> = arrayListOf()
)

View File

@@ -0,0 +1,9 @@
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<MenuOptionInfoRequestDto>
)

View File

@@ -0,0 +1,13 @@
package io.beaniejoy.dongnecafe.domain.cafe.dto.request
import java.math.BigDecimal
data class MenuOptionInfoRequestDto(
val title: String,
val optionDetailList: List<OptionDetailInfoRequestDto>
)
data class OptionDetailInfoRequestDto(
val name: String,
val extraPrice: BigDecimal
)

View File

@@ -1,37 +1,84 @@
package io.beaniejoy.dongnecafe.domain.cafe.entity
import io.beaniejoy.dongnecafe.common.entity.BaseTimeEntity
import io.beaniejoy.dongnecafe.domain.cafe.dto.request.CafeMenuInfoRequestDto
import javax.persistence.*
@Entity
@Table(name = "cafe")
class Cafe(
class Cafe protected constructor(
name: String,
address: String,
phoneNumber: String,
description: String,
) : BaseTimeEntity() {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
val id: Long = 0L,
val id: Long = 0L
@Column(name = "name", nullable = false)
var name: String,
var name: String = name
protected set
@Column(name = "address", nullable = false)
var address: String,
var address: String = address
protected set
@Column(name = "phone_number", nullable = false)
var phoneNumber: String,
var phoneNumber: String = phoneNumber
protected set
@Column(name = "total_rate", nullable = false)
val totalRate: Double,
val totalRate: Double = 0.0
@Column(name = "description", nullable = false)
var description: String,
var description: String = description
protected set
@OneToMany(mappedBy = "cafe", fetch = FetchType.LAZY)
val cafeMenuList: MutableList<CafeMenu>,
@OneToMany(mappedBy = "cafe", fetch = FetchType.LAZY, cascade = [CascadeType.ALL])
val cafeMenuList: MutableList<CafeMenu> = arrayListOf()
@OneToMany(mappedBy = "cafe", fetch = FetchType.LAZY)
val cafeImageList: MutableList<CafeImage>
) : BaseTimeEntity() {
fun updateInfo(name: String, address: String, phoneNumber: String, description: String) {
@OneToMany(mappedBy = "cafe", fetch = FetchType.LAZY, cascade = [CascadeType.ALL])
val cafeImageList: MutableList<CafeImage> = arrayListOf()
companion object {
fun createCafe(
name: String,
address: String,
phoneNumber: String,
description: String,
cafeMenuRequestList: List<CafeMenuInfoRequestDto>,
): Cafe {
val cafeMenuEntityList = cafeMenuRequestList.map { cafeMenuRequestDto ->
CafeMenu.createCafeMenu(
name = cafeMenuRequestDto.name!!,
price = cafeMenuRequestDto.price,
menuOptionRequestList = cafeMenuRequestDto.menuOptionList
)
}
return Cafe(
name = name,
address = address,
phoneNumber = phoneNumber,
description = description
).apply {
cafeMenuEntityList.forEach { this.addCafeMenu(it) }
}
}
}
fun addCafeMenu(cafeMenu: CafeMenu) {
this.cafeMenuList.add(cafeMenu)
cafeMenu.updateCafe(this)
}
fun updateInfo(
name: String,
address: String,
phoneNumber: String,
description: String,
) {
this.name = name
this.address = address
this.phoneNumber = phoneNumber

View File

@@ -1,26 +1,58 @@
package io.beaniejoy.dongnecafe.domain.cafe.entity
import io.beaniejoy.dongnecafe.common.entity.BaseTimeEntity
import io.beaniejoy.dongnecafe.domain.cafe.dto.request.MenuOptionInfoRequestDto
import java.math.BigDecimal
import javax.persistence.*
@Entity
@Table(name = "cafe_menu")
class CafeMenu(
class CafeMenu protected constructor(
name: String,
price: BigDecimal,
) : BaseTimeEntity() {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
val id: Long = 0L,
val id: Long = 0L
@Column(name = "name", nullable = false)
val name: String,
val name: String = name
@Column(name = "price", nullable = false)
val price: BigDecimal = BigDecimal.ZERO,
val price: BigDecimal = price
@ManyToOne
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "cafe_id", nullable = false)
val cafe: Cafe,
var cafe: Cafe? = null
protected set
@OneToMany(mappedBy = "cafeMenu", fetch = FetchType.LAZY)
val menuOptionList: MutableList<MenuOption>
) : BaseTimeEntity()
@OneToMany(mappedBy = "cafeMenu", fetch = FetchType.LAZY, cascade = [CascadeType.ALL])
val menuOptionList: MutableList<MenuOption> = arrayListOf()
companion object {
fun createCafeMenu(name: String, price: BigDecimal, menuOptionRequestList: List<MenuOptionInfoRequestDto>): CafeMenu {
val menuOptionEntityList = menuOptionRequestList.map { menuOptionRequestDto ->
MenuOption.createMenuOption(
title = menuOptionRequestDto.title,
optionDetailRequestList = menuOptionRequestDto.optionDetailList
)
}
return CafeMenu(
name = name,
price = price
).apply {
menuOptionEntityList.forEach { this.addMenuOption(it) }
}
}
}
fun updateCafe(cafe: Cafe) {
this.cafe = cafe
}
fun addMenuOption(menuOption: MenuOption) {
this.menuOptionList.add(menuOption)
menuOption.updateCafeMenu(this)
}
}

View File

@@ -1,22 +1,52 @@
package io.beaniejoy.dongnecafe.domain.cafe.entity
import io.beaniejoy.dongnecafe.common.entity.BaseTimeEntity
import io.beaniejoy.dongnecafe.domain.cafe.dto.request.OptionDetailInfoRequestDto
import javax.persistence.*
@Entity
@Table(name = "menu_option")
class MenuOption(
class MenuOption protected constructor(
title: String
) : BaseTimeEntity() {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
val id: Long = 0L,
val id: Long = 0L
@Column(name = "title", nullable = false)
val title: String,
val title: String = title
@ManyToOne
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "menu_id", nullable = false)
val cafeMenu: CafeMenu,
var cafeMenu: CafeMenu? = null
protected set
@OneToMany(mappedBy = "menuOption", fetch = FetchType.EAGER)
val optionDetailList: MutableList<OptionDetail>
) : BaseTimeEntity()
@OneToMany(mappedBy = "menuOption", fetch = FetchType.EAGER, cascade = [CascadeType.ALL])
val optionDetailList: MutableList<OptionDetail> = arrayListOf()
companion object {
fun createMenuOption(title: String, optionDetailRequestList: List<OptionDetailInfoRequestDto>): MenuOption {
val optionDetailEntityList = optionDetailRequestList.map { optionDetailRequestDto ->
OptionDetail.createOptionDetail(
name = optionDetailRequestDto.name,
extraPrice = optionDetailRequestDto.extraPrice
)
}
return MenuOption(
title = title
).apply {
optionDetailEntityList.forEach { this.addOptionDetail(it) }
}
}
}
fun updateCafeMenu(cafeMenu: CafeMenu) {
this.cafeMenu = cafeMenu
}
fun addOptionDetail(optionDetail: OptionDetail) {
this.optionDetailList.add(optionDetail)
optionDetail.updateMenuOption(this)
}
}

View File

@@ -6,18 +6,35 @@ import javax.persistence.*
@Entity
@Table(name = "option_detail")
class OptionDetail(
class OptionDetail protected constructor(
name: String,
extraPrice: BigDecimal
) : BaseTimeEntity() {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
val id: Long = 0L,
val id: Long = 0L
@Column(name = "name", nullable = false)
val name: String,
val name: String = name
@Column(name = "extra_price", nullable = false)
val extraPrice: BigDecimal,
val extraPrice: BigDecimal = extraPrice
@ManyToOne
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "option_id", nullable = false)
val menuOption: MenuOption
): BaseTimeEntity()
var menuOption: MenuOption? = null
protected set
companion object {
fun createOptionDetail(name: String, extraPrice: BigDecimal): OptionDetail {
return OptionDetail(
name = name,
extraPrice = extraPrice
)
}
}
fun updateMenuOption(menuOption: MenuOption) {
this.menuOption = menuOption
}
}

View File

@@ -0,0 +1,3 @@
package io.beaniejoy.dongnecafe.domain.cafe.error
class CafeExistedException(name: String): RuntimeException("Cafe[$name] is already existed")

View File

@@ -4,4 +4,5 @@ import io.beaniejoy.dongnecafe.domain.cafe.entity.Cafe
import org.springframework.data.jpa.repository.JpaRepository
interface CafeRepository : JpaRepository<Cafe, Long> {
fun findByName(name: String): Cafe?
}

View File

@@ -2,7 +2,12 @@ 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.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
import mu.KLogging
@@ -13,20 +18,56 @@ import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional
@Service
@Transactional
@Transactional(readOnly = true)
class CafeService(
private val cafeRepository: CafeRepository
private val cafeRepository: CafeRepository,
) {
companion object: KLogging()
companion object : KLogging()
/**
* 카페 생성 로직
* - 카페 생성시 카페정보 뿐만 아니라 하위 메뉴정보, 옵션, 옵션상세 같이 생성
* - 카페 정보(이름, 주소, 전화번호, 소개글)
* - 카페 메뉴정보 (메뉴 이름, 가격 /ex. 아메리카노, 2,800)
* - 메뉴 옵션 (옵션 이름 /ex. 사이즈)
* - 옵션 상세 (상세 이름, 추가 금액 /ex. [(medium, 0), (large, 200), (venti, 700)])
*/
@Transactional
fun createCafe(
name: String,
address: String,
phoneNumber: String,
description: String,
cafeMenuRequestList: List<CafeMenuInfoRequestDto>,
): Long {
checkCafeExistedByName(name)
val cafe = Cafe.createCafe(
name = name,
address = address,
phoneNumber = phoneNumber,
description = description,
cafeMenuRequestList = cafeMenuRequestList
)
val savedCafe = cafeRepository.save(cafe)
return savedCafe.id
}
private fun checkCafeExistedByName(name: String) {
val findCafe = cafeRepository.findByName(name)
if (findCafe != null) {
throw CafeExistedException(name)
}
}
@Transactional(readOnly = true)
fun getCafeList(pageable: Pageable): Page<CafeSearchResponseDto> {
val cafeList: Page<Cafe> = cafeRepository.findAll(pageable)
return cafeList.map { CafeSearchResponseDto.of(it) }
}
@Transactional(readOnly = true)
fun getCafeInfoByCafeId(id: Long): CafeInfoResponseDto {
val cafe = cafeRepository.findByIdOrNull(id)
?: throw CafeNotFoundException(id)
@@ -34,6 +75,11 @@ class CafeService(
return CafeInfoResponseDto.of(cafe)
}
/**
* 카페 정보 수정
* - 카페 정보만 수정 (하위 엔티티에 대해서는 각 도메인 영역에서 수정)
*/
@Transactional
fun updateCafe(
id: Long,
name: String,

View File

@@ -11,8 +11,13 @@ spring:
hibernate:
dialect: org.hibernate.dialect.MySQL5InnoDBDialect
format_sql: true
show-sql: true
show-sql: false
flyway:
baseline-on-migrate: true
locations: classpath:db/migration,classpath:db/seed
# baseline-version: 0
logging:
level:
org.hibernate.SQL: debug # logger 통해 로깅
# org.hibernate.type: trace

View File

@@ -0,0 +1,21 @@
package io.beaniejoy.dongnecafe.domain.cafe.entity
import io.beaniejoy.dongnecafe.domain.cafe.utils.CafeTestUtils
import org.junit.jupiter.api.Test
internal class CafeTest {
@Test
fun create_cafe_test() {
val cafeRequestDto = CafeTestUtils.createCafeRequestDto()
val cafe = Cafe.createCafe(
name = cafeRequestDto.name!!,
address = cafeRequestDto.address!!,
phoneNumber = cafeRequestDto.phoneNumber!!,
description = cafeRequestDto.description!!,
cafeMenuRequestList = cafeRequestDto.cafeMenuList
)
CafeTestUtils.assertCafeEquals(request = cafeRequestDto, entity = cafe)
}
}

View File

@@ -0,0 +1,84 @@
package io.beaniejoy.dongnecafe.domain.cafe.repository
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 org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.DisplayName
import org.junit.jupiter.api.Test
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest
import org.springframework.context.annotation.ComponentScan
import org.springframework.context.annotation.FilterType
import org.springframework.data.repository.findByIdOrNull
@DataJpaTest(
includeFilters = [
ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = [AuditingConfig::class]),
ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = [BaseEntityAuditorAware::class])
]
)
internal class CafeRepositoryTest {
@Autowired
lateinit var cafeRepository: CafeRepository
@Test
@DisplayName("[JPA] 신규 Cafe save 테스트")
fun save_cafe_test() {
val cafeRequestDto = CafeTestUtils.createCafeRequestDto()
val cafe = cafeRequestDto.let {
Cafe.createCafe(
name = it.name!!,
address = it.address!!,
phoneNumber = it.phoneNumber!!,
description = it.description!!,
cafeMenuRequestList = it.cafeMenuList
)
}
val savedCafe = cafeRepository.save(cafe)
assertEquals(1L, savedCafe.id)
CafeTestUtils.assertCafeEquals(cafeRequestDto, savedCafe)
}
@Test
@DisplayName("[JPA] 기존 Cafe 정보 update 테스트")
fun update_cafe_test() {
// TODO 테스트용 카페 데이터 주입 구성하기
val cafeRequestDto = CafeTestUtils.createCafeRequestDto()
val cafe = cafeRequestDto.let {
Cafe.createCafe(
name = it.name!!,
address = it.address!!,
phoneNumber = it.phoneNumber!!,
description = it.description!!,
cafeMenuRequestList = it.cafeMenuList
)
}
val savedId = cafeRepository.save(cafe).id
val findCafe = cafeRepository.findByIdOrNull(savedId)
val updatedName = "update cafe name"
val updatedAddress = "update cafe address"
val updatedPhoneNumber = "01011112222"
val updatedDescription = "update description"
findCafe!!.updateInfo(
name = updatedName,
address = updatedAddress,
phoneNumber = updatedPhoneNumber,
description = updatedDescription
)
val updatedCafe = cafeRepository.findByIdOrNull(savedId)
assertEquals(updatedName, updatedCafe!!.name)
assertEquals(updatedAddress, updatedCafe.address)
assertEquals(updatedPhoneNumber, updatedCafe.phoneNumber)
assertEquals(updatedDescription, updatedCafe.description)
}
}

View File

@@ -0,0 +1,149 @@
package io.beaniejoy.dongnecafe.domain.cafe.service
import io.beaniejoy.dongnecafe.domain.cafe.entity.Cafe
import io.beaniejoy.dongnecafe.domain.cafe.error.CafeExistedException
import io.beaniejoy.dongnecafe.domain.cafe.error.CafeNotFoundException
import io.beaniejoy.dongnecafe.domain.cafe.repository.CafeRepository
import io.beaniejoy.dongnecafe.domain.cafe.utils.CafeTestUtils
import org.junit.jupiter.api.*
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.extension.ExtendWith
import org.mockito.InjectMocks
import org.mockito.Mock
import org.mockito.Mockito.*
import org.mockito.junit.jupiter.MockitoExtension
import java.util.*
import javax.persistence.GeneratedValue
@ExtendWith(MockitoExtension::class)
@TestMethodOrder(MethodOrderer.DisplayName::class)
internal class CafeServiceTest {
@InjectMocks
lateinit var mockCafeService: CafeService
@Mock
lateinit var mockCafeRepository: CafeRepository
@Test
@DisplayName("카페 신규 생성 테스트")
fun create_cafe_test() {
// given
val cafeRequestDto = CafeTestUtils.createCafeRequestDto()
val savedMockCafeId = 100L
`when`(mockCafeRepository.findByName(cafeRequestDto.name!!)).thenReturn(null)
`when`(mockCafeRepository.save(any(Cafe::class.java))).thenAnswer {
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
)
// then
verify(mockCafeRepository).findByName(cafeRequestDto.name!!) // TODO eq 에러 발생 이유
verify(mockCafeRepository).save(any(Cafe::class.java))
assertEquals(savedCafeId, savedMockCafeId)
}
@Test
@DisplayName("카페 신규 생성시 이미 존재하는 카페 예외 발생 테스트")
fun fail_create_cafe_when_existed() {
// given
val cafeRequestDto = CafeTestUtils.createCafeRequestDto()
val cafe = Cafe.createCafe(
name = cafeRequestDto.name!!,
address = cafeRequestDto.address!!,
phoneNumber = cafeRequestDto.phoneNumber!!,
description = cafeRequestDto.description!!,
cafeMenuRequestList = cafeRequestDto.cafeMenuList
)
`when`(mockCafeRepository.findByName(cafeRequestDto.name!!)).thenReturn(cafe)
// then
assertThrows<CafeExistedException> {
// when
mockCafeService.createCafe(
name = cafeRequestDto.name!!,
address = cafeRequestDto.address!!,
phoneNumber = cafeRequestDto.phoneNumber!!,
description = cafeRequestDto.description!!,
cafeMenuRequestList = cafeRequestDto.cafeMenuList
)
}
verify(mockCafeRepository).findByName(cafeRequestDto.name!!)
}
@Test
@DisplayName("카페 정보 변경 테스트")
fun update_cafe_test() {
// given
val cafeRequestDto = CafeTestUtils.createCafeRequestDto()
val cafe = Cafe.createCafe(
name = cafeRequestDto.name!!,
address = cafeRequestDto.address!!,
phoneNumber = cafeRequestDto.phoneNumber!!,
description = cafeRequestDto.description!!,
cafeMenuRequestList = cafeRequestDto.cafeMenuList
)
val cafeId = 50L
// TODO findByIdOrNull은 kotlin test 라이브러리 필요한 듯
`when`(mockCafeRepository.findById(cafeId)).thenReturn(Optional.of(cafe))
// then
mockCafeService.updateCafe(
id = cafeId,
name = "",
address = "",
phoneNumber = "",
description = "",
)
verify(mockCafeRepository).findById(eq(cafeId))
// TODO update TEST 방법?
}
@Test
@DisplayName("카페 정보 변경시 존재하지 않는 카페 예외 발생 테스트")
fun fail_update_cafe_when_not_found() {
// given
val cafeId = 50L
`when`(mockCafeRepository.findById(cafeId)).thenReturn(Optional.empty())
assertThrows<CafeNotFoundException> {
mockCafeService.updateCafe(
id = cafeId,
name = "",
address = "",
phoneNumber = "",
description = "",
)
}
}
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
}
}

View File

@@ -0,0 +1,102 @@
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.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
class CafeTestUtils {
companion object {
fun assertCafeEquals(request: CafeInfoRequestDto, 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)
}
private fun assertCafeMenuListEquals(
cafeMenuRequestList: List<CafeMenuInfoRequestDto>,
cafeMenuList: List<CafeMenu>,
) {
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<MenuOptionInfoRequestDto>,
menuOptionList: List<MenuOption>,
) {
for (index in menuOptionRequestList.indices) {
assertEquals(menuOptionRequestList[index].title, menuOptionList[index].title)
assertOptionDetailListEquals(
menuOptionRequestList[index].optionDetailList,
menuOptionList[index].optionDetailList
)
}
}
private fun assertOptionDetailListEquals(
optionDetailRequestList: List<OptionDetailInfoRequestDto>,
optionDetailList: MutableList<OptionDetail>,
) {
for (index in optionDetailRequestList.indices) {
assertEquals(optionDetailRequestList[index].name, optionDetailList[index].name)
assertEquals(optionDetailRequestList[index].extraPrice, optionDetailList[index].extraPrice)
}
}
fun createCafeRequestDto(): CafeInfoRequestDto {
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(
name = cafeName,
address = cafeAddress,
phoneNumber = phoneNumber,
description = description,
cafeMenuList = cafeMenuList
)
}
}
}

View File

@@ -0,0 +1,13 @@
spring:
flyway:
enabled: false
jpa:
properties:
hibernate:
format_sql: true
show_sql: false
logging:
level:
org.hibernate.SQL: debug
org.hibernate.type: trace