Skip to content

Commit c570c24

Browse files
authored
지원서 테스트 코드 추가 및 오류 수정 (#158)
* Feat: 테스트용 지원서 생성 시 이름도 함께 생성 * Test: 멤버 테스트 공통 메서드 추출을 위한 클래스 작성 * Test: 누락된 teardown 추가 * Refac: import문 최적화 * Test: 누락된 필드 추가 * Fix: 누락된 연관 관계 매핑 추가 * Test: 지원서 서비스 테스트 작성 * Test: 답변, 만료된 기수 테스트용 생성 메서드 추가 * Refac: 에러코드 이름을 좀 더 알맞게 변경 * Test: 테스트 지원서 생성 시 빈 답변을 포함하게 변경 * Test: 지원서 도메인 테스트 작성 * Test: ApplicationTestEntityFactory 메서드 적용 * Refac: 변경된 에러코드 적용 * Fix: ApplicationAnswer 오류 에러코드 추가, 그에 맞게 고유 에러 코드 변경 * Test: 테스트 코드 동기화 * Merge branch 'dev' into feat/issue-#152 * Refac: membertest와 커플링 제거 * Refac: 코드 스타일 통일 * Refac: application에 member, classyear 연관관계 설정을 메서드로 단순화 * Refac: 반환값 가독성 개선 * Refac: applicationtest - membertest 커플링 제거 * Refac: camelCase로 올바르게 수정 * Refac: saveApplication then 비교 필드를 가독성 있게 수정 * Refac: application - classyear 연관관계 설정 메서드로 단순화 * Rename: ApplicationTestEntityFactory -> ApplicationTestFactory (사용 예에 맞게 포괄적으로 변경)
1 parent cc080ea commit c570c24

File tree

15 files changed

+533
-126
lines changed

15 files changed

+533
-126
lines changed

src/main/java/com/gdsc_knu/official_homepage/entity/application/Application.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ public Application(Member member, ApplicationModel applicationModel) {
8383
.map(answers -> ApplicationAnswer.builder()
8484
.questionNumber(answers.getQuestionNumber())
8585
.answer(answers.getAnswer())
86+
.application(this)
8687
.build()).toList();
8788
this.submittedAt = LocalDateTime.now();
8889
}
@@ -108,7 +109,7 @@ private void updateNewAnswers(List<ApplicationAnswerDTO> newAnswersDTO) {
108109
.collect(Collectors.toMap(ApplicationAnswer::getQuestionNumber, answer -> answer));
109110
int answerSize = oldAnswers.size();
110111
if (answerSize != newAnswers.size()) {
111-
throw new IllegalArgumentException("지원서의 질문 응답 개수가 일치하지 않습니다.");
112+
throw new CustomException(ErrorCode.APPLICATION_ANSWER_UNMATCHED);
112113
}
113114
for (int i = 0; i < answerSize; i++) {
114115
if (!oldAnswers.get(i).getAnswer().equals(newAnswers.get(i))) {

src/main/java/com/gdsc_knu/official_homepage/exception/ErrorCode.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,15 @@ public enum ErrorCode {
2626

2727
// Application
2828
APPLICATION_NOT_FOUND(404,HttpStatus.NOT_FOUND, "지원서를 찾을 수 없습니다","A404"),
29-
APPLICATION_DUPLICATED(409, HttpStatus.CONFLICT, "이미 작성 중이거나 최종 제출한 지원서가 존재합니다.","A409"),
29+
APPLICATION_CONFLICT(409, HttpStatus.CONFLICT, "이미 작성 중이거나 최종 제출한 지원서가 존재합니다.","A409"),
3030
INVALID_APPLICATION_STATE(400, HttpStatus.BAD_REQUEST,"지원서 상태가 유효하지 않습니다.","A400"),
31-
APPLICATION_DEADLINE_EXPIRED(400, HttpStatus.BAD_REQUEST,"지원 기간이 만료되었습니다.","AA400"),
31+
APPLICATION_DEADLINE_EXPIRED(400, HttpStatus.BAD_REQUEST,"지원 기간이 만료되었습니다.","AD400"),
3232
CLASS_YEAR_NOT_FOUND(404, HttpStatus.NOT_FOUND,"존재하지 않는 기수입니다.","AC404"),
3333
INVALID_CLASS_YEAR(400, HttpStatus.BAD_REQUEST,"기수 정보 설정이 잘못 되었습니다.","AC400"),
3434
CLASS_YEAR_DUPLICATED(409, HttpStatus.CONFLICT,"이미 존재하는 기수 이름입니다.","AC409"),
3535
APPLICATION_FORBIDDEN(403, HttpStatus.FORBIDDEN, "지원서에 접근할 수 있는 권한이 없습니다.","A403"),
3636
CONCURRENT_FAILED(409, HttpStatus.CONFLICT, "다른 사용자가 수정중입니다.","AN409"),
37+
APPLICATION_ANSWER_UNMATCHED(400, HttpStatus.BAD_REQUEST, "답변 개수가 일치하지 않습니다.","AA400"),
3738
// Team
3839

3940

src/main/java/com/gdsc_knu/official_homepage/service/application/ApplicationServiceImpl.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ public Long saveApplication(String email, ApplicationRequest applicationRequest)
5959
Member member = validateMember(email);
6060
applicationRepository.findByNameAndStudentNumberAndClassYearId(member.getName(), member.getStudentNumber(), applicationRequest.getClassYearId())
6161
.ifPresent(application -> {
62-
throw new CustomException(ErrorCode.APPLICATION_DUPLICATED);
62+
throw new CustomException(ErrorCode.APPLICATION_CONFLICT);
6363
});
6464
member.updateTrack(applicationRequest.getTrack());
6565
Application application = new Application(member, new ApplicationModel(applicationRequest));
@@ -122,7 +122,7 @@ private Application validateApplicationAccess(String name, String studentNumber,
122122
Application application = applicationRepository.findByNameAndStudentNumberAndClassYearId(name, studentNumber, classYearId)
123123
.orElseThrow(() -> new CustomException(ErrorCode.APPLICATION_NOT_FOUND));
124124
if (!application.getApplicationStatus().equals(ApplicationStatus.TEMPORAL)) {
125-
throw new CustomException(ErrorCode.APPLICATION_DUPLICATED);
125+
throw new CustomException(ErrorCode.APPLICATION_CONFLICT);
126126
}
127127
return application;
128128
}

src/test/java/com/gdsc_knu/official_homepage/application/ApplicationTestEntityFactory.java

-61
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
package com.gdsc_knu.official_homepage.application;
2+
3+
import com.gdsc_knu.official_homepage.dto.application.ApplicationAnswerDTO;
4+
import com.gdsc_knu.official_homepage.dto.application.ApplicationModel;
5+
import com.gdsc_knu.official_homepage.dto.application.ApplicationRequest;
6+
import com.gdsc_knu.official_homepage.entity.ClassYear;
7+
import com.gdsc_knu.official_homepage.entity.Member;
8+
import com.gdsc_knu.official_homepage.entity.application.Application;
9+
import com.gdsc_knu.official_homepage.entity.enumeration.ApplicationStatus;
10+
import com.gdsc_knu.official_homepage.entity.enumeration.Role;
11+
import com.gdsc_knu.official_homepage.entity.enumeration.Track;
12+
13+
import java.time.LocalDateTime;
14+
import java.util.ArrayList;
15+
import java.util.List;
16+
17+
public class ApplicationTestFactory {
18+
public static ClassYear createClassYear(Long id) {
19+
LocalDateTime now = LocalDateTime.now();
20+
return ClassYear.builder()
21+
.id(id)
22+
.name(String.format("test%s기", id))
23+
.applicationStartDateTime(now)
24+
.applicationEndDateTime(now.plusDays(1))
25+
.build();
26+
}
27+
28+
public static ClassYear createExpiredClassYear(Long id) {
29+
LocalDateTime now = LocalDateTime.now();
30+
return ClassYear.builder()
31+
.id(id)
32+
.name(String.format("test%s기", id))
33+
.applicationStartDateTime(now.minusDays(2))
34+
.applicationEndDateTime(now.minusDays(1))
35+
.build();
36+
}
37+
38+
public static Application createApplication(Long id, Track track, ApplicationStatus status) {
39+
return Application.builder()
40+
.id(id)
41+
.email(String.format("test%[email protected]", id))
42+
.studentNumber(String.valueOf(id))
43+
.phoneNumber(String.format("010-0000-%s", id))
44+
.applicationStatus(status)
45+
.track(track)
46+
.build();
47+
}
48+
49+
public static Application createApplication(Long id, Track track, ApplicationStatus status,
50+
ClassYear classYear, Member member) {
51+
return Application.builder()
52+
.id(id)
53+
.email(member.getEmail())
54+
.name(member.getName())
55+
.studentNumber(member.getStudentNumber())
56+
.phoneNumber(member.getPhoneNumber())
57+
.major(member.getMajor())
58+
.techStack("Java")
59+
.links("https://github.com")
60+
.submittedAt(LocalDateTime.now())
61+
.applicationStatus(status)
62+
.track(track)
63+
.answers(new ArrayList<>())
64+
.classYear(classYear)
65+
.build();
66+
}
67+
68+
public static Application createApplication(Long id, Track track, ApplicationStatus status,
69+
ClassYear classYear) {
70+
return Application.builder()
71+
.id(id)
72+
.email(String.format("test%[email protected]", id))
73+
.name(String.format("test%s", id))
74+
.studentNumber(String.valueOf(id))
75+
.phoneNumber(String.format("010-0000-%s", id))
76+
.major(String.format("컴퓨터학부-%s", id))
77+
.techStack("Java")
78+
.links("https://github.com")
79+
.submittedAt(LocalDateTime.now())
80+
.applicationStatus(status)
81+
.track(track)
82+
.answers(new ArrayList<>())
83+
.classYear(classYear)
84+
.build();
85+
}
86+
87+
public static List<Application> createApplicationList(int startNum, int count, Track track, ApplicationStatus status){
88+
List<Application> applicationList = new ArrayList<>();
89+
for (int i=startNum; i<count; i++) {
90+
applicationList.add(createApplication((long) i, track, status));
91+
}
92+
return applicationList;
93+
}
94+
95+
public static List<ClassYear> createClassYearList(int startNum, int count) {
96+
List<ClassYear> classYearList = new ArrayList<>();
97+
for (int i=startNum; i<count; i++) {
98+
classYearList.add(createClassYear((long) i));
99+
}
100+
return classYearList;
101+
}
102+
103+
public static void setClassYear(List<Application> applications, List<ClassYear> classYears) {
104+
for (int i = 0; i < applications.size(); i++) {
105+
int classYearIdx = i % classYears.size();
106+
applications.get(i).updateClassYear(classYears.get(classYearIdx));
107+
}
108+
}
109+
110+
public static void setClassYear(List<Application> applications, ClassYear classYear) {
111+
for (int i = 0; i < applications.size(); i++) {
112+
applications.get(i).updateClassYear(classYear);
113+
}
114+
}
115+
116+
public static ApplicationRequest createApplicationRequest(Long classYearId) {
117+
return ApplicationRequest.builder()
118+
.classYearId(classYearId)
119+
.techStack("Java")
120+
.links("https://github.com")
121+
.track(Track.BACK_END)
122+
.answers(new ArrayList<>())
123+
.applicationStatus(ApplicationStatus.TEMPORAL)
124+
.build();
125+
}
126+
127+
public static ApplicationModel createApplicationModel() {
128+
return ApplicationModel.builder()
129+
.techStack("Java")
130+
.links("https://github.com")
131+
.track(Track.BACK_END)
132+
.answers(new ArrayList<>())
133+
.applicationStatus(ApplicationStatus.TEMPORAL)
134+
.build();
135+
}
136+
137+
public static ApplicationModel createApplicationModel(List<ApplicationAnswerDTO> answerList) {
138+
return ApplicationModel.builder()
139+
.techStack("Java")
140+
.links("https://github.com")
141+
.track(Track.BACK_END)
142+
.answers(answerList)
143+
.applicationStatus(ApplicationStatus.TEMPORAL)
144+
.build();
145+
}
146+
147+
public static ApplicationAnswerDTO createApplicationAnswerDTO(int questionNumber, String answer) {
148+
return ApplicationAnswerDTO.builder()
149+
.questionNumber(questionNumber)
150+
.answer(answer)
151+
.build();
152+
}
153+
154+
public static List<ApplicationAnswerDTO> createApplicationAnswerDTOList(int count, String defaultAnswer) {
155+
List<ApplicationAnswerDTO> answerList = new ArrayList<>();
156+
for (int i=0; i<count; i++) {
157+
answerList.add(createApplicationAnswerDTO(i, defaultAnswer+i));
158+
}
159+
return answerList;
160+
}
161+
162+
public static Member createMember(Long id) {
163+
return Member.builder()
164+
.id(id)
165+
.email(String.format("test%[email protected]", id))
166+
.name(String.format("test%s", id))
167+
.age((int) (20 + id % 5))
168+
.major(String.format("컴퓨터학부-%s", id))
169+
.studentNumber(String.format("2024%06d", id))
170+
.track(Track.UNDEFINED)
171+
.role(Role.ROLE_TEMP)
172+
.phoneNumber(String.format("010-0000-%04d", id))
173+
.profileUrl(String.format("www.test%s.com", id))
174+
.build();
175+
}
176+
}

src/test/java/com/gdsc_knu/official_homepage/application/domain/ApplicationTest.java

+21-1
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
package com.gdsc_knu.official_homepage.application.domain;
22

3+
import com.gdsc_knu.official_homepage.dto.application.ApplicationAnswerDTO;
4+
import com.gdsc_knu.official_homepage.entity.Member;
35
import com.gdsc_knu.official_homepage.entity.application.Application;
46
import com.gdsc_knu.official_homepage.entity.enumeration.ApplicationStatus;
57
import com.gdsc_knu.official_homepage.entity.enumeration.Track;
68
import org.junit.jupiter.api.DisplayName;
79
import org.junit.jupiter.api.Test;
810

9-
import static com.gdsc_knu.official_homepage.application.ApplicationTestEntityFactory.createApplication;
11+
import java.util.List;
12+
13+
import static com.gdsc_knu.official_homepage.application.ApplicationTestFactory.*;
1014
import static org.assertj.core.api.Assertions.assertThat;
1115

1216
public class ApplicationTest {
@@ -32,4 +36,20 @@ void failedUpdateTemporal() {
3236
// then
3337
assertThat(application.getApplicationStatus()).isEqualTo(ApplicationStatus.TEMPORAL);
3438
}
39+
40+
@Test
41+
@DisplayName("지원서 엔티티 생성 시 applicationAnswer와 연관관계 매핑이 된다.")
42+
void createApplicationAndAnswerRelationship() {
43+
// given
44+
int answerCount = 2;
45+
Member member = createMember(1L);
46+
List<ApplicationAnswerDTO> answerList = createApplicationAnswerDTOList(answerCount, "답변");
47+
// when
48+
Application application = new Application(member, createApplicationModel(answerList));
49+
// then
50+
assertThat(application.getAnswers()).hasSize(2);
51+
for (int i = 0; i < answerCount; i++) {
52+
assertThat(application.getAnswers().get(i).getApplication()).isEqualTo(application);
53+
}
54+
}
3555
}

src/test/java/com/gdsc_knu/official_homepage/application/repository/AdminApplicationRepositoryTest.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,10 @@
2424
import java.util.stream.Collectors;
2525
import java.util.stream.Stream;
2626

27-
import static com.gdsc_knu.official_homepage.application.ApplicationTestEntityFactory.*;
27+
import static com.gdsc_knu.official_homepage.application.ApplicationTestFactory.*;
2828
import static com.gdsc_knu.official_homepage.entity.enumeration.ApplicationStatus.*;
29-
import static com.gdsc_knu.official_homepage.entity.enumeration.Track.*;
29+
import static com.gdsc_knu.official_homepage.entity.enumeration.Track.AI;
30+
import static com.gdsc_knu.official_homepage.entity.enumeration.Track.BACK_END;
3031
import static org.assertj.core.api.Assertions.assertThat;
3132
import static org.junit.jupiter.api.Assertions.assertAll;
3233

src/test/java/com/gdsc_knu/official_homepage/application/service/AdminApplicationServiceTest.java

+5-7
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,11 @@
2727
import java.util.concurrent.Executors;
2828
import java.util.stream.Stream;
2929

30-
import static com.gdsc_knu.official_homepage.application.ApplicationTestEntityFactory.*;
31-
import static com.gdsc_knu.official_homepage.application.ApplicationTestEntityFactory.setClassYear;
30+
import static com.gdsc_knu.official_homepage.application.ApplicationTestFactory.*;
3231
import static org.assertj.core.api.Assertions.assertThat;
3332
import static org.junit.jupiter.api.Assertions.assertThrows;
34-
import static org.mockito.Mockito.*;
33+
import static org.mockito.ArgumentMatchers.any;
34+
import static org.mockito.Mockito.doThrow;
3535

3636

3737
@SpringBootTest
@@ -56,10 +56,9 @@ void tearDown() {
5656
@DisplayName("메일 전송에 실패하더라도 status 변경은 저장한다.(SAVED -> APPROVED)")
5757
void updateStatus() {
5858
// given
59-
Application application = createApplication(null, Track.AI, ApplicationStatus.SAVED);
6059
ClassYear classYear = createClassYear(1L);
6160
classYearRepository.save(classYear);
62-
application.updateClassYear(classYear);
61+
Application application = createApplication(null, Track.AI, ApplicationStatus.SAVED, classYear);
6362
applicationRepository.save(application);
6463
doThrow(CustomException.class).when(mailService).sendEach(any());
6564
// when
@@ -126,10 +125,9 @@ void updateNoteFailed() {
126125
@Test
127126
@DisplayName("동시에 지원서를 수정하는 경우 처음 시도만 남고 오류를 반환한다.")
128127
void updateNoteConcurrentFailed() throws InterruptedException {
129-
Application application = createApplication(1L, Track.AI, ApplicationStatus.SAVED);
130128
ClassYear classYear = createClassYear(1L);
131129
classYearRepository.save(classYear);
132-
application.updateClassYear(classYear);
130+
Application application = createApplication(1L, Track.AI, ApplicationStatus.SAVED, classYear);
133131
applicationRepository.saveAndFlush(application);
134132

135133
int threadCount = 2;

0 commit comments

Comments
 (0)