From 50df6b156f584c80e64d9484cfb77ffb22cbb447 Mon Sep 17 00:00:00 2001 From: namo Date: Mon, 9 Aug 2021 20:40:52 +0900 Subject: [PATCH 1/5] =?UTF-8?q?feature(member-join):=20=ED=9A=8C=EC=9B=90?= =?UTF-8?q?=20=EA=B0=80=EC=9E=85=EC=8B=9C=20=EC=82=AC=EC=97=85=EC=9E=90?= =?UTF-8?q?=EB=93=B1=EB=A1=9D=EB=B2=88=ED=98=B8=EB=A5=BC=20=EC=9E=85?= =?UTF-8?q?=EB=A0=A5=EB=B0=9B=EB=8A=94=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BREAKING CHANGE: 사업자등록번호 추가 --- datajpatest/pom.xml | 16 ++++++ .../controller/MemberController.java | 3 +- .../controller/MemberJoinRequest.java | 18 ++++--- .../controller/MemberJoinRequestSpec.groovy | 53 +++++++++++++++++++ 4 files changed, 81 insertions(+), 9 deletions(-) create mode 100644 datajpatest/src/test/java/com/example/datajpatest/controller/MemberJoinRequestSpec.groovy diff --git a/datajpatest/pom.xml b/datajpatest/pom.xml index b06b907..98580d8 100644 --- a/datajpatest/pom.xml +++ b/datajpatest/pom.xml @@ -29,7 +29,17 @@ org.springframework.boot spring-boot-starter-web + + org.springframework.boot + spring-boot-maven-plugin + 2.5.3 + + + org.hibernate.validator + hibernate-validator + 6.2.0.Final + javax.validation validation-api @@ -76,6 +86,12 @@ 1.4.200 test + + org.spockframework + spock-core + RELEASE + test + diff --git a/datajpatest/src/main/java/com/example/datajpatest/controller/MemberController.java b/datajpatest/src/main/java/com/example/datajpatest/controller/MemberController.java index 1ee297b..f34c566 100644 --- a/datajpatest/src/main/java/com/example/datajpatest/controller/MemberController.java +++ b/datajpatest/src/main/java/com/example/datajpatest/controller/MemberController.java @@ -7,6 +7,7 @@ import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; +import javax.validation.Valid; import java.net.URI; import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo; @@ -22,7 +23,7 @@ public MemberController(MemberRepository memberRepository) { } @PostMapping("/member") - public ResponseEntity joinMember(@RequestBody MemberJoinRequest request) { + public ResponseEntity joinMember(@Valid @RequestBody MemberJoinRequest request) { MemberJpaEntity entity = MemberJpaEntity.from(request); MemberJpaEntity saved = memberRepository.save(entity); final Long memberId = saved.getId(); diff --git a/datajpatest/src/main/java/com/example/datajpatest/controller/MemberJoinRequest.java b/datajpatest/src/main/java/com/example/datajpatest/controller/MemberJoinRequest.java index a88cb44..6b86d47 100644 --- a/datajpatest/src/main/java/com/example/datajpatest/controller/MemberJoinRequest.java +++ b/datajpatest/src/main/java/com/example/datajpatest/controller/MemberJoinRequest.java @@ -2,17 +2,19 @@ import com.example.datajpatest.model.Member; import lombok.Getter; +import lombok.Setter; -import java.beans.ConstructorProperties; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; @Getter +@Setter public class MemberJoinRequest implements Member { - private final Long id; - private final String name; + @NotNull + private Long id; + @NotBlank + private String name; + @NotNull + private String businessNumber; - @ConstructorProperties({"id", "name"}) - public MemberJoinRequest(Long id, String name) { - this.id = id; - this.name = name; - } } diff --git a/datajpatest/src/test/java/com/example/datajpatest/controller/MemberJoinRequestSpec.groovy b/datajpatest/src/test/java/com/example/datajpatest/controller/MemberJoinRequestSpec.groovy new file mode 100644 index 0000000..030d13d --- /dev/null +++ b/datajpatest/src/test/java/com/example/datajpatest/controller/MemberJoinRequestSpec.groovy @@ -0,0 +1,53 @@ +package com.example.datajpatest.controller + +import spock.lang.Shared +import spock.lang.Specification +import spock.lang.Subject + +import javax.validation.ConstraintViolation +import javax.validation.Validation +import javax.validation.Validator +import javax.validation.ValidatorFactory + +class MemberJoinRequestSpec extends Specification { + + @Subject + private MemberJoinRequest sut + + @Shared + private Validator validator + + def setupSpec() { + ValidatorFactory factory = Validation.buildDefaultValidatorFactory() + validator = factory.getValidator() + } + + def setup() { + sut = getNoConstraintValidationMemberJoinRequest() + } + + def "사업자 등록번호는 null 을 허용하지 않는다."() { + given: + sut.setBusinessNumber(null) + + when: + Set> constraintViolations = validator.validate(sut) + + then: + constraintViolations.size() == 1 + with(constraintViolations[0]) { + propertyPath.toString() == 'businessNumber' + invalidValue == null + messageTemplate == '{javax.validation.constraints.NotNull.message}' + } + } + + static def getNoConstraintValidationMemberJoinRequest() { + def req = new MemberJoinRequest() + req.id = 1 + req.name = "테스터" + req.businessNumber = "1234567890" + return req + } + +} From fe9a79f2f1e281c16a9bfe33ce8a114d94d4ca2a Mon Sep 17 00:00:00 2001 From: namo Date: Mon, 9 Aug 2021 20:52:06 +0900 Subject: [PATCH 2/5] =?UTF-8?q?feature(member-join):=20@NotNull=20?= =?UTF-8?q?=EC=9D=84=20@Length=20=EB=A1=9C=20=EB=8C=80=EC=B2=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 실패하는 테스트 예제 --- .../com/example/datajpatest/controller/MemberJoinRequest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/datajpatest/src/main/java/com/example/datajpatest/controller/MemberJoinRequest.java b/datajpatest/src/main/java/com/example/datajpatest/controller/MemberJoinRequest.java index 6b86d47..69f5c86 100644 --- a/datajpatest/src/main/java/com/example/datajpatest/controller/MemberJoinRequest.java +++ b/datajpatest/src/main/java/com/example/datajpatest/controller/MemberJoinRequest.java @@ -3,6 +3,7 @@ import com.example.datajpatest.model.Member; import lombok.Getter; import lombok.Setter; +import org.hibernate.validator.constraints.Length; import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; @@ -14,7 +15,7 @@ public class MemberJoinRequest implements Member { private Long id; @NotBlank private String name; - @NotNull + @Length(min = 10, max = 12) private String businessNumber; } From 71aba9c740c2c4ba84c4a897f87408f8e53b841c Mon Sep 17 00:00:00 2001 From: namo Date: Mon, 9 Aug 2021 20:55:28 +0900 Subject: [PATCH 3/5] =?UTF-8?q?feature(member-join):=20@NotNull=20+=20@Len?= =?UTF-8?q?gth=20=EB=A1=9C=20=EB=8C=80=EC=B2=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 성공하는 테스트 - @Length 에 대한 테스트 추가 --- .../controller/MemberJoinRequest.java | 1 + .../controller/MemberJoinRequestSpec.groovy | 21 +++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/datajpatest/src/main/java/com/example/datajpatest/controller/MemberJoinRequest.java b/datajpatest/src/main/java/com/example/datajpatest/controller/MemberJoinRequest.java index 69f5c86..d9f2dc1 100644 --- a/datajpatest/src/main/java/com/example/datajpatest/controller/MemberJoinRequest.java +++ b/datajpatest/src/main/java/com/example/datajpatest/controller/MemberJoinRequest.java @@ -15,6 +15,7 @@ public class MemberJoinRequest implements Member { private Long id; @NotBlank private String name; + @NotNull @Length(min = 10, max = 12) private String businessNumber; diff --git a/datajpatest/src/test/java/com/example/datajpatest/controller/MemberJoinRequestSpec.groovy b/datajpatest/src/test/java/com/example/datajpatest/controller/MemberJoinRequestSpec.groovy index 030d13d..06816d9 100644 --- a/datajpatest/src/test/java/com/example/datajpatest/controller/MemberJoinRequestSpec.groovy +++ b/datajpatest/src/test/java/com/example/datajpatest/controller/MemberJoinRequestSpec.groovy @@ -3,6 +3,7 @@ package com.example.datajpatest.controller import spock.lang.Shared import spock.lang.Specification import spock.lang.Subject +import spock.lang.Unroll import javax.validation.ConstraintViolation import javax.validation.Validation @@ -42,6 +43,26 @@ class MemberJoinRequestSpec extends Specification { } } + @Unroll + def "사업자 등록번호가 #testBusinessNumber.length() 자리이면 길이 제약조건 위반이 발생한다."() { + given: + sut.setBusinessNumber(testBusinessNumber) + + when: + Set> constraintViolations = validator.validate(sut) + + then: + constraintViolations.size() == 1 + with(constraintViolations[0]) { + propertyPath.toString() == 'businessNumber' + invalidValue.toString() == testBusinessNumber + messageTemplate == '{org.hibernate.validator.constraints.Length.message}' + } + + where: + testBusinessNumber << ['', '1', '123456789', '1234567890123', '12345678901234'] + } + static def getNoConstraintValidationMemberJoinRequest() { def req = new MemberJoinRequest() req.id = 1 From d7bf5d5cb09bb3ab1f3299f47760f85f0ef296fb Mon Sep 17 00:00:00 2001 From: namo Date: Mon, 9 Aug 2021 21:11:57 +0900 Subject: [PATCH 4/5] =?UTF-8?q?feature(member-join):=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 사업자 등록번호는 문자열을 허용한다. - 사업자 등록번호는 11 자리의 길이를 허용한다. --- .../controller/MemberJoinRequestSpec.groovy | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/datajpatest/src/test/java/com/example/datajpatest/controller/MemberJoinRequestSpec.groovy b/datajpatest/src/test/java/com/example/datajpatest/controller/MemberJoinRequestSpec.groovy index 06816d9..6b65a38 100644 --- a/datajpatest/src/test/java/com/example/datajpatest/controller/MemberJoinRequestSpec.groovy +++ b/datajpatest/src/test/java/com/example/datajpatest/controller/MemberJoinRequestSpec.groovy @@ -63,6 +63,32 @@ class MemberJoinRequestSpec extends Specification { testBusinessNumber << ['', '1', '123456789', '1234567890123', '12345678901234'] } + def "사업자 등록번호는 문자열을 허용한다."() { + given: + sut.setBusinessNumber('tablelands') + + when: + Set> constraintViolations = validator.validate(sut) + + then: + noConstraintViolation(constraintViolations) + } + + @Unroll + def "사업자 등록번호는 #testBusinessNumber.length() 자리의 길이를 허용한다."() { + given: + sut.setBusinessNumber(testBusinessNumber) + + when: + Set> constraintViolations = validator.validate(sut) + + then: + noConstraintViolation(constraintViolations) + + where: + testBusinessNumber = '12345678901' + } + static def getNoConstraintValidationMemberJoinRequest() { def req = new MemberJoinRequest() req.id = 1 @@ -71,4 +97,8 @@ class MemberJoinRequestSpec extends Specification { return req } + static def noConstraintViolation(Set> constraintViolations) { + constraintViolations.isEmpty() + } + } From 47c0116af5c4a02520921058b9cf200fb9e25600 Mon Sep 17 00:00:00 2001 From: namo Date: Mon, 9 Aug 2021 21:31:25 +0900 Subject: [PATCH 5/5] =?UTF-8?q?feature(member-join):=20@NotNull=20?= =?UTF-8?q?=EC=97=90=20@Pattern=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 테스트 변경 --- .../controller/MemberJoinRequest.java | 4 +- .../controller/MemberJoinRequestSpec.groovy | 44 ++++++++++++------- 2 files changed, 29 insertions(+), 19 deletions(-) diff --git a/datajpatest/src/main/java/com/example/datajpatest/controller/MemberJoinRequest.java b/datajpatest/src/main/java/com/example/datajpatest/controller/MemberJoinRequest.java index d9f2dc1..84d675c 100644 --- a/datajpatest/src/main/java/com/example/datajpatest/controller/MemberJoinRequest.java +++ b/datajpatest/src/main/java/com/example/datajpatest/controller/MemberJoinRequest.java @@ -3,10 +3,10 @@ import com.example.datajpatest.model.Member; import lombok.Getter; import lombok.Setter; -import org.hibernate.validator.constraints.Length; import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; +import javax.validation.constraints.Pattern; @Getter @Setter @@ -16,7 +16,7 @@ public class MemberJoinRequest implements Member { @NotBlank private String name; @NotNull - @Length(min = 10, max = 12) + @Pattern(regexp = "[0-9]{10}|[0-9]{3}-[0-9]{2}-[0-9]{5}", message = "10자리의 숫자 또는 대시를 포함한 12자리의 숫자만 입력가능합니다.") private String businessNumber; } diff --git a/datajpatest/src/test/java/com/example/datajpatest/controller/MemberJoinRequestSpec.groovy b/datajpatest/src/test/java/com/example/datajpatest/controller/MemberJoinRequestSpec.groovy index 6b65a38..8635a86 100644 --- a/datajpatest/src/test/java/com/example/datajpatest/controller/MemberJoinRequestSpec.groovy +++ b/datajpatest/src/test/java/com/example/datajpatest/controller/MemberJoinRequestSpec.groovy @@ -27,6 +27,21 @@ class MemberJoinRequestSpec extends Specification { sut = getNoConstraintValidationMemberJoinRequest() } + @Unroll + def "사업자 등록번호가 #testBusinessNumber 를 허용한다."() { + given: + sut.setBusinessNumber(testBusinessNumber) + + when: + Set> constraintViolations = validator.validate(sut) + + then: + noConstraintViolation(constraintViolations) + + where: + testBusinessNumber << ['1448125784', '144-81-25784'] + } + def "사업자 등록번호는 null 을 허용하지 않는다."() { given: sut.setBusinessNumber(null) @@ -44,7 +59,7 @@ class MemberJoinRequestSpec extends Specification { } @Unroll - def "사업자 등록번호가 #testBusinessNumber.length() 자리이면 길이 제약조건 위반이 발생한다."() { + def "사업자 등록번호는 #testBusinessNumber.length() 자리를 허용하지 않는다."() { given: sut.setBusinessNumber(testBusinessNumber) @@ -56,26 +71,15 @@ class MemberJoinRequestSpec extends Specification { with(constraintViolations[0]) { propertyPath.toString() == 'businessNumber' invalidValue.toString() == testBusinessNumber - messageTemplate == '{org.hibernate.validator.constraints.Length.message}' + message == '10자리의 숫자 또는 대시를 포함한 12자리의 숫자만 입력가능합니다.' } where: - testBusinessNumber << ['', '1', '123456789', '1234567890123', '12345678901234'] - } - - def "사업자 등록번호는 문자열을 허용한다."() { - given: - sut.setBusinessNumber('tablelands') - - when: - Set> constraintViolations = validator.validate(sut) - - then: - noConstraintViolation(constraintViolations) + testBusinessNumber << ['', '1', '123456789', '12345678901', '1234567890123', '12345678901234'] } @Unroll - def "사업자 등록번호는 #testBusinessNumber.length() 자리의 길이를 허용한다."() { + def "사업자 등록번호는 문자열 #testBusinessNumber (#testBusinessNumber.length()) 을 허용하지 않는다."() { given: sut.setBusinessNumber(testBusinessNumber) @@ -83,12 +87,18 @@ class MemberJoinRequestSpec extends Specification { Set> constraintViolations = validator.validate(sut) then: - noConstraintViolation(constraintViolations) + constraintViolations.size() == 1 + with(constraintViolations[0]) { + propertyPath.toString() == 'businessNumber' + invalidValue.toString() == testBusinessNumber + message == '10자리의 숫자 또는 대시를 포함한 12자리의 숫자만 입력가능합니다.' + } where: - testBusinessNumber = '12345678901' + testBusinessNumber << ['apple', 'tablelands'] } + static def getNoConstraintValidationMemberJoinRequest() { def req = new MemberJoinRequest() req.id = 1