diff --git a/build.gradle.kts b/build.gradle.kts index 3d53822..29597a7 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -7,6 +7,7 @@ plugins { kotlin("plugin.jpa") apply false id("org.springframework.boot") apply false id("io.spring.dependency-management") apply false + id("org.jlleitschuh.gradle.ktlint") version "11.6.0" id("jacoco") } @@ -43,6 +44,7 @@ subprojects { apply(plugin = "org.springframework.boot") apply(plugin = "io.spring.dependency-management") apply(plugin = "jacoco") + apply(plugin = "org.jlleitschuh.gradle.ktlint") tasks.getByName("bootJar") { enabled = false diff --git a/commerce-api/build.gradle.kts b/commerce-api/build.gradle.kts index d40756e..04e1705 100644 --- a/commerce-api/build.gradle.kts +++ b/commerce-api/build.gradle.kts @@ -8,5 +8,6 @@ dependencies { runtimeOnly(project(":commerce-infra:db-main")) implementation("org.springframework.boot:spring-boot-starter-web") + implementation("org.springframework.boot:spring-boot-starter-validation") testRuntimeOnly("com.h2database:h2") } diff --git a/commerce-api/src/main/kotlin/com/hanghae/commerce/user/application/CustomerWriterService.kt b/commerce-api/src/main/kotlin/com/hanghae/commerce/user/application/CustomerWriterService.kt new file mode 100644 index 0000000..bea032c --- /dev/null +++ b/commerce-api/src/main/kotlin/com/hanghae/commerce/user/application/CustomerWriterService.kt @@ -0,0 +1,27 @@ +package com.hanghae.commerce.user.application + +import com.hanghae.commerce.user.domain.User +import com.hanghae.commerce.user.domain.UserType +import com.hanghae.commerce.user.domain.UserWriter +import com.hanghae.commerce.user.presentation.dto.* +import org.springframework.stereotype.Service + +@Service +class CustomerWriterService( + private val userWriter: UserWriter, +) { + + fun createCustomer(request: CreateCustomerRequest): CreateCustomerResponse { + val savedUserId = userWriter.save( + User.of( + name = request.name, + age = request.age, + email = request.email, + address = request.address, + userType = UserType.CUSTOMER, + ), + ) + + return CreateCustomerResponse(id = savedUserId) + } +} diff --git a/commerce-api/src/main/kotlin/com/hanghae/commerce/user/application/Dummy.kt b/commerce-api/src/main/kotlin/com/hanghae/commerce/user/application/Dummy.kt deleted file mode 100644 index a4b1c84..0000000 --- a/commerce-api/src/main/kotlin/com/hanghae/commerce/user/application/Dummy.kt +++ /dev/null @@ -1,3 +0,0 @@ -package com.hanghae.commerce.user.application - -class Dummy diff --git a/commerce-api/src/main/kotlin/com/hanghae/commerce/user/application/SellerWriterService.kt b/commerce-api/src/main/kotlin/com/hanghae/commerce/user/application/SellerWriterService.kt new file mode 100644 index 0000000..d414a7d --- /dev/null +++ b/commerce-api/src/main/kotlin/com/hanghae/commerce/user/application/SellerWriterService.kt @@ -0,0 +1,27 @@ +package com.hanghae.commerce.user.application + +import com.hanghae.commerce.user.domain.User +import com.hanghae.commerce.user.domain.UserType +import com.hanghae.commerce.user.domain.UserWriter +import com.hanghae.commerce.user.presentation.dto.* +import org.springframework.stereotype.Service + +@Service +class SellerWriterService( + private val userWriter: UserWriter, +) { + + fun createSeller(request: CreateSellerRequest): CreateSellerResponse { + val savedUserId = userWriter.save( + User.of( + name = request.name, + age = request.age, + email = request.email, + address = request.address, + userType = UserType.SELLER, + ), + ) + + return CreateSellerResponse(id = savedUserId) + } +} diff --git a/commerce-api/src/main/kotlin/com/hanghae/commerce/user/application/UserReaderService.kt b/commerce-api/src/main/kotlin/com/hanghae/commerce/user/application/UserReaderService.kt new file mode 100644 index 0000000..acd9e9d --- /dev/null +++ b/commerce-api/src/main/kotlin/com/hanghae/commerce/user/application/UserReaderService.kt @@ -0,0 +1,16 @@ +package com.hanghae.commerce.user.application + +import com.hanghae.commerce.user.domain.UserReader +import com.hanghae.commerce.user.presentation.dto.GetUserResponse +import org.springframework.stereotype.Service + +@Service +class UserReaderService( + private val userReader: UserReader, +) { + + fun getUserById(userId: Long): GetUserResponse { + val user = userReader.read(userId) ?: throw IllegalArgumentException() + return GetUserResponse.of(user) + } +} diff --git a/commerce-api/src/main/kotlin/com/hanghae/commerce/user/domain/User.kt b/commerce-api/src/main/kotlin/com/hanghae/commerce/user/domain/User.kt index 8d23879..0d915af 100644 --- a/commerce-api/src/main/kotlin/com/hanghae/commerce/user/domain/User.kt +++ b/commerce-api/src/main/kotlin/com/hanghae/commerce/user/domain/User.kt @@ -1,6 +1,28 @@ package com.hanghae.commerce.user.domain class User( - var id: Long? = null, val name: String, -) + val age: Int, + val email: String, + val address: String, + val userType: UserType, + var id: Long? = null, +) { + init { + if (name.isBlank()) { + throw IllegalArgumentException("이름은 비어 있을 수 없습니다") + } + if (email.isBlank()) { + throw IllegalArgumentException("이메일은 비어 있을 수 없습니다") + } + if (address.isBlank()) { + throw IllegalArgumentException("주소는 비어 있을 수 없습니다") + } + } + + companion object { + fun of(name: String, age: Int, email: String, address: String, userType: UserType): User { + return User(name, age, email, address, userType) + } + } +} diff --git a/commerce-api/src/main/kotlin/com/hanghae/commerce/user/domain/UserReader.kt b/commerce-api/src/main/kotlin/com/hanghae/commerce/user/domain/UserReader.kt index 552e799..19b809b 100644 --- a/commerce-api/src/main/kotlin/com/hanghae/commerce/user/domain/UserReader.kt +++ b/commerce-api/src/main/kotlin/com/hanghae/commerce/user/domain/UserReader.kt @@ -6,11 +6,6 @@ import org.springframework.stereotype.Component class UserReader( private val userRepository: UserRepository, ) { - - fun save(name: String) { - userRepository.save(User(name = name)) - } - fun read(id: Long): User? { return userRepository.read(id) } diff --git a/commerce-api/src/main/kotlin/com/hanghae/commerce/user/domain/UserRepository.kt b/commerce-api/src/main/kotlin/com/hanghae/commerce/user/domain/UserRepository.kt index dd6e8c3..608ec31 100644 --- a/commerce-api/src/main/kotlin/com/hanghae/commerce/user/domain/UserRepository.kt +++ b/commerce-api/src/main/kotlin/com/hanghae/commerce/user/domain/UserRepository.kt @@ -1,6 +1,10 @@ package com.hanghae.commerce.user.domain +import org.springframework.stereotype.Repository + +@Repository interface UserRepository { - fun save(user: User) + fun save(user: User): Long fun read(id: Long): User? + fun allDelete() } diff --git a/commerce-api/src/main/kotlin/com/hanghae/commerce/user/domain/UserType.kt b/commerce-api/src/main/kotlin/com/hanghae/commerce/user/domain/UserType.kt new file mode 100644 index 0000000..b1dfe58 --- /dev/null +++ b/commerce-api/src/main/kotlin/com/hanghae/commerce/user/domain/UserType.kt @@ -0,0 +1,6 @@ +package com.hanghae.commerce.user.domain + +enum class UserType { + CUSTOMER, + SELLER, +} diff --git a/commerce-api/src/main/kotlin/com/hanghae/commerce/user/domain/UserWriter.kt b/commerce-api/src/main/kotlin/com/hanghae/commerce/user/domain/UserWriter.kt new file mode 100644 index 0000000..722a7be --- /dev/null +++ b/commerce-api/src/main/kotlin/com/hanghae/commerce/user/domain/UserWriter.kt @@ -0,0 +1,12 @@ +package com.hanghae.commerce.user.domain + +import org.springframework.stereotype.Component + +@Component +class UserWriter( + private val userRepository: UserRepository, +) { + fun save(user: User): Long { + return userRepository.save(user) + } +} diff --git a/commerce-api/src/main/kotlin/com/hanghae/commerce/user/presentation/CustomerController.kt b/commerce-api/src/main/kotlin/com/hanghae/commerce/user/presentation/CustomerController.kt new file mode 100644 index 0000000..c4ee2b6 --- /dev/null +++ b/commerce-api/src/main/kotlin/com/hanghae/commerce/user/presentation/CustomerController.kt @@ -0,0 +1,17 @@ +package com.hanghae.commerce.user.presentation + +import com.hanghae.commerce.user.application.CustomerWriterService +import com.hanghae.commerce.user.presentation.dto.* +import org.springframework.web.bind.annotation.* + +@RestController +@RequestMapping("/customer") +class CustomerController( + private val customerWriterService: CustomerWriterService, +) { + + @PostMapping + fun createCustomer(@RequestBody createCustomerRequest: CreateCustomerRequest): CreateCustomerResponse { + return customerWriterService.createCustomer(createCustomerRequest) + } +} diff --git a/commerce-api/src/main/kotlin/com/hanghae/commerce/user/presentation/SellerController.kt b/commerce-api/src/main/kotlin/com/hanghae/commerce/user/presentation/SellerController.kt new file mode 100644 index 0000000..3780a33 --- /dev/null +++ b/commerce-api/src/main/kotlin/com/hanghae/commerce/user/presentation/SellerController.kt @@ -0,0 +1,17 @@ +package com.hanghae.commerce.user.presentation + +import com.hanghae.commerce.user.application.SellerWriterService +import com.hanghae.commerce.user.presentation.dto.* +import org.springframework.web.bind.annotation.* + +@RestController +@RequestMapping("/seller") +class SellerController( + private val sellerService: SellerWriterService, +) { + + @PostMapping + fun createSeller(@RequestBody createSellerRequest: CreateSellerRequest): CreateSellerResponse { + return sellerService.createSeller(createSellerRequest) + } +} diff --git a/commerce-api/src/main/kotlin/com/hanghae/commerce/user/presentation/UserController.kt b/commerce-api/src/main/kotlin/com/hanghae/commerce/user/presentation/UserController.kt index a7fa617..3452a87 100644 --- a/commerce-api/src/main/kotlin/com/hanghae/commerce/user/presentation/UserController.kt +++ b/commerce-api/src/main/kotlin/com/hanghae/commerce/user/presentation/UserController.kt @@ -1,6 +1,17 @@ package com.hanghae.commerce.user.presentation -import org.springframework.web.bind.annotation.RestController +import com.hanghae.commerce.user.application.UserReaderService +import com.hanghae.commerce.user.presentation.dto.GetUserResponse +import org.springframework.web.bind.annotation.* @RestController -class UserController +@RequestMapping("/user") +class UserController( + private val userService: UserReaderService, +) { + + @GetMapping("/{userId}") + fun getUser(@PathVariable userId: Long): GetUserResponse { + return userService.getUserById(userId) + } +} diff --git a/commerce-api/src/main/kotlin/com/hanghae/commerce/user/presentation/dto/CreateCustomerRequest.kt b/commerce-api/src/main/kotlin/com/hanghae/commerce/user/presentation/dto/CreateCustomerRequest.kt new file mode 100644 index 0000000..d6e85a3 --- /dev/null +++ b/commerce-api/src/main/kotlin/com/hanghae/commerce/user/presentation/dto/CreateCustomerRequest.kt @@ -0,0 +1,13 @@ +package com.hanghae.commerce.user.presentation.dto + +import jakarta.validation.constraints.NotBlank + +data class CreateCustomerRequest( + @field:NotBlank(message = "이름을 공백으로 할 수 없습니다.") + val name: String, + val age: Int, + @field:NotBlank(message = "이메일을 공백으로 할 수 없습니다.") + val email: String, + @field:NotBlank(message = "주소를 공백으로 할 수 없습니다.") + val address: String, +) diff --git a/commerce-api/src/main/kotlin/com/hanghae/commerce/user/presentation/dto/CreateCustomerResponse.kt b/commerce-api/src/main/kotlin/com/hanghae/commerce/user/presentation/dto/CreateCustomerResponse.kt new file mode 100644 index 0000000..87a55a5 --- /dev/null +++ b/commerce-api/src/main/kotlin/com/hanghae/commerce/user/presentation/dto/CreateCustomerResponse.kt @@ -0,0 +1,5 @@ +package com.hanghae.commerce.user.presentation.dto + +data class CreateCustomerResponse( + val id: Long, +) diff --git a/commerce-api/src/main/kotlin/com/hanghae/commerce/user/presentation/dto/CreateSellerRequest.kt b/commerce-api/src/main/kotlin/com/hanghae/commerce/user/presentation/dto/CreateSellerRequest.kt new file mode 100644 index 0000000..36adebb --- /dev/null +++ b/commerce-api/src/main/kotlin/com/hanghae/commerce/user/presentation/dto/CreateSellerRequest.kt @@ -0,0 +1,13 @@ +package com.hanghae.commerce.user.presentation.dto + +import jakarta.validation.constraints.NotBlank + +data class CreateSellerRequest( + @field:NotBlank(message = "이름을 공백으로 할 수 없습니다.") + val name: String, + val age: Int, + @field:NotBlank(message = "이메일을 공백으로 할 수 없습니다.") + val email: String, + @field:NotBlank(message = "주소를 공백으로 할 수 없습니다.") + val address: String, +) diff --git a/commerce-api/src/main/kotlin/com/hanghae/commerce/user/presentation/dto/CreateSellerResponse.kt b/commerce-api/src/main/kotlin/com/hanghae/commerce/user/presentation/dto/CreateSellerResponse.kt new file mode 100644 index 0000000..47c3a75 --- /dev/null +++ b/commerce-api/src/main/kotlin/com/hanghae/commerce/user/presentation/dto/CreateSellerResponse.kt @@ -0,0 +1,5 @@ +package com.hanghae.commerce.user.presentation.dto + +data class CreateSellerResponse( + val id: Long, +) diff --git a/commerce-api/src/main/kotlin/com/hanghae/commerce/user/presentation/dto/GetUserResponse.kt b/commerce-api/src/main/kotlin/com/hanghae/commerce/user/presentation/dto/GetUserResponse.kt new file mode 100644 index 0000000..66fdab2 --- /dev/null +++ b/commerce-api/src/main/kotlin/com/hanghae/commerce/user/presentation/dto/GetUserResponse.kt @@ -0,0 +1,26 @@ +package com.hanghae.commerce.user.presentation.dto + +import com.hanghae.commerce.user.domain.User +import com.hanghae.commerce.user.domain.UserType + +data class GetUserResponse( + val name: String, + val age: Int, + val email: String, + val address: String, + val id: Long, + val userType: UserType, +) { + companion object { + fun of(user: User): GetUserResponse { + return GetUserResponse( + name = user.name, + age = user.age, + email = user.email, + address = user.address, + userType = user.userType, + id = user.id!!, + ) + } + } +} diff --git a/commerce-api/src/main/resources/application-develop.yml b/commerce-api/src/main/resources/application-develop.yml index 5d30eb8..0b96a13 100644 --- a/commerce-api/src/main/resources/application-develop.yml +++ b/commerce-api/src/main/resources/application-develop.yml @@ -3,5 +3,5 @@ spring: config: activate: on-profile: develop - - + import: + - logging.yml diff --git a/commerce-api/src/main/resources/application-local.yml b/commerce-api/src/main/resources/application-local.yml index 2cc254a..727fcb5 100644 --- a/commerce-api/src/main/resources/application-local.yml +++ b/commerce-api/src/main/resources/application-local.yml @@ -3,3 +3,5 @@ spring: config: activate: on-profile: local + import: + - logging.yml diff --git a/commerce-api/src/main/resources/application-prod.yml b/commerce-api/src/main/resources/application-prod.yml index 649ba02..7352fc2 100644 --- a/commerce-api/src/main/resources/application-prod.yml +++ b/commerce-api/src/main/resources/application-prod.yml @@ -3,3 +3,5 @@ spring: config: activate: on-profile: prod + import: + - logging.yml diff --git a/commerce-api/src/main/resources/application.yml b/commerce-api/src/main/resources/application.yml index 1a52eaa..4200345 100644 --- a/commerce-api/src/main/resources/application.yml +++ b/commerce-api/src/main/resources/application.yml @@ -7,5 +7,4 @@ spring: config: import: - - logging.yml - db-main.yml diff --git a/commerce-api/src/test/kotlin/com/hanghae/commerce/user/application/CustomerWriterServiceTest.kt b/commerce-api/src/test/kotlin/com/hanghae/commerce/user/application/CustomerWriterServiceTest.kt new file mode 100644 index 0000000..6f909c5 --- /dev/null +++ b/commerce-api/src/test/kotlin/com/hanghae/commerce/user/application/CustomerWriterServiceTest.kt @@ -0,0 +1,40 @@ +package com.hanghae.commerce.user.application + +import com.hanghae.commerce.testconfiguration.IntegrationTest +import com.hanghae.commerce.user.domain.UserRepository +import com.hanghae.commerce.user.presentation.dto.CreateCustomerRequest +import org.assertj.core.api.Assertions +import org.junit.jupiter.api.AfterEach +import org.junit.jupiter.api.Test +import org.springframework.beans.factory.annotation.Autowired + +@IntegrationTest +class CustomerWriterServiceTest( + @Autowired + private val customerWriterService: CustomerWriterService, + @Autowired + private val userRepository: UserRepository, +) { + + @AfterEach + fun tearDown() { + userRepository.allDelete() + } + + @Test + fun createCustomer() { + // given + val request = CreateCustomerRequest( + name = "sangmin", + age = 20, + email = "hanghae001@gmail.com", + address = "seoul", + ) + + // when + val result = customerWriterService.createCustomer(request) + + // then + Assertions.assertThat(result.id).isNotNull + } +} diff --git a/commerce-api/src/test/kotlin/com/hanghae/commerce/user/application/SellerWriterServiceTest.kt b/commerce-api/src/test/kotlin/com/hanghae/commerce/user/application/SellerWriterServiceTest.kt new file mode 100644 index 0000000..d556e01 --- /dev/null +++ b/commerce-api/src/test/kotlin/com/hanghae/commerce/user/application/SellerWriterServiceTest.kt @@ -0,0 +1,40 @@ +package com.hanghae.commerce.user.application + +import com.hanghae.commerce.testconfiguration.IntegrationTest +import com.hanghae.commerce.user.domain.UserRepository +import com.hanghae.commerce.user.presentation.dto.CreateSellerRequest +import org.assertj.core.api.Assertions +import org.junit.jupiter.api.AfterEach +import org.junit.jupiter.api.Test +import org.springframework.beans.factory.annotation.Autowired + +@IntegrationTest +class SellerWriterServiceTest( + @Autowired + private val sellerWriterService: SellerWriterService, + @Autowired + private val userRepository: UserRepository, +) { + + @AfterEach + fun tearDown() { + userRepository.allDelete() + } + + @Test + fun createSeller() { + // given + val request = CreateSellerRequest( + name = "sangmin", + age = 20, + email = "hanghae001@gmail.com", + address = "seoul", + ) + + // when + val result = sellerWriterService.createSeller(request) + + // then + Assertions.assertThat(result.id).isNotNull + } +} diff --git a/commerce-api/src/test/kotlin/com/hanghae/commerce/user/application/UserReaderServiceTest.kt b/commerce-api/src/test/kotlin/com/hanghae/commerce/user/application/UserReaderServiceTest.kt new file mode 100644 index 0000000..edf6150 --- /dev/null +++ b/commerce-api/src/test/kotlin/com/hanghae/commerce/user/application/UserReaderServiceTest.kt @@ -0,0 +1,77 @@ +package com.hanghae.commerce.user.application + +import com.hanghae.commerce.testconfiguration.IntegrationTest +import com.hanghae.commerce.user.domain.UserRepository +import com.hanghae.commerce.user.domain.UserType +import com.hanghae.commerce.user.presentation.dto.CreateCustomerRequest +import com.hanghae.commerce.user.presentation.dto.CreateSellerRequest +import org.assertj.core.api.Assertions +import org.junit.jupiter.api.AfterEach +import org.junit.jupiter.api.Test +import org.springframework.beans.factory.annotation.Autowired + +@IntegrationTest +class UserReaderServiceTest( + @Autowired + private val userReaderService: UserReaderService, + @Autowired + private val customerWriterService: CustomerWriterService, + @Autowired + private val sellerWriterService: SellerWriterService, + @Autowired + private val userRepository: UserRepository, +) { + + @AfterEach + fun tearDown() { + userRepository.allDelete() + } + + @Test + fun getCustomerUserById() { + // given + val request = CreateCustomerRequest( + name = "sangmin", + age = 20, + email = "hanghae001@gmail.com", + address = "seoul", + ) + + val createdCustomer = customerWriterService.createCustomer(request) + + // when + val result = userReaderService.getUserById(createdCustomer.id) + + // then + Assertions.assertThat(result.id).isEqualTo(createdCustomer.id) + Assertions.assertThat(result.name).isEqualTo(request.name) + Assertions.assertThat(result.age).isEqualTo(request.age) + Assertions.assertThat(result.email).isEqualTo(request.email) + Assertions.assertThat(result.address).isEqualTo(request.address) + Assertions.assertThat(result.userType).isEqualTo(UserType.CUSTOMER) + } + + @Test + fun getSellerUserById() { + // given + val request = CreateSellerRequest( + name = "sangmin", + age = 20, + email = "hanghae001@gmail.com", + address = "seoul", + ) + + val createdSeller = sellerWriterService.createSeller(request) + + // when + val result = userReaderService.getUserById(createdSeller.id) + + // then + Assertions.assertThat(result.id).isEqualTo(createdSeller.id) + Assertions.assertThat(result.name).isEqualTo(request.name) + Assertions.assertThat(result.age).isEqualTo(request.age) + Assertions.assertThat(result.email).isEqualTo(request.email) + Assertions.assertThat(result.address).isEqualTo(request.address) + Assertions.assertThat(result.userType).isEqualTo(UserType.SELLER) + } +} diff --git a/commerce-api/src/test/kotlin/com/hanghae/commerce/user/domain/UserRepositoryTest.kt b/commerce-api/src/test/kotlin/com/hanghae/commerce/user/domain/UserRepositoryTest.kt new file mode 100644 index 0000000..b922146 --- /dev/null +++ b/commerce-api/src/test/kotlin/com/hanghae/commerce/user/domain/UserRepositoryTest.kt @@ -0,0 +1,53 @@ +package com.hanghae.commerce.user.domain + +import com.hanghae.commerce.testconfiguration.IntegrationTest +import org.assertj.core.api.Assertions +import org.junit.jupiter.api.Test +import org.springframework.beans.factory.annotation.Autowired + +@IntegrationTest +class UserRepositoryTest( + @Autowired + private val userRepository: UserRepository, +) { + @Test + fun save() { + // given + val user = User.of( + name = "sangmin", + age = 20, + email = "hanghae001@gmail.com", + address = "seoul", + UserType.CUSTOMER, + ) + + // when + val userId = userRepository.save(user) + + // then + Assertions.assertThat(userId).isNotNull + } + + @Test + fun read() { + // given + val user = User.of( + name = "sangmin", + age = 20, + email = "hanghae001@gmail.com", + address = "seoul", + UserType.CUSTOMER, + ) + val userId = userRepository.save(user) + + // when + val savedUser = userRepository.read(userId) + + // then + Assertions.assertThat(savedUser!!.name).isEqualTo("sangmin") + Assertions.assertThat(savedUser!!.age).isEqualTo(20) + Assertions.assertThat(savedUser!!.email).isEqualTo("hanghae001@gmail.com") + Assertions.assertThat(savedUser!!.address).isEqualTo("seoul") + Assertions.assertThat(savedUser!!.userType).isEqualTo(UserType.CUSTOMER) + } +} diff --git a/commerce-api/src/test/kotlin/com/hanghae/commerce/user/domain/UserTest.kt b/commerce-api/src/test/kotlin/com/hanghae/commerce/user/domain/UserTest.kt new file mode 100644 index 0000000..716efd4 --- /dev/null +++ b/commerce-api/src/test/kotlin/com/hanghae/commerce/user/domain/UserTest.kt @@ -0,0 +1,74 @@ +package com.hanghae.commerce.user.domain + +import com.hanghae.commerce.testconfiguration.UnitTest +import org.assertj.core.api.Assertions +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +@UnitTest +class UserTest { + + @Test + fun createUser() { + val user = User.of( + name = "sangmin", + age = 20, + email = "hanghae001@gmail.com", + address = "seoul", + userType = UserType.CUSTOMER, + ) + + assertThat(user.name).isEqualTo("sangmin") + assertThat(user.age).isEqualTo(20) + assertThat(user.email).isEqualTo("hanghae001@gmail.com") + assertThat(user.address).isEqualTo("seoul") + } + + @Test + fun createUserWithBlankName() { + // then + Assertions.assertThatThrownBy { + User.of( + name = "", + age = 20, + email = "hanghae001@gmail.com", + address = "seoul", + userType = UserType.CUSTOMER, + ) + } + .isInstanceOf(IllegalArgumentException::class.java) + .hasMessage("이름은 비어 있을 수 없습니다") + } + + @Test + fun createUserWithBlankEmail() { + //then + Assertions.assertThatThrownBy { + User.of( + name = "sangmin", + age = 20, + email = "", + address = "seoul", + userType = UserType.CUSTOMER, + ) + } + .isInstanceOf(IllegalArgumentException::class.java) + .hasMessage("이메일은 비어 있을 수 없습니다") + } + + @Test + fun createUserWithBlankAddress() { + // then + Assertions.assertThatThrownBy { + User.of( + name = "sangmin", + age = 20, + email = "hanghae001@gmail.com", + address = "", + userType = UserType.CUSTOMER, + ) + } + .isInstanceOf(IllegalArgumentException::class.java) + .hasMessage("주소는 비어 있을 수 없습니다") + } +} diff --git a/commerce-api/src/test/kotlin/com/hanghae/commerce/user/presentation/dto/CreateCustomerRequestTest.kt b/commerce-api/src/test/kotlin/com/hanghae/commerce/user/presentation/dto/CreateCustomerRequestTest.kt new file mode 100644 index 0000000..599492c --- /dev/null +++ b/commerce-api/src/test/kotlin/com/hanghae/commerce/user/presentation/dto/CreateCustomerRequestTest.kt @@ -0,0 +1,80 @@ +package com.hanghae.commerce.user.presentation.dto + +import com.hanghae.commerce.testconfiguration.UnitTest +import jakarta.validation.ConstraintViolation +import jakarta.validation.Validation +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +@UnitTest +class CreateCustomerRequestTest { + + @Test + fun validateName() { + // given + val validator = Validation.buildDefaultValidatorFactory().validator + val request = CreateCustomerRequest( + name = "", + age = 20, + email = "hanghae001@gmail.com", + address = "seoul", + ) + + // when + val violations: Set> = validator.validate(request) + + val violation: ConstraintViolation = violations.stream() + .filter { v -> v.getPropertyPath().toString().equals("name") } + .findFirst() + .get() + + // then + assertThat(violation.getMessage()).isEqualTo("이름을 공백으로 할 수 없습니다.") + } + + @Test + fun validateEmail() { + // given + val validator = Validation.buildDefaultValidatorFactory().validator + val request = CreateCustomerRequest( + name = "hanghae", + age = 20, + email = "", + address = "seoul", + ) + + // when + val violations: Set> = validator.validate(request) + + val violation: ConstraintViolation = violations.stream() + .filter { v -> v.getPropertyPath().toString().equals("email") } + .findFirst() + .get() + + // then + assertThat(violation.getMessage()).isEqualTo("이메일을 공백으로 할 수 없습니다.") + } + + @Test + fun validateAddress() { + // given + val validator = Validation.buildDefaultValidatorFactory().validator + val request = CreateCustomerRequest( + name = "hanghae", + age = 20, + email = "hanghae001@gmail.com", + address = "", + ) + + // when + val violations: Set> = validator.validate(request) + + val violation: ConstraintViolation = violations.stream() + .filter { v -> v.getPropertyPath().toString().equals("address") } + .findFirst() + .get() + + // then + assertThat(violation.getMessage()).isEqualTo("주소를 공백으로 할 수 없습니다.") + } +} diff --git a/commerce-api/src/test/kotlin/com/hanghae/commerce/user/presentation/dto/CreateSellerRequestTest.kt b/commerce-api/src/test/kotlin/com/hanghae/commerce/user/presentation/dto/CreateSellerRequestTest.kt new file mode 100644 index 0000000..20186da --- /dev/null +++ b/commerce-api/src/test/kotlin/com/hanghae/commerce/user/presentation/dto/CreateSellerRequestTest.kt @@ -0,0 +1,80 @@ +package com.hanghae.commerce.user.presentation.dto + +import com.hanghae.commerce.testconfiguration.UnitTest +import jakarta.validation.ConstraintViolation +import jakarta.validation.Validation +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +@UnitTest +class CreateSellerRequestTest { + + @Test + fun validateName() { + // given + val validator = Validation.buildDefaultValidatorFactory().validator + val request = CreateSellerRequest( + name = "", + age = 20, + email = "hanghae001@gmail.com", + address = "seoul", + ) + + // when + val violations: Set> = validator.validate(request) + + val violation: ConstraintViolation = violations.stream() + .filter { v -> v.getPropertyPath().toString().equals("name") } + .findFirst() + .get() + + // then + assertThat(violation.getMessage()).isEqualTo("이름을 공백으로 할 수 없습니다.") + } + + @Test + fun validateEmail() { + // given + val validator = Validation.buildDefaultValidatorFactory().validator + val request = CreateSellerRequest( + name = "hanghae", + age = 20, + email = "", + address = "seoul", + ) + + // when + val violations: Set> = validator.validate(request) + + val violation: ConstraintViolation = violations.stream() + .filter { v -> v.getPropertyPath().toString().equals("email") } + .findFirst() + .get() + + // then + assertThat(violation.getMessage()).isEqualTo("이메일을 공백으로 할 수 없습니다.") + } + + @Test + fun validateAddress() { + // given + val validator = Validation.buildDefaultValidatorFactory().validator + val request = CreateSellerRequest( + name = "hanghae", + age = 20, + email = "hanghae001@gmail.com", + address = "", + ) + + // when + val violations: Set> = validator.validate(request) + + val violation: ConstraintViolation = violations.stream() + .filter { v -> v.getPropertyPath().toString().equals("address") } + .findFirst() + .get() + + // then + assertThat(violation.getMessage()).isEqualTo("주소를 공백으로 할 수 없습니다.") + } +} diff --git a/commerce-infra/db-main/src/main/kotlin/com/hanghae/commerce/data/domain/UserEntity.kt b/commerce-infra/db-main/src/main/kotlin/com/hanghae/commerce/data/domain/UserEntity.kt index 69b5b2e..070b942 100644 --- a/commerce-infra/db-main/src/main/kotlin/com/hanghae/commerce/data/domain/UserEntity.kt +++ b/commerce-infra/db-main/src/main/kotlin/com/hanghae/commerce/data/domain/UserEntity.kt @@ -1,21 +1,32 @@ package com.hanghae.commerce.data.domain -import jakarta.persistence.Column -import jakarta.persistence.Entity -import jakarta.persistence.GeneratedValue -import jakarta.persistence.GenerationType -import jakarta.persistence.Id +import com.hanghae.commerce.user.domain.User +import com.hanghae.commerce.user.domain.UserType +import jakarta.persistence.* @Entity +@Table(name = "users") class UserEntity( - private val initName: String, -) { + val name: String, + val age: Int, + val email: String, + val address: String, + @Enumerated(EnumType.STRING) + val userType: UserType, @Id @GeneratedValue(strategy = GenerationType.IDENTITY) - var id: Long? = null - - @Column - var name: String = initName - protected set + var id: Long? = null, +) { + companion object { + fun from(user: User): UserEntity { + return UserEntity( + name = user.name, + age = user.age, + email = user.email, + address = user.address, + userType = user.userType, + ) + } + } } diff --git a/commerce-infra/db-main/src/main/kotlin/com/hanghae/commerce/data/domain/UserEntityRepository.kt b/commerce-infra/db-main/src/main/kotlin/com/hanghae/commerce/data/domain/UserEntityRepository.kt index 51b2d62..d3fdbc6 100644 --- a/commerce-infra/db-main/src/main/kotlin/com/hanghae/commerce/data/domain/UserEntityRepository.kt +++ b/commerce-infra/db-main/src/main/kotlin/com/hanghae/commerce/data/domain/UserEntityRepository.kt @@ -2,18 +2,37 @@ package com.hanghae.commerce.data.domain import com.hanghae.commerce.user.domain.User import com.hanghae.commerce.user.domain.UserRepository +import org.springframework.data.repository.findByIdOrNull import org.springframework.stereotype.Repository +import org.springframework.transaction.annotation.Transactional @Repository class UserEntityRepository( private val jpaUserRepository: JpaUserRepository, ) : UserRepository { - override fun save(user: User) { - TODO("Not yet implemented") + @Transactional + override fun save(user: User): Long { + return jpaUserRepository.save( + UserEntity.from(user), + ).id!! } + @Transactional(readOnly = true) override fun read(id: Long): User? { - TODO("Not yet implemented") + return jpaUserRepository.findByIdOrNull(id)?.let { + User( + id = it.id!!, + name = it.name!!, + email = it.email!!, + address = it.address!!, + age = it.age, + userType = it.userType, + ) + } + } + + override fun allDelete() { + jpaUserRepository.deleteAllInBatch() } } diff --git a/commerce-support/logging/src/main/resources/logback/logback-test.xml b/commerce-support/logging/src/main/resources/logback/logback-test.xml new file mode 100644 index 0000000..cd75f37 --- /dev/null +++ b/commerce-support/logging/src/main/resources/logback/logback-test.xml @@ -0,0 +1,18 @@ + + + + + + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + utf8 + + + + + +8 + + + +