Skip to content

Commit b362131

Browse files
committed
[EA3-168] feature: 스터디 신청 생성, 거절, 승인 테스트 작성
1 parent f27c120 commit b362131

File tree

4 files changed

+201
-2
lines changed

4 files changed

+201
-2
lines changed

src/main/java/grep/neogul_coder/domain/studyapplication/exception/code/ApplicationErrorCode.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ public enum ApplicationErrorCode implements ErrorCode {
99
APPLICATION_NOT_FOUND("SA001",HttpStatus.NOT_FOUND,"신청서를 찾을 수 없습니다."),
1010

1111
ALREADY_APPLICATION("SA002", HttpStatus.BAD_REQUEST, "이미 지원한 모집글입니다."),
12-
ALREADY_APPLYING("SA003", HttpStatus.BAD_REQUEST, "신청 상태가 APPLYING이 아닙니다."),
12+
APPLICATION_NOT_APPLYING("SA003", HttpStatus.BAD_REQUEST, "신청 상태가 APPLYING이 아닙니다."),
1313

1414
LEADER_CANNOT_APPLY("SA004", HttpStatus.BAD_REQUEST, "스터디장은 스터디를 신청할 수 없습니다."),
1515
LEADER_ONLY_APPROVED("SA005", HttpStatus.BAD_REQUEST, "스터디장만 승인이 가능합니다."),

src/main/java/grep/neogul_coder/domain/studyapplication/repository/ApplicationRepository.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,12 @@
44
import org.springframework.data.jpa.repository.JpaRepository;
55

66
import java.util.List;
7+
import java.util.Optional;
78

89
public interface ApplicationRepository extends JpaRepository<StudyApplication, Long> {
910
List<StudyApplication> findByRecruitmentPostId(Long recruitmentPostId);
1011

1112
boolean existsByRecruitmentPostIdAndUserId(Long recruitmentPostId, Long userId);
13+
14+
Optional<StudyApplication> findByIdAndActivatedTrue(Long applicationId);
1215
}

src/main/java/grep/neogul_coder/domain/studyapplication/service/ApplicationService.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ private void validateNotAlreadyApplied(Long recruitmentPostId, Long userId) {
115115

116116
private static void validateStatusIsApplying(StudyApplication application) {
117117
if (application.getStatus() != ApplicationStatus.APPLYING) {
118-
throw new BusinessException(ALREADY_APPLYING);
118+
throw new BusinessException(APPLICATION_NOT_APPLYING);
119119
}
120120
}
121121

Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
package grep.neogul_coder.domain.studyapplication.service;
2+
3+
import grep.neogul_coder.domain.IntegrationTestSupport;
4+
import grep.neogul_coder.domain.recruitment.post.RecruitmentPost;
5+
import grep.neogul_coder.domain.recruitment.post.repository.RecruitmentPostRepository;
6+
import grep.neogul_coder.domain.study.Study;
7+
import grep.neogul_coder.domain.study.StudyMember;
8+
import grep.neogul_coder.domain.study.repository.StudyMemberRepository;
9+
import grep.neogul_coder.domain.study.repository.StudyRepository;
10+
import grep.neogul_coder.domain.studyapplication.StudyApplication;
11+
import grep.neogul_coder.domain.studyapplication.controller.dto.request.ApplicationCreateRequest;
12+
import grep.neogul_coder.domain.studyapplication.repository.ApplicationRepository;
13+
import grep.neogul_coder.domain.users.entity.User;
14+
import grep.neogul_coder.domain.users.repository.UserRepository;
15+
import grep.neogul_coder.global.exception.business.BusinessException;
16+
import jakarta.persistence.EntityManager;
17+
import org.junit.jupiter.api.BeforeEach;
18+
import org.junit.jupiter.api.DisplayName;
19+
import org.junit.jupiter.api.Test;
20+
import org.springframework.beans.factory.annotation.Autowired;
21+
22+
import java.time.LocalDateTime;
23+
import java.util.List;
24+
25+
import static grep.neogul_coder.domain.study.enums.StudyMemberRole.LEADER;
26+
import static grep.neogul_coder.domain.study.enums.StudyMemberRole.MEMBER;
27+
import static grep.neogul_coder.domain.studyapplication.ApplicationStatus.*;
28+
import static grep.neogul_coder.domain.studyapplication.exception.code.ApplicationErrorCode.APPLICATION_NOT_APPLYING;
29+
import static org.assertj.core.api.Assertions.assertThat;
30+
import static org.assertj.core.api.Assertions.assertThatThrownBy;
31+
32+
class ApplicationServiceTest extends IntegrationTestSupport {
33+
34+
@Autowired
35+
private EntityManager em;
36+
37+
@Autowired
38+
private UserRepository userRepository;
39+
40+
@Autowired
41+
private StudyRepository studyRepository;
42+
43+
@Autowired
44+
private StudyMemberRepository studyMemberRepository;
45+
46+
@Autowired
47+
private RecruitmentPostRepository recruitmentPostRepository;
48+
49+
@Autowired
50+
private ApplicationService applicationService;
51+
52+
@Autowired
53+
private ApplicationRepository applicationRepository;
54+
55+
private Long userId1;
56+
private Long userId2;
57+
private Long studyId;
58+
private Long recruitmentPostId;
59+
60+
@BeforeEach
61+
void init() {
62+
User user1 = createUser("test1");
63+
User user2 = createUser("test2");
64+
userRepository.saveAll(List.of(user1, user2));
65+
userId1 = user1.getId();
66+
userId2 = user2.getId();
67+
68+
Study study = createStudy("스터디", LocalDateTime.parse("2025-07-25T20:20:20"), LocalDateTime.parse("2025-07-28T20:20:20"));
69+
studyRepository.save(study);
70+
studyId = study.getId();
71+
72+
StudyMember studyLeader = createStudyLeader(study, userId1);
73+
StudyMember studyMember = createStudyMember(study, userId2);
74+
studyMemberRepository.saveAll(List.of(studyLeader, studyMember));
75+
76+
RecruitmentPost recruitmentPost = createRecruitmentPost(studyId, userId1, "제목", "내용", 1);
77+
recruitmentPostRepository.save(recruitmentPost);
78+
recruitmentPostId = recruitmentPost.getId();
79+
}
80+
81+
@DisplayName("신청서를 생성합니다.")
82+
@Test
83+
void createApplication() {
84+
// given
85+
ApplicationCreateRequest request = ApplicationCreateRequest.builder()
86+
.applicationReason("자바를 더 공부하고 싶어 지원합니다.")
87+
.build();
88+
89+
// when
90+
Long id = applicationService.createApplication(recruitmentPostId, request, userId2);
91+
em.flush();
92+
em.clear();
93+
94+
// then
95+
StudyApplication application = applicationRepository.findByIdAndActivatedTrue(id).orElseThrow();
96+
assertThat(application.getApplicationReason()).isEqualTo("자바를 더 공부하고 싶어 지원합니다.");
97+
}
98+
99+
@DisplayName("스터디장이 신청서를 승인합니다.")
100+
@Test
101+
void approveApplication() {
102+
// given
103+
StudyApplication application = createApplication(recruitmentPostId, userId2);
104+
applicationRepository.save(application);
105+
Long id = application.getId();
106+
107+
// when
108+
applicationService.approveApplication(id, userId1);
109+
em.flush();
110+
em.clear();
111+
112+
// then
113+
assertThat(application.getStatus()).isEqualTo(APPROVED);
114+
}
115+
116+
@DisplayName("스터디장이 신청서를 거절합니다.")
117+
@Test
118+
void rejectApplication() {
119+
// given
120+
StudyApplication application = createApplication(recruitmentPostId, userId2);
121+
applicationRepository.save(application);
122+
Long id = application.getId();
123+
124+
// when
125+
applicationService.rejectApplication(id, userId1);
126+
em.flush();
127+
em.clear();
128+
129+
// then
130+
assertThat(application.getStatus()).isEqualTo(REJECTED);
131+
}
132+
133+
@DisplayName("스터디장이 이미 승인이나 거절한 경우 신청서 거절 시 예외가 발생합니다.")
134+
@Test
135+
void rejectApplicationFail() {
136+
// given
137+
StudyApplication application = createApplication(recruitmentPostId, userId2);
138+
applicationRepository.save(application);
139+
Long id = application.getId();
140+
applicationService.rejectApplication(id, userId1);
141+
142+
// when then
143+
assertThatThrownBy(() ->
144+
applicationService.rejectApplication(id, userId1))
145+
.isInstanceOf(BusinessException.class).hasMessage(APPLICATION_NOT_APPLYING.getMessage());
146+
}
147+
148+
private static User createUser(String nickname) {
149+
return User.builder()
150+
.nickname(nickname)
151+
.build();
152+
}
153+
154+
private static Study createStudy(String name, LocalDateTime startDate, LocalDateTime endDate) {
155+
return Study.builder()
156+
.name(name)
157+
.startDate(startDate)
158+
.endDate(endDate)
159+
.build();
160+
}
161+
162+
private StudyMember createStudyLeader(Study study, Long userId) {
163+
return StudyMember.builder()
164+
.study(study)
165+
.userId(userId)
166+
.role(LEADER)
167+
.build();
168+
}
169+
170+
private StudyMember createStudyMember(Study study, Long userId) {
171+
return StudyMember.builder()
172+
.study(study)
173+
.userId(userId)
174+
.role(MEMBER)
175+
.build();
176+
}
177+
178+
private RecruitmentPost createRecruitmentPost(Long studyId ,Long userId, String subject, String content, int count) {
179+
return RecruitmentPost.builder()
180+
.subject(subject)
181+
.content(content)
182+
.recruitmentCount(count)
183+
.studyId(studyId)
184+
.userId(userId)
185+
.build();
186+
}
187+
188+
private StudyApplication createApplication(Long recruitmentPostId, Long userId) {
189+
return StudyApplication.builder()
190+
.recruitmentPostId(recruitmentPostId)
191+
.userId(userId)
192+
.applicationReason("자바를 더 공부하고 싶어 지원합니다.")
193+
.status(APPLYING)
194+
.build();
195+
}
196+
}

0 commit comments

Comments
 (0)