correct notification, add community

Change-Id: Ifb87c82f5a074b1e4b653fe109bcea403b9848f8
diff --git a/src/test/java/com/g9/g9backend/controller/CommunityControllerTest.java b/src/test/java/com/g9/g9backend/controller/CommunityControllerTest.java
new file mode 100644
index 0000000..da9bf57
--- /dev/null
+++ b/src/test/java/com/g9/g9backend/controller/CommunityControllerTest.java
@@ -0,0 +1,268 @@
+package com.g9.g9backend.controller;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.g9.g9backend.pojo.Community;
+import com.g9.g9backend.pojo.Subscription;
+import com.g9.g9backend.pojo.Thread;
+import com.g9.g9backend.service.CommunityService;
+import com.g9.g9backend.service.SubscriptionService;
+import com.g9.g9backend.service.ThreadLikeService;
+import com.g9.g9backend.service.ThreadService;
+import org.jetbrains.annotations.NotNull;
+import org.junit.jupiter.api.BeforeEach;
+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 org.springframework.http.MediaType;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.when;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
+
+@ExtendWith(MockitoExtension.class)
+public class CommunityControllerTest {
+
+    private MockMvc mockMvc;
+
+    @InjectMocks
+    private CommunityController communityController;
+
+    @Mock
+    private CommunityService communityService;
+
+    @Mock
+    private ThreadService threadService;
+
+    @Mock
+    private SubscriptionService subscriptionService;
+
+    @Mock
+    private ThreadLikeService threadLikeService;
+
+    private final ObjectMapper objectMapper = new ObjectMapper();
+
+    @BeforeEach
+    public void setup() {
+        mockMvc = MockMvcBuilders.standaloneSetup(communityController).build();
+    }
+
+    @Test
+    public void shouldReturnHotCommunities_whenCallingHotEndpoint() throws Exception {
+        Community c1 = new Community(1, "社区A", "pic", "desc", 9.0f, "type", 5, 1);
+        Page<Community> page = createCommunityPage(List.of(c1));
+        when(communityService.page(any(), any())).thenReturn(page);
+
+        mockMvc.perform(get("/community/hot"))
+                .andExpect(status().isOk())
+                .andExpect(jsonPath("$.communityList[0].communityId").value(1));
+    }
+
+    @Test
+    public void shouldReturnCommonCommunities_whenCallingCommonEndpoint() throws Exception {
+        Community c1 = new Community(2, "社区B", "pic", "desc", 7.0f, "type", 3, 1);
+        Page<Community> page = createCommunityPage(List.of(c1));
+        when(communityService.page(any(), any())).thenReturn(page);
+
+        mockMvc.perform(get("/community/common"))
+                .andExpect(status().isOk())
+                .andExpect(jsonPath("$.communityList[0].communityId").value(2));
+    }
+
+    @Test
+    public void shouldReturnCommunityInfo_whenIdIsValid() throws Exception {
+        Community community = new Community(3, "社区C", "pic", "desc", 6.0f, "type", 4, 2);
+        when(communityService.getById(3)).thenReturn(community);
+
+        mockMvc.perform(get("/community/info").param("communityId", "3"))
+                .andExpect(status().isOk())
+                .andExpect(jsonPath("$.communityId").value(3));
+    }
+
+    @Test
+    public void shouldReturnThreadDetails_whenThreadIdAndUserIdAreValid() throws Exception {
+        Thread thread = mockThread(1, 10);
+        when(threadService.getById(1)).thenReturn(thread);
+        when(threadLikeService.getOne(any())).thenReturn(null);
+
+        mockMvc.perform(get("/thread")
+                        .param("threadId", "1")
+                        .param("userId", "10"))
+                .andExpect(status().isOk())
+                .andExpect(jsonPath("$.threadId").value(1))
+                .andExpect(jsonPath("$.userId").value(10));
+    }
+
+    @Test
+    public void shouldPostThread_whenValidRequest() throws Exception {
+        Thread thread = new Thread();
+        thread.setThreadId(100);
+        thread.setCommunityId(1);
+
+        Community community = new Community();
+        community.setCommunityId(1);
+        community.setThreadNumber(5);
+
+        when(communityService.getById(1)).thenReturn(community);
+
+        mockMvc.perform(post("/thread")
+                        .contentType(MediaType.APPLICATION_JSON)
+                        .content(objectMapper.writeValueAsString(thread)))
+                .andExpect(status().isOk());
+    }
+
+    @Test
+    public void shouldLikeThread_whenValidInput() throws Exception {
+        Thread thread = new Thread();
+        thread.setThreadId(100);
+        thread.setLikes(5);
+
+        when(threadService.getById(100)).thenReturn(thread);
+
+        mockMvc.perform(post("/thread/like")
+                        .contentType(MediaType.APPLICATION_JSON)
+                        .content("{\"userId\":1, \"threadId\":100}"))
+                .andExpect(status().isOk());
+    }
+
+    @Test
+    public void shouldDeleteThread_whenThreadExists() throws Exception {
+        Thread thread = new Thread();
+        thread.setThreadId(100);
+        thread.setCommunityId(1);
+
+        Community community = new Community();
+        community.setCommunityId(1);
+        community.setThreadNumber(5);
+
+        when(threadService.getById(100)).thenReturn(thread);
+        when(communityService.getById(1)).thenReturn(community);
+
+        mockMvc.perform(delete("/thread").param("threadId", "100"))
+                .andExpect(status().isNoContent());
+    }
+
+    @Test
+    public void shouldCancelLike_whenValidRequest() throws Exception {
+        Thread thread = new Thread();
+        thread.setThreadId(100);
+        thread.setLikes(5);
+
+        when(threadService.getById(100)).thenReturn(thread);
+
+        mockMvc.perform(delete("/thread/like")
+                        .param("userId", "1")
+                        .param("threadId", "100"))
+                .andExpect(status().isNoContent());
+    }
+
+    @Test
+    public void shouldReturnCommunities_whenSearchingByType() throws Exception {
+        Community c = new Community(1, "搜索社区", "pic", "desc", 9.5f, "test", 8, 5);
+        Page<Community> page = createCommunityPage(List.of(c));
+
+        when(communityService.page(any(), any())).thenReturn(page);
+
+        mockMvc.perform(get("/community")
+                        .param("searchValue", "搜索")
+                        .param("type", "test")
+                        .param("pageNumber", "1")
+                        .param("rows", "10"))
+                .andExpect(status().isOk())
+                .andExpect(jsonPath("$.records[0].communityId").value(1));
+    }
+
+    @Test
+    public void shouldReturnHotThreads_whenOptionIsHot() throws Exception {
+        Thread t = new Thread();
+        t.setThreadId(1);
+        t.setUserId(2);
+        t.setTitle("热帖");
+        t.setLikes(10);
+        Page<Thread> page = new Page<>(1, 10);
+        page.setRecords(List.of(t));
+        page.setTotal(1L);
+
+        when(threadService.page(any(), any())).thenReturn(page);
+
+        mockMvc.perform(get("/community/threads")
+                        .param("communityId", "1")
+                        .param("pageNumber", "1")
+                        .param("rows", "10")
+                        .param("option", "最高热度")
+                        .param("searchValue", "")
+                        .param("userId", "2"))
+                .andExpect(status().isOk())
+                .andExpect(jsonPath("$.records[0].threadId").value(1));
+    }
+
+    @Test
+    public void shouldReturnFollowedThreads_whenOptionIsFollowed() throws Exception {
+        Subscription s = new Subscription();
+        s.setUserId(1);
+        s.setFollowerId(2);
+
+        List<Subscription> subscriptions = new ArrayList<>();
+        subscriptions.add(s);
+
+        @SuppressWarnings("unchecked")
+        LambdaQueryWrapper<Subscription> wrapper = any(LambdaQueryWrapper.class);
+        when(subscriptionService.list(wrapper)).thenReturn(subscriptions);
+
+        Thread t = new Thread();
+        t.setThreadId(2);
+        t.setUserId(2);
+        t.setTitle("关注者帖子");
+        t.setLikes(8);
+
+        Page<Thread> page = new Page<>(1, 10);
+        page.setRecords(List.of(t));
+        page.setTotal(1L);
+
+        when(threadService.page(any(), any())).thenReturn(page);
+
+        mockMvc.perform(get("/community/threads")
+                        .param("communityId", "1")
+                        .param("pageNumber", "1")
+                        .param("rows", "10")
+                        .param("option", "关注者")
+                        .param("searchValue", "")
+                        .param("userId", "1"))
+                .andExpect(status().isOk())
+                .andExpect(jsonPath("$.records[0].threadId").value(2));
+    }
+
+    @NotNull
+    private Page<Community> createCommunityPage(List<Community> communities) {
+        Page<Community> page = new Page<>(1, 3);
+        page.setRecords(communities);
+        page.setTotal(communities.size());
+        return page;
+    }
+
+    @NotNull
+    @SuppressWarnings("SameParameterValue")
+    private Thread mockThread(int threadId, int userId) {
+        Thread thread = new Thread();
+        thread.setThreadId(threadId);
+        thread.setUserId(userId);
+        thread.setThreadPicture("pic");
+        thread.setTitle("title");
+        thread.setContent("content");
+        thread.setLikes(5);
+        thread.setCreateAt(new Date());
+        thread.setCommentNumber(2);
+        thread.setCommunityId(99);
+        return thread;
+    }
+}