Skip to content

Commit

Permalink
#29 - 파일 출력기를 서비스 로직을 거쳐 컨트롤러까지 연결
Browse files Browse the repository at this point in the history
  • Loading branch information
djkeh committed Aug 7, 2024
1 parent f031610 commit 7dbde10
Show file tree
Hide file tree
Showing 4 changed files with 150 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -31,6 +32,7 @@
public class TableSchemaController {

private final TableSchemaService tableSchemaService;
private final SchemaExportService schemaExportService;
private final ObjectMapper mapper;

@GetMapping("/table-schema")
Expand Down Expand Up @@ -89,12 +91,20 @@ public String deleteMySchema(
}

@GetMapping("/table-schema/export")
public ResponseEntity<String> exportTableSchema(TableSchemaExportRequest tableSchemaExportRequest) {
public ResponseEntity<String> 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);
}


Expand All @@ -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);
}
}

}
Original file line number Diff line number Diff line change
@@ -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);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -42,6 +43,7 @@ class TableSchemaControllerTest {
@Autowired private ObjectMapper mapper;

@MockBean private TableSchemaService tableSchemaService;
@MockBean private SchemaExportService schemaExportService;

@DisplayName("[GET] 테이블 스키마 조회, 비로그인 최초 진입 (정상)")
@Test
Expand Down Expand Up @@ -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
Expand All @@ -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", "[email protected]");
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());
}

}
Original file line number Diff line number Diff line change
@@ -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);
}

}

0 comments on commit 7dbde10

Please sign in to comment.