Skip to content

Commit

Permalink
Merge pull request #121 from depromeet/feature/#120
Browse files Browse the repository at this point in the history
[feat][#120] list도 추가
  • Loading branch information
sejoon00 authored Sep 11, 2024
2 parents 4957f0c + 923ed95 commit b3f59b0
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 48 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,9 @@
import com.server.bbo_gak.global.utils.BaseDateTimeFormatter;
import java.util.List;
import java.util.Optional;
import lombok.AccessLevel;
import lombok.Builder;

@Builder(access = AccessLevel.PRIVATE)
@Builder
public record CardGetResponse(
String title,
String content,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
package com.server.bbo_gak.domain.card.dto.response;

import com.server.bbo_gak.domain.card.entity.Tag;
import lombok.AccessLevel;
import lombok.Builder;

@Builder(access = AccessLevel.PRIVATE)
@Builder
public record TagGetResponse(
Long id,
String name,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,19 @@
import com.server.bbo_gak.domain.card.dto.request.CardCreateRequest;
import com.server.bbo_gak.domain.card.dto.request.CardTitleUpdateRequest;
import com.server.bbo_gak.domain.card.dto.request.CardTypeUpdateRequest;
import com.server.bbo_gak.domain.card.dto.response.CardGetResponse;
import com.server.bbo_gak.domain.card.dto.response.TagGetResponse;
import com.server.bbo_gak.domain.card.entity.Card;
import com.server.bbo_gak.domain.card.entity.CardType;
import com.server.bbo_gak.domain.card.entity.CardTypeValueGroup;
import com.server.bbo_gak.global.AbstractRestDocsTests;
import com.server.bbo_gak.global.RestDocsFactory;
import jakarta.persistence.EntityManager;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.List;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
Expand Down Expand Up @@ -86,38 +91,52 @@ class 카드_타입_카운트_조회 {
@Nested
class 카드_단건_조회 {

private CardGetResponse response;

@BeforeEach
void setUp() {
TagGetResponse tag1 = TagGetResponse.builder()
.id(1L)
.name("스프링")
.type("역량")
.build();

List<TagGetResponse> tagList = List.of(tag1);

List<String> cardTypeValueList = List.of("Type1", "Type2");

CardGetResponse response = CardGetResponse.builder()
.title("test_title")
.content("test_content")
.createdDate(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")))
.updatedDate(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")))
.recruitTitle("Recruit Title")
.cardTypeValueGroup("Type1")
.cardTypeValueList(cardTypeValueList)
.tagList(tagList)
.build();
}

@Test
public void 성공() throws Exception {
mockMvc.perform(get(DEFAULT_URL + "/cards/{card-id}", 1).contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON)).andExpect(status().isOk()).andDo(
document("[select] 카드 단건 조회", preprocessResponse(prettyPrint()), resource(
ResourceSnippetParameters.builder().description("카드 단건 조회").tags("Card")
.pathParameters(parameterWithName("card-id").description("card-id"))
.responseSchema(Schema.schema("CardGetResponse"))
.responseFields(fieldWithPath("title").type(JsonFieldType.STRING).description("Card 제목"),
fieldWithPath("content").type(JsonFieldType.STRING).description("Card 내용"),
fieldWithPath("recruitTitle").type(JsonFieldType.STRING).optional().description("공고 제목"),
fieldWithPath("cardTypeValueList").type(JsonFieldType.ARRAY).description("Card 타입값 리스트"),
fieldWithPath("createdDate").type(JsonFieldType.STRING).description("Card 생성일시"),
fieldWithPath("updatedDate").type(JsonFieldType.STRING).description("Card 수정일시"),
fieldWithPath("cardTypeValueGroup").type(JsonFieldType.STRING).description("Card 그룹 이름"),
fieldWithPath("tagList.[].id").type(JsonFieldType.NUMBER).description("태그 ID"),
fieldWithPath("tagList.[].name").type(JsonFieldType.STRING).description("태그 이름"),
fieldWithPath("tagList.[].type").type(JsonFieldType.STRING).description("태그 타입"))
.build())));
mockMvc.perform(
restDocsFactory.createRequest(DEFAULT_URL + "/cards/{card-id}", null, HttpMethod.GET, objectMapper,
1L))
.andExpect(status().isOk())
.andDo(
restDocsFactory.getSuccessResource("[select] 카드 단건 조회", "카드 단건 조회", "Card",
null, response));
}

@Test
public void 카드_찾기_실패() throws Exception {
mockMvc.perform(get(DEFAULT_URL + "/cards/{card-id}", 9999).contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON)).andExpect(status().isNotFound()).andDo(
document("[select] 카드 찾기 실패", preprocessResponse(prettyPrint()), resource(
ResourceSnippetParameters.builder().description("카드 단건 조회").tags("Card")
.pathParameters(parameterWithName("card-id").description("card-id"))
.responseSchema(Schema.schema("ErrorResponse")).responseFields(
fieldWithPath("message").type(JsonFieldType.STRING).description("Error message"),
fieldWithPath("status").type(JsonFieldType.STRING).description("HTTP status code")).build())));

mockMvc.perform(
restDocsFactory.createRequest(DEFAULT_URL + "/cards/{card-id}", null, HttpMethod.GET, objectMapper,
9999L))
.andExpect(status().isNotFound())
.andDo(
restDocsFactory.getFailureResource("[select] 카드 찾기 실패", "Card",
null));
}
}

Expand Down
52 changes: 34 additions & 18 deletions src/test/java/com/server/bbo_gak/global/RestDocsFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -325,28 +325,40 @@ public <T> FieldDescriptor[] getFieldsList(T dto) {
}

private <T> void generateFieldDescriptors(T dto, String pathPrefix, List<FieldDescriptor> fields) {
if (isSimpleType(dto)) {
return;
}

Field[] declaredFields = dto.getClass().getDeclaredFields();
for (Field field : declaredFields) {
field.setAccessible(true);
String name = pathPrefix + field.getName();
JsonFieldType type = determineFieldType(field.getType());
Object value = getFieldValue(dto, field);

if (type == JsonFieldType.OBJECT) {
// 중첩된 객체 처리
fields.add(fieldWithPath(name)
.type(JsonFieldType.OBJECT)
.description(field.getName())
.optional());
if (value != null) {
generateFieldDescriptors(value, name + ".", fields);
String fieldPath = pathPrefix + field.getName();
JsonFieldType fieldType = determineFieldType(field.getType());
Object fieldValue = getFieldValue(dto, field);

FieldDescriptor descriptor = fieldWithPath(fieldPath)
.type(fieldType)
.description(field.getName())
.optional();

if (fieldType != JsonFieldType.OBJECT && fieldType != JsonFieldType.ARRAY) {
descriptor.attributes(
Attributes.key("example").value(fieldValue != null ? fieldValue.toString() : "null"));
}

fields.add(descriptor);

// 리스트 타입 처리
if (fieldType == JsonFieldType.ARRAY && fieldValue instanceof List<?> list) {
if (!list.isEmpty()) {
Object firstElement = list.getFirst();
generateFieldDescriptors(firstElement, fieldPath + "[].", fields);
}
} else {
fields.add(fieldWithPath(name)
.type(type)
.description(field.getName())
.optional()
.attributes(Attributes.key("example").value(value != null ? value.toString() : "null")));
}

// 오브젝트 타입 처리
if (fieldType == JsonFieldType.OBJECT && fieldValue != null) {
generateFieldDescriptors(fieldValue, fieldPath + ".", fields);
}
}
}
Expand All @@ -359,6 +371,10 @@ private <T> Object getFieldValue(T dto, Field field) {
}
}

private boolean isSimpleType(Object dto) {
return dto instanceof String || dto instanceof Number || dto instanceof Boolean || dto.getClass().isEnum();
}

private JsonFieldType determineFieldType(Class<?> fieldType) {
if (fieldType == String.class || fieldType.isEnum()) {
return JsonFieldType.STRING;
Expand Down

0 comments on commit b3f59b0

Please sign in to comment.