Add article query
게시글 단건 조회 추가
This commit is contained in:
@@ -1,8 +1,11 @@
|
||||
package com.yam.app.article.application;
|
||||
|
||||
import com.yam.app.article.domain.ArticleNotFoundException;
|
||||
import com.yam.app.article.domain.ArticleReader;
|
||||
import com.yam.app.article.domain.WriteArticleProcessor;
|
||||
import com.yam.app.article.presentation.ArticlePreviewResponse;
|
||||
import com.yam.app.article.presentation.ArticleResponse;
|
||||
import com.yam.app.article.presentation.TagResponse;
|
||||
import com.yam.app.article.presentation.WriteArticleCommand;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
@@ -38,4 +41,26 @@ public class ArticleFacade {
|
||||
dto.getStatus())
|
||||
).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public ArticleResponse findById(Long articleId) {
|
||||
var article = articleReader.findById(articleId).orElseThrow(
|
||||
() -> new ArticleNotFoundException(articleId));
|
||||
|
||||
return ArticleResponse.builder()
|
||||
.id(article.getId())
|
||||
.authorId(article.getAuthorId())
|
||||
.title(article.getTitle())
|
||||
.content(article.getContent())
|
||||
.image(article.getImage())
|
||||
.createdAt(article.getCreatedAt())
|
||||
.modifiedAt(article.getModifiedAt())
|
||||
.tags(
|
||||
article.getTags().stream()
|
||||
.map(a -> TagResponse.of(a.getTag().getId(), a.getTag().getName()))
|
||||
.collect(Collectors.toList())
|
||||
)
|
||||
.build();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import com.yam.app.common.ApiResult;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
@@ -29,4 +30,9 @@ public final class ArticleQueryApi {
|
||||
return ResponseEntity.ok(
|
||||
ApiResult.success(articleFacade.findAll(offset, limit)));
|
||||
}
|
||||
|
||||
@GetMapping("/api/articles/{articleId}")
|
||||
public ResponseEntity<ArticleResponse> showArticle(@PathVariable Long articleId) {
|
||||
return ResponseEntity.ok(articleFacade.findById(articleId));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.yam.app.article.presentation;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@Builder
|
||||
public final class ArticleResponse {
|
||||
|
||||
private final Long id;
|
||||
private final Long authorId;
|
||||
private final String title;
|
||||
private final String content;
|
||||
private final String image;
|
||||
private final LocalDateTime createdAt;
|
||||
private final LocalDateTime modifiedAt;
|
||||
private final List<TagResponse> tags;
|
||||
|
||||
private ArticleResponse(Long id, Long authorId, String title, String content, String image,
|
||||
LocalDateTime createdAt, LocalDateTime modifiedAt,
|
||||
List<TagResponse> tags) {
|
||||
this.id = id;
|
||||
this.authorId = authorId;
|
||||
this.title = title;
|
||||
this.content = content;
|
||||
this.image = image;
|
||||
this.createdAt = createdAt;
|
||||
this.modifiedAt = modifiedAt;
|
||||
this.tags = tags;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.yam.app.article.presentation;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
public final class TagResponse {
|
||||
|
||||
private final Long id;
|
||||
private final String name;
|
||||
|
||||
private TagResponse(Long id, String name) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public static TagResponse of(Long id, String name) {
|
||||
return new TagResponse(id, name);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -4,6 +4,8 @@ public final class ArticleApiUri {
|
||||
|
||||
public static final String WRITE_ARTICLE = "/api/articles/write";
|
||||
public static final String FIND_ALL = "/api/articles/all";
|
||||
public static final String FIND_BY_ID = "/api/articles/";
|
||||
|
||||
private ArticleApiUri() {}
|
||||
private ArticleApiUri() {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
package com.yam.app.article.presentation;
|
||||
|
||||
import static com.yam.app.article.presentation.ArticleApiUri.FIND_BY_ID;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
import com.yam.app.article.application.ArticleFacade;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.test.context.ActiveProfiles;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
|
||||
@DisplayName("Article Qurey HTTP API")
|
||||
@WebMvcTest(ArticleQueryApi.class)
|
||||
@ActiveProfiles("test")
|
||||
class ArticleQueryApiTest {
|
||||
|
||||
@Autowired
|
||||
private MockMvc mockMvc;
|
||||
@MockBean
|
||||
private ArticleFacade articleFacade;
|
||||
|
||||
@Test
|
||||
@DisplayName("인증되지 않은 사용자가 게시글 조회 요청을 보냈다면 401에러를 반환한다.")
|
||||
void unauthenticated_user_request() throws Exception {
|
||||
//Act
|
||||
final var actions = mockMvc.perform(get(FIND_BY_ID + 1)
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.accept(MediaType.APPLICATION_JSON)
|
||||
);
|
||||
|
||||
//Assert
|
||||
actions
|
||||
.andExpect(status().isUnauthorized())
|
||||
.andExpect(jsonPath("$.success").value(false))
|
||||
.andExpect(jsonPath("$.data").doesNotExist())
|
||||
.andExpect(jsonPath("$.message").value("Unauthorized request"));
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user