Skip to content

Commit

Permalink
KL-68/feat: validate product update request
Browse files Browse the repository at this point in the history
- 상품 정보 수정 시 유효성 검사
  - 상품명, 상품설명, 주소 길이 검사
  - 가격 범위 검사
- 상품 정보 수정 dto 필드 순서 변경
  - 이에 따라 테스트코드 수정
  • Loading branch information
ohhamma committed Jul 31, 2024
1 parent e731989 commit d0adeae
Show file tree
Hide file tree
Showing 6 changed files with 128 additions and 54 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public ResponseEntity<ProductDetailResponseDto> createProduct(
@Operation(summary = "상품 정보 수정", description = "상품 정보를 수정합니다.")
public ResponseEntity<ProductDetailResponseDto> updateProduct(
@PathVariable Long id,
@RequestBody ProductUpdateRequestDto updateRequest
@Valid @RequestBody ProductUpdateRequestDto updateRequest
) {
ProductDetailResponseDto productDto = productService.updateProduct(id, updateRequest);
return ResponseEntity.ok().body(productDto);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,28 @@
package taco.klkl.domain.product.dto.request;

import jakarta.validation.constraints.PositiveOrZero;
import jakarta.validation.constraints.Size;
import taco.klkl.global.common.constants.ProductConstants;
import taco.klkl.global.common.constants.ProductValidationMessages;

public record ProductUpdateRequestDto(
@Size(max = ProductConstants.NAME_MAX_LENGTH, message = ProductValidationMessages.NAME_SIZE)
String name,

@Size(max = ProductConstants.DESCRIPTION_MAX_LENGTH, message = ProductValidationMessages.DESCRIPTION_SIZE)
String description,

@Size(max = ProductConstants.ADDRESS_MAX_LENGTH, message = ProductValidationMessages.ADDRESS_SIZE)
String address,

@PositiveOrZero(message = ProductValidationMessages.PRICE_POSITIVE_OR_ZERO)
Integer price,

Long cityId,

Long subcategoryId,
Long currencyId,
String address,
Integer price

Long currencyId

) {
}
Original file line number Diff line number Diff line change
Expand Up @@ -161,11 +161,11 @@ public void testUpdateProduct() throws Exception {
ProductUpdateRequestDto updateRequest = new ProductUpdateRequestDto(
"Updated Name",
"Updated Description",
"Updated Address",
2000,
2L,
3L,
4L,
"Updated Address",
2000
4L
);

when(productService.updateProduct(eq(productId), any(ProductUpdateRequestDto.class)))
Expand Down
12 changes: 6 additions & 6 deletions src/test/java/taco/klkl/domain/product/domain/ProductTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -121,11 +121,11 @@ public void testUpdate() {
ProductUpdateRequestDto updateDto = new ProductUpdateRequestDto(
"Updated Name",
"Updated Description",
"Updated Address",
200,
2L,
2L,
2L,
"Updated Address",
200
2L
);

// when
Expand Down Expand Up @@ -159,10 +159,10 @@ public void testPartialUpdate() {
null,
"Updated Description",
null,
2L,
200,
null,
null,
200
2L,
null
);

// when
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,17 @@
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;

import jakarta.validation.ConstraintViolation;
import jakarta.validation.Validation;
import jakarta.validation.Validator;
import jakarta.validation.ValidatorFactory;
import taco.klkl.global.common.constants.ProductValidationMessages;

class ProductUpdateRequestDtoTest {

private Validator validator;

@BeforeEach
Expand All @@ -23,65 +27,119 @@ void setUp() {
}

@Test
@DisplayName("모든 필드가 유효한 값일 때 유효성 검사 성공")
void testProductUpdateRequestDtoWithAllValidFields() {
// given
@DisplayName("유효한 ProductUpdateRequestDto 생성 시 검증 통과")
void validProductUpdateRequestDto() {
ProductUpdateRequestDto dto = new ProductUpdateRequestDto(
"맛있는 곤약젤리",
"탱글탱글 맛있는 곤약젤리",
"Valid Product Name",
"Valid product description",
"Valid address",
100,
1L,
2L,
3L,
"신사이바시 메가돈키호테",
100
3L
);

// when
Set<ConstraintViolation<ProductUpdateRequestDto>> violations = validator.validate(dto);

// then
assertTrue(violations.isEmpty());
}

@Test
@DisplayName("모든 필드가 null일 때 유효성 검사 성공")
void testProductUpdateRequestDtoWithAllNullFields() {
// given
@ParameterizedTest
@ValueSource(ints = {101, 200, 1000})
@DisplayName("상품명이 최대 길이를 초과할 때 검증 실패")
void productNameExceedsMaxLength(int nameLength) {
String longName = "a".repeat(nameLength);
ProductUpdateRequestDto dto = new ProductUpdateRequestDto(
null,
null,
null,
null,
null,
null,
null
longName,
"Valid product description",
"Valid address",
100,
1L,
2L,
3L
);

// when
Set<ConstraintViolation<ProductUpdateRequestDto>> violations = validator.validate(dto);
assertFalse(violations.isEmpty());
assertTrue(violations.stream()
.anyMatch(violation -> violation.getMessage().equals(ProductValidationMessages.NAME_SIZE)));
}

// then
assertTrue(violations.isEmpty());
@ParameterizedTest
@ValueSource(ints = {2001, 3000, 5000})
@DisplayName("상품 설명이 최대 길이를 초과할 때 검증 실패")
void productDescriptionExceedsMaxLength(int descriptionLength) {
String longDescription = "a".repeat(descriptionLength);
ProductUpdateRequestDto dto = new ProductUpdateRequestDto(
"Valid Product Name",
longDescription,
"Valid address",
100,
1L,
2L,
3L
);

Set<ConstraintViolation<ProductUpdateRequestDto>> violations = validator.validate(dto);
assertFalse(violations.isEmpty());
assertTrue(violations.stream()
.anyMatch(violation -> violation.getMessage().equals(ProductValidationMessages.DESCRIPTION_SIZE)));
}

@ParameterizedTest
@ValueSource(ints = {101, 200, 500})
@DisplayName("주소가 최대 길이를 초과할 때 검증 실패")
void addressExceedsMaxLength(int addressLength) {
String longAddress = "a".repeat(addressLength);
ProductUpdateRequestDto dto = new ProductUpdateRequestDto(
"Valid Product Name",
"Valid product description",
longAddress,
100,
1L,
2L,
3L
);

Set<ConstraintViolation<ProductUpdateRequestDto>> violations = validator.validate(dto);
assertFalse(violations.isEmpty());
assertTrue(violations.stream()
.anyMatch(violation -> violation.getMessage().equals(ProductValidationMessages.ADDRESS_SIZE)));
}

@ParameterizedTest
@ValueSource(ints = {-1, -100, -1000})
@DisplayName("가격이 음수일 때 검증 실패")
void negativePrice(int price) {
ProductUpdateRequestDto dto = new ProductUpdateRequestDto(
"Valid Product Name",
"Valid product description",
"Valid address",
price,
1L,
2L,
3L
);

Set<ConstraintViolation<ProductUpdateRequestDto>> violations = validator.validate(dto);
assertFalse(violations.isEmpty());
assertTrue(violations.stream()
.anyMatch(violation -> violation.getMessage().equals(ProductValidationMessages.PRICE_POSITIVE_OR_ZERO)));
}

@Test
@DisplayName("일부 필드가 null일 때 유효성 검사 성공")
void testProductUpdateRequestDtoWithSomeNullFields() {
// given
@DisplayName("모든 필드가 null이어도 검증 통과 (부분 업데이트 허용)")
void allFieldsNullShouldPass() {
ProductUpdateRequestDto dto = new ProductUpdateRequestDto(
"맛있는 곤약젤리",
null,
1L,
null,
3L,
"신사이바시 메가돈키호테",
null,
null,
null,
null,
null
);

// when
Set<ConstraintViolation<ProductUpdateRequestDto>> violations = validator.validate(dto);

// then
assertTrue(violations.isEmpty());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -173,11 +173,11 @@ void testUpdateProduct_Success() {
ProductUpdateRequestDto updateDto = new ProductUpdateRequestDto(
"Updated Name",
"Updated Description",
"Updated Address",
200,
2L,
2L,
2L,
"Updated Address",
200
2L
);

when(productRepository.findById(productId)).thenReturn(Optional.of(existingProduct));
Expand Down Expand Up @@ -208,11 +208,11 @@ void testUpdateProduct_NotFound() {
ProductUpdateRequestDto updateDto = new ProductUpdateRequestDto(
"Updated Name",
"Updated Description",
"Updated Address",
200,
2L,
2L,
2L,
"Updated Address",
200
2L
);

when(productRepository.findById(productId)).thenReturn(Optional.empty());
Expand Down

0 comments on commit d0adeae

Please sign in to comment.