Skip to content

Commit

Permalink
[feature/#209] 정책 관련 API 구현
Browse files Browse the repository at this point in the history
[feature/#209] 정책 관련 API 구현
  • Loading branch information
skytin1004 authored Jan 8, 2024
2 parents 9169abf + 32e568a commit d06b3f9
Show file tree
Hide file tree
Showing 17 changed files with 721 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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)
Expand Down Expand Up @@ -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());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
@@ -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());
}

}
Original file line number Diff line number Diff line change
@@ -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);
}

}
Original file line number Diff line number Diff line change
@@ -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;
}

}
Original file line number Diff line number Diff line change
@@ -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;
}

}
Original file line number Diff line number Diff line change
@@ -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<PolicyTerm, Long> {
}
Original file line number Diff line number Diff line change
@@ -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);

}
Original file line number Diff line number Diff line change
@@ -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);

}

}
Original file line number Diff line number Diff line change
@@ -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<PolicyTermDto> 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<PolicyTermDto> updatePolicyTerm(@PathVariable Long policyTermId,
@Valid @RequestBody SavePolicyTernDto savePolicyTernDto) {

policyTermService.updatePolicyTerm(policyTermId, savePolicyTernDto);
return ResponseEntity.noContent().build();

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -130,13 +131,15 @@ void getClubHistories_Success() {
.dateHistory(LocalDateTime.now())
.build();
List<ClubHistory> 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<ClubHistoryDto> clubHistoryDtoList = clubHistoryService.getClubHistories();

//then
then(clubHistoryRepository).should().findAll();
then(clubHistoryRepository).should().findAll(sort);
assertThat(clubHistoryDtoList)
.hasSize(1)
.extracting("title", "content")
Expand Down
Original file line number Diff line number Diff line change
@@ -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);

}

}
Loading

0 comments on commit d06b3f9

Please sign in to comment.