diff --git a/src/docs/asciidoc/form.adoc b/src/docs/asciidoc/form.adoc index 144a8e8f..89dbc23f 100644 --- a/src/docs/asciidoc/form.adoc +++ b/src/docs/asciidoc/form.adoc @@ -131,6 +131,27 @@ include::{snippets}/form-controller-test/원서를_반려한다/http-response.ad ===== 해당하는 원서가 없는 경우 include::{snippets}/form-controller-test/원서를_반려할_때_원서가_없으면_에러가_발생한다/http-response.adoc[] +=== 원서 입학등록 +최종합격한 유저는 입학등록원을 제출한 후 원서를 입학등록상태로 변경할 수 있습니다. + +==== 요청 형식 +===== Request Header +include::{snippets}/form-controller-test/원서의_상태를_입학등록원_제출로_변경한다/request-headers.adoc[] + +==== 요청 +include::{snippets}/form-controller-test/원서의_상태를_입학등록원_제출로_변경한다/http-request.adoc[] + +==== 응답 + +===== 정상 응답 +include::{snippets}/form-controller-test/원서의_상태를_입학등록원_제출로_변경한다/http-response.adoc[] + +===== 원서 상태가 적합하지 않은 경우 +include::{snippets}/form-controller-test/입학등록원을_제출했거나_최종합격한_지원자가_아닌_지원자가_원서의_상태를_변경하면_에러가_발생한다/http-response.adoc[] + +===== 원서가 존재하지 않는 경우 +include::{snippets}/form-controller-test/원서를_입학등록_상태로_변경할_때_원서가_없으면_에러가_발생한다/http-response.adoc[] + === 원서 접수 어드민은 서류 원본을 받은 후 원서를 검토해 최종 접수할 수 있습니다. @@ -658,7 +679,22 @@ include::{snippets}/form-controller-test/선택한_원서의_원서url을_조회 ===== 정상 응답 include::{snippets}/form-controller-test/선택한_원서의_원서url을_조회한다/http-response.adoc[] +=== 선택한 원서의 입락등록원 및 금연서약서 url 조회 +어드민은 선택한 원서의 입학등록원 및 금연서약서 url을 조회할 수 있습니다. + +==== 요청 형식 +===== Request Header +include::{snippets}/form-controller-test/선택한_원서들의_입학등록원_및_금연서약서url을_조회한다/request-headers.adoc[] + +===== Query Parameter +include::{snippets}/form-controller-test/선택한_원서들의_입학등록원_및_금연서약서url을_조회한다/query-parameters.adoc[] + +==== 요청 +include::{snippets}/form-controller-test/선택한_원서들의_입학등록원_및_금연서약서url을_조회한다/http-request.adoc[] +==== 응답 +===== 정상 응답 +include::{snippets}/form-controller-test/선택한_원서들의_입학등록원_및_금연서약서url을_조회한다/http-response.adoc[] === 2차 합격 자동 처리 diff --git a/src/main/java/com/bamdoliro/maru/application/form/DownloadAdmissionAndPledgeFormatUseCase.java b/src/main/java/com/bamdoliro/maru/application/form/DownloadAdmissionAndPledgeFormatUseCase.java index 823e6106..dac993b1 100644 --- a/src/main/java/com/bamdoliro/maru/application/form/DownloadAdmissionAndPledgeFormatUseCase.java +++ b/src/main/java/com/bamdoliro/maru/application/form/DownloadAdmissionAndPledgeFormatUseCase.java @@ -59,7 +59,7 @@ public ByteArrayResource execute(User user) { } private void validate(Form form) { - if (!form.isPassedNow()) + if (!form.isPassedNow() && !form.isEntered()) throw new InvalidFormStatusException(); } } diff --git a/src/main/java/com/bamdoliro/maru/application/form/EnterFormUseCase.java b/src/main/java/com/bamdoliro/maru/application/form/EnterFormUseCase.java new file mode 100644 index 00000000..bf3a5127 --- /dev/null +++ b/src/main/java/com/bamdoliro/maru/application/form/EnterFormUseCase.java @@ -0,0 +1,29 @@ +package com.bamdoliro.maru.application.form; + +import com.bamdoliro.maru.domain.form.domain.Form; +import com.bamdoliro.maru.domain.form.exception.InvalidFormStatusException; +import com.bamdoliro.maru.domain.form.service.FormFacade; +import com.bamdoliro.maru.domain.user.domain.User; +import com.bamdoliro.maru.shared.annotation.UseCase; +import lombok.RequiredArgsConstructor; +import org.springframework.transaction.annotation.Transactional; + +@RequiredArgsConstructor +@UseCase +public class EnterFormUseCase { + + private final FormFacade formFacade; + + @Transactional + public void execute(User user) { + Form form = formFacade.getForm(user); + validate(form); + + form.enter(); + } + + private void validate(Form form) { + if(!form.isPassedNow() && !form.isEntered()) + throw new InvalidFormStatusException(); + } +} diff --git a/src/main/java/com/bamdoliro/maru/application/form/QueryAdmissionAndPledgeUrlUseCase.java b/src/main/java/com/bamdoliro/maru/application/form/QueryAdmissionAndPledgeUrlUseCase.java new file mode 100644 index 00000000..1654ff34 --- /dev/null +++ b/src/main/java/com/bamdoliro/maru/application/form/QueryAdmissionAndPledgeUrlUseCase.java @@ -0,0 +1,28 @@ +package com.bamdoliro.maru.application.form; + +import com.bamdoliro.maru.infrastructure.persistence.form.FormRepository; +import com.bamdoliro.maru.infrastructure.s3.FileService; +import com.bamdoliro.maru.infrastructure.s3.constants.FolderConstant; +import com.bamdoliro.maru.presentation.form.dto.response.AdmissionAndPledgeUrlResponse; +import com.bamdoliro.maru.presentation.form.dto.response.FormUrlResponse; +import com.bamdoliro.maru.shared.annotation.UseCase; +import lombok.RequiredArgsConstructor; + +import java.util.List; + +@RequiredArgsConstructor +@UseCase +public class QueryAdmissionAndPledgeUrlUseCase { + + private final FormRepository formRepository; + private final FileService fileService; + + public List execute(List formIdList) { + return formRepository.findFormUrlByFormIdList(formIdList).stream() + .map(vo -> new AdmissionAndPledgeUrlResponse( + vo.getExaminationNumber(), + vo.getName(), + fileService.getPresignedUrl(FolderConstant.ADMISSION_AND_PLEDGE, vo.getUuid()).getDownloadUrl() + )).toList(); + } +} diff --git a/src/main/java/com/bamdoliro/maru/application/form/UploadAdmissionAndPledgeUseCase.java b/src/main/java/com/bamdoliro/maru/application/form/UploadAdmissionAndPledgeUseCase.java index 592ec8ea..737a9969 100644 --- a/src/main/java/com/bamdoliro/maru/application/form/UploadAdmissionAndPledgeUseCase.java +++ b/src/main/java/com/bamdoliro/maru/application/form/UploadAdmissionAndPledgeUseCase.java @@ -25,7 +25,7 @@ public UrlResponse execute(User user) { } private void validate(Form form) { - if(!form.isPassedNow()) + if(!form.isPassedNow() && !form.isEntered()) throw new InvalidFormStatusException(); } } diff --git a/src/main/java/com/bamdoliro/maru/domain/form/domain/Form.java b/src/main/java/com/bamdoliro/maru/domain/form/domain/Form.java index e9e1b7bf..610ab34a 100644 --- a/src/main/java/com/bamdoliro/maru/domain/form/domain/Form.java +++ b/src/main/java/com/bamdoliro/maru/domain/form/domain/Form.java @@ -131,6 +131,8 @@ public void noShow() { this.status = FormStatus.NO_SHOW; } + public void enter() { this.status = FormStatus.ENTERED; } + public void isApplicant(User user) { if (!this.user.equals(user)) { throw new AuthorityMismatchException(); @@ -147,11 +149,17 @@ public boolean isRejected() { return status.equals(FormStatus.REJECTED); } - public boolean isSubmitted() { return status.equals(FormStatus.SUBMITTED); } + public boolean isSubmitted() { + return status.equals(FormStatus.SUBMITTED); + } - public boolean isFinalSubmitted() { return status.equals(FormStatus.FINAL_SUBMITTED); } + public boolean isFinalSubmitted() { + return status.equals(FormStatus.FINAL_SUBMITTED); + } - public boolean isApproved() { return status.equals(FormStatus.APPROVED); } + public boolean isApproved() { + return status.equals(FormStatus.APPROVED); + } public boolean isReceived() { return isFirstPassed() != null || status.equals(FormStatus.RECEIVED); @@ -165,6 +173,10 @@ public boolean isFirstPassedNow() { return status.equals(FormStatus.FIRST_PASSED); } + public boolean isEntered() { + return status.equals(FormStatus.ENTERED); + } + public Boolean isFirstPassed() { if (isFirstPassedNow() || isPassed() != null || isNoShow()) { return true; @@ -182,13 +194,14 @@ public boolean isPassedNow() { } public Boolean isPassed() { - if (isPassedNow()) { + if (isPassedNow() || isEntered()) { return true; } return isFailedNow() || isNoShow() ? false : null; } + public boolean isFailedNow() { return status.equals(FormStatus.FAILED); } @@ -210,7 +223,7 @@ public void changeToRegularSecondRound(CalculateFormScoreService calculateFormSc this.score.updateSubjectScore(subjectGradeScore); this.score.updateSecondRoundMeisterScoreToRegular(); - } else if (type.isSocial()){ + } else if (type.isSocial()) { this.type = FormType.REGULAR; Double subjectGradeScore = calculateFormScoreService.calculateSubjectGradeScore(this); this.score.updateSubjectScore(subjectGradeScore); diff --git a/src/main/java/com/bamdoliro/maru/domain/form/domain/type/FormStatus.java b/src/main/java/com/bamdoliro/maru/domain/form/domain/type/FormStatus.java index b6936fdc..f4daa415 100644 --- a/src/main/java/com/bamdoliro/maru/domain/form/domain/type/FormStatus.java +++ b/src/main/java/com/bamdoliro/maru/domain/form/domain/type/FormStatus.java @@ -16,7 +16,8 @@ public enum FormStatus implements EnumProperty { FIRST_FAILED("1차 불합격"), PASSED("최종 합격"), FAILED("불합격"), - NO_SHOW("불참"); + NO_SHOW("불참"), + ENTERED("입학"); private final String description; } diff --git a/src/main/java/com/bamdoliro/maru/presentation/form/FormController.java b/src/main/java/com/bamdoliro/maru/presentation/form/FormController.java index 1fda739f..f6bd522e 100644 --- a/src/main/java/com/bamdoliro/maru/presentation/form/FormController.java +++ b/src/main/java/com/bamdoliro/maru/presentation/form/FormController.java @@ -8,10 +8,7 @@ import com.bamdoliro.maru.presentation.form.dto.request.PassOrFailFormListRequest; import com.bamdoliro.maru.presentation.form.dto.request.SubmitFormRequest; import com.bamdoliro.maru.presentation.form.dto.request.UpdateFormRequest; -import com.bamdoliro.maru.presentation.form.dto.response.FormResponse; -import com.bamdoliro.maru.presentation.form.dto.response.FormResultResponse; -import com.bamdoliro.maru.presentation.form.dto.response.FormSimpleResponse; -import com.bamdoliro.maru.presentation.form.dto.response.FormUrlResponse; +import com.bamdoliro.maru.presentation.form.dto.response.*; import com.bamdoliro.maru.shared.auth.AuthenticationPrincipal; import com.bamdoliro.maru.shared.auth.Authority; import com.bamdoliro.maru.shared.response.CommonResponse; @@ -50,6 +47,7 @@ public class FormController { private final ApproveFormUseCase approveFormUseCase; private final RejectFormUseCase rejectFormUseCase; private final ReceiveFormUseCase receiveFormUseCase; + private final EnterFormUseCase enterFormUseCase; private final QuerySubmittedFormUseCase querySubmittedFormUseCase; private final QueryFormUseCase queryFormUseCase; private final QueryFormStatusUseCase queryFormStatusUseCase; @@ -75,6 +73,7 @@ public class FormController { private final SelectSecondPassUseCase selectSecondPassUseCase; private final UpdateOriginalTypeUseCase updateOriginalTypeUseCase; private final GenerateAllAdmissionTicketUseCase generateAllAdmissionTicketUseCase; + private final QueryAdmissionAndPledgeUrlUseCase queryAdmissionAndPledgeUrlUseCase; @ResponseStatus(HttpStatus.CREATED) @PostMapping @@ -120,6 +119,14 @@ public void receiveForm( receiveFormUseCase.execute(formId); } + @ResponseStatus(HttpStatus.NO_CONTENT) + @PatchMapping("/enter") + public void enterForm( + @AuthenticationPrincipal(authority = Authority.USER) User user + ) { + enterFormUseCase.execute(user); + } + @GetMapping("/review") public ListCommonResponse getSubmittedFormList( @AuthenticationPrincipal(authority = Authority.ADMIN) User user @@ -159,7 +166,7 @@ public void updateForm( } @ResponseStatus(HttpStatus.CREATED) - @PostMapping(value = "/identification-picture") + @PostMapping( "/identification-picture") public SingleCommonResponse uploadIdentificationPicture( @AuthenticationPrincipal(authority = Authority.USER) User user ) { @@ -169,7 +176,7 @@ public SingleCommonResponse uploadIdentificationPicture( } @ResponseStatus(HttpStatus.CREATED) - @PostMapping(value = "/form-document") + @PostMapping("/form-document") public SingleCommonResponse uploadFormDocument( @AuthenticationPrincipal(authority = Authority.USER) User user ) { @@ -178,7 +185,7 @@ public SingleCommonResponse uploadFormDocument( ); } - @GetMapping(value = "/export") + @GetMapping("/export") public ResponseEntity exportForm( @AuthenticationPrincipal(authority = Authority.USER) User user, Model model @@ -189,7 +196,7 @@ public ResponseEntity exportForm( .body(exportFormUseCase.execute(user)); } - @GetMapping(value = "/admission-and-pledge") + @GetMapping( "/admission-and-pledge") public ResponseEntity downloadAdmissionAndPledgeFormat( @AuthenticationPrincipal(authority = Authority.USER) User user ) { @@ -198,7 +205,7 @@ public ResponseEntity downloadAdmissionAndPledgeFormat( .body(downloadAdmissionAndPledgeFormatUseCase.execute(user)); } - @PostMapping(value = "/admission-and-pledge") + @PostMapping("/admission-and-pledge") public SingleCommonResponse uploadAdmissionAndPledge( @AuthenticationPrincipal(authority = Authority.USER) User user ) { @@ -337,6 +344,17 @@ public ListCommonResponse getFormUrl( ); } + + @GetMapping("/admission-and-pledge-url") + public ListCommonResponse getAdmissionAndPledgeUrl( + @AuthenticationPrincipal(authority = Authority.ADMIN) User user, + @RequestParam(name = "id-list") List formIdList + ) { + return CommonResponse.ok( + queryAdmissionAndPledgeUrlUseCase.execute(formIdList) + ); + } + @ResponseStatus(HttpStatus.NO_CONTENT) @PatchMapping("/second-round/select") public void selectSecondPass( diff --git a/src/main/java/com/bamdoliro/maru/presentation/form/dto/response/AdmissionAndPledgeUrlResponse.java b/src/main/java/com/bamdoliro/maru/presentation/form/dto/response/AdmissionAndPledgeUrlResponse.java new file mode 100644 index 00000000..7408dc98 --- /dev/null +++ b/src/main/java/com/bamdoliro/maru/presentation/form/dto/response/AdmissionAndPledgeUrlResponse.java @@ -0,0 +1,14 @@ +package com.bamdoliro.maru.presentation.form.dto.response; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public class AdmissionAndPledgeUrlResponse { + + private Long examinationNumber; + private String name; + private String admissionAndPledgeUrl; + +} diff --git a/src/main/java/com/bamdoliro/maru/shared/config/WebConfig.java b/src/main/java/com/bamdoliro/maru/shared/config/WebConfig.java index 3326d879..1f866d2d 100644 --- a/src/main/java/com/bamdoliro/maru/shared/config/WebConfig.java +++ b/src/main/java/com/bamdoliro/maru/shared/config/WebConfig.java @@ -25,9 +25,6 @@ public void addArgumentResolvers(List resolvers) public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOrigins( - "http://localhost:3000", - "http://localhost:3001", - "http://localhost:3002", "https://maru.bamdoliro.com", "https://madmin.bamdoliro.com" ) diff --git a/src/main/resources/templates/registration.html b/src/main/resources/templates/registration.html index 2839d95d..8b8edbbf 100644 --- a/src/main/resources/templates/registration.html +++ b/src/main/resources/templates/registration.html @@ -1,187 +1,187 @@ - - - 원서 + + + 원서
- -
2025학년도 부산소프트웨어마이스터고등학교
-
입학등록원
-
- - - - - - - - - - - - - - - - - - - - - - - -
수험번호1000성 명
성별생년월일1000
학생 연락처보호자 연락처1000
출신 중학교
+ +
2025학년도 부산소프트웨어마이스터고등학교
+
입학등록원
+
+ + + + + + + + + + + + + + + + + + + + + + + +
수험번호1000성 명
성별생년월일1000
학생 연락처보호자 연락처1000
출신 중학교
- + -

상기 본인은 2025학년도 부산소프트웨어마이스터고등학교 최종 합격자로서 본교 제1학년에 입학하고자 다음과 같이 입학등록원을 제출합니다.

-
-
2024년 12월 21일
-
+

상기 본인은 2025학년도 부산소프트웨어마이스터고등학교 최종 합격자로서 본교 제1학년에 입학하고자 다음과 같이 입학등록원을 제출합니다.

+
+
2024년 12월 21일
+

- 학    생 : - - (서명 또는 날인) + 학    생 : + + (서명 또는 날인)

- 보호자 : - - (서명 또는 날인) + 보호자 : + + (서명 또는 날인)

부산소프트웨어마이스터고등학교장 귀하

※ 고등학교 무상교육(입학금, 수업료, 학교운영지원비, 교과서비, 중식비) - 이 실시됨에 따라 ‘입학등록원’을 제출해야만 입학생으로 처리되며, - 등록 포기 시 별도의 입학등록포기원을 작성하여 제출하여야 함

-
-

※ 등록 포기 시, 2025학년도에는 타 학교에 진학할 수 없음

+ 이 실시됨에 따라 ‘입학등록원’을 제출해야만 입학생으로 처리되며, + 등록 포기 시 별도의 입학등록포기원을 작성하여 제출하여야 함

+
+

※ 등록 포기 시, 2025학년도에는 타 학교에 진학할 수 없음

- + \ No newline at end of file diff --git a/src/test/java/com/bamdoliro/maru/application/form/EnterFormUseCaseTest.java b/src/test/java/com/bamdoliro/maru/application/form/EnterFormUseCaseTest.java new file mode 100644 index 00000000..08d0da4a --- /dev/null +++ b/src/test/java/com/bamdoliro/maru/application/form/EnterFormUseCaseTest.java @@ -0,0 +1,75 @@ +package com.bamdoliro.maru.application.form; + +import com.bamdoliro.maru.domain.form.domain.Form; +import com.bamdoliro.maru.domain.form.domain.type.FormStatus; +import com.bamdoliro.maru.domain.form.domain.type.FormType; +import com.bamdoliro.maru.domain.form.exception.InvalidFormStatusException; +import com.bamdoliro.maru.domain.form.service.FormFacade; +import com.bamdoliro.maru.domain.user.domain.User; +import com.bamdoliro.maru.shared.fixture.FormFixture; +import com.bamdoliro.maru.shared.fixture.UserFixture; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.BDDMockito.given; +import static org.mockito.BDDMockito.times; +import static org.mockito.Mockito.verify; + +@ExtendWith(MockitoExtension.class) +public class EnterFormUseCaseTest { + + @InjectMocks + private EnterFormUseCase enterFormUseCase; + + @Mock + private FormFacade formFacade; + + @Test + void 최종합격자가_입학등록원_및_금연서약서를_제출한다() { + // given + User user = UserFixture.createUser(); + Form form = FormFixture.createForm(FormType.REGULAR); + form.pass(); + given(formFacade.getForm(user)).willReturn(form); + + // when + enterFormUseCase.execute(user); + + // then + verify(formFacade, times(1)).getForm(user); + assertEquals(form.getStatus(), FormStatus.ENTERED); + } + + @Test + void 입학등록원_및_금연서약서를_제출한_지원자가_재제출한다() { + // given + User user = UserFixture.createUser(); + Form form = FormFixture.createForm(FormType.REGULAR); + form.enter(); + given(formFacade.getForm(user)).willReturn(form); + + // when + enterFormUseCase.execute(user); + + // then + verify(formFacade, times(1)).getForm(user); + assertEquals(form.getStatus(), FormStatus.ENTERED); + } + + @Test + void 입학등록원을_제출했거나_최종합격한_지원자가_아닌_지원자가_입학등록원_및_금연서약서를_제출하면_에러가_발생한다() { + //given + User user = UserFixture.createUser(); + Form form = FormFixture.createForm(FormType.REGULAR); + given(formFacade.getForm(user)).willReturn(form); + + //when and then + assertThrows(InvalidFormStatusException.class, () -> enterFormUseCase.execute(user)); + verify(formFacade, times(1)).getForm(user); + } +} diff --git a/src/test/java/com/bamdoliro/maru/application/form/QueryAdmissionAndPledgeUrlUseCaseTest.java b/src/test/java/com/bamdoliro/maru/application/form/QueryAdmissionAndPledgeUrlUseCaseTest.java new file mode 100644 index 00000000..6c1c2230 --- /dev/null +++ b/src/test/java/com/bamdoliro/maru/application/form/QueryAdmissionAndPledgeUrlUseCaseTest.java @@ -0,0 +1,54 @@ +package com.bamdoliro.maru.application.form; + +import com.bamdoliro.maru.infrastructure.persistence.form.FormRepository; +import com.bamdoliro.maru.infrastructure.s3.FileService; +import com.bamdoliro.maru.presentation.form.dto.response.AdmissionAndPledgeUrlResponse; +import com.bamdoliro.maru.shared.fixture.FormFixture; +import com.bamdoliro.maru.shared.fixture.SharedFixture; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +@ExtendWith(MockitoExtension.class) +public class QueryAdmissionAndPledgeUrlUseCaseTest { + + @InjectMocks + private QueryAdmissionAndPledgeUrlUseCase queryAdmissionAndPledgeUrlUseCase; + + @Mock + private FormRepository formRepository; + + @Mock + private FileService fileService; + + @Test + void 입학등록원_및_금연서약서_url을_조회한다() { + // given + List idList = List.of(1L, 2L, 3L); + given(formRepository.findFormUrlByFormIdList(idList)).willReturn(List.of( + FormFixture.createFormUrlVo(), + FormFixture.createFormUrlVo(), + FormFixture.createFormUrlVo() + )); + given(fileService.getPresignedUrl(any(String.class), any(String.class))).willReturn(SharedFixture.createAdmissionAndPledgeUrlResponse()); + + // when + List responseList = queryAdmissionAndPledgeUrlUseCase.execute(idList); + + // then + assertEquals(idList.size(), responseList.size()); + + verify(formRepository, times(1)).findFormUrlByFormIdList(idList); + } +} diff --git a/src/test/java/com/bamdoliro/maru/presentation/form/FormControllerTest.java b/src/test/java/com/bamdoliro/maru/presentation/form/FormControllerTest.java index fd085b6a..dfb0de23 100644 --- a/src/test/java/com/bamdoliro/maru/presentation/form/FormControllerTest.java +++ b/src/test/java/com/bamdoliro/maru/presentation/form/FormControllerTest.java @@ -1259,6 +1259,69 @@ class FormControllerTest extends RestDocsTestSupport { verify(uploadAdmissionAndPledgeUseCase, times(1)).execute(user); } + @Test + void 원서의_상태를_입학등록원_제출로_변경한다() throws Exception { + User user = UserFixture.createUser(); + + given(authenticationArgumentResolver.supportsParameter(any(MethodParameter.class))).willReturn(true); + given(authenticationArgumentResolver.resolveArgument(any(), any(), any(), any())).willReturn(user); + willDoNothing().given(enterFormUseCase).execute(user); + + mockMvc.perform(patch("/form/enter") + .header(HttpHeaders.AUTHORIZATION, AuthFixture.createAuthHeader()) + .accept(MediaType.APPLICATION_JSON) + ) + + .andExpect(status().isNoContent()) + + .andDo(restDocs.document( + requestHeaders( + headerWithName(HttpHeaders.AUTHORIZATION) + .description("Bearer token") + ) + )); + } + + @Test + void 입학등록원을_제출했거나_최종합격한_지원자가_아닌_지원자가_원서의_상태를_변경하면_에러가_발생한다() throws Exception { + User user = UserFixture.createUser(); + + given(authenticationArgumentResolver.supportsParameter(any(MethodParameter.class))).willReturn(true); + given(authenticationArgumentResolver.resolveArgument(any(), any(), any(), any())).willReturn(user); + doThrow(new InvalidFormStatusException()).when(enterFormUseCase).execute(user); + + mockMvc.perform(patch("/form/enter") + .header(HttpHeaders.AUTHORIZATION, AuthFixture.createAuthHeader()) + .accept(MediaType.APPLICATION_JSON) + ) + + .andExpect(status().isConflict()) + + .andDo(restDocs.document()); + + verify(enterFormUseCase, times(1)).execute(user); + } + + @Test + void 원서를_입학등록_상태로_변경할_때_원서가_없으면_에러가_발생한다() throws Exception { + User user = UserFixture.createUser(); + + given(authenticationArgumentResolver.supportsParameter(any(MethodParameter.class))).willReturn(true); + given(authenticationArgumentResolver.resolveArgument(any(), any(), any(), any())).willReturn(user); + doThrow(new FormNotFoundException()).when(enterFormUseCase).execute(user); + + mockMvc.perform(patch("/form/enter") + .header(HttpHeaders.AUTHORIZATION, AuthFixture.createAuthHeader()) + .accept(MediaType.APPLICATION_JSON) + ) + + .andExpect(status().isNotFound()) + + .andDo(restDocs.document()); + + verify(enterFormUseCase, times(1)).execute(user); + } + @Test void 원서를_pdf로_다운받는다() throws Exception { User user = UserFixture.createUser(); @@ -2047,4 +2110,40 @@ class FormControllerTest extends RestDocsTestSupport { verify(selectSecondPassUseCase, times(1)).execute(); } + + @Test + void 선택한_원서들의_입학등록원_및_금연서약서url을_조회한다() throws Exception { + User user = UserFixture.createAdminUser(); + List idList = List.of(1L, 2L, 3L, 4L, 5L); + + given(authenticationArgumentResolver.supportsParameter(any(MethodParameter.class))).willReturn(true); + given(authenticationArgumentResolver.resolveArgument(any(), any(), any(), any())).willReturn(user); + given(queryAdmissionAndPledgeUrlUseCase.execute(idList)).willReturn( + List.of(FormFixture.createAdmissionAndPledgeUrlResponse(), + FormFixture.createAdmissionAndPledgeUrlResponse(), + FormFixture.createAdmissionAndPledgeUrlResponse(), + FormFixture.createAdmissionAndPledgeUrlResponse(), + FormFixture.createAdmissionAndPledgeUrlResponse()) + ); + + mockMvc.perform(get("/form/admission-and-pledge-url") + .header(HttpHeaders.AUTHORIZATION, AuthFixture.createAuthHeader()) + .param("id-list", "1,2,3,4,5") + .accept(MediaType.APPLICATION_JSON)) + + .andExpect(status().isOk()) + + .andDo(restDocs.document( + requestHeaders( + headerWithName(HttpHeaders.AUTHORIZATION) + .description("Bearer token") + ), + queryParameters( + parameterWithName("id-list") + .description("조회할 원서 id 목록") + ) + )); + + verify(queryAdmissionAndPledgeUrlUseCase, times(1)).execute(idList); + } } \ No newline at end of file diff --git a/src/test/java/com/bamdoliro/maru/shared/fixture/FormFixture.java b/src/test/java/com/bamdoliro/maru/shared/fixture/FormFixture.java index a1637f9f..70ee42dd 100644 --- a/src/test/java/com/bamdoliro/maru/shared/fixture/FormFixture.java +++ b/src/test/java/com/bamdoliro/maru/shared/fixture/FormFixture.java @@ -32,16 +32,7 @@ import com.bamdoliro.maru.presentation.form.dto.request.SubjectRequest; import com.bamdoliro.maru.presentation.form.dto.request.SubmitFormRequest; import com.bamdoliro.maru.presentation.form.dto.request.UpdateFormRequest; -import com.bamdoliro.maru.presentation.form.dto.response.ApplicantResponse; -import com.bamdoliro.maru.presentation.form.dto.response.AttendanceResponse; -import com.bamdoliro.maru.presentation.form.dto.response.DocumentResponse; -import com.bamdoliro.maru.presentation.form.dto.response.EducationResponse; -import com.bamdoliro.maru.presentation.form.dto.response.FormResponse; -import com.bamdoliro.maru.presentation.form.dto.response.FormSimpleResponse; -import com.bamdoliro.maru.presentation.form.dto.response.FormUrlResponse; -import com.bamdoliro.maru.presentation.form.dto.response.GradeResponse; -import com.bamdoliro.maru.presentation.form.dto.response.ParentResponse; -import com.bamdoliro.maru.presentation.form.dto.response.SubjectResponse; +import com.bamdoliro.maru.presentation.form.dto.response.*; import java.time.LocalDate; import java.util.List; @@ -616,4 +607,13 @@ public static FormUrlResponse createFormUrlResponse() { "https://maru.bamdoliro.com/form.pdf" ); } + + public static AdmissionAndPledgeUrlResponse createAdmissionAndPledgeUrlResponse() { + FormUrlVo formUrlVo = createFormUrlVo(); + return new AdmissionAndPledgeUrlResponse( + formUrlVo.getExaminationNumber(), + formUrlVo.getName(), + "https://maru.bamdoliro.com/admission-and-pledge.pdf" + ); + } } \ No newline at end of file diff --git a/src/test/java/com/bamdoliro/maru/shared/util/ControllerTest.java b/src/test/java/com/bamdoliro/maru/shared/util/ControllerTest.java index 9eac4e32..006240ab 100644 --- a/src/test/java/com/bamdoliro/maru/shared/util/ControllerTest.java +++ b/src/test/java/com/bamdoliro/maru/shared/util/ControllerTest.java @@ -105,6 +105,9 @@ public abstract class ControllerTest { @MockBean protected ReceiveFormUseCase receiveFormUseCase; + @MockBean + protected EnterFormUseCase enterFormUseCase; + @MockBean protected QuerySubmittedFormUseCase querySubmittedFormUseCase; @@ -266,6 +269,9 @@ public abstract class ControllerTest { @MockBean protected UploadAdmissionAndPledgeUseCase uploadAdmissionAndPledgeUseCase; + @MockBean + protected QueryAdmissionAndPledgeUrlUseCase queryAdmissionAndPledgeUrlUseCase; + protected String toJson(Object object) throws JsonProcessingException { return objectMapper.writeValueAsString(object); }