Skip to content

Commit

Permalink
Merge pull request #82 from le2sky/refactor/79
Browse files Browse the repository at this point in the history
[๊ฐœ์„ ] ๊ฐ€๊ฒŒ ์ƒ์„ฑ ์‹œ ์ฃผ์†Œ ์ •๋ณด ์ถ”๊ฐ€ (issue#79)
  • Loading branch information
le2sky authored Oct 4, 2023
2 parents 0cad251 + 621ebd7 commit 18b958c
Show file tree
Hide file tree
Showing 28 changed files with 576 additions and 34 deletions.
4 changes: 3 additions & 1 deletion .github/workflows/mealkitary-main-develop-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ jobs:
./mealkitary-infrastructure/adapter-paymentgateway-tosspayments/build/test-results/**/*.xml
./mealkitary-infrastructure/adapter-firebase-notification/build/test-results/**/*.xml
./mealkitary-infrastructure/business-registration-number-validator/adapter-simple-brn-validator/build/test-results/**/*.xml
./mealkitary-infrastructure/adapter-address-resolver/build/test-results/**/*.xml
- name: Jacoco Coverage ๋ฆฌํฌํŠธ ์ „์†ก
uses: codecov/codecov-action@v3
Expand All @@ -67,7 +68,8 @@ jobs:
./mealkitary-infrastructure/adapter-persistence-spring-data-jpa/build/reports/jacoco/test/jacocoTestReport.xml,
./mealkitary-infrastructure/adapter-paymentgateway-tosspayments/build/reports/jacoco/test/jacocoTestReport.xml,
./mealkitary-infrastructure/adapter-firebase-notification/build/reports/jacoco/test/jacocoTestReport.xml,
./mealkitary-infrastructure/business-registration-number-validator/adapter-simple-brn-validator/build/reports/jacoco/test/jacocoTestReport.xml
./mealkitary-infrastructure/business-registration-number-validator/adapter-simple-brn-validator/build/reports/jacoco/test/jacocoTestReport.xml,
./mealkitary-infrastructure/adapter-address-resolver/build/reports/jacoco/test/jacocoTestReport.xml
name: mealkitary-codecov
verbose: true

Expand Down
5 changes: 4 additions & 1 deletion .github/workflows/mealkitary-test-coverage-automation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ jobs:
./mealkitary-infrastructure/adapter-paymentgateway-tosspayments/build/test-results/**/*.xml
./mealkitary-infrastructure/adapter-firebase-notification/build/test-results/**/*.xml
./mealkitary-infrastructure/business-registration-number-validator/adapter-simple-brn-validator/build/test-results/**/*.xml
./mealkitary-infrastructure/adapter-address-resolver/build/test-results/**/*.xml
- name: Jacoco Coverage ๋ฆฌํฌํŠธ ์ „์†ก
uses: codecov/codecov-action@v3
Expand All @@ -55,6 +56,8 @@ jobs:
./mealkitary-infrastructure/adapter-persistence-spring-data-jpa/build/reports/jacoco/test/jacocoTestReport.xml,
./mealkitary-infrastructure/adapter-paymentgateway-tosspayments/build/reports/jacoco/test/jacocoTestReport.xml,
./mealkitary-infrastructure/adapter-firebase-notification/build/reports/jacoco/test/jacocoTestReport.xml,
./mealkitary-infrastructure/business-registration-number-validator/adapter-simple-brn-validator/build/reports/jacoco/test/jacocoTestReport.xml
./mealkitary-infrastructure/business-registration-number-validator/adapter-simple-brn-validator/build/reports/jacoco/test/jacocoTestReport.xml,
./mealkitary-infrastructure/adapter-address-resolver/build/reports/jacoco/test/jacocoTestReport.xml
name: mealkitary-codecov
verbose: true
2 changes: 2 additions & 0 deletions mealkitary-api/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ val snippetsDir by extra { file("build/generated-snippets") }
val asciidoctorExt: Configuration by configurations.creating

bootJar.enabled = true
bootJar.duplicatesStrategy = DuplicatesStrategy.EXCLUDE
jar.enabled = false

plugins {
Expand All @@ -21,6 +22,7 @@ dependencies {
implementation(project(":mealkitary-infrastructure:adapter-persistence-spring-data-jpa"))
implementation(project(":mealkitary-infrastructure:adapter-paymentgateway-tosspayments"))
implementation(project(":mealkitary-infrastructure:adapter-firebase-notification"))
implementation(project(":mealkitary-infrastructure:adapter-address-resolver"))
implementation(
project(
":mealkitary-infrastructure:business-registration-number-validator:adapter-open-api-brn-validator",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,11 @@ data class RegisterShopWebRequest(
val title: String? = null,

@field:NotBlank(message = "์‚ฌ์—…์ž ๋ฒˆํ˜ธ๋Š” ํ•„์ˆ˜์ž…๋‹ˆ๋‹ค.")
val brn: String? = null
val brn: String? = null,

@field:NotBlank(message = "์ฃผ์†Œ๋Š” ํ•„์ˆ˜์ž…๋‹ˆ๋‹ค.")
val address: String? = null
) {

fun mapToServiceRequest() = RegisterShopRequest(title!!, brn!!)
fun mapToServiceRequest() = RegisterShopRequest(title!!, brn!!, address!!)
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class RegisterShopControllerDocsTest : RestDocsSupport() {
fun `api docs test - registerShop`() {
every { registerShopUseCase.register(any()) } answers { 1L }

val registerShopWebRequest = RegisterShopWebRequest("์ง‘๋ฐฅ๋š๋”ฑ ์•ˆ์–‘์ ", "123-23-12345")
val registerShopWebRequest = RegisterShopWebRequest("์ง‘๋ฐฅ๋š๋”ฑ ์•ˆ์–‘์ ", "123-23-12345", "๊ฒฝ๊ธฐ๋„ ์•ˆ์–‘์‹œ ๋™์•ˆ๊ตฌ ๋ฒŒ๋ง๋กœ")

mvc.perform(
RestDocumentationRequestBuilders.post("/shops")
Expand All @@ -45,6 +45,7 @@ class RegisterShopControllerDocsTest : RestDocsSupport() {
requestFields(
fieldWithPath("title").type(JsonFieldType.STRING).description("๋“ฑ๋ก ๋Œ€์ƒ ๊ฐ€๊ฒŒ ์ด๋ฆ„"),
fieldWithPath("brn").type(JsonFieldType.STRING).description("์‚ฌ์—…์ž ๋ฒˆํ˜ธ"),
fieldWithPath("address").type(JsonFieldType.STRING).description("๊ฐ€๊ฒŒ ๋„๋กœ๋ช… ์ฃผ์†Œ"),
),
responseHeaders(headerWithName("Location").description("์ƒ์„ฑ๋œ ๊ฐ€๊ฒŒ ๋ฆฌ์†Œ์Šค URI")),
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class RegisterShopControllerTest : WebIntegrationTestSupport() {
fun `api integration test - registerShop`() {
every { registerShopUseCase.register(any()) } answers { 1L }

val registerShopWebRequest = RegisterShopWebRequest("์ง‘๋ฐฅ๋š๋”ฑ ์•ˆ์–‘์ ", "123-23-12345")
val registerShopWebRequest = RegisterShopWebRequest("์ง‘๋ฐฅ๋š๋”ฑ ์•ˆ์–‘์ ", "123-23-12345", "๊ฒฝ๊ธฐ๋„ ์•ˆ์–‘์‹œ ๋™์•ˆ๊ตฌ ๋ฒŒ๋ง๋กœ 40")

mvc.perform(
MockMvcRequestBuilders.post("/shops")
Expand All @@ -28,7 +28,7 @@ class RegisterShopControllerTest : WebIntegrationTestSupport() {

@Test
fun `api integration test - ๊ฐ€๊ฒŒ ์ด๋ฆ„์ด ๋ˆ„๋ฝ๋œ ๊ฒฝ์šฐ 400 ์—๋Ÿฌ๋ฅผ ๋ฐœ์ƒํ•œ๋‹ค`() {
val registerShopWebRequest = RegisterShopWebRequest(brn = "123-23-12345")
val registerShopWebRequest = RegisterShopWebRequest(brn = "123-23-12345", address = "๊ฒฝ๊ธฐ๋„ ์•ˆ์–‘์‹œ ๋™์•ˆ๊ตฌ ๋ฒŒ๋ง๋กœ 40")

mvc.perform(
MockMvcRequestBuilders.post("/shops")
Expand All @@ -44,7 +44,7 @@ class RegisterShopControllerTest : WebIntegrationTestSupport() {

@Test
fun `api integration test - ์‚ฌ์—…์ž ๋ฒˆํ˜ธ๊ฐ€ ๋ˆ„๋ฝ๋œ ๊ฒฝ์šฐ 400 ์—๋Ÿฌ๋ฅผ ๋ฐœ์ƒํ•œ๋‹ค`() {
val registerShopWebRequest = RegisterShopWebRequest(title = "์ง‘๋ฐฅ๋š๋”ฑ ์•ˆ์–‘์ ")
val registerShopWebRequest = RegisterShopWebRequest(title = "์ง‘๋ฐฅ๋š๋”ฑ ์•ˆ์–‘์ ", address = "๊ฒฝ๊ธฐ๋„ ์•ˆ์–‘์‹œ ๋™์•ˆ๊ตฌ ๋ฒŒ๋ง๋กœ 40")

mvc.perform(
MockMvcRequestBuilders.post("/shops")
Expand All @@ -58,6 +58,22 @@ class RegisterShopControllerTest : WebIntegrationTestSupport() {
.andExpect(jsonPath("$..errors[0].reason").value("์‚ฌ์—…์ž ๋ฒˆํ˜ธ๋Š” ํ•„์ˆ˜์ž…๋‹ˆ๋‹ค."))
}

@Test
fun `api integration test - ์ฃผ์†Œ๊ฐ€ ๋ˆ„๋ฝ๋œ ๊ฒฝ์šฐ 400 ์—๋Ÿฌ๋ฅผ ๋ฐœ์ƒํ•œ๋‹ค`() {
val registerShopWebRequest = RegisterShopWebRequest(title = "์ง‘๋ฐฅ๋š๋”ฑ ์•ˆ์–‘์ ", brn = "123-23-12345")

mvc.perform(
MockMvcRequestBuilders.post("/shops")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(registerShopWebRequest))
)
.andExpect(status().isBadRequest)
.andExpect(jsonPath("$.status").value("400"))
.andExpect(jsonPath("$.message").value("์ž˜๋ชป๋œ ์ž…๋ ฅ๊ฐ’์ž…๋‹ˆ๋‹ค."))
.andExpect(jsonPath("$..errors[0].field").value("address"))
.andExpect(jsonPath("$..errors[0].reason").value("์ฃผ์†Œ๋Š” ํ•„์ˆ˜์ž…๋‹ˆ๋‹ค."))
}

@Test
fun `api integration test - JSON ํ˜•์‹์ด ์•„๋‹Œ ๊ฒฝ์šฐ 400 ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค`() {
mvc.perform(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@ package com.mealkitary.shop.application.port.input

data class RegisterShopRequest(
val title: String,
val brn: String
val brn: String,
val address: String
)
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,23 @@ package com.mealkitary.shop.application.service
import com.mealkitary.shop.application.port.input.RegisterShopRequest
import com.mealkitary.shop.application.port.input.RegisterShopUseCase
import com.mealkitary.shop.application.port.output.SaveShopPort
import com.mealkitary.shop.domain.shop.factory.ShopBusinessNumberValidator
import com.mealkitary.shop.domain.shop.factory.ShopFactory
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional

@Service
@Transactional(readOnly = true)
@Transactional
class RegisterShopService(
private val saveShopPort: SaveShopPort,
shopBusinessNumberValidator: ShopBusinessNumberValidator
private val shopFactory: ShopFactory
) : RegisterShopUseCase {

private val shopFactory = ShopFactory(shopBusinessNumberValidator)

@Transactional
override fun register(registerShopRequest: RegisterShopRequest): Long {
val shop = shopFactory.createOne(registerShopRequest.title, registerShopRequest.brn)
val shop = shopFactory.createOne(
registerShopRequest.title,
registerShopRequest.brn,
registerShopRequest.address
)

return saveShopPort.saveOne(shop)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
package com.mealkitary.shop.application.service

import com.mealkitary.common.model.Address
import com.mealkitary.common.model.Coordinates
import com.mealkitary.shop.application.port.input.ShopResponse
import com.mealkitary.shop.application.port.output.LoadShopPort
import com.mealkitary.shop.domain.shop.Shop
import com.mealkitary.shop.domain.shop.ShopBusinessNumber
import com.mealkitary.shop.domain.shop.ShopStatus
import com.mealkitary.shop.domain.shop.ShopTitle
import com.mealkitary.shop.domain.shop.address.ShopAddress
import io.kotest.core.spec.style.AnnotationSpec
import io.kotest.matchers.shouldBe
import io.mockk.every
Expand All @@ -24,6 +27,19 @@ class GetShopServiceTest : AnnotationSpec() {
ShopTitle.from("์ง‘๋ฐฅ๋š๋”ฑ"),
ShopStatus.VALID,
ShopBusinessNumber.from("123-45-67890"),
ShopAddress.of(
"1234567890",
Coordinates.of(
126.99599512792346,
35.976749396987046
),
Address.of(
"region1DepthName",
"region2DepthName",
"region3DepthName",
"roadName"
)
),
mutableListOf(),
mutableListOf()
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
package com.mealkitary.shop.application.service

import com.mealkitary.common.model.Address
import com.mealkitary.common.model.Coordinates
import com.mealkitary.shop.application.port.input.RegisterShopRequest
import com.mealkitary.shop.application.port.output.SaveShopPort
import com.mealkitary.shop.domain.product.Product
import com.mealkitary.shop.domain.shop.Shop
import com.mealkitary.shop.domain.shop.ShopBusinessNumber
import com.mealkitary.shop.domain.shop.ShopStatus
import com.mealkitary.shop.domain.shop.ShopTitle
import com.mealkitary.shop.domain.shop.address.ShopAddress
import com.mealkitary.shop.domain.shop.factory.AddressResolver
import com.mealkitary.shop.domain.shop.factory.ShopBusinessNumberValidator
import com.mealkitary.shop.domain.shop.factory.ShopFactory
import io.kotest.assertions.throwables.shouldThrow
import io.kotest.core.spec.style.AnnotationSpec
import io.kotest.matchers.collections.shouldBeEmpty
Expand All @@ -12,35 +21,60 @@ import io.kotest.matchers.throwable.shouldHaveMessage
import io.mockk.every
import io.mockk.mockk
import io.mockk.slot
import java.time.LocalTime

class RegisterShopServiceTest : AnnotationSpec() {

private val saveShopPort = mockk<SaveShopPort>()
private val shopFactory = mockk<ShopFactory>()
private val shopBusinessNumberValidator = mockk<ShopBusinessNumberValidator>()
private val registerShopService = RegisterShopService(saveShopPort, shopBusinessNumberValidator)
private val addressResolver = mockk<AddressResolver>()
private val registerShopService = RegisterShopService(saveShopPort, shopFactory)

@Test
fun `service unit test - ์‹ ๊ทœ ๊ฐ€๊ฒŒ๋ฅผ ๋“ฑ๋กํ•œ๋‹ค`() {
val shopSlot = slot<Shop>()
val request = RegisterShopRequest("์ง‘๋ฐฅ๋š๋”ฑ ์•ˆ์–‘์ ", "123-23-12345")
val request = RegisterShopRequest("์ง‘๋ฐฅ๋š๋”ฑ ์•ˆ์–‘์ ", "123-23-12345", "๊ฒฝ๊ธฐ๋„ ์•ˆ์–‘์‹œ ๋™์•ˆ๊ตฌ ๋ฒŒ๋ง๋กœ 40")
val expectedShopAddress =
ShopAddress.of("1234567890", Coordinates.of(0.0, 0.0), Address.of("๊ฒฝ๊ธฐ๋„", "์•ˆ์–‘์‹œ ๋™์•ˆ๊ตฌ", "๋ฒŒ๋ง๋กœ", "40"))

val mockedShop = Shop(
ShopTitle.from(request.title),
ShopStatus.VALID,
ShopBusinessNumber.from(request.brn),
expectedShopAddress,
emptyList<LocalTime>().toMutableList(),
emptyList<Product>().toMutableList()
)

every {
shopFactory.createOne(request.title, request.brn, request.address)
} returns mockedShop
every { saveShopPort.saveOne(capture(shopSlot)) } answers { 1L }
every { shopBusinessNumberValidator.validate(any()) } answers {}

val result = registerShopService.register(request)

val capturedShop = shopSlot.captured
result shouldBe 1L
capturedShop.businessNumber.value shouldBe "123-23-12345"
capturedShop.title.value shouldBe "์ง‘๋ฐฅ๋š๋”ฑ ์•ˆ์–‘์ "
capturedShop.address shouldBe expectedShopAddress
capturedShop.products.shouldBeEmpty()
capturedShop.reservableTimes.shouldBeEmpty()
}

@Test
fun `service unit test - ๊ฐ€๊ฒŒ ์ด๋ฆ„ ํ˜•์‹์— ๋งž์ง€ ์•Š์œผ๋ฉด ์˜ˆ์™ธ๋ฅผ ๋ฐœ์ƒํ•œ๋‹ค`() {
val request = RegisterShopRequest("invalid!#@", "123-23-12345")
val request = RegisterShopRequest("invalid!#@", "123-23-12345", "๊ฒฝ๊ธฐ๋„ ์•ˆ์–‘์‹œ ๋™์•ˆ๊ตฌ ๋ฒŒ๋ง๋กœ 40")
val expectedShopAddress =
ShopAddress.of("1234567890", Coordinates.of(0.0, 0.0), Address.of("๊ฒฝ๊ธฐ๋„", "์•ˆ์–‘์‹œ ๋™์•ˆ๊ตฌ", "๋ฒŒ๋ง๋กœ", "40"))

every {
shopFactory.createOne(any(), any(), any())
} throws IllegalArgumentException("์˜ฌ๋ฐ”๋ฅธ ๊ฐ€๊ฒŒ ์ด๋ฆ„ ํ˜•์‹์ด ์•„๋‹™๋‹ˆ๋‹ค.(ํ•œ๊ธ€, ์˜๋ฌธ, ๊ณต๋ฐฑ, ์ˆซ์ž๋งŒ ํฌํ•จ ๊ฐ€๋Šฅ)")
every { saveShopPort.saveOne(any()) } answers { 1L }
every { shopBusinessNumberValidator.validate(any()) } answers {}
every { addressResolver.resolveAddress("๊ฒฝ๊ธฐ๋„ ์•ˆ์–‘์‹œ ๋™์•ˆ๊ตฌ ๋ฒŒ๋ง๋กœ 40") } returns expectedShopAddress

shouldThrow<IllegalArgumentException> {
registerShopService.register(request)
Expand All @@ -49,7 +83,11 @@ class RegisterShopServiceTest : AnnotationSpec() {

@Test
fun `service unit test - ์‚ฌ์—…์ž ๋ฒˆํ˜ธ ํ˜•์‹์— ๋งž์ง€ ์•Š์œผ๋ฉด ์˜ˆ์™ธ๋ฅผ ๋ฐœ์ƒํ•œ๋‹ค`() {
val request = RegisterShopRequest("์ง‘๋ฐฅ๋š๋”ฑ ์•ˆ์–‘์ ", "invalid-brn")
val request = RegisterShopRequest("์ง‘๋ฐฅ๋š๋”ฑ ์•ˆ์–‘์ ", "invalid-brn", "๊ฒฝ๊ธฐ๋„ ์•ˆ์–‘์‹œ ๋™์•ˆ๊ตฌ ๋ฒŒ๋ง๋กœ 40")

every {
shopFactory.createOne(any(), any(), any())
} throws IllegalArgumentException("์˜ฌ๋ฐ”๋ฅธ ์‚ฌ์—…์ž๋ฒˆํ˜ธ ํ˜•์‹์ด ์•„๋‹™๋‹ˆ๋‹ค.")
every { saveShopPort.saveOne(any()) } answers { 1L }
every { shopBusinessNumberValidator.validate(any()) } answers {}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
package com.mealkitary.shop.application.service

import com.mealkitary.common.model.Address
import com.mealkitary.common.model.Coordinates
import com.mealkitary.shop.application.port.output.CheckExistenceShopPort
import com.mealkitary.shop.application.port.output.LoadShopPort
import com.mealkitary.shop.domain.shop.Shop
import com.mealkitary.shop.domain.shop.ShopBusinessNumber
import com.mealkitary.shop.domain.shop.ShopStatus
import com.mealkitary.shop.domain.shop.ShopTitle
import com.mealkitary.shop.domain.shop.address.ShopAddress
import io.kotest.assertions.throwables.shouldThrow
import io.kotest.core.spec.style.AnnotationSpec
import io.kotest.matchers.shouldBe
Expand All @@ -25,6 +28,19 @@ class UpdateShopStatusServiceTest : AnnotationSpec() {
ShopTitle.from("์ œ๋ชฉ"),
ShopStatus.VALID,
ShopBusinessNumber.from("123-12-12345"),
ShopAddress.of(
"1234567890",
Coordinates.of(
126.99599512792346,
35.976749396987046
),
Address.of(
"region1DepthName",
"region2DepthName",
"region3DepthName",
"roadName"
)
),
mutableListOf(),
mutableListOf()
)
Expand All @@ -44,6 +60,19 @@ class UpdateShopStatusServiceTest : AnnotationSpec() {
ShopTitle.from("์ œ๋ชฉ"),
ShopStatus.INVALID,
ShopBusinessNumber.from("123-12-12345"),
ShopAddress.of(
"1234567890",
Coordinates.of(
126.99599512792346,
35.976749396987046
),
Address.of(
"region1DepthName",
"region2DepthName",
"region3DepthName",
"roadName"
)
),
mutableListOf(),
mutableListOf()
)
Expand All @@ -63,6 +92,19 @@ class UpdateShopStatusServiceTest : AnnotationSpec() {
ShopTitle.from("์ œ๋ชฉ"),
ShopStatus.VALID,
ShopBusinessNumber.from("123-12-12345"),
ShopAddress.of(
"1234567890",
Coordinates.of(
126.99599512792346,
35.976749396987046
),
Address.of(
"region1DepthName",
"region2DepthName",
"region3DepthName",
"roadName"
)
),
mutableListOf(),
mutableListOf()
)
Expand Down
Loading

0 comments on commit 18b958c

Please sign in to comment.