From a22967fc0ce4045d2dc5f62f93a6c61a7b1db629 Mon Sep 17 00:00:00 2001 From: Tim <135014430+nagisa77@users.noreply.github.com> Date: Mon, 4 Aug 2025 20:37:43 +0800 Subject: [PATCH] test: verify post dtos --- .../controller/PostControllerTest.java | 217 ++++++++++-------- 1 file changed, 115 insertions(+), 102 deletions(-) diff --git a/backend/src/test/java/com/openisle/controller/PostControllerTest.java b/backend/src/test/java/com/openisle/controller/PostControllerTest.java index 7da8cdb25..d9c786e6b 100644 --- a/backend/src/test/java/com/openisle/controller/PostControllerTest.java +++ b/backend/src/test/java/com/openisle/controller/PostControllerTest.java @@ -1,46 +1,36 @@ package com.openisle.controller; -import com.openisle.model.Post; -import com.openisle.model.User; -import com.openisle.model.Category; -import com.openisle.model.Tag; -import com.openisle.service.PostService; -import com.openisle.service.CommentService; -import com.openisle.service.ReactionService; -import com.openisle.service.CaptchaService; -import com.openisle.service.DraftService; -import com.openisle.service.LevelService; +import com.openisle.mapper.PostMapper; +import com.openisle.model.*; +import com.openisle.service.*; import org.junit.jupiter.api.Test; -import org.mockito.Mockito; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; 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.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.util.ReflectionTestUtils; import java.time.LocalDateTime; import java.util.List; +import java.util.Set; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -import org.springframework.test.util.ReflectionTestUtils; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.never; +import static org.mockito.ArgumentMatchers.*; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; +import static org.mockito.Mockito.*; @WebMvcTest(PostController.class) @AutoConfigureMockMvc(addFilters = false) +@Import(PostMapper.class) class PostControllerTest { @Autowired private MockMvc mockMvc; @Autowired private PostController postController; - @MockBean private PostService postService; @MockBean @@ -53,6 +43,10 @@ class PostControllerTest { private DraftService draftService; @MockBean private LevelService levelService; + @MockBean + private SubscriptionService subscriptionService; + @MockBean + private UserVisitService userVisitService; @Test void createAndGetPost() throws Exception { @@ -61,13 +55,9 @@ class PostControllerTest { Category cat = new Category(); cat.setId(1L); cat.setName("tech"); - cat.setDescription("d"); - cat.setIcon("i"); Tag tag = new Tag(); tag.setId(1L); tag.setName("java"); - tag.setDescription("td"); - tag.setIcon("ti"); Post post = new Post(); post.setId(1L); post.setTitle("t"); @@ -75,21 +65,70 @@ class PostControllerTest { post.setCreatedAt(LocalDateTime.now()); post.setAuthor(user); post.setCategory(cat); - post.setTags(java.util.Set.of(tag)); - Mockito.when(commentService.getParticipants(Mockito.anyLong(), Mockito.anyInt())).thenReturn(java.util.List.of()); - Mockito.when(postService.createPost(eq("alice"), eq(1L), eq("t"), eq("c"), eq(java.util.List.of(1L)))).thenReturn(post); - Mockito.when(postService.viewPost(eq(1L), Mockito.isNull())).thenReturn(post); + post.setTags(Set.of(tag)); + + when(postService.createPost(eq("alice"), eq(1L), eq("t"), eq("c"), eq(List.of(1L)))).thenReturn(post); + when(postService.viewPost(eq(1L), any())).thenReturn(post); + when(commentService.getCommentsForPost(eq(1L), any())).thenReturn(List.of()); + when(commentService.getParticipants(anyLong(), anyInt())).thenReturn(List.of()); + when(reactionService.getReactionsForPost(1L)).thenReturn(List.of()); + when(commentService.getLastCommentTime(1L)).thenReturn(null); mockMvc.perform(post("/api/posts") .contentType("application/json") .content("{\"title\":\"t\",\"content\":\"c\",\"categoryId\":1,\"tagIds\":[1]}") .principal(new UsernamePasswordAuthenticationToken("alice", "p"))) .andExpect(status().isOk()) - .andExpect(jsonPath("$.title").value("t")); + .andExpect(jsonPath("$.title").value("t")) + .andExpect(jsonPath("$.comments").isArray()) + .andExpect(jsonPath("$.comments").isEmpty()) + .andExpect(jsonPath("$.author.username").value("alice")) + .andExpect(jsonPath("$.category.name").value("tech")) + .andExpect(jsonPath("$.tags[0].name").value("java")) + .andExpect(jsonPath("$.subscribed").value(false)); mockMvc.perform(get("/api/posts/1")) .andExpect(status().isOk()) - .andExpect(jsonPath("$.id").value(1)); + .andExpect(jsonPath("$.id").value(1)) + .andExpect(jsonPath("$.comments").isArray()) + .andExpect(jsonPath("$.comments").isEmpty()) + .andExpect(jsonPath("$.subscribed").value(false)); + } + + @Test + void updatePostReturnsDetailDto() throws Exception { + User user = new User(); + user.setUsername("alice"); + Category cat = new Category(); + cat.setId(1L); + cat.setName("tech"); + Tag tag = new Tag(); + tag.setId(1L); + tag.setName("java"); + Post post = new Post(); + post.setId(1L); + post.setTitle("t2"); + post.setContent("c2"); + post.setCreatedAt(LocalDateTime.now()); + post.setAuthor(user); + post.setCategory(cat); + post.setTags(Set.of(tag)); + + when(postService.updatePost(eq(1L), eq("alice"), eq(1L), eq("t2"), eq("c2"), eq(List.of(1L)))).thenReturn(post); + when(commentService.getCommentsForPost(eq(1L), any())).thenReturn(List.of()); + when(commentService.getParticipants(anyLong(), anyInt())).thenReturn(List.of()); + when(reactionService.getReactionsForPost(1L)).thenReturn(List.of()); + when(commentService.getLastCommentTime(1L)).thenReturn(null); + + mockMvc.perform(put("/api/posts/1") + .contentType("application/json") + .content("{\"title\":\"t2\",\"content\":\"c2\",\"categoryId\":1,\"tagIds\":[1]}") + .principal(new UsernamePasswordAuthenticationToken("alice", "p"))) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.title").value("t2")) + .andExpect(jsonPath("$.comments").isArray()) + .andExpect(jsonPath("$.comments").isEmpty()) + .andExpect(jsonPath("$.author.username").value("alice")); } @Test @@ -99,13 +138,9 @@ class PostControllerTest { Category cat = new Category(); cat.setId(1L); cat.setName("tech"); - cat.setDescription("d"); - cat.setIcon("i"); Tag tag = new Tag(); tag.setId(1L); tag.setName("java"); - tag.setDescription("td"); - tag.setIcon("ti"); Post post = new Post(); post.setId(2L); post.setTitle("hello"); @@ -113,21 +148,28 @@ class PostControllerTest { post.setCreatedAt(LocalDateTime.now()); post.setAuthor(user); post.setCategory(cat); - post.setTags(java.util.Set.of(tag)); - Mockito.when(commentService.getParticipants(Mockito.anyLong(), Mockito.anyInt())).thenReturn(java.util.List.of()); - Mockito.when(postService.listPostsByCategories(Mockito.isNull(), Mockito.isNull(), Mockito.isNull())) - .thenReturn(List.of(post)); + post.setTags(Set.of(tag)); + + when(postService.listPostsByCategories(null, null, null)).thenReturn(List.of(post)); + when(commentService.getParticipants(anyLong(), anyInt())).thenReturn(List.of()); + when(reactionService.getReactionsForPost(anyLong())).thenReturn(List.of()); + when(commentService.getLastCommentTime(anyLong())).thenReturn(null); mockMvc.perform(get("/api/posts")) .andExpect(status().isOk()) - .andExpect(jsonPath("$[0].title").value("hello")); + .andExpect(jsonPath("$[0].title").value("hello")) + .andExpect(jsonPath("$[0].comments").doesNotExist()) + .andExpect(jsonPath("$[0].author.username").value("bob")) + .andExpect(jsonPath("$[0].category.name").value("tech")) + .andExpect(jsonPath("$[0].tags[0].name").value("java")) + .andExpect(jsonPath("$[0].subscribed").value(false)); } @Test void createPostRejectsInvalidCaptcha() throws Exception { - org.springframework.test.util.ReflectionTestUtils.setField(postController, "captchaEnabled", true); - org.springframework.test.util.ReflectionTestUtils.setField(postController, "postCaptchaEnabled", true); - Mockito.when(captchaService.verify("bad")).thenReturn(false); + ReflectionTestUtils.setField(postController, "captchaEnabled", true); + ReflectionTestUtils.setField(postController, "postCaptchaEnabled", true); + when(captchaService.verify("bad")).thenReturn(false); mockMvc.perform(post("/api/posts") .contentType("application/json") @@ -155,7 +197,7 @@ class PostControllerTest { post.setCreatedAt(LocalDateTime.now()); post.setAuthor(user); post.setCategory(cat); - post.setTags(java.util.Set.of(tag)); + post.setTags(Set.of(tag)); com.openisle.model.Comment comment = new com.openisle.model.Comment(); comment.setId(2L); @@ -183,84 +225,55 @@ class PostControllerTest { cr.setComment(comment); cr.setType(com.openisle.model.ReactionType.LIKE); - Mockito.when(postService.viewPost(eq(1L), Mockito.isNull())).thenReturn(post); - Mockito.when(commentService.getCommentsForPost(eq(1L), any())).thenReturn(List.of(comment)); - Mockito.when(commentService.getReplies(2L)).thenReturn(List.of(reply)); - Mockito.when(commentService.getReplies(3L)).thenReturn(List.of()); - Mockito.when(commentService.getParticipants(Mockito.anyLong(), Mockito.anyInt())).thenReturn(java.util.List.of()); - Mockito.when(reactionService.getReactionsForPost(1L)).thenReturn(List.of(pr)); - Mockito.when(reactionService.getReactionsForComment(2L)).thenReturn(List.of(cr)); - Mockito.when(reactionService.getReactionsForComment(3L)).thenReturn(List.of()); + when(postService.viewPost(eq(1L), any())).thenReturn(post); + when(commentService.getCommentsForPost(eq(1L), any())).thenReturn(List.of(comment)); + when(commentService.getReplies(2L)).thenReturn(List.of(reply)); + when(commentService.getReplies(3L)).thenReturn(List.of()); + when(commentService.getParticipants(anyLong(), anyInt())).thenReturn(List.of()); + when(commentService.getLastCommentTime(1L)).thenReturn(null); + when(reactionService.getReactionsForPost(1L)).thenReturn(List.of(pr)); + when(reactionService.getReactionsForComment(2L)).thenReturn(List.of(cr)); + when(reactionService.getReactionsForComment(3L)).thenReturn(List.of()); mockMvc.perform(get("/api/posts/1")) .andExpect(status().isOk()) .andExpect(jsonPath("$.reactions[0].id").value(10)) .andExpect(jsonPath("$.comments[0].replies[0].id").value(3)) - .andExpect(jsonPath("$.comments[0].reactions[0].id").value(11)); + .andExpect(jsonPath("$.comments[0].reactions[0].id").value(11)) + .andExpect(jsonPath("$.author.username").value("alice")) + .andExpect(jsonPath("$.category.name").value("tech")) + .andExpect(jsonPath("$.tags[0].name").value("java")); } @Test - void listPostsByCategoriesAndTags() throws Exception { + void getPostSubscriptionStatus() throws Exception { User user = new User(); user.setUsername("alice"); Category cat = new Category(); + cat.setId(1L); cat.setName("tech"); - Tag tag = new Tag(); - tag.setId(1L); - tag.setName("java"); Post post = new Post(); - post.setId(2L); - post.setTitle("hello"); + post.setId(1L); + post.setTitle("t"); + post.setContent("c"); post.setCreatedAt(LocalDateTime.now()); post.setAuthor(user); post.setCategory(cat); - post.setTags(java.util.Set.of(tag)); - Mockito.when(commentService.getParticipants(Mockito.anyLong(), Mockito.anyInt())).thenReturn(java.util.List.of()); + post.setTags(Set.of()); - Mockito.when(postService.listPostsByCategoriesAndTags(eq(java.util.List.of(1L)), eq(java.util.List.of(1L, 2L)), eq(0), eq(5))) - .thenReturn(List.of(post)); + when(postService.viewPost(eq(1L), any())).thenReturn(post); + when(commentService.getCommentsForPost(eq(1L), any())).thenReturn(List.of()); + when(commentService.getParticipants(anyLong(), anyInt())).thenReturn(List.of()); + when(reactionService.getReactionsForPost(1L)).thenReturn(List.of()); + when(commentService.getLastCommentTime(1L)).thenReturn(null); + when(subscriptionService.isPostSubscribed("alice", 1L)).thenReturn(true); - mockMvc.perform(get("/api/posts") - .param("tagIds", "1,2") - .param("page", "0") - .param("pageSize", "5") - .param("categoryId", "1")) + mockMvc.perform(get("/api/posts/1").principal(new UsernamePasswordAuthenticationToken("alice", "p"))) .andExpect(status().isOk()) - .andExpect(jsonPath("$[0].id").value(2)); + .andExpect(jsonPath("$.subscribed").value(true)); - verify(postService).listPostsByCategoriesAndTags(eq(java.util.List.of(1L)), eq(java.util.List.of(1L, 2L)), eq(0), eq(5)); - verify(postService, never()).listPostsByCategories(any(), any(), any()); - } - - @Test - void rankingPostsFiltered() throws Exception { - User user = new User(); - user.setUsername("alice"); - Category cat = new Category(); - cat.setName("tech"); - Tag tag = new Tag(); - tag.setId(1L); - tag.setName("java"); - Post post = new Post(); - post.setId(3L); - post.setTitle("rank"); - post.setCreatedAt(LocalDateTime.now()); - post.setAuthor(user); - post.setCategory(cat); - post.setTags(java.util.Set.of(tag)); - Mockito.when(commentService.getParticipants(Mockito.anyLong(), Mockito.anyInt())).thenReturn(java.util.List.of()); - - Mockito.when(postService.listPostsByViews(eq(java.util.List.of(1L)), eq(java.util.List.of(1L, 2L)), eq(0), eq(5))) - .thenReturn(List.of(post)); - - mockMvc.perform(get("/api/posts/ranking") - .param("tagIds", "1,2") - .param("page", "0") - .param("pageSize", "5") - .param("categoryId", "1")) + mockMvc.perform(get("/api/posts/1")) .andExpect(status().isOk()) - .andExpect(jsonPath("$[0].id").value(3)); - - verify(postService).listPostsByViews(eq(java.util.List.of(1L)), eq(java.util.List.of(1L, 2L)), eq(0), eq(5)); + .andExpect(jsonPath("$.subscribed").value(false)); } }