From 82928a9522e6d0d53dd3f1cf1ab9b764a97614bd Mon Sep 17 00:00:00 2001 From: songsunkook Date: Sat, 6 Jan 2024 19:33:36 +0900 Subject: [PATCH] =?UTF-8?q?refactor:=20DB=EC=97=90=EC=84=9C=20enum?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EA=B5=AC=EC=A1=B0=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit cc. #152 --- .../domain/dept/dto/DeptListItemResponse.java | 13 ++- .../koin/domain/dept/dto/DeptResponse.java | 6 +- .../koin/domain/dept/model/Dept.java | 44 ++++++++++ .../koin/domain/dept/model/DeptInfo.java | 47 ----------- .../koin/domain/dept/model/DeptNum.java | 40 --------- .../koin/domain/dept/model/DeptNumId.java | 23 ----- .../dept/repository/DeptInfoRepository.java | 14 ---- .../dept/repository/DeptNumRepository.java | 15 ---- .../koin/domain/dept/service/DeptService.java | 15 ++-- .../koin/acceptance/DeptApiTest.java | 83 +++---------------- 10 files changed, 70 insertions(+), 230 deletions(-) create mode 100644 src/main/java/in/koreatech/koin/domain/dept/model/Dept.java delete mode 100644 src/main/java/in/koreatech/koin/domain/dept/model/DeptInfo.java delete mode 100644 src/main/java/in/koreatech/koin/domain/dept/model/DeptNum.java delete mode 100644 src/main/java/in/koreatech/koin/domain/dept/model/DeptNumId.java delete mode 100644 src/main/java/in/koreatech/koin/domain/dept/repository/DeptInfoRepository.java delete mode 100644 src/main/java/in/koreatech/koin/domain/dept/repository/DeptNumRepository.java diff --git a/src/main/java/in/koreatech/koin/domain/dept/dto/DeptListItemResponse.java b/src/main/java/in/koreatech/koin/domain/dept/dto/DeptListItemResponse.java index 6f654f251..474228147 100644 --- a/src/main/java/in/koreatech/koin/domain/dept/dto/DeptListItemResponse.java +++ b/src/main/java/in/koreatech/koin/domain/dept/dto/DeptListItemResponse.java @@ -5,19 +5,16 @@ import com.fasterxml.jackson.databind.PropertyNamingStrategies.SnakeCaseStrategy; import com.fasterxml.jackson.databind.annotation.JsonNaming; -import in.koreatech.koin.domain.dept.model.DeptInfo; -import in.koreatech.koin.domain.dept.model.DeptNum; +import in.koreatech.koin.domain.dept.model.Dept; @JsonNaming(value = SnakeCaseStrategy.class) public record DeptListItemResponse(String name, String curriculumLink, List deptNums) { - public static DeptListItemResponse from(DeptInfo deptInfo) { + public static DeptListItemResponse from(Dept dept) { return new DeptListItemResponse( - deptInfo.getName(), - deptInfo.getCurriculumLink(), - deptInfo.getDeptNums().stream() - .map(DeptNum::getNumber) - .toList() + dept.getName(), + dept.getCurriculumLink(), + dept.getNumbers() ); } } diff --git a/src/main/java/in/koreatech/koin/domain/dept/dto/DeptResponse.java b/src/main/java/in/koreatech/koin/domain/dept/dto/DeptResponse.java index 056bbb5b5..fe6e47d72 100644 --- a/src/main/java/in/koreatech/koin/domain/dept/dto/DeptResponse.java +++ b/src/main/java/in/koreatech/koin/domain/dept/dto/DeptResponse.java @@ -4,12 +4,12 @@ import com.fasterxml.jackson.databind.annotation.JsonNaming; -import in.koreatech.koin.domain.dept.model.DeptNum; +import in.koreatech.koin.domain.dept.model.Dept; @JsonNaming(value = SnakeCaseStrategy.class) public record DeptResponse(Long deptNum, String name) { - public static DeptResponse from(DeptNum deptNum) { - return new DeptResponse(deptNum.getNumber(), deptNum.getDeptInfo().getName()); + public static DeptResponse from(Long findNumber, Dept dept) { + return new DeptResponse(findNumber, dept.getName()); } } diff --git a/src/main/java/in/koreatech/koin/domain/dept/model/Dept.java b/src/main/java/in/koreatech/koin/domain/dept/model/Dept.java new file mode 100644 index 000000000..9303b5699 --- /dev/null +++ b/src/main/java/in/koreatech/koin/domain/dept/model/Dept.java @@ -0,0 +1,44 @@ +package in.koreatech.koin.domain.dept.model; + +import java.util.Arrays; +import java.util.List; +import java.util.Optional; + +import lombok.Getter; + +@Getter +public enum Dept { + ARCHITECTURAL_ENGINEERING("건축공학부", List.of(72L), "https://cms3.koreatech.ac.kr/arch/1083/subview.do"), + EMPLOYMENT_SERVICE_POLICY_DEPARTMENT("고용서비스정책학과", List.of(85L), "https://www.koreatech.ac.kr/kor/CMS/UnivOrganMgr/subMain.do?mCode=MN451"), + MECHANICAL_ENGINEERING("기계공학부", List.of(20L), "https://cms3.koreatech.ac.kr/me/795/subview.do"), + DESIGN_ENGINEERING("디자인공학부", List.of(51L), "https://cms3.koreatech.ac.kr/ide/1047/subview.do"), + MECHATRONICS_ENGINEERING("메카트로닉스공학부", List.of(40L), "https://www.koreatech.ac.kr/kor/CMS/UnivOrganMgr/subMain.do?mCode=MN076"), + INDUSTRIAL_MANAGEMENT("산업경영학부", List.of(80L), "https://cms3.koreatech.ac.kr/sim/1167/subview.do"), + NEW_ENERGY_MATERIALS_CHEMICAL_ENGINEERING("에너지신소재화학공학부", List.of(74L), "https://cms3.koreatech.ac.kr/ace/992/subview.do"), + ELECTRICAL_AND_ELECTRONIC_COMMUNICATION_ENGINEERING("전기전자통신공학부", List.of(61L), "https://cms3.koreatech.ac.kr/ite/842/subview.do"), + COMPUTER_SCIENCE("컴퓨터공학부", List.of(35L, 36L), "https://cse.koreatech.ac.kr/page_izgw21"), + ; + + private final String name; + private final List numbers; + private final String curriculumLink; + + Dept(String name, List numbers, String curriculumLink) { + this.name = name; + this.numbers = numbers; + this.curriculumLink = curriculumLink; + } + + public static Optional findByNumber(Long number) { + for (Dept dept : Dept.values()) { + if (dept.numbers.contains(number)) { + return Optional.of(dept); + } + } + return Optional.empty(); + } + + public static List findAll() { + return Arrays.stream(values()).toList(); + } +} diff --git a/src/main/java/in/koreatech/koin/domain/dept/model/DeptInfo.java b/src/main/java/in/koreatech/koin/domain/dept/model/DeptInfo.java deleted file mode 100644 index e7e182792..000000000 --- a/src/main/java/in/koreatech/koin/domain/dept/model/DeptInfo.java +++ /dev/null @@ -1,47 +0,0 @@ -package in.koreatech.koin.domain.dept.model; - -import java.util.ArrayList; -import java.util.List; - -import jakarta.persistence.Column; -import jakarta.persistence.Entity; -import jakarta.persistence.Id; -import jakarta.persistence.OneToMany; -import jakarta.persistence.Table; -import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Size; -import lombok.AccessLevel; -import lombok.Builder; -import lombok.Getter; -import lombok.NoArgsConstructor; - -@Getter -@Entity -@Table(name = "dept_infos") -@NoArgsConstructor(access = AccessLevel.PROTECTED) -public class DeptInfo { - - @Id - @NotNull - @Size(max = 45) - @Column(name = "name", nullable = false, length = 45) - private String name; - - @NotNull - @Size(max = 255) - @Column(name = "curriculum_link", nullable = false, length = 255) - private String curriculumLink; - - @NotNull - @Column(name = "is_deleted", nullable = true) - private Boolean isDeleted = false; - - @OneToMany(mappedBy = "deptInfo") - private List deptNums = new ArrayList<>(); - - @Builder - private DeptInfo(String name, String curriculumLink) { - this.name = name; - this.curriculumLink = curriculumLink; - } -} diff --git a/src/main/java/in/koreatech/koin/domain/dept/model/DeptNum.java b/src/main/java/in/koreatech/koin/domain/dept/model/DeptNum.java deleted file mode 100644 index 6dc3d2e1a..000000000 --- a/src/main/java/in/koreatech/koin/domain/dept/model/DeptNum.java +++ /dev/null @@ -1,40 +0,0 @@ -package in.koreatech.koin.domain.dept.model; - -import jakarta.persistence.Column; -import jakarta.persistence.Entity; -import jakarta.persistence.FetchType; -import jakarta.persistence.Id; -import jakarta.persistence.IdClass; -import jakarta.persistence.JoinColumn; -import jakarta.persistence.ManyToOne; -import jakarta.persistence.MapsId; -import jakarta.persistence.Table; -import jakarta.validation.constraints.NotNull; -import lombok.AccessLevel; -import lombok.Builder; -import lombok.Getter; -import lombok.NoArgsConstructor; - -@Getter -@Entity -@Table(name = "dept_nums") -@IdClass(DeptNumId.class) -@NoArgsConstructor(access = AccessLevel.PROTECTED) -public class DeptNum { - - @Id - @NotNull - @Column(name = "dept_num", nullable = false) - private Long number; - - @MapsId - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "dept_name") - private DeptInfo deptInfo; - - @Builder - private DeptNum(Long number, DeptInfo deptInfo) { - this.number = number; - this.deptInfo = deptInfo; - } -} diff --git a/src/main/java/in/koreatech/koin/domain/dept/model/DeptNumId.java b/src/main/java/in/koreatech/koin/domain/dept/model/DeptNumId.java deleted file mode 100644 index 66a52886d..000000000 --- a/src/main/java/in/koreatech/koin/domain/dept/model/DeptNumId.java +++ /dev/null @@ -1,23 +0,0 @@ -package in.koreatech.koin.domain.dept.model; - -import java.io.Serializable; - -import jakarta.persistence.Column; -import jakarta.persistence.FetchType; -import jakarta.persistence.JoinColumn; -import jakarta.persistence.ManyToOne; -import lombok.AccessLevel; -import lombok.EqualsAndHashCode; -import lombok.NoArgsConstructor; - -@NoArgsConstructor(access = AccessLevel.PROTECTED) -@EqualsAndHashCode -public class DeptNumId implements Serializable { - - @Column(name = "dept_num", nullable = false) - private Long number; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "dept_name") - private DeptInfo deptInfo; -} diff --git a/src/main/java/in/koreatech/koin/domain/dept/repository/DeptInfoRepository.java b/src/main/java/in/koreatech/koin/domain/dept/repository/DeptInfoRepository.java deleted file mode 100644 index aefc17c97..000000000 --- a/src/main/java/in/koreatech/koin/domain/dept/repository/DeptInfoRepository.java +++ /dev/null @@ -1,14 +0,0 @@ -package in.koreatech.koin.domain.dept.repository; - -import java.util.List; - -import org.springframework.data.repository.Repository; - -import in.koreatech.koin.domain.dept.model.DeptInfo; - -public interface DeptInfoRepository extends Repository { - - DeptInfo save(DeptInfo deptInfo); - - List findAll(); -} diff --git a/src/main/java/in/koreatech/koin/domain/dept/repository/DeptNumRepository.java b/src/main/java/in/koreatech/koin/domain/dept/repository/DeptNumRepository.java deleted file mode 100644 index 6c94612d3..000000000 --- a/src/main/java/in/koreatech/koin/domain/dept/repository/DeptNumRepository.java +++ /dev/null @@ -1,15 +0,0 @@ -package in.koreatech.koin.domain.dept.repository; - -import java.util.Optional; - -import org.springframework.data.repository.Repository; - -import in.koreatech.koin.domain.dept.model.DeptNum; -import in.koreatech.koin.domain.dept.model.DeptNumId; - -public interface DeptNumRepository extends Repository { - - DeptNum save(DeptNum deptNum); - - Optional findByNumber(Long number); -} diff --git a/src/main/java/in/koreatech/koin/domain/dept/service/DeptService.java b/src/main/java/in/koreatech/koin/domain/dept/service/DeptService.java index 347d8fad8..56b2a7ee9 100644 --- a/src/main/java/in/koreatech/koin/domain/dept/service/DeptService.java +++ b/src/main/java/in/koreatech/koin/domain/dept/service/DeptService.java @@ -5,11 +5,9 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import in.koreatech.koin.domain.dept.model.DeptNum; -import in.koreatech.koin.domain.dept.dto.DeptResponse; import in.koreatech.koin.domain.dept.dto.DeptListItemResponse; -import in.koreatech.koin.domain.dept.repository.DeptInfoRepository; -import in.koreatech.koin.domain.dept.repository.DeptNumRepository; +import in.koreatech.koin.domain.dept.dto.DeptResponse; +import in.koreatech.koin.domain.dept.model.Dept; import lombok.RequiredArgsConstructor; @Service @@ -17,18 +15,15 @@ @Transactional(readOnly = true) public class DeptService { - private final DeptInfoRepository deptInfoRepository; - private final DeptNumRepository deptNumRepository; - public DeptResponse findById(Long id) { - DeptNum deptNum = deptNumRepository.findByNumber(id) + Dept dept = Dept.findByNumber(id) .orElseThrow(() -> new IllegalArgumentException("존재하지 않는 학부 코드입니다.")); - return DeptResponse.from(deptNum); + return DeptResponse.from(id, dept); } public List findAll() { - return deptInfoRepository.findAll() + return Dept.findAll() .stream() .map(DeptListItemResponse::from) .toList(); diff --git a/src/test/java/in/koreatech/koin/acceptance/DeptApiTest.java b/src/test/java/in/koreatech/koin/acceptance/DeptApiTest.java index d5002747a..409bd9dc5 100644 --- a/src/test/java/in/koreatech/koin/acceptance/DeptApiTest.java +++ b/src/test/java/in/koreatech/koin/acceptance/DeptApiTest.java @@ -4,48 +4,21 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import in.koreatech.koin.AcceptanceTest; -import in.koreatech.koin.domain.dept.model.DeptInfo; -import in.koreatech.koin.domain.dept.model.DeptNum; -import in.koreatech.koin.domain.dept.repository.DeptInfoRepository; -import in.koreatech.koin.domain.dept.repository.DeptNumRepository; +import in.koreatech.koin.domain.dept.model.Dept; import io.restassured.RestAssured; import io.restassured.response.ExtractableResponse; import io.restassured.response.Response; class DeptApiTest extends AcceptanceTest { - @Autowired - private DeptInfoRepository deptInfoRepository; - - @Autowired - private DeptNumRepository deptNumRepository; - @Test @DisplayName("학과 번호를 통해 학과 이름을 조회한다.") void findDeptNameByDeptNumber() { // given - DeptInfo deptInfo = DeptInfo.builder() - .name("컴퓨터공학부") - .curriculumLink("https://cse.koreatech.ac.kr/page_izgw21") - .build(); - - deptInfoRepository.save(deptInfo); - - DeptNum deptNum1 = DeptNum.builder() - .deptInfo(deptInfo) - .number(35L) - .build(); - DeptNum deptNum2 = DeptNum.builder() - .deptInfo(deptInfo) - .number(36L) - .build(); - - deptNumRepository.save(deptNum1); - deptNumRepository.save(deptNum2); + Dept dept = Dept.COMPUTER_SCIENCE; // when then ExtractableResponse response = RestAssured @@ -53,7 +26,7 @@ void findDeptNameByDeptNumber() { .log().all() .when() .log().all() - .param("dept_num", deptNum1.getNumber()) + .param("dept_num", dept.getNumbers().get(0)) .get("/dept") .then() .log().all() @@ -62,8 +35,8 @@ void findDeptNameByDeptNumber() { assertSoftly( softly -> { - softly.assertThat(response.body().jsonPath().getString("dept_num")).isEqualTo(deptNum1.getNumber().toString()); - softly.assertThat(response.body().jsonPath().getString("name")).isEqualTo(deptInfo.getName()); + softly.assertThat(response.body().jsonPath().getLong("dept_num")).isEqualTo(dept.getNumbers().get(0)); + softly.assertThat(response.body().jsonPath().getString("name")).isEqualTo(dept.getName()); } ); } @@ -72,36 +45,7 @@ void findDeptNameByDeptNumber() { @DisplayName("모든 학과 정보를 조회한다.") void findAllDepts() { //given - final int DEPT_SIZE = 2; - - DeptInfo deptInfo1 = DeptInfo.builder() - .name("컴퓨터공학부") - .curriculumLink("https://cse.koreatech.ac.kr/page_izgw21") - .build(); - DeptInfo deptInfo2 = DeptInfo.builder() - .name("기계공학부") - .curriculumLink("https://cms3.koreatech.ac.kr/me/795/subview.do") - .build(); - - deptInfoRepository.save(deptInfo1); - deptInfoRepository.save(deptInfo2); - - DeptNum deptNum1_1 = DeptNum.builder() - .deptInfo(deptInfo1) - .number(35L) - .build(); - DeptNum deptNum1_2 = DeptNum.builder() - .deptInfo(deptInfo1) - .number(36L) - .build(); - DeptNum deptNum2 = DeptNum.builder() - .deptInfo(deptInfo2) - .number(20L) - .build(); - - deptNumRepository.save(deptNum1_1); - deptNumRepository.save(deptNum1_2); - deptNumRepository.save(deptNum2); + final int DEPT_SIZE = Dept.values().length; //when then ExtractableResponse response = RestAssured @@ -117,14 +61,13 @@ void findAllDepts() { assertSoftly( softly -> { - softly.assertThat(response.body().jsonPath().getList(".").size()).isEqualTo(DEPT_SIZE); - softly.assertThat(response.body().jsonPath().getString("[0].name")).isEqualTo(deptInfo2.getName()); - softly.assertThat(response.body().jsonPath().getString("[1].name")).isEqualTo(deptInfo1.getName()); - softly.assertThat(response.body().jsonPath().getString("[0].curriculum_link")).isEqualTo(deptInfo2.getCurriculumLink()); - softly.assertThat(response.body().jsonPath().getString("[1].curriculum_link")).isEqualTo(deptInfo1.getCurriculumLink()); - softly.assertThat(response.body().jsonPath().getLong("[0].dept_nums[0]")).isEqualTo(deptInfo2.getDeptNums().get(0)); - softly.assertThat(response.body().jsonPath().getLong("[1].dept_nums[0]")).isEqualTo(deptInfo1.getDeptNums().get(0)); - softly.assertThat(response.body().jsonPath().getLong("[1].dept_nums[1]")).isEqualTo(deptInfo1.getDeptNums().get(1)); + softly.assertThat(response.body().jsonPath().getList(".").size()) + .isEqualTo(DEPT_SIZE); + for (int i = 0; i < DEPT_SIZE; i++) { + softly.assertThat(response.body().jsonPath().getString(String.format("[%d].name", i))).isNotEmpty(); + softly.assertThat(response.body().jsonPath().getString(String.format("[%d].curriculum_link", i))).isNotEmpty(); + softly.assertThat(response.body().jsonPath().getString(String.format("[%d].dept_nums[0]", i))).isNotEmpty(); + } } ); }