From 09099731aa09db7dbe92bb08e690f407a4825bae Mon Sep 17 00:00:00 2001 From: Uno Kim Date: Thu, 8 Aug 2024 00:11:01 +0900 Subject: [PATCH] =?UTF-8?q?#27=20-=20=ED=8C=8C=EC=9D=BC=20=EC=B6=9C?= =?UTF-8?q?=EB=A0=A5=EA=B8=B0=EB=A5=BC=20=EC=84=9C=EB=B9=84=EC=8A=A4=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=EC=9D=84=20=EA=B1=B0=EC=B3=90=20=EC=BB=A8?= =?UTF-8?q?=ED=8A=B8=EB=A1=A4=EB=9F=AC=EA=B9=8C=EC=A7=80=20=EC=97=B0?= =?UTF-8?q?=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/TableSchemaController.java | 22 +++--- .../testdata/service/SchemaExportService.java | 27 +++++++ .../controller/TableSchemaControllerTest.java | 42 ++++++++++- .../service/SchemaExportServiceTest.java | 71 +++++++++++++++++++ 4 files changed, 150 insertions(+), 12 deletions(-) create mode 100644 src/main/java/uno/fastcampus/testdata/service/SchemaExportService.java create mode 100644 src/test/java/uno/fastcampus/testdata/service/SchemaExportServiceTest.java diff --git a/src/main/java/uno/fastcampus/testdata/controller/TableSchemaController.java b/src/main/java/uno/fastcampus/testdata/controller/TableSchemaController.java index 02be04e..5ee52ad 100644 --- a/src/main/java/uno/fastcampus/testdata/controller/TableSchemaController.java +++ b/src/main/java/uno/fastcampus/testdata/controller/TableSchemaController.java @@ -21,6 +21,7 @@ import uno.fastcampus.testdata.dto.response.SimpleTableSchemaResponse; import uno.fastcampus.testdata.dto.response.TableSchemaResponse; import uno.fastcampus.testdata.dto.security.GithubUser; +import uno.fastcampus.testdata.service.SchemaExportService; import uno.fastcampus.testdata.service.TableSchemaService; import java.util.Arrays; @@ -31,6 +32,7 @@ public class TableSchemaController { private final TableSchemaService tableSchemaService; + private final SchemaExportService schemaExportService; private final ObjectMapper mapper; @GetMapping("/table-schema") @@ -89,12 +91,20 @@ public String deleteMySchema( } @GetMapping("/table-schema/export") - public ResponseEntity exportTableSchema(TableSchemaExportRequest tableSchemaExportRequest) { + public ResponseEntity exportTableSchema( + @AuthenticationPrincipal GithubUser githubUser, + TableSchemaExportRequest tableSchemaExportRequest + ) { + String body = schemaExportService.export( + tableSchemaExportRequest.getFileType(), + tableSchemaExportRequest.toDto(githubUser != null ? githubUser.id() : null), + tableSchemaExportRequest.getRowCount() + ); String filename = tableSchemaExportRequest.getSchemaName() + "." + tableSchemaExportRequest.getFileType().name().toLowerCase(); return ResponseEntity.ok() .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + filename) - .body(json(tableSchemaExportRequest)); // TODO: 나중에 데이터 바꿔야 함 + .body(body); } @@ -111,12 +121,4 @@ private TableSchemaResponse defaultTableSchema(String schemaName) { ); } - private String json(Object object) { - try { - return mapper.writeValueAsString(object); - } catch (JsonProcessingException jpe) { - throw new RuntimeException(jpe); - } - } - } diff --git a/src/main/java/uno/fastcampus/testdata/service/SchemaExportService.java b/src/main/java/uno/fastcampus/testdata/service/SchemaExportService.java new file mode 100644 index 0000000..d47adcd --- /dev/null +++ b/src/main/java/uno/fastcampus/testdata/service/SchemaExportService.java @@ -0,0 +1,27 @@ +package uno.fastcampus.testdata.service; + +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import uno.fastcampus.testdata.domain.TableSchema; +import uno.fastcampus.testdata.domain.constant.ExportFileType; +import uno.fastcampus.testdata.dto.TableSchemaDto; +import uno.fastcampus.testdata.repository.TableSchemaRepository; +import uno.fastcampus.testdata.service.exporter.MockDataFileExporterContext; + +@RequiredArgsConstructor +@Service +public class SchemaExportService { + + private final MockDataFileExporterContext mockDataFileExporterContext; + private final TableSchemaRepository tableSchemaRepository; + + public String export(ExportFileType fileType, TableSchemaDto dto, Integer rowCount) { + if (dto.userId() != null) { + tableSchemaRepository.findByUserIdAndSchemaName(dto.userId(), dto.schemaName()) + .ifPresent(TableSchema::markExported); + } + + return mockDataFileExporterContext.export(fileType, dto, rowCount); + } + +} diff --git a/src/test/java/uno/fastcampus/testdata/controller/TableSchemaControllerTest.java b/src/test/java/uno/fastcampus/testdata/controller/TableSchemaControllerTest.java index 15ede75..e1730c7 100644 --- a/src/test/java/uno/fastcampus/testdata/controller/TableSchemaControllerTest.java +++ b/src/test/java/uno/fastcampus/testdata/controller/TableSchemaControllerTest.java @@ -18,6 +18,7 @@ import uno.fastcampus.testdata.dto.request.TableSchemaExportRequest; import uno.fastcampus.testdata.dto.request.TableSchemaRequest; import uno.fastcampus.testdata.dto.security.GithubUser; +import uno.fastcampus.testdata.service.SchemaExportService; import uno.fastcampus.testdata.service.TableSchemaService; import uno.fastcampus.testdata.util.FormDataEncoder; @@ -42,6 +43,7 @@ class TableSchemaControllerTest { @Autowired private ObjectMapper mapper; @MockBean private TableSchemaService tableSchemaService; + @MockBean private SchemaExportService schemaExportService; @DisplayName("[GET] 테이블 스키마 조회, 비로그인 최초 진입 (정상)") @Test @@ -162,7 +164,7 @@ void givenAuthenticatedUserAndSchemaName_whenDeleting_thenRedirectsToTableSchema then(tableSchemaService).should().deleteTableSchema(githubUser.id(), schemaName); } - @DisplayName("[GET] 테이블 스키마 파일 다운로드 (정상)") + @DisplayName("[GET] 테이블 스키마 파일 다운로드, 비로그인 (정상)") @Test void givenTableSchema_whenDownloading_thenReturnsFile() throws Exception { // Given @@ -177,13 +179,49 @@ void givenTableSchema_whenDownloading_thenReturnsFile() throws Exception { ) ); String queryParam = formDataEncoder.encode(request, false); + String expectedBody = "id,name,age\n1,uno,20"; + given(schemaExportService.export(request.getFileType(), request.toDto(null), request.getRowCount())) + .willReturn(expectedBody); // When & Then mvc.perform(get("/table-schema/export?" + queryParam)) .andExpect(status().isOk()) .andExpect(content().contentTypeCompatibleWith(MediaType.TEXT_PLAIN)) .andExpect(header().string(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=test.csv")) - .andExpect(content().json(mapper.writeValueAsString(request))); // TODO: 나중에 데이터 바꿔야 함 + .andExpect(content().string(expectedBody)); + then(schemaExportService).should().export(request.getFileType(), request.toDto(null), request.getRowCount()); + } + + @DisplayName("[GET] 테이블 스키마 파일 다운로드, 로그인 (정상)") + @Test + void givenAuthenticatedUserAndTableSchema_whenDownloading_thenReturnsFile() throws Exception { + // Given + var githubUser = new GithubUser("test-id", "test-name", "test@email.com"); + TableSchemaExportRequest request = TableSchemaExportRequest.of( + "test", + 77, + ExportFileType.CSV, + List.of( + SchemaFieldRequest.of("id", MockDataType.ROW_NUMBER, 1, 0, null, null), + SchemaFieldRequest.of("name", MockDataType.STRING, 1, 0, "option", "well"), + SchemaFieldRequest.of("age", MockDataType.NUMBER, 3, 20, null, null) + ) + ); + String queryParam = formDataEncoder.encode(request, false); + String expectedBody = "id,name,age\n1,uno,20"; + given(schemaExportService.export(request.getFileType(), request.toDto(githubUser.id()), request.getRowCount())) + .willReturn(expectedBody); + + // When & Then + mvc.perform( + get("/table-schema/export?" + queryParam) + .with(oauth2Login().oauth2User(githubUser)) + ) + .andExpect(status().isOk()) + .andExpect(content().contentTypeCompatibleWith(MediaType.TEXT_PLAIN)) + .andExpect(header().string(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=test.csv")) + .andExpect(content().string(expectedBody)); + then(schemaExportService).should().export(request.getFileType(), request.toDto(githubUser.id()), request.getRowCount()); } } diff --git a/src/test/java/uno/fastcampus/testdata/service/SchemaExportServiceTest.java b/src/test/java/uno/fastcampus/testdata/service/SchemaExportServiceTest.java new file mode 100644 index 0000000..346218d --- /dev/null +++ b/src/test/java/uno/fastcampus/testdata/service/SchemaExportServiceTest.java @@ -0,0 +1,71 @@ +package uno.fastcampus.testdata.service; + +import org.junit.jupiter.api.DisplayName; +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 uno.fastcampus.testdata.domain.TableSchema; +import uno.fastcampus.testdata.domain.constant.ExportFileType; +import uno.fastcampus.testdata.dto.TableSchemaDto; +import uno.fastcampus.testdata.repository.TableSchemaRepository; +import uno.fastcampus.testdata.service.exporter.MockDataFileExporterContext; + +import java.util.Optional; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.BDDMockito.given; +import static org.mockito.BDDMockito.then; + +@DisplayName("[Service] 스키마 파일 출력 서비스 테스트") +@ExtendWith(MockitoExtension.class) +class SchemaExportServiceTest { + + @InjectMocks private SchemaExportService sut; + + @Mock private MockDataFileExporterContext mockDataFileExporterContext; + @Mock private TableSchemaRepository tableSchemaRepository; + + @DisplayName("출력 파일 유형과 스키마 정보와 행 수가 주어지면, 엔티티 출력 여부를 마킹하고 알맞은 파일 유형으로 가짜 테이터 파일을 반환한다.") + @Test + void givenFileTypeAndSchemaAndRowCount_whenExporting_thenMarksEntityExportedAndReturnsFileFormattedString() { + // Given + ExportFileType exportFileType = ExportFileType.CSV; + TableSchemaDto dto = TableSchemaDto.of("test_schema", "uno", null, null); + int rowCount = 5; + TableSchema exectedTableSchema = TableSchema.of(dto.schemaName(), dto.userId()); + given(tableSchemaRepository.findByUserIdAndSchemaName(dto.userId(), dto.schemaName())) + .willReturn(Optional.of(exectedTableSchema)); + given(mockDataFileExporterContext.export(exportFileType, dto, rowCount)).willReturn("test,file,format"); + + // When + String result = sut.export(exportFileType, dto, rowCount); + + // Then + assertThat(result).isEqualTo("test,file,format"); + assertThat(exectedTableSchema.isExported()).isTrue(); + then(tableSchemaRepository).should().findByUserIdAndSchemaName(dto.userId(), dto.schemaName()); + then(mockDataFileExporterContext).should().export(exportFileType, dto, rowCount); + } + + @DisplayName("입력 파라미터 중에 유저 식별 정보가 없으면, 스키마 테이블 조회를 시도하지 않는다.") + @Test + void givenNoUserIdInParams_whenExporting_thenDoesNotTrySelectingTableSchema() { + // Given + ExportFileType exportFileType = ExportFileType.CSV; + TableSchemaDto dto = TableSchemaDto.of("test_schema", null, null, null); + int rowCount = 5; + given(mockDataFileExporterContext.export(exportFileType, dto, rowCount)).willReturn("test,file,format"); + + // When + String result = sut.export(exportFileType, dto, rowCount); + + // Then + assertThat(result).isEqualTo("test,file,format"); + then(tableSchemaRepository).shouldHaveNoInteractions(); + then(mockDataFileExporterContext).should().export(exportFileType, dto, rowCount); + } + +}