Skip to content

Commit

Permalink
[feature] menu 도메인 정의 및 테스트 작성 (#29)
Browse files Browse the repository at this point in the history
* create menu entity

* menu mother and test
  • Loading branch information
dojinyou authored Oct 15, 2023
1 parent 1c72804 commit 24cca35
Show file tree
Hide file tree
Showing 4 changed files with 242 additions and 0 deletions.
67 changes: 67 additions & 0 deletions src/main/kotlin/com/mjucow/eatda/domain/store/entity/Menu.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package com.mjucow.eatda.domain.store.entity

import com.mjucow.eatda.domain.common.BaseEntity
import jakarta.persistence.Column
import jakarta.persistence.Entity
import jakarta.persistence.FetchType
import jakarta.persistence.JoinColumn
import jakarta.persistence.ManyToOne
import jakarta.persistence.Table

@Entity
@Table(name = "menu")
class Menu(
@JoinColumn(name = "store_id", updatable = false)
@ManyToOne(fetch = FetchType.LAZY, optional = false)
val store: Store,
) : BaseEntity() {
constructor(
name: String,
price: Int,
imageAddress: String? = null,
store: Store,
) : this(store) {
this.name = name
this.price = price
this.imageAddress = imageAddress
}

@Column(nullable = false)
var name: String = ""
set(value) {
validateName(value)
field = value.trim()
}

@Column(nullable = false)
var price: Int = 0
set(value) {
validatePrice(value)
field = value
}

@Column(nullable = true)
var imageAddress: String? = null
set(value) {
field = value?.also { validateImageAddress(it) }
}

private fun validateName(name: String) {
require(name.isNotBlank() && name.length <= MAX_NAME_LENGTH)
}

private fun validatePrice(price: Int) {
require(MIN_PRICE <= price && price % PRICE_UNIT == 0)
}

private fun validateImageAddress(imageAddress: String) {
require(imageAddress.isNotBlank() && imageAddress.length <= MAX_IMAGE_ADDRESS_LENGTH)
}

companion object {
const val MIN_PRICE = 100
const val PRICE_UNIT = 100
const val MAX_NAME_LENGTH = 31
const val MAX_IMAGE_ADDRESS_LENGTH = 255
}
}
12 changes: 12 additions & 0 deletions src/main/resources/db/changelog/231014-menu.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
-- liquibase formatted sql

-- changeset liquibase:5
CREATE TABLE menu (
id bigserial NOT NULL PRIMARY KEY ,
name varchar(31) NOT NULL,
price integer NOT NULL,
image_address varchar(255) NULL,
created_at timestamp NOT NULL DEFAULT NOW(),
updated_at timestamp NOT NULL,
store_id bigint NOT NULL REFERENCES store
);
140 changes: 140 additions & 0 deletions src/test/kotlin/com/mjucow/eatda/domain/store/entity/MenuTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
package com.mjucow.eatda.domain.store.entity

import com.mjucow.eatda.domain.store.entity.objectmother.MenuMother
import com.mjucow.eatda.domain.store.entity.objectmother.StoreMother
import org.assertj.core.api.Assertions.assertThat
import org.assertj.core.api.Assertions.catchThrowable
import org.junit.jupiter.api.DisplayName
import org.junit.jupiter.api.Test
import org.junit.jupiter.params.ParameterizedTest
import org.junit.jupiter.params.provider.EmptySource
import org.junit.jupiter.params.provider.NullSource
import org.junit.jupiter.params.provider.ValueSource

class MenuTest {
@DisplayName("이름이 빈 값이라면 예외를 던진다")
@ParameterizedTest
@EmptySource
fun test1(name: String) {
// given
val store = StoreMother.create()

// when
val throwable = catchThrowable {
Menu(name = name, price = MenuMother.PRICE, store = store)
}

// then
assertThat(throwable).isNotNull()
}

@DisplayName("이름이 길이가 최대길이보다 길면 예외를 던진다")
@Test
fun test2() {
// given
val store = StoreMother.create()
val name = "a".repeat(Menu.MAX_NAME_LENGTH + 1)

// when
val throwable = catchThrowable {
Menu(name = name, price = MenuMother.PRICE, store = store)
}

// then
assertThat(throwable).isNotNull()
}

@DisplayName("가격이 최소 가격보다 작다면 예외를 던진다")
@ParameterizedTest
@ValueSource(ints = [Int.MIN_VALUE, -1, 0, 1, Menu.MIN_PRICE - 1])
fun test3(price: Int) {
// given
val store = StoreMother.create()

// when
val throwable = catchThrowable {
Menu(name = MenuMother.NAME, price = price, store = store)
}

// then
assertThat(throwable).isNotNull()
}

@DisplayName("가격이 단위 가격을 준수하지 않으면 예외를 던진다")
@Test
fun test4() {
// given
val store = StoreMother.create()
val price = MenuMother.PRICE + Menu.PRICE_UNIT - 1

// when
val throwable = catchThrowable {
Menu(name = MenuMother.NAME, price = price, store = store)
}

// then
assertThat(throwable).isNotNull()
}

@DisplayName("이미지 주소가 빈 값이라면 예외를 던진다")
@ParameterizedTest
@EmptySource
fun test4(imageAddress: String) {
// given
val store = StoreMother.create()

// when
val throwable = catchThrowable {
Menu(
name = MenuMother.NAME,
price = MenuMother.PRICE,
imageAddress = imageAddress,
store = store
)
}

// then
assertThat(throwable).isNotNull()
}

@DisplayName("이미지 주소가 최대 길이보다 길다면 예외를 던진다")
@Test
fun test5() {
// given
val store = StoreMother.create()
val imageAddress = "a".repeat(Menu.MAX_IMAGE_ADDRESS_LENGTH + 1)

// when
val throwable = catchThrowable {
Menu(
name = MenuMother.NAME,
price = MenuMother.PRICE,
imageAddress = imageAddress,
store = store
)
}

// then
assertThat(throwable).isNotNull()
}

@DisplayName("정상적인 값이라면 생성된다")
@ParameterizedTest
@NullSource
@ValueSource(strings = [MenuMother.IMAGE_ADDRESS])
fun test6(imageAddress: String?) {
// given
val store = StoreMother.create()

// when
val menu = Menu(
name = MenuMother.NAME,
price = MenuMother.PRICE,
imageAddress = imageAddress,
store = store
)

// then
assertThat(menu).isNotNull()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.mjucow.eatda.domain.store.entity.objectmother

import com.mjucow.eatda.common.objectmother.EntityMother
import com.mjucow.eatda.domain.store.entity.Menu

object MenuMother : EntityMother<Menu>() {
const val NAME = "menu"
const val PRICE = 1000
const val IMAGE_ADDRESS = "/eatda/public/menu/232D8241-C6A9-4AD9-B0EA-56F6DD24BADF.jpg"

override fun createFillInstance() = Menu(
name = NAME,
price = PRICE,
imageAddress = IMAGE_ADDRESS,
store = StoreMother.create()
)

override fun createDefaultInstance() = Menu(
name = NAME,
price = PRICE,
store = StoreMother.create()
)
}

0 comments on commit 24cca35

Please sign in to comment.