From 4a87dc911cb72f9297b31fd03352b4601482d265 Mon Sep 17 00:00:00 2001 From: jongmee Date: Mon, 26 Aug 2024 22:20:50 +0900 Subject: [PATCH] =?UTF-8?q?fix:=20=EB=8F=99=EC=95=84=EB=A6=AC=20=EA=B4=80?= =?UTF-8?q?=EB=A6=AC=EC=9E=90=EA=B0=80=20=EC=A7=80=EC=9B=90=EC=84=9C=20?= =?UTF-8?q?=EC=83=81=EC=84=B8=20=EC=A0=95=EB=B3=B4=20=EC=A1=B0=ED=9A=8C?= =?UTF-8?q?=ED=95=98=EB=8A=94=20=EA=B8=B0=EB=8A=A5=20=EA=B6=8C=ED=95=9C=20?= =?UTF-8?q?=EA=B4=80=EB=A0=A8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../application/ApplicationService.java | 11 ++--- .../crews/applicant/domain/Application.java | 7 +-- .../presentation/ApplicationController.java | 8 ++-- .../repository/ApplicationRepository.java | 8 ++++ .../crews/recruitment/domain/Recruitment.java | 4 ++ .../crews/api/ApplicationApiDocuments.java | 4 +- .../server/crews/api/ApplicationApiTest.java | 4 +- .../application/ApplicationServiceTest.java | 47 +------------------ 8 files changed, 28 insertions(+), 65 deletions(-) diff --git a/src/main/java/com/server/crews/applicant/application/ApplicationService.java b/src/main/java/com/server/crews/applicant/application/ApplicationService.java index 569de1e8..1e28a2a8 100644 --- a/src/main/java/com/server/crews/applicant/application/ApplicationService.java +++ b/src/main/java/com/server/crews/applicant/application/ApplicationService.java @@ -17,7 +17,6 @@ import com.server.crews.applicant.repository.NarrativeAnswerRepository; import com.server.crews.applicant.repository.SelectiveAnswerRepository; import com.server.crews.auth.domain.Applicant; -import com.server.crews.auth.dto.LoginUser; import com.server.crews.auth.repository.ApplicantRepository; import com.server.crews.global.exception.CrewsException; import com.server.crews.global.exception.ErrorCode; @@ -143,18 +142,18 @@ public List findAllApplicationsByRecruitment(Long publishe .toList(); } - public ApplicationDetailsResponse findApplicationDetails(Long applicationId, LoginUser loginUser) { - Application application = applicationRepository.findById(applicationId) + public ApplicationDetailsResponse findApplicationDetails(Long applicationId, Long publisherId) { + Application application = applicationRepository.findByIdWithRecruitmentAndPublisher(applicationId) .orElseThrow(() -> new CrewsException(ErrorCode.APPLICATION_NOT_FOUND)); - checkPermission(application, loginUser); + checkPermission(application, publisherId); List narrativeAnswers = narrativeAnswerRepository.findAllByApplication(application); Map> selectiveAnswers = collectSelectiveAnswersByQuestion( selectiveAnswerRepository.findAllByApplication(application)); return ApplicationDetailsResponse.of(application, narrativeAnswers, selectiveAnswers); } - private void checkPermission(Application application, LoginUser loginUser) { - if (!application.canBeAccessedBy(loginUser.userId(), loginUser.role())) { + private void checkPermission(Application application, Long publisherId) { + if (!application.canBeAccessedBy(publisherId)) { throw new CrewsException(ErrorCode.UNAUTHORIZED_USER); } } diff --git a/src/main/java/com/server/crews/applicant/domain/Application.java b/src/main/java/com/server/crews/applicant/domain/Application.java index c50471eb..7eb62788 100644 --- a/src/main/java/com/server/crews/applicant/domain/Application.java +++ b/src/main/java/com/server/crews/applicant/domain/Application.java @@ -99,10 +99,7 @@ public boolean isNotDetermined() { return outcome.equals(Outcome.PENDING); } - public boolean canBeAccessedBy(Long userId, Role role) { - if (role == Role.ADMIN) { - return true; - } - return applicant.getId().equals(userId); + public boolean canBeAccessedBy(Long publisherId) { + return this.recruitment.isPublishedBy(publisherId); } } diff --git a/src/main/java/com/server/crews/applicant/presentation/ApplicationController.java b/src/main/java/com/server/crews/applicant/presentation/ApplicationController.java index e59b090e..e7b0f8cc 100644 --- a/src/main/java/com/server/crews/applicant/presentation/ApplicationController.java +++ b/src/main/java/com/server/crews/applicant/presentation/ApplicationController.java @@ -36,16 +36,14 @@ public ResponseEntity saveApplication( .body(applicationService.saveApplication(loginUser.userId(), request)); } - // Todo: 지원서 수정 api 추가 - /** - * 특정 지원자의 지원서를 조회한다. + * 동아리 관리자가 특정 지원자의 지원서를 조회한다. */ @GetMapping("/{application-id}") public ResponseEntity getApplicationDetails( - @ApplicantAuthentication LoginUser loginUser, + @AdminAuthentication LoginUser loginUser, @PathVariable(value = "application-id") Long applicationId) { - return ResponseEntity.ok(applicationService.findApplicationDetails(applicationId, loginUser)); + return ResponseEntity.ok(applicationService.findApplicationDetails(applicationId, loginUser.userId())); } /** diff --git a/src/main/java/com/server/crews/applicant/repository/ApplicationRepository.java b/src/main/java/com/server/crews/applicant/repository/ApplicationRepository.java index dca5c38e..f8dba58e 100644 --- a/src/main/java/com/server/crews/applicant/repository/ApplicationRepository.java +++ b/src/main/java/com/server/crews/applicant/repository/ApplicationRepository.java @@ -20,4 +20,12 @@ select count(application) from Application application where a.applicant.id = :applicantId """) Optional findByApplicantId(@Param("applicantId") Long applicantId); + + @Query(""" + select a from Application a + join fetch a.recruitment r + join fetch r.publisher + where a.id = :id + """) + Optional findByIdWithRecruitmentAndPublisher(@Param("id") Long id); } diff --git a/src/main/java/com/server/crews/recruitment/domain/Recruitment.java b/src/main/java/com/server/crews/recruitment/domain/Recruitment.java index 29726215..2039ae00 100644 --- a/src/main/java/com/server/crews/recruitment/domain/Recruitment.java +++ b/src/main/java/com/server/crews/recruitment/domain/Recruitment.java @@ -126,4 +126,8 @@ public boolean hasPassedDeadline(LocalDateTime now) { public void sortQuestions() { this.sections.forEach(Section::sortQuestions); } + + public boolean isPublishedBy(Long publisherId) { + return this.publisher.getId().equals(publisherId); + } } diff --git a/src/test/java/com/server/crews/api/ApplicationApiDocuments.java b/src/test/java/com/server/crews/api/ApplicationApiDocuments.java index 676994a2..def9ecb1 100644 --- a/src/test/java/com/server/crews/api/ApplicationApiDocuments.java +++ b/src/test/java/com/server/crews/api/ApplicationApiDocuments.java @@ -50,8 +50,8 @@ public static RestDocumentationFilter SAVE_APPLICATION_400_DOCUMENT() { } public static RestDocumentationFilter GET_APPLICATION_200_DOCUMENT() { - return document(APPLICATION_API + "지원서 상세 조회", - new ResourceSnippetParametersBuilder().description("지원서 상세 정보를 조회한다.") + return document(APPLICATION_API + "동아리 관리자 지원서 상세 조회", + new ResourceSnippetParametersBuilder().description("동아리 관리자가 지원서 상세 정보를 조회한다.") .pathParameters(parameterWithName("application-id").description("지원서 id"))); } diff --git a/src/test/java/com/server/crews/api/ApplicationApiTest.java b/src/test/java/com/server/crews/api/ApplicationApiTest.java index 3732ab38..809584d7 100644 --- a/src/test/java/com/server/crews/api/ApplicationApiTest.java +++ b/src/test/java/com/server/crews/api/ApplicationApiTest.java @@ -138,7 +138,7 @@ void saveApplicationWithDuplicatedNarrativeAnswer() { } @Test - @DisplayName("지원서의 상세 정보를 조회한다.") + @DisplayName("동아리 관리자가 지원서 상세 정보를 조회한다.") void getApplicationDetails() { // given AdminLoginResponse adminTokenResponse = signUpAdmin(TEST_CLUB_NAME, TEST_PASSWORD); @@ -154,7 +154,7 @@ void getApplicationDetails() { .filter(ApplicationApiDocuments.GET_APPLICATION_200_DOCUMENT()) .contentType(MediaType.APPLICATION_JSON_VALUE) .header(HttpHeaders.AUTHORIZATION, - AuthorizationExtractor.BEARER_TYPE + applicantLoginResponse.accessToken()) + AuthorizationExtractor.BEARER_TYPE + adminTokenResponse.accessToken()) .pathParam("application-id", testApplication.id()) .when().get("/applications/{application-id}") .then().log().all() diff --git a/src/test/java/com/server/crews/applicant/application/ApplicationServiceTest.java b/src/test/java/com/server/crews/applicant/application/ApplicationServiceTest.java index 82dfa2d0..54e213e8 100644 --- a/src/test/java/com/server/crews/applicant/application/ApplicationServiceTest.java +++ b/src/test/java/com/server/crews/applicant/application/ApplicationServiceTest.java @@ -9,7 +9,6 @@ import static com.server.crews.fixture.SectionFixture.BACKEND_SECTION_NAME; import static com.server.crews.fixture.SectionFixture.FRONTEND_SECTION_NAME; import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatCode; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.junit.jupiter.api.Assertions.assertAll; @@ -29,12 +28,9 @@ import com.server.crews.applicant.repository.SelectiveAnswerRepository; import com.server.crews.auth.domain.Administrator; import com.server.crews.auth.domain.Applicant; -import com.server.crews.auth.domain.Role; -import com.server.crews.auth.dto.LoginUser; import com.server.crews.environ.service.ServiceTest; import com.server.crews.environ.service.TestRecruitment; import com.server.crews.global.exception.CrewsException; -import com.server.crews.global.exception.ErrorCode; import com.server.crews.recruitment.domain.Choice; import com.server.crews.recruitment.domain.NarrativeQuestion; import com.server.crews.recruitment.domain.Recruitment; @@ -146,10 +142,9 @@ void findApplicationDetails() { .saveSelectiveAnswers(selectiveQuestion, choices.get(1)) .application(); - LoginUser loginUser = new LoginUser(publisher.getId(), Role.ADMIN); - // when - ApplicationDetailsResponse response = applicationService.findApplicationDetails(application.getId(), loginUser); + ApplicationDetailsResponse response = applicationService.findApplicationDetails(application.getId(), + publisher.getId()); // then assertAll(() -> { @@ -160,44 +155,6 @@ void findApplicationDetails() { }); } - @ParameterizedTest - @MethodSource("provideRole") - @DisplayName("지원서의 작성자 혹은 동아리 관리자만이 지원서 상세 정보를 조회할 수 있다.") - void checkApplicationPermission(Role givenRole) { - // given - Administrator publisher = LIKE_LION_ADMIN().administrator(); - Recruitment testRecruitment = LIKE_LION_RECRUITMENT(publisher).recruitment(); - Applicant applicant = JONGMEE_APPLICANT().applicant(); - Application application = JONGMEE_APPLICATION(applicant, testRecruitment).application(); - - LoginUser loginUser = new LoginUser(1L, givenRole); - - // when & then - assertThatCode(() -> applicationService.findApplicationDetails(application.getId(), loginUser)) - .doesNotThrowAnyException(); - } - - private static Stream provideRole() { - return Stream.of(Role.APPLICANT, Role.ADMIN); - } - - @Test - @DisplayName("지원서 작성자가 아닌 지원자는 지원서 상세 정보를 조회할 수 없다.") - void checkInvalidApplicationPermission() { - // given - Administrator publisher = LIKE_LION_ADMIN().administrator(); - Recruitment testRecruitment = LIKE_LION_RECRUITMENT(publisher).recruitment(); - Applicant jongmeeApplicant = JONGMEE_APPLICANT().applicant(); - Application application = JONGMEE_APPLICATION(jongmeeApplicant, testRecruitment).application(); - Applicant kyunghoApplicant = KYUNGHO_APPLICANT().applicant(); - - LoginUser loginUser = new LoginUser(kyunghoApplicant.getId(), Role.APPLICANT); - - // when & then - assertThatThrownBy(() -> applicationService.findApplicationDetails(application.getId(), loginUser)) - .hasMessage(ErrorCode.UNAUTHORIZED_USER.getMessage()); - } - @Test @DisplayName("지원자들을 평가한다.") void decideOutcome() {