diff --git a/resource-server/src/main/java/com/inhabas/api/config/WebSecurityConfig.java b/resource-server/src/main/java/com/inhabas/api/config/WebSecurityConfig.java index dbaee3f6..7d383cda 100644 --- a/resource-server/src/main/java/com/inhabas/api/config/WebSecurityConfig.java +++ b/resource-server/src/main/java/com/inhabas/api/config/WebSecurityConfig.java @@ -46,6 +46,7 @@ public class WebSecurityConfig { private static final String[] AUTH_WHITELIST_SIGNUP = {"/signUp/schedule", "/signUp/questionnaires", "/signUp/majorInfo"}; private static final String[] AUTH_WHITELIST_CLUB = {"/club/histories", "/club/history/**"}; + private static final String[] AUTH_WHITELIST_POLICY = {"/policy/**"}; @Order(1) @EnableGlobalMethodSecurity(prePostEnabled = true, jsr250Enabled = true) @@ -70,6 +71,7 @@ public void configure(AuthenticationManagerBuilder auth) throws Exception { @Override public void configure(WebSecurity web) throws Exception { web.ignoring() + .antMatchers(HttpMethod.GET, AUTH_WHITELIST_POLICY) .antMatchers(HttpMethod.GET, AUTH_WHITELIST_SIGNUP) .antMatchers(HttpMethod.GET, AUTH_WHITELIST_CLUB) .antMatchers(AUTH_WHITELIST_SWAGGER) @@ -126,6 +128,9 @@ protected void configure(HttpSecurity http) throws Exception { // 동아리 연혁 수정 .antMatchers("/club/history/**").hasRole(EXECUTIVES.toString()) + // 정책 수정 + .antMatchers(HttpMethod.PUT, "/policy/**").hasAnyRole(CHIEF.toString(), VICE_CHIEF.toString()) + // 그 외 .anyRequest().hasRole(ANONYMOUS.toString()); diff --git a/resource-server/src/main/java/com/inhabas/api/domain/BaseEntity.java b/resource-server/src/main/java/com/inhabas/api/domain/BaseEntity.java index 9d655b92..a6ec71ed 100644 --- a/resource-server/src/main/java/com/inhabas/api/domain/BaseEntity.java +++ b/resource-server/src/main/java/com/inhabas/api/domain/BaseEntity.java @@ -19,6 +19,7 @@ public abstract class BaseEntity { @Column(nullable = false, updatable = false, insertable = false, columnDefinition = "DATETIME(0) DEFAULT CURRENT_TIMESTAMP") private LocalDateTime dateCreated; + @CreatedDate @LastModifiedDate @Column(columnDefinition = "DATETIME(0)") private LocalDateTime dateUpdated; diff --git a/resource-server/src/main/java/com/inhabas/api/domain/policy/domain/PolicyTerm.java b/resource-server/src/main/java/com/inhabas/api/domain/policy/domain/PolicyTerm.java new file mode 100644 index 00000000..6bb3e2fa --- /dev/null +++ b/resource-server/src/main/java/com/inhabas/api/domain/policy/domain/PolicyTerm.java @@ -0,0 +1,40 @@ +package com.inhabas.api.domain.policy.domain; + +import com.inhabas.api.domain.BaseEntity; +import com.inhabas.api.domain.board.domain.valueObject.Content; +import com.inhabas.api.domain.policy.dto.SavePolicyTernDto; +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import javax.persistence.*; + +@Entity +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Table(name = "POLICY_TERM") +@Getter +public class PolicyTerm extends BaseEntity { + + @Id + @GeneratedValue + private Long id; + + @ManyToOne(fetch = FetchType.LAZY, optional = false) + @JoinColumn(name = "POLICY_TYPE_ID") + private PolicyType policyType; + + @Embedded + private Content content; + + @Builder + public PolicyTerm(PolicyType policyType, String content) { + this.policyType = policyType; + this.content = new Content(content); + } + + public void updatePolicyTerm(SavePolicyTernDto savePolicyTernDto) { + this.content = new Content(savePolicyTernDto.getContent()); + } + +} diff --git a/resource-server/src/main/java/com/inhabas/api/domain/policy/domain/PolicyType.java b/resource-server/src/main/java/com/inhabas/api/domain/policy/domain/PolicyType.java new file mode 100644 index 00000000..fc7f0f86 --- /dev/null +++ b/resource-server/src/main/java/com/inhabas/api/domain/policy/domain/PolicyType.java @@ -0,0 +1,26 @@ +package com.inhabas.api.domain.policy.domain; + +import com.inhabas.api.domain.board.domain.valueObject.Title; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import javax.persistence.*; + +@Entity +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class PolicyType { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(name = "TITLE") + private Title title; + + public PolicyType(String title) { + this.title = new Title(title); + } + +} diff --git a/resource-server/src/main/java/com/inhabas/api/domain/policy/dto/PolicyTermDto.java b/resource-server/src/main/java/com/inhabas/api/domain/policy/dto/PolicyTermDto.java new file mode 100644 index 00000000..0484afc3 --- /dev/null +++ b/resource-server/src/main/java/com/inhabas/api/domain/policy/dto/PolicyTermDto.java @@ -0,0 +1,25 @@ +package com.inhabas.api.domain.policy.dto; + +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotNull; + +@Getter +@NoArgsConstructor +public class PolicyTermDto { + + @NotNull + private String title; + + @NotNull + private String content; + + @Builder + public PolicyTermDto(String title, String content) { + this.title = title; + this.content = content; + } + +} diff --git a/resource-server/src/main/java/com/inhabas/api/domain/policy/dto/SavePolicyTernDto.java b/resource-server/src/main/java/com/inhabas/api/domain/policy/dto/SavePolicyTernDto.java new file mode 100644 index 00000000..1f7d91ff --- /dev/null +++ b/resource-server/src/main/java/com/inhabas/api/domain/policy/dto/SavePolicyTernDto.java @@ -0,0 +1,21 @@ +package com.inhabas.api.domain.policy.dto; + +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotNull; + +@Getter +@NoArgsConstructor +public class SavePolicyTernDto { + + @NotNull + private String content; + + @Builder + public SavePolicyTernDto(String content) { + this.content = content; + } + +} diff --git a/resource-server/src/main/java/com/inhabas/api/domain/policy/respository/PolicyTermRepository.java b/resource-server/src/main/java/com/inhabas/api/domain/policy/respository/PolicyTermRepository.java new file mode 100644 index 00000000..2df87b15 --- /dev/null +++ b/resource-server/src/main/java/com/inhabas/api/domain/policy/respository/PolicyTermRepository.java @@ -0,0 +1,7 @@ +package com.inhabas.api.domain.policy.respository; + +import com.inhabas.api.domain.policy.domain.PolicyTerm; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface PolicyTermRepository extends JpaRepository { +} diff --git a/resource-server/src/main/java/com/inhabas/api/domain/policy/usecase/PolicyTermService.java b/resource-server/src/main/java/com/inhabas/api/domain/policy/usecase/PolicyTermService.java new file mode 100644 index 00000000..7e6d5b59 --- /dev/null +++ b/resource-server/src/main/java/com/inhabas/api/domain/policy/usecase/PolicyTermService.java @@ -0,0 +1,12 @@ +package com.inhabas.api.domain.policy.usecase; + +import com.inhabas.api.domain.policy.dto.PolicyTermDto; +import com.inhabas.api.domain.policy.dto.SavePolicyTernDto; + +public interface PolicyTermService { + + PolicyTermDto findPolicyTerm(Long policyTermId); + + void updatePolicyTerm(Long policyTermId, SavePolicyTernDto savePolicyTernDto); + +} diff --git a/resource-server/src/main/java/com/inhabas/api/domain/policy/usecase/PolicyTermServiceImpl.java b/resource-server/src/main/java/com/inhabas/api/domain/policy/usecase/PolicyTermServiceImpl.java new file mode 100644 index 00000000..6f86d2d9 --- /dev/null +++ b/resource-server/src/main/java/com/inhabas/api/domain/policy/usecase/PolicyTermServiceImpl.java @@ -0,0 +1,40 @@ +package com.inhabas.api.domain.policy.usecase; + +import com.inhabas.api.auth.domain.error.businessException.NotFoundException; +import com.inhabas.api.domain.policy.domain.PolicyTerm; +import com.inhabas.api.domain.policy.dto.PolicyTermDto; +import com.inhabas.api.domain.policy.dto.SavePolicyTernDto; +import com.inhabas.api.domain.policy.respository.PolicyTermRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +public class PolicyTermServiceImpl implements PolicyTermService{ + + private final PolicyTermRepository policyTermRepository; + + @Override + @Transactional(readOnly = true) + public PolicyTermDto findPolicyTerm(Long policyTermId) { + + PolicyTerm policyTerm = policyTermRepository.findById(policyTermId).orElseThrow(NotFoundException::new); + + return PolicyTermDto.builder() + .title(policyTerm.getPolicyType().getTitle().getValue()) + .content(policyTerm.getContent().getValue()) + .build(); + + } + + @Override + @Transactional + public void updatePolicyTerm(Long policyTermId, SavePolicyTernDto savePolicyTernDto) { + + PolicyTerm policyTerm = policyTermRepository.findById(policyTermId).orElseThrow(NotFoundException::new); + policyTerm.updatePolicyTerm(savePolicyTernDto); + + } + +} diff --git a/resource-server/src/main/java/com/inhabas/api/web/PolicyTermController.java b/resource-server/src/main/java/com/inhabas/api/web/PolicyTermController.java new file mode 100644 index 00000000..ad28cb23 --- /dev/null +++ b/resource-server/src/main/java/com/inhabas/api/web/PolicyTermController.java @@ -0,0 +1,82 @@ +package com.inhabas.api.web; + +import com.inhabas.api.auth.domain.error.ErrorResponse; +import com.inhabas.api.domain.policy.dto.PolicyTermDto; +import com.inhabas.api.domain.policy.dto.SavePolicyTernDto; +import com.inhabas.api.domain.policy.usecase.PolicyTermService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.ExampleObject; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.security.SecurityRequirements; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import javax.validation.Valid; + +@Tag(name = "정책 관리") +@RestController +@RequiredArgsConstructor +public class PolicyTermController { + + private final PolicyTermService policyTermService; + + @GetMapping("/policy/{policyTermId}") + @SecurityRequirements(value = {}) + @Operation(summary = "해당 정책을 조회한다.", + description = "policyTermId는 1,2,3만 존재") + @ApiResponses({ + @ApiResponse(responseCode = "200", content = @Content( + schema = @Schema(implementation = PolicyTermDto.class) + )), + @ApiResponse(responseCode = "400 ", description = "입력값이 없거나, 타입이 유효하지 않습니다.", content = @Content( + schema = @Schema(implementation = ErrorResponse.class), + examples = @ExampleObject( + value = "{\"status\": 400, \"code\": \"G003\", \"message\": \"입력값이 없거나, 타입이 유효하지 않습니다.\"}" + ) + )), + @ApiResponse(responseCode = "404", description = "데이터가 존재하지 않습니다.", content = @Content( + schema = @Schema(implementation = ErrorResponse.class), + examples = @ExampleObject( + value = "{\"status\": 404, \"code\": \"G004\", \"message\": \"데이터가 존재하지 않습니다.\"}" + ) + )) + }) + public ResponseEntity findPolicyTerm(@PathVariable Long policyTermId) { + + PolicyTermDto policyTermDto = policyTermService.findPolicyTerm(policyTermId); + return ResponseEntity.ok(policyTermDto); + + } + + @PutMapping("/policy/{policyTermId}") + @Operation(summary = "해당 정책을 수정한다.", + description = "policyTermId는 1,2,3만 존재") + @ApiResponses({ + @ApiResponse(responseCode = "204"), + @ApiResponse(responseCode = "400 ", description = "입력값이 없거나, 타입이 유효하지 않습니다.", content = @Content( + schema = @Schema(implementation = ErrorResponse.class), + examples = @ExampleObject( + value = "{\"status\": 400, \"code\": \"G003\", \"message\": \"입력값이 없거나, 타입이 유효하지 않습니다.\"}" + ) + )), + @ApiResponse(responseCode = "404", description = "데이터가 존재하지 않습니다.", content = @Content( + schema = @Schema(implementation = ErrorResponse.class), + examples = @ExampleObject( + value = "{\"status\": 404, \"code\": \"G004\", \"message\": \"데이터가 존재하지 않습니다.\"}" + ) + )) + }) + public ResponseEntity updatePolicyTerm(@PathVariable Long policyTermId, + @Valid @RequestBody SavePolicyTernDto savePolicyTernDto) { + + policyTermService.updatePolicyTerm(policyTermId, savePolicyTernDto); + return ResponseEntity.noContent().build(); + + } + +} diff --git a/resource-server/src/test/java/com/inhabas/api/domain/club/usecase/ClubHistoryServiceImplTest.java b/resource-server/src/test/java/com/inhabas/api/domain/club/usecase/ClubHistoryServiceImplTest.java index 49ee9b42..ade445e2 100644 --- a/resource-server/src/test/java/com/inhabas/api/domain/club/usecase/ClubHistoryServiceImplTest.java +++ b/resource-server/src/test/java/com/inhabas/api/domain/club/usecase/ClubHistoryServiceImplTest.java @@ -17,6 +17,7 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.data.domain.Sort; import org.springframework.test.util.ReflectionTestUtils; import org.springframework.transaction.annotation.Transactional; @@ -130,13 +131,15 @@ void getClubHistories_Success() { .dateHistory(LocalDateTime.now()) .build(); List clubHistoryList = List.of(clubHistory); - given(clubHistoryRepository.findAll()).willReturn(clubHistoryList); + + Sort sort = Sort.by(Sort.Direction.DESC, "dateHistory"); + given(clubHistoryRepository.findAll(sort)).willReturn(clubHistoryList); //when List clubHistoryDtoList = clubHistoryService.getClubHistories(); //then - then(clubHistoryRepository).should().findAll(); + then(clubHistoryRepository).should().findAll(sort); assertThat(clubHistoryDtoList) .hasSize(1) .extracting("title", "content") diff --git a/resource-server/src/test/java/com/inhabas/api/domain/policy/domain/PolicyTermTest.java b/resource-server/src/test/java/com/inhabas/api/domain/policy/domain/PolicyTermTest.java new file mode 100644 index 00000000..75b1a12d --- /dev/null +++ b/resource-server/src/test/java/com/inhabas/api/domain/policy/domain/PolicyTermTest.java @@ -0,0 +1,40 @@ +package com.inhabas.api.domain.policy.domain; + +import com.inhabas.api.auth.domain.error.businessException.InvalidInputException; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +class PolicyTermTest { + + @DisplayName("Content는 null 일 수 없다.") + @Test + void Content_Notnull() { + //given + PolicyType policyType = new PolicyType("goodTitle"); + String nullString = null; + + //then + Assertions.assertThatThrownBy(() -> new PolicyTerm(policyType, nullString)) + .isInstanceOf(InvalidInputException.class) + .hasMessage("입력값이 없거나, 타입이 유효하지 않습니다."); + + } + + @DisplayName("올바른 PolicyTerm을 생성한다.") + @Test + void createPolicyTerm() { + //given + PolicyType policyType = new PolicyType("goodTitle"); + String goodContent = "goodContent"; + + //when + PolicyTerm policyTerm = new PolicyTerm(policyType, goodContent); + + + //then + Assertions.assertThat(policyTerm.getContent().getValue()).isEqualTo(goodContent); + + } + +} \ No newline at end of file diff --git a/resource-server/src/test/java/com/inhabas/api/domain/policy/domain/PolicyTypeTest.java b/resource-server/src/test/java/com/inhabas/api/domain/policy/domain/PolicyTypeTest.java new file mode 100644 index 00000000..e25796c0 --- /dev/null +++ b/resource-server/src/test/java/com/inhabas/api/domain/policy/domain/PolicyTypeTest.java @@ -0,0 +1,41 @@ +package com.inhabas.api.domain.policy.domain; + +import com.inhabas.api.auth.domain.error.businessException.InvalidInputException; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +class PolicyTypeTest { + + @DisplayName("Title은 null, empty일 수 없다.") + @Test + void Title_Notnull_NotEmpty() { + //given + String white = "\t"; + + //then + assertThatThrownBy(() -> new PolicyType(white)) + .isInstanceOf(InvalidInputException.class) + .hasMessage("입력값이 없거나, 타입이 유효하지 않습니다."); + + } + + @DisplayName("올바른 PolicyType을 생성한다.") + @Test + void createPolicyType() { + //given + String goodTitle = "good"; + + //when + PolicyType policyType = new PolicyType(goodTitle); + + //then + Assertions.assertThat(policyType.getTitle().getValue()).isEqualTo(goodTitle); + + } + + + +} \ No newline at end of file diff --git a/resource-server/src/test/java/com/inhabas/api/domain/policy/dto/PolicyTermDtoTest.java b/resource-server/src/test/java/com/inhabas/api/domain/policy/dto/PolicyTermDtoTest.java new file mode 100644 index 00000000..bacc4034 --- /dev/null +++ b/resource-server/src/test/java/com/inhabas/api/domain/policy/dto/PolicyTermDtoTest.java @@ -0,0 +1,50 @@ +package com.inhabas.api.domain.policy.dto; + +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import javax.validation.ConstraintViolation; +import javax.validation.Validation; +import javax.validation.Validator; +import javax.validation.ValidatorFactory; +import java.util.Set; + +import static org.assertj.core.api.Assertions.assertThat; + +class PolicyTermDtoTest { + + private static ValidatorFactory validatorFactory; + private static Validator validator; + + @BeforeAll + public static void init() { + validatorFactory = Validation.buildDefaultValidatorFactory(); + validator = validatorFactory.getValidator(); + } + + @AfterAll + public static void close() { + validatorFactory.close(); + } + + + @DisplayName("title, content 가 null 이면 validation 실패") + @Test + void NotNull_Test() { + //given + PolicyTermDto policyTermDto = PolicyTermDto.builder() + .title(null) + .content(null) + .build(); + + //when + Set> violations = validator.validate(policyTermDto); + + //then + assertThat(violations).hasSize(2); + + } + +} \ No newline at end of file diff --git a/resource-server/src/test/java/com/inhabas/api/domain/policy/dto/SavePolicyTernDtoTest.java b/resource-server/src/test/java/com/inhabas/api/domain/policy/dto/SavePolicyTernDtoTest.java new file mode 100644 index 00000000..202e4364 --- /dev/null +++ b/resource-server/src/test/java/com/inhabas/api/domain/policy/dto/SavePolicyTernDtoTest.java @@ -0,0 +1,49 @@ +package com.inhabas.api.domain.policy.dto; + +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import javax.validation.ConstraintViolation; +import javax.validation.Validation; +import javax.validation.Validator; +import javax.validation.ValidatorFactory; +import java.util.Set; + +import static org.assertj.core.api.Assertions.assertThat; + +class SavePolicyTernDtoTest { + + private static ValidatorFactory validatorFactory; + private static Validator validator; + + @BeforeAll + public static void init() { + validatorFactory = Validation.buildDefaultValidatorFactory(); + validator = validatorFactory.getValidator(); + } + + @AfterAll + public static void close() { + validatorFactory.close(); + } + + + @DisplayName("title, content 가 null 이면 validation 실패") + @Test + void NotNull_Test() { + //given + SavePolicyTernDto savePolicyTernDto = SavePolicyTernDto.builder() + .content(null) + .build(); + + //when + Set> violations = validator.validate(savePolicyTernDto); + + //then + assertThat(violations).hasSize(1); + + } + +} \ No newline at end of file diff --git a/resource-server/src/test/java/com/inhabas/api/domain/policy/usecase/PolicyTermServiceTest.java b/resource-server/src/test/java/com/inhabas/api/domain/policy/usecase/PolicyTermServiceTest.java new file mode 100644 index 00000000..de797c40 --- /dev/null +++ b/resource-server/src/test/java/com/inhabas/api/domain/policy/usecase/PolicyTermServiceTest.java @@ -0,0 +1,104 @@ +package com.inhabas.api.domain.policy.usecase; + +import com.inhabas.api.auth.domain.error.businessException.NotFoundException; +import com.inhabas.api.domain.policy.domain.PolicyTerm; +import com.inhabas.api.domain.policy.domain.PolicyType; +import com.inhabas.api.domain.policy.dto.PolicyTermDto; +import com.inhabas.api.domain.policy.dto.SavePolicyTernDto; +import com.inhabas.api.domain.policy.respository.PolicyTermRepository; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.util.Objects; +import java.util.Optional; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.*; + +@ExtendWith(MockitoExtension.class) +public class PolicyTermServiceTest { + + @InjectMocks + PolicyTermServiceImpl policyTermService; + + @Mock + PolicyTermRepository policyTermRepository; + + + @DisplayName("policyTermId로 policyTerm 을 조회한다.") + @Test + void findPolicyTermTest() { + //given + Long policyTermId = 1L; + PolicyType policyType = new PolicyType("title"); // PolicyType에 적절한 생성자 또는 setter 메소드가 필요합니다. + PolicyTerm policyTerm = PolicyTerm.builder() + .policyType(policyType) + .content("content") + .build(); + + given(policyTermRepository.findById(policyTermId)).willReturn(Optional.ofNullable(policyTerm)); + + //when + PolicyTermDto result = policyTermService.findPolicyTerm(policyTermId); + + //then + verify(policyTermRepository).findById(policyTermId); + assertThat(result.getTitle()).isEqualTo(Objects.requireNonNull(policyTerm).getPolicyType().getTitle().getValue()); + assertThat(result.getContent()).isEqualTo(policyTerm.getContent().getValue()); + + } + + @DisplayName("존재하지 않는 policyTermId 조회 시 NotFoundException") + @Test + void findPolicyTermTest_NotFound() { + //given + given(policyTermRepository.findById(any())).willReturn(Optional.empty()); + + //then + assertThatThrownBy(() -> policyTermService.findPolicyTerm(any())) + .isInstanceOf(NotFoundException.class) + .hasMessage("데이터가 존재하지 않습니다."); + + } + + @DisplayName("policyTerm 을 수정한다.") + @Test + void updatePolicyTermTest() { + //given + Long policyTermId = 1L; + SavePolicyTernDto savePolicyTermDto = new SavePolicyTernDto("content"); + PolicyTerm policyTerm = mock(PolicyTerm.class); + + given(policyTermRepository.findById(policyTermId)).willReturn(Optional.of(policyTerm)); + + //when + policyTermService.updatePolicyTerm(policyTermId, savePolicyTermDto); + + //then + verify(policyTermRepository).findById(policyTermId); + verify(policyTerm).updatePolicyTerm(savePolicyTermDto); + + } + + @DisplayName("존재하지 않는 policyTermId 수정 시 NotFoundException") + @Test + void updatePolicyTermTest_NotFound() { + //given + Long policyTermId = 1L; + SavePolicyTernDto savePolicyTermDto = new SavePolicyTernDto("content"); + + //then + assertThatThrownBy(() -> policyTermService.updatePolicyTerm(policyTermId, savePolicyTermDto)) + .isInstanceOf(NotFoundException.class) + .hasMessage("데이터가 존재하지 않습니다."); + + } + +} \ No newline at end of file diff --git a/resource-server/src/test/java/com/inhabas/api/web/PolicyTermControllerTest.java b/resource-server/src/test/java/com/inhabas/api/web/PolicyTermControllerTest.java new file mode 100644 index 00000000..84bc86ba --- /dev/null +++ b/resource-server/src/test/java/com/inhabas/api/web/PolicyTermControllerTest.java @@ -0,0 +1,173 @@ +package com.inhabas.api.web; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.inhabas.api.auth.domain.error.businessException.InvalidInputException; +import com.inhabas.api.auth.domain.error.businessException.NotFoundException; +import com.inhabas.api.domain.policy.dto.PolicyTermDto; +import com.inhabas.api.domain.policy.dto.SavePolicyTernDto; +import com.inhabas.api.domain.policy.usecase.PolicyTermService; +import com.inhabas.testAnnotataion.NoSecureWebMvcTest; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.http.MediaType; +import org.springframework.test.web.servlet.MockMvc; + +import java.nio.charset.StandardCharsets; + +import static com.inhabas.api.auth.domain.error.ErrorCode.INVALID_INPUT_VALUE; +import static com.inhabas.api.auth.domain.error.ErrorCode.NOT_FOUND; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.doThrow; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@NoSecureWebMvcTest(PolicyTermController.class) +public class PolicyTermControllerTest { + + @Autowired + private MockMvc mvc; + + @MockBean + private PolicyTermService policyTermService; + + @Autowired + private ObjectMapper objectMapper; + + private String jsonOf(Object response) throws JsonProcessingException { + return objectMapper.writeValueAsString(response); + } + + + @DisplayName("정책 단일 조회 성공 200") + @Test + void findPolicyTerm() throws Exception { + //given + PolicyTermDto policyTermDto = PolicyTermDto.builder() + .title("title") + .content("content") + .build(); + given(policyTermService.findPolicyTerm(any())).willReturn(policyTermDto); + + //when + String response = mvc.perform(get("/policy/{policyTermId}", 1L)) + .andExpect(status().isOk()) + .andReturn() + .getResponse() + .getContentAsString(StandardCharsets.UTF_8); + + //then + assertThat(response).isEqualTo(jsonOf(policyTermDto)); + + } + + @DisplayName("정책 단일 조회 데이터가 올바르지 않다면 400") + @Test + void findPolicyTerm_Invalid_Input() throws Exception { + //given + PolicyTermDto policyTermDto = PolicyTermDto.builder() + .title("title") + .content("content") + .build(); + given(policyTermService.findPolicyTerm(any())).willReturn(policyTermDto); + + //when + String response = mvc.perform(get("/policy/{policyTermId}", "invalid")) + .andExpect(status().isBadRequest()) + .andReturn() + .getResponse() + .getContentAsString(StandardCharsets.UTF_8); + + //then + assertThat(response).contains(INVALID_INPUT_VALUE.getMessage()); + + } + + @DisplayName("정책 단일 조회 해당 id가 없다면 404") + @Test + void findPolicyTerm_Not_Found() throws Exception { + //given + doThrow(NotFoundException.class).when(policyTermService).findPolicyTerm(any()); + + //when + String response = mvc.perform(get("/policy/{policyTermId}", 1L)) + .andExpect(status().isNotFound()) + .andReturn() + .getResponse() + .getContentAsString(StandardCharsets.UTF_8); + + //then + assertThat(response).contains(NOT_FOUND.getMessage()); + + } + + @DisplayName("정책 수정 성공 204") + @Test + void updatePolicyTerm() throws Exception { + //given + SavePolicyTernDto savePolicyTernDto = SavePolicyTernDto.builder() + .content("meaningless") + .build(); + doNothing().when(policyTermService).updatePolicyTerm(any(), any()); + + //when then + mvc.perform(put("/policy/{policyTermId}", 1L) + .contentType(MediaType.APPLICATION_JSON) + .content(jsonOf(savePolicyTernDto))) + .andExpect(status().isNoContent()); + + } + + @DisplayName("정책 수정 데이터가 올바르지 않다면 400") + @Test + void updatePolicyTerm_Invalid_Input() throws Exception { + //given + SavePolicyTernDto savePolicyTernDto = SavePolicyTernDto.builder() + .content("meaningless") + .build(); + doThrow(InvalidInputException.class).when(policyTermService).updatePolicyTerm(any(), any()); + + //when + String response = mvc.perform(put("/policy/{policyTermId}", 1L) + .contentType(MediaType.APPLICATION_JSON) + .content(jsonOf(savePolicyTernDto))) + .andExpect(status().isBadRequest()) + .andReturn() + .getResponse() + .getContentAsString(StandardCharsets.UTF_8); + + //then + assertThat(response).contains(INVALID_INPUT_VALUE.getMessage()); + + } + + @DisplayName("정책 수정 해당 id가 존재하지 않다면 404") + @Test + void updatePolicyTerm_Not_Found() throws Exception { + //given + SavePolicyTernDto savePolicyTernDto = SavePolicyTernDto.builder() + .content("meaningless") + .build(); + doThrow(NotFoundException.class).when(policyTermService).updatePolicyTerm(any(), any()); + + //when + String response = mvc.perform(put("/policy/{policyTermId}", 1L) + .contentType(MediaType.APPLICATION_JSON) + .content(jsonOf(savePolicyTernDto))) + .andExpect(status().isNotFound()) + .andReturn() + .getResponse() + .getContentAsString(StandardCharsets.UTF_8); + + //then + assertThat(response).contains(NOT_FOUND.getMessage()); + + } + +} \ No newline at end of file