Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[배포] v0.5.1(PR#81,PR#82) #83

Merged
merged 28 commits into from
Oct 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
31794b2
refactor : WebClientConfig 클래스 분리
le2sky Oct 1, 2023
9a548ff
refactor : brn 어댑터 모듈 네이밍 개선
le2sky Oct 1, 2023
f2a32f7
refactor : 모듈 이름 변경 대응
le2sky Oct 1, 2023
a5ad0ef
chore : uriBuilderFactory 설정
le2sky Oct 1, 2023
8e4b139
feat : open api brn 검증기 구현
le2sky Oct 2, 2023
5cbb342
feat : open api webclient 구현
le2sky Oct 2, 2023
a9dd64e
feat : http 요청/응답 페이로드 구현
le2sky Oct 2, 2023
6984274
chore : webflux 의존성 설정
le2sky Oct 2, 2023
e7e8d02
fix : bean 주입 우선순위 변경
le2sky Oct 2, 2023
5a6e771
fix : 프로젝트 버전 변경
le2sky Oct 2, 2023
7ef0ccc
fix : 신규 모듈 테스트 커버리지 분석 등록
le2sky Oct 2, 2023
0a56e96
refactor: 가게 생성 시에 주소도 입력받도록 수정
1o18z Oct 3, 2023
362e52f
refactor: 가게 엔티티에 주소 필드 추가
1o18z Oct 3, 2023
c096b9a
refactor: 도로명 주소를 주소 객체로 변환하는 로직 작성
1o18z Oct 3, 2023
534af9c
chore: 주소 변환기 모듈 의존성 추가
1o18z Oct 3, 2023
b5b2098
refactor: 불필요한 어노테이션 제거
1o18z Oct 3, 2023
d85a9e2
fix: 파일 중복 문제를 위해 build.gradle 수정
1o18z Oct 3, 2023
c6e148f
refactor: 주소 변수명 변경
1o18z Oct 3, 2023
a8e12ce
refactor: 지역 코드 길이 상수 추출
1o18z Oct 3, 2023
4d21a4f
refactor: 좌표 범위 검증 메서드명 변경
1o18z Oct 3, 2023
a11411f
chore: 불필요한 콤마 제거
1o18z Oct 3, 2023
b72b1c8
refactor : 의미가 드러나는 이름으로 개선
le2sky Oct 3, 2023
828ec4c
chore: 주소, 좌표 클래스 패키지 이동
1o18z Oct 4, 2023
65a2a07
refactor: 누락된 `@Component` 추가
1o18z Oct 4, 2023
621ebd7
fix: 컴포넌트 스캔 미적용 문제 해결
1o18z Oct 4, 2023
18b958c
Merge pull request #82 from le2sky/refactor/79
le2sky Oct 4, 2023
7e9563a
fix : 충돌 해결
le2sky Oct 4, 2023
7204ea2
Merge pull request #81 from le2sky/feat/80
le2sky Oct 4, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions .github/workflows/mealkitary-main-develop-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,9 @@ jobs:
./mealkitary-infrastructure/adapter-persistence-spring-data-jpa/build/test-results/**/*.xml
./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-business-registration-number-validator/simple-brn-validator/build/test-results/**/*.xml
./mealkitary-infrastructure/adapter-business-registration-number-validator/open-api-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 +69,9 @@ 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/adapter-business-registration-number-validator/simple-brn-validator/build/reports/jacoco/test/jacocoTestReport.xml,
./mealkitary-infrastructure/adapter-business-registration-number-validator/open-api-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
8 changes: 6 additions & 2 deletions .github/workflows/mealkitary-test-coverage-automation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,9 @@ jobs:
./mealkitary-infrastructure/adapter-persistence-spring-data-jpa/build/test-results/**/*.xml
./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-business-registration-number-validator/simple-brn-validator/build/test-results/**/*.xml
./mealkitary-infrastructure/adapter-business-registration-number-validator/open-api-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 +57,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/adapter-business-registration-number-validator/simple-brn-validator/build/reports/jacoco/test/jacocoTestReport.xml,
./mealkitary-infrastructure/adapter-business-registration-number-validator/open-api-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: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ ktlintVersion=11.0.0
springBootVersion=2.7.11
springDependencyManagementVersion=1.0.15.RELEASE
# project
applicationVersion=0.5.0
applicationVersion=0.5.1
projectGroup=com.mealkitary
# test
kotestVersion=4.4.3
Expand Down
7 changes: 5 additions & 2 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,14 +22,16 @@ 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-configuration"))
implementation(project(":mealkitary-infrastructure:adapter-address-resolver"))
implementation(
project(
":mealkitary-infrastructure:business-registration-number-validator:adapter-open-api-brn-validator",
":mealkitary-infrastructure:adapter-business-registration-number-validator:open-api-brn-validator",
)
)
implementation(
project(
":mealkitary-infrastructure:business-registration-number-validator:adapter-simple-brn-validator",
":mealkitary-infrastructure:adapter-business-registration-number-validator:simple-brn-validator",
)
)
testImplementation("org.springframework.restdocs:spring-restdocs-mockmvc")
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
Loading