Skip to content

Commit 0f7e3ce

Browse files
authored
refactor: 기수 관리 추가 및 기존 기능과 연동
* feat: 기수관리를 위한 엔티티, 서비스, 레포지토리 생성 및 대응하는 에러코드 추가 (DASOMBE-16) * test: GenerationService의 테스트 코드 작성 (DASOMBE-16) * refactor: 모집일정에 기수를 의미하는 GENERATION 키 생성 (DASOMBE-16) * refactor: 모집일정의 조회, 수정 부분에 기수 반영 및 테스트코드에 반영하고 기수 조회, 수정 코드 하단에 추가 (DASOMBE-16) * refactor: 멤버 엔티티에 기수 추가 및 회원가입 시 GenerationService의 값을 읽어 자동으로 기수 기입하게 구현 및 테스트 코드에 반영 (DASOMBE-16) * feat: 기수 관리(조회,수정) 을 담당하는 AdminGenerationController 추가 (DASOMBE-16) * fix: ErrorCode 에 리베이스 중 누락된 EXECUTIVE_NOT_FOUND 추가 * refactor: 기수 시스템을 모집일정에 통합시키기 위해 Generation 관련 기능 삭제(DASOMBE-16) * refactor: 기수 시스템을 모집일정에 통합 && 코드 정리 및 통합 * refactor: 기수 시스템을 모집일정에 통합함에 따라 멤버의 기수 코드 수정 후 코드 정리 && 회원가입 시 선택적으로 기수를 입력받고 값이 없을경우, 현재 모집일정의 기수를 기입하게 수정 (DASOMBE-16)
1 parent 5cd02b2 commit 0f7e3ce

File tree

11 files changed

+140
-20
lines changed

11 files changed

+140
-20
lines changed

