Skip to content

Commit

Permalink
Merge pull request #164 from Bamdoliro/feat/#163
Browse files Browse the repository at this point in the history
[새기능] 어드민 수험표 전체 다운로드
  • Loading branch information
cabbage16 authored Oct 21, 2024
2 parents e613f63 + b3d60ec commit 9a1a6c4
Show file tree
Hide file tree
Showing 6 changed files with 207 additions and 3 deletions.
16 changes: 16 additions & 0 deletions src/docs/asciidoc/form.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,22 @@ include::{snippets}/form-controller-test/수험표를_발급받을_때_원서를
===== 불합격한 경우
include::{snippets}/form-controller-test/수험표를_발급받을_때_불합격자라면_에러가_발생한다/http-response.adoc[]

=== 수험표 전체 발급
어드민은 1차 전형에서 합격한 전체 유저의 수험표를 발급받을 수 있습니다.

==== 요청 형식

===== 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[]

=== 접수증 발급
원서를 최종 제출한 유저는 접수증을 발급받을 수 있습니다.

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
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.infrastructure.pdf.GeneratePdfService;
import com.bamdoliro.maru.infrastructure.pdf.MergePdfService;
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.infrastructure.thymeleaf.ProcessTemplateService;
import com.bamdoliro.maru.infrastructure.thymeleaf.Templates;
import com.bamdoliro.maru.shared.annotation.UseCase;
import com.bamdoliro.maru.shared.constants.Schedule;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.kernel.utils.PdfMerger;
import lombok.RequiredArgsConstructor;
import org.springframework.core.io.ByteArrayResource;

import java.util.List;

import java.io.ByteArrayOutputStream;
import java.util.Map;

import static com.bamdoliro.maru.shared.constants.Schedule.*;

