#16 board : article controller impl

This commit is contained in:
haerong22
2022-08-14 04:17:09 +09:00
parent 7e1ed339b1
commit 05a75ee55b
3 changed files with 81 additions and 13 deletions

View File

@@ -1,27 +1,43 @@
package com.example.board.controller;
import com.example.board.domain.type.SearchType;
import com.example.board.dto.response.ArticleResponse;
import com.example.board.dto.response.ArticleWithCommentsResponse;
import com.example.board.service.ArticleService;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.web.PageableDefault;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
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 java.util.List;
@RequiredArgsConstructor
@RequestMapping("/articles")
@Controller
public class ArticleController {
private final ArticleService articleService;
@GetMapping
public String articles(ModelMap map) {
map.addAttribute("articles", List.of());
public String articles(
@RequestParam(required = false) SearchType searchType,
@RequestParam(required = false) String searchValue,
@PageableDefault(size = 10, sort = "createdAt", direction = Sort.Direction.DESC) Pageable pageable,
ModelMap map) {
map.addAttribute("articles", articleService.searchArticles(searchType, searchValue, pageable).map(ArticleResponse::from));
return "articles/index";
}
@GetMapping("/{articleId}")
public String article(@PathVariable Long articleId, ModelMap map) {
map.addAttribute("article", "article");
map.addAttribute("articleComments", List.of());
ArticleWithCommentsResponse article = ArticleWithCommentsResponse.from(articleService.getArticle(articleId));
map.addAttribute("article", article);
map.addAttribute("articleComments", article.articleCommentsResponse());
return "articles/detail";
}
}

View File

@@ -8,7 +8,7 @@ import java.util.LinkedHashSet;
import java.util.Set;
import java.util.stream.Collectors;
public record ArticleWithCommentResponse(
public record ArticleWithCommentsResponse(
Long id,
String title,
String content,
@@ -16,20 +16,20 @@ public record ArticleWithCommentResponse(
LocalDateTime createdAt,
String email,
String nickname,
Set<ArticleCommentResponse> articleCommentResponses
Set<ArticleCommentResponse> articleCommentsResponse
) implements Serializable {
public static ArticleWithCommentResponse of(Long id, String title, String content, String hashtag, LocalDateTime createdAt, String email, String nickname, Set<ArticleCommentResponse> articleCommentResponses) {
return new ArticleWithCommentResponse(id, title, content, hashtag, createdAt, email, nickname, articleCommentResponses);
public static ArticleWithCommentsResponse of(Long id, String title, String content, String hashtag, LocalDateTime createdAt, String email, String nickname, Set<ArticleCommentResponse> articleCommentResponses) {
return new ArticleWithCommentsResponse(id, title, content, hashtag, createdAt, email, nickname, articleCommentResponses);
}
public static ArticleWithCommentResponse from(ArticleWithCommentsDto dto) {
public static ArticleWithCommentsResponse from(ArticleWithCommentsDto dto) {
String nickname = dto.userAccountDto().nickname();
if (nickname == null || nickname.isBlank()) {
nickname = dto.userAccountDto().userId();
}
return new ArticleWithCommentResponse(
return new ArticleWithCommentsResponse(
dto.id(),
dto.title(),
dto.content(),

View File

@@ -1,15 +1,25 @@
package com.example.board.controller;
import com.example.board.config.SecurityConfig;
import com.example.board.dto.ArticleWithCommentsDto;
import com.example.board.dto.UserAccountDto;
import com.example.board.service.ArticleService;
import org.junit.jupiter.api.Disabled;
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.context.annotation.Import;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import java.time.LocalDateTime;
import java.util.Set;
import static org.mockito.BDDMockito.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
@@ -20,6 +30,9 @@ class ArticleControllerTest {
private final MockMvc mockMvc;
@MockBean
private ArticleService articleService;
public ArticleControllerTest(@Autowired MockMvc mockMvc) {
this.mockMvc = mockMvc;
}
@@ -28,6 +41,8 @@ class ArticleControllerTest {
@Test
public void givenNothing_whenRequestingArticlesView_thenReturnsArticlesView() throws Exception {
// given
given(articleService.searchArticles(eq(null), eq(null), any(Pageable.class)))
.willReturn(Page.empty());
// when & then
mockMvc.perform(get("/articles"))
@@ -36,21 +51,28 @@ class ArticleControllerTest {
.andExpect(view().name("articles/index"))
.andExpect(model().attributeExists("articles"))
;
then(articleService).should().searchArticles(eq(null), eq(null), any(Pageable.class));
}
@DisplayName("[view][GET] 게시글 상세 페이지 - 정상 호출")
@Test
public void givenNothing_whenRequestingArticleView_thenReturnsArticleView() throws Exception {
// given
Long articleId = 1L;
given(articleService.getArticle(articleId)).willReturn(createArticleWithCommentDto());
// when & then
mockMvc.perform(get("/articles/1"))
mockMvc.perform(get("/articles/" + articleId))
.andExpect(status().isOk())
.andExpect(content().contentTypeCompatibleWith(MediaType.TEXT_HTML))
.andExpect(view().name("articles/detail"))
.andExpect(model().attributeExists("article"))
.andExpect(model().attributeExists("articleComments"))
;
then(articleService).should().getArticle(articleId);
}
@Disabled("구현 중")
@@ -80,4 +102,34 @@ class ArticleControllerTest {
.andExpect(view().name("articles/search-hashtag"))
;
}
private ArticleWithCommentsDto createArticleWithCommentDto() {
return ArticleWithCommentsDto.of(
1L,
createUserAccountDto(),
Set.of(),
"title",
"content",
"#java",
LocalDateTime.now(),
"bobby",
LocalDateTime.now(),
"bobby"
);
}
private UserAccountDto createUserAccountDto() {
return UserAccountDto.of(
1L,
"bobby",
"1234",
"bobby@email.com",
"bobby",
"memo",
LocalDateTime.now(),
"bobby",
LocalDateTime.now(),
"bobby"
);
}
}