src/main/java/dmu/dasom/api/domain/common/exception/ErrorCode.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@ public enum ErrorCode {
3838
RECRUITMENT_NOT_ACTIVE(400, "C029", "모집 기간이 아닙니다."),
3939
NOT_FOUND_PARTICIPANT(400, "C030", "참가자를 찾을 수 없습니다."),
4040
EXECUTIVE_NOT_FOUND(400, "C031", "임원진을 찾을 수 없습니다."),
41-
;
41+
GENERATION_NOT_FOUND(400, "C032", "저장된 기수를 찾을 수 없습니다."),
42+
INVALID_GENERATION_FORMAT(400, "C033", "유효하지 않은 기수 형식입니다. (예: '1기')");
4243

4344
private final int status;
4445
private final String code;

src/main/java/dmu/dasom/api/domain/member/dto/SignupRequestDto.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,15 @@ public class SignupRequestDto {
2222
@Schema(description = "비밀번호", example = "password", minLength = 8, maxLength = 128)
2323
private String password;
2424

25-
public Member toEntity(final String password) {
25+
@Length(max = 4)
26+
@Schema(description = "기수 (선택)", example = "34기", nullable = true)
27+
private String generation;
28+
29+
public Member toEntity(final String password, final String generation) {
2630
return Member.builder()
2731
.email(this.email)
2832
.password(password)
33+
.generation(generation)
2934
.build();
3035
}
3136
}

src/main/java/dmu/dasom/api/domain/member/entity/Member.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,7 @@ public class Member extends BaseEntity {
3333
@Enumerated(EnumType.STRING)
3434
private Role role = Role.ROLE_MEMBER;
3535

36-
}
36+
// 기수 정보를 저장할 필드 추가
37+
@Column(name = "generation", length = 4, nullable = false)
38+
private String generation;
39+
}

src/main/java/dmu/dasom/api/domain/member/service/MemberServiceImpl.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import dmu.dasom.api.domain.common.exception.CustomException;
44
import dmu.dasom.api.domain.common.exception.ErrorCode;
5+
import dmu.dasom.api.domain.recruit.service.RecruitService;
56
import dmu.dasom.api.domain.member.dto.SignupRequestDto;
67
import dmu.dasom.api.domain.member.entity.Member;
78
import dmu.dasom.api.domain.member.repository.MemberRepository;
@@ -24,6 +25,7 @@ public class MemberServiceImpl implements MemberService {
2425

2526
private final BCryptPasswordEncoder encoder;
2627
private final MemberRepository memberRepository;
28+
private final RecruitService recruitService;
2729
private final JwtUtil jwtUtil;
2830

2931
// 이메일로 사용자 조회
@@ -45,9 +47,13 @@ public void signUp(final SignupRequestDto request) {
4547
// 이미 가입된 이메일인지 확인
4648
if (checkByEmail(request.getEmail()))
4749
throw new CustomException(ErrorCode.SIGNUP_FAILED);
50+
//기수는 선택적으로 가져오며, 없을 경우 신입 부붠 처리하여, 모집일정의 기수 사용
51+
String generation = (request.getGeneration() != null && !request.getGeneration().isEmpty())
52+
? request.getGeneration()
53+
: recruitService.getCurrentGeneration();
4854

49-
// 비밀번호 암호화 후 저장
50-
memberRepository.save(request.toEntity(encoder.encode(request.getPassword())));
55+
// 비밀번호 암호화 후 저장, 기수도 같이 기입
56+
memberRepository.save(request.toEntity(encoder.encode(request.getPassword()), generation));
5157
}
5258

5359
// 토큰 갱신

src/main/java/dmu/dasom/api/domain/recruit/entity/Recruit.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,19 @@ public void updateTime(final LocalTime time) {
3737
this.value = time.format(TIME_FORMATTER);
3838
}
3939

40+
41+
// 기수 업데이트
42+
public void updateGeneration(final String generation) {
43+
this.value = generation; // ex. "34기"
44+
}
45+
4046
public RecruitConfigResponseDto toResponse() {
47+
if(this.key == ConfigKey.GENERATION){
48+
return RecruitConfigResponseDto.builder()
49+
.key(key)
50+
.value(value)
51+
.build();
52+
}
4153
LocalDateTime dateTime = LocalDateTime.parse(this.value, DATE_TIME_FORMATTER);
4254
return RecruitConfigResponseDto.builder()
4355
.key(key)

src/main/java/dmu/dasom/api/domain/recruit/enums/ConfigKey.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ public enum ConfigKey {
1818
INTERVIEW_TIME_END, // 면접 종료 시간
1919

2020
// 2차 합격 발표일 (시간 포함)
21-
INTERVIEW_PASS_ANNOUNCEMENT // 2차 합격 발표일
21+
INTERVIEW_PASS_ANNOUNCEMENT, // 2차 합격 발표일
2222

23+
GENERATION //현재 모집중인 기수 정보
2324
}

src/main/java/dmu/dasom/api/domain/recruit/service/RecruitService.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ public interface RecruitService {
1515

1616
void modifyRecruitSchedule(final RecruitScheduleModifyRequestDto requestDto);
1717

18+
void modifyGeneration(String newGeneration);
19+
20+
String getCurrentGeneration();
21+
1822
String generateReservationCode(String studentNo, String contactLastDigits);
1923

2024
LocalDateTime getResultAnnouncementSchedule(ResultCheckType type);

src/main/java/dmu/dasom/api/domain/recruit/service/RecruitServiceImpl.java

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,13 @@ public class RecruitServiceImpl implements RecruitService {
2525

2626
private final RecruitRepository recruitRepository;
2727

28-
// 모집 일정 설정 조회
28+
// 모집 설정 조회
2929
@Override
3030
public List<RecruitConfigResponseDto> getRecruitSchedule() {
3131
return findAll().stream()
32-
.map(config -> config.getKey() == ConfigKey.INTERVIEW_TIME_START || config.getKey() == ConfigKey.INTERVIEW_TIME_END
33-
? config.toTimeResponse() : config.toResponse())
34-
.toList();
32+
.map(config -> config.getKey() == ConfigKey.INTERVIEW_TIME_START || config.getKey() == ConfigKey.INTERVIEW_TIME_END
33+
? config.toTimeResponse() : config.toResponse())
34+
.toList();
3535
}
3636

3737
// 모집 일정 설정 수정
@@ -50,6 +50,20 @@ public void modifyRecruitSchedule(final RecruitScheduleModifyRequestDto request)
5050
config.updateDateTime(dateTime);
5151
}
5252

53+
54+
//기수 수정
55+
@Override
56+
@Transactional
57+
public void modifyGeneration(String newGeneration) {
58+
final Recruit config = findByKey(ConfigKey.GENERATION);
59+
config.updateGeneration(newGeneration);
60+
}
61+
// 기수 조회
62+
@Override
63+
public String getCurrentGeneration() {
64+
Recruit generationConfig = findByKey(ConfigKey.GENERATION);
65+
return generationConfig.getValue();
66+
}
5367
// 모집 기간 여부 확인
5468
@Override
5569
public boolean isRecruitmentActive() {

src/main/java/dmu/dasom/api/global/admin/controller/AdminRecruitController.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,19 @@ public ResponseEntity<Void> modifyRecruitSchedule(@Valid @RequestBody final Recr
5757
.build();
5858
}
5959

60+
@Operation(summary = "모집 기수 변경")
61+
@ApiResponses(value = {
62+
@ApiResponse(responseCode = "200", description = "모집 기수 수정 성공"),
63+
@ApiResponse(responseCode = "400", description = "잘못된 요청")
64+
})
65+
@PatchMapping("/generation")
66+
public ResponseEntity<Void> modifyGeneration(@Valid @RequestBody String request) {
67+
recruitService.modifyGeneration(request);
68+
return ResponseEntity.ok()
69+
.build();
70+
}
71+
72+
6073
@Operation(summary = "면접 일정 생성", description = "새로운 면접 일정을 생성합니다.")
6174
@ApiResponses(value = {
6275
@ApiResponse(responseCode = "200", description = "면접 일정 생성 성공"),

src/test/java/dmu/dasom/api/domain/member/MemberServiceTest.java

Lines changed: 40 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,15 @@
66
import dmu.dasom.api.domain.member.entity.Member;
77
import dmu.dasom.api.domain.member.repository.MemberRepository;
88
import dmu.dasom.api.domain.member.service.MemberServiceImpl;
9+
import dmu.dasom.api.domain.recruit.service.RecruitService;
910
import org.junit.jupiter.api.DisplayName;
1011
import org.junit.jupiter.api.Test;
1112
import org.junit.jupiter.api.extension.ExtendWith;
1213
import org.mockito.InjectMocks;
1314
import org.mockito.Mock;
1415
import org.mockito.junit.jupiter.MockitoExtension;
1516
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
17+
import org.springframework.test.util.ReflectionTestUtils;
1618

1719
import java.util.Optional;
1820

@@ -28,6 +30,9 @@ class MemberServiceTest {
2830
@Mock
2931
MemberRepository memberRepository;
3032

33+
@Mock
34+
RecruitService recruitService; // RecruitService 주입
35+
3136
@InjectMocks
3237
private MemberServiceImpl memberService;
3338

@@ -92,23 +97,49 @@ void checkByEmail_false() {
9297
assertFalse(result);
9398
}
9499

100+
95101
@Test
96-
@DisplayName("회원가입 - 성공")
97-
void signUp_success() {
98-
// given
99-
SignupRequestDto request = mock(SignupRequestDto.class);
100-
when(request.getEmail()).thenReturn("[email protected]");
101-
when(request.getPassword()).thenReturn("password");
102+
@DisplayName("회원가입 - 기수 선택값 전달 시 사용")
103+
void signUp_withGenerationProvided() {
104+
// 실제 DTO 객체 사용
105+
SignupRequestDto request = new SignupRequestDto();
106+
// Reflection 또는 생성자/Setter로 값 설정
107+
ReflectionTestUtils.setField(request, "email", "[email protected]");
108+
ReflectionTestUtils.setField(request, "password", "password");
109+
ReflectionTestUtils.setField(request, "generation", "35기");
110+
102111
when(encoder.encode("password")).thenReturn("encodedPassword");
103112
when(memberRepository.existsByEmail("[email protected]")).thenReturn(false);
104113

105-
// when
106114
memberService.signUp(request);
107115

108-
// then
109-
verify(memberRepository, times(1)).save(any());
116+
verify(memberRepository, times(1)).save(argThat(member ->
117+
"35기".equals(member.getGeneration())
118+
));
119+
verify(recruitService, never()).getCurrentGeneration();
110120
}
111121

122+
@Test
123+
@DisplayName("회원가입 - 기수 선택값 없으면 기본값 사용")
124+
void signUp_withGenerationDefault() {
125+
SignupRequestDto request = new SignupRequestDto();
126+
ReflectionTestUtils.setField(request, "email", "[email protected]");
127+
ReflectionTestUtils.setField(request, "password", "password");
128+
ReflectionTestUtils.setField(request, "generation", null);
129+
130+
when(encoder.encode("password")).thenReturn("encodedPassword");
131+
when(memberRepository.existsByEmail("[email protected]")).thenReturn(false);
132+
when(recruitService.getCurrentGeneration()).thenReturn("34기");
133+
134+
memberService.signUp(request);
135+
136+
verify(memberRepository, times(1)).save(argThat(member ->
137+
"34기".equals(member.getGeneration())
138+
));
139+
verify(recruitService, times(1)).getCurrentGeneration();
140+
}
141+
142+
112143
@Test
113144
@DisplayName("회원가입 - 실패")
114145
void signUp_fail() {

0 commit comments

Comments
 (0)