@RequiredArgsConstructor
@UseCase
public class GenerateAllAdmissionTicketUseCase {

private final FormRepository formRepository;
private final ProcessTemplateService processTemplateService;
private final GeneratePdfService generatePdfService;
private final MergePdfService mergePdfService;
private final FileService fileService;

public ByteArrayResource execute() {
List<Form> formList = formRepository.findByStatus(FormStatus.FIRST_PASSED);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
PdfDocument mergedDocument = new PdfDocument(new PdfWriter(outputStream));
PdfMerger pdfMerger = new PdfMerger(mergedDocument);

formList.forEach(form -> mergePdfService.execute(pdfMerger, generateAdmissionTicket(form)));

mergedDocument.close();
pdfMerger.close();

return new ByteArrayResource(outputStream.toByteArray());
}

private ByteArrayOutputStream generateAdmissionTicket(Form form) {

Map<String, Object> formMap = Map.ofEntries(
Map.entry("form", form),
Map.entry("year", Schedule.getAdmissionYear()),
Map.entry("codingTest", Schedule.toLocaleString(CODING_TEST)),
Map.entry("ncs", Schedule.toLocaleString(NCS)),
Map.entry("depthInterview", Schedule.toLocaleString(DEPTH_INTERVIEW)),
Map.entry("physicalExamination", Schedule.toLocaleString(PHYSICAL_EXAMINATION)),
Map.entry("announcementOfSecondPass", Schedule.toLocaleString(ANNOUNCEMENT_OF_SECOND_PASS)),
Map.entry("meisterTalentEntranceTime", Schedule.toLocaleString(MEISTER_TALENT_ENTRANCE_TIME)),
Map.entry("meisterTalentExclusionEntranceTime", Schedule.toLocaleString(MEISTER_TALENT_EXCLUSION_ENTRANCE_TIME)),
Map.entry("entranceRegistrationTime", Schedule.toLocaleString(ENTRANCE_REGISTRATION_PERIOD_START, ENTRANCE_REGISTRATION_PERIOD_END)),
Map.entry("identificationPictureUri", fileService.getPresignedUrl(FolderConstant.IDENTIFICATION_PICTURE, form.getUser().getUuid().toString()).getDownloadUrl())
);
String html = processTemplateService.execute(Templates.ADMISSION_TICKET, formMap);

return generatePdfService.execute(html);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ public class FormController {
private final QueryFormUrlUseCase queryFormUrlUseCase;
private final SelectSecondPassUseCase selectSecondPassUseCase;
private final UpdateOriginalTypeUseCase updateOriginalTypeUseCase;
private final GenerateAllAdmissionTicketUseCase generateAllAdmissionTicketUseCase;

@ResponseStatus(HttpStatus.CREATED)
@PostMapping
Expand Down Expand Up @@ -225,6 +226,15 @@ public ResponseEntity<Resource> generateAdmissionTicket(
.body(generateAdmissionTicketUseCase.execute(user));
}

@GetMapping("/admission-ticket/all")
public ResponseEntity<Resource> generateAllAdmissionTicket(
@AuthenticationPrincipal(authority = Authority.ADMIN) User user
) {
return ResponseEntity.ok()
.contentType(MediaType.APPLICATION_PDF)
.body(generateAllAdmissionTicketUseCase.execute());
}

@GetMapping("/proof-of-application")
public ResponseEntity<Resource> generateProofOfApplication(
@AuthenticationPrincipal(authority = Authority.USER) User user
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
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.infrastructure.pdf.GeneratePdfService;
import com.bamdoliro.maru.infrastructure.pdf.MergePdfService;
import com.bamdoliro.maru.infrastructure.persistence.form.FormRepository;
import com.bamdoliro.maru.infrastructure.s3.FileService;
import com.bamdoliro.maru.infrastructure.thymeleaf.ProcessTemplateService;
import com.bamdoliro.maru.shared.fixture.FormFixture;
import com.bamdoliro.maru.shared.fixture.SharedFixture;
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.io.ByteArrayOutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

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 GenerateAllAdmissionTicketUseCaseTest {

@InjectMocks
private GenerateAllAdmissionTicketUseCase generateAllAdmissionTicketUseCase;

@Mock
private ProcessTemplateService processTemplateService;

@Mock
private GeneratePdfService generatePdfService;

@Mock
private FileService fileService;

@Mock
private MergePdfService mergePdfService;

@Mock
private FormRepository formRepository;

@Test
void 모든_1_합격자의_수험표를_생성한다() {
// given
List<Form> formList = new ArrayList<>();
formList.add(FormFixture.createForm(FormType.REGULAR));
formList.add(FormFixture.createForm(FormType.MEISTER_TALENT));
formList.forEach(Form::firstPass);
given(formRepository.findByStatus(FormStatus.FIRST_PASSED)).willReturn(formList);
given(processTemplateService.execute(any(String.class), any(Map.class))).willReturn("html");
given(fileService.getPresignedUrl(any(String.class), any(String.class))).willReturn(SharedFixture.createFormUrlResponse());
given(generatePdfService.execute(any(String.class))).willReturn(new ByteArrayOutputStream());

// when
generateAllAdmissionTicketUseCase.execute();

//then
verify(formRepository, times(1)).findByStatus(FormStatus.FIRST_PASSED);
verify(processTemplateService, times(2)).execute(any(String.class), any(Map.class));
verify(generatePdfService, times(2)).execute(any(String.class));
verify(fileService, times(2)).getPresignedUrl(any(String.class), any(String.class));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1438,11 +1438,45 @@ class FormControllerTest extends RestDocsTestSupport {

.andExpect(status().isNotFound())

.andDo(restDocs.document());
.andDo(restDocs.document(
requestHeaders(
headerWithName(HttpHeaders.AUTHORIZATION)
.description("Bearer token")
)
));

verify(generateAdmissionTicketUseCase, times(1)).execute(user);
}

@Test
void 수험표_전체를_발급받는다() throws Exception {
User user = UserFixture.createAdminUser();
MockMultipartFile file = new MockMultipartFile(
"admission-ticket-all",
"admission-ticket-all.pdf",
MediaType.APPLICATION_PDF_VALUE,
"<<file>>".getBytes()
);
given(authenticationArgumentResolver.supportsParameter(any(MethodParameter.class))).willReturn(true);
given(authenticationArgumentResolver.resolveArgument(any(), any(), any(), any())).willReturn(user);
given(generateAllAdmissionTicketUseCase.execute()).willReturn(new ByteArrayResource(file.getBytes()));

mockMvc.perform(get("/form/admission-ticket/all")
.header(HttpHeaders.AUTHORIZATION, AuthFixture.createAuthHeader())
.accept(MediaType.APPLICATION_PDF))

.andExpect(status().isOk())

.andDo(restDocs.document(
requestHeaders(
headerWithName(HttpHeaders.AUTHORIZATION)
.description("Bearer token")
)
));

verify(generateAllAdmissionTicketUseCase, times(1)).execute();
}

@Test
void 접수증을_발급받는다() throws Exception {
User user = UserFixture.createUser();
Expand Down Expand Up @@ -1868,7 +1902,7 @@ class FormControllerTest extends RestDocsTestSupport {
willDoNothing().given(selectSecondPassUseCase).execute();

mockMvc.perform(patch("/form/second-round/select")
.header(HttpHeaders.AUTHORIZATION, AuthFixture.createAuthHeader()))
.header(HttpHeaders.AUTHORIZATION, AuthFixture.createAuthHeader()))

.andExpect(status().isNoContent())

Expand All @@ -1890,7 +1924,7 @@ class FormControllerTest extends RestDocsTestSupport {
willThrow(new MissingTotalScoreException()).given(selectSecondPassUseCase).execute();

mockMvc.perform(patch("/form/second-round/select")
.header(HttpHeaders.AUTHORIZATION, AuthFixture.createAuthHeader()))
.header(HttpHeaders.AUTHORIZATION, AuthFixture.createAuthHeader()))

.andExpect(status().isConflict())

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,9 @@ public abstract class ControllerTest {
@MockBean
protected UpdateOriginalTypeUseCase updateOriginalTypeUseCase;

@MockBean
protected GenerateAllAdmissionTicketUseCase generateAllAdmissionTicketUseCase;

protected String toJson(Object object) throws JsonProcessingException {
return objectMapper.writeValueAsString(object);
}
Expand Down

0 comments on commit 9a1a6c4

Please sign in to comment.