帖子的相关用户前端与管理员后端
Change-Id: I957181738817aeeaa89fabe23ceaf59d00c37a71
diff --git a/src/api/__tests__/post.test.js b/src/api/__tests__/post.test.js
new file mode 100644
index 0000000..89fe48f
--- /dev/null
+++ b/src/api/__tests__/post.test.js
@@ -0,0 +1,160 @@
+const axios = require('axios');
+const MockAdapter = require('axios-mock-adapter');
+
+const {
+ createPost,
+ togglePinPost,
+ deletePost,
+ updatePost,
+ searchPosts,
+ likePost,
+ unlikePost,
+ pinPost,
+ unpinPost,
+ findPostsByUserId,
+ findPinnedPosts,
+ getAllPostsSorted,
+ getPostById
+} = require('../post'); // 注意根据你的实际路径修改
+
+jest.mock('axios');
+
+describe('Post API Tests', () => {
+ beforeEach(() => {
+ jest.clearAllMocks();
+ });
+
+ test('createPost should post form data', async () => {
+ const formData = new FormData();
+ formData.append('userid', '1');
+ formData.append('post_title', 'Test');
+ axios.post.mockResolvedValue({ data: true });
+
+ const response = await createPost(formData);
+
+ expect(axios.post).toHaveBeenCalledWith(
+ 'http://localhost:8080/post/create',
+ formData,
+ { headers: { 'Content-Type': 'multipart/form-data' } }
+ );
+ expect(response.data).toBe(true);
+ });
+
+ test('togglePinPost should send PUT request', async () => {
+ axios.put.mockResolvedValue({ data: true });
+
+ const response = await togglePinPost(123);
+
+ expect(axios.put).toHaveBeenCalledWith('http://localhost:8080/post/togglePin/123');
+ expect(response.data).toBe(true);
+ });
+
+ test('deletePost should send DELETE request', async () => {
+ axios.delete.mockResolvedValue({ data: true });
+
+ const response = await deletePost(123);
+
+ expect(axios.delete).toHaveBeenCalledWith('http://localhost:8080/post/delete/123');
+ expect(response.data).toBe(true);
+ });
+
+ test('updatePost should send PUT request with JSON', async () => {
+ const post = { postid: 1, post_title: 'Updated Title' };
+ axios.put.mockResolvedValue({ data: true });
+
+ const response = await updatePost(post);
+
+ expect(axios.put).toHaveBeenCalledWith(
+ 'http://localhost:8080/post/update',
+ JSON.stringify(post),
+ { headers: { 'Content-Type': 'application/json' } }
+ );
+ expect(response.data).toBe(true);
+ });
+
+ test('searchPosts should send GET request with keyword', async () => {
+ const mockData = { data: [{ post_title: 'Keyword Match' }] };
+ axios.get.mockResolvedValue(mockData);
+
+ const response = await searchPosts('test');
+
+ expect(axios.get).toHaveBeenCalledWith('http://localhost:8080/post/search?keyword=test');
+ expect(response.data).toEqual(mockData.data);
+ });
+
+ test('likePost should send PUT request', async () => {
+ axios.put.mockResolvedValue({ data: true });
+
+ const response = await likePost(1);
+
+ expect(axios.put).toHaveBeenCalledWith('http://localhost:8080/post/like/1');
+ expect(response.data).toBe(true);
+ });
+
+ test('unlikePost should send PUT request', async () => {
+ axios.put.mockResolvedValue({ data: true });
+
+ const response = await unlikePost(1);
+
+ expect(axios.put).toHaveBeenCalledWith('http://localhost:8080/post/unlike/1');
+ expect(response.data).toBe(true);
+ });
+
+ test('pinPost should send PUT request', async () => {
+ axios.put.mockResolvedValue({ data: true });
+
+ const response = await pinPost(1);
+
+ expect(axios.put).toHaveBeenCalledWith('http://localhost:8080/post/pin/1');
+ expect(response.data).toBe(true);
+ });
+
+ test('unpinPost should send PUT request', async () => {
+ axios.put.mockResolvedValue({ data: true });
+
+ const response = await unpinPost(1);
+
+ expect(axios.put).toHaveBeenCalledWith('http://localhost:8080/post/unpin/1');
+ expect(response.data).toBe(true);
+ });
+
+ test('findPostsByUserId should fetch user posts', async () => {
+ const mockData = { data: [{ postid: 1, userid: 2 }] };
+ axios.get.mockResolvedValue(mockData);
+
+ const response = await findPostsByUserId(2);
+
+ expect(axios.get).toHaveBeenCalledWith('http://localhost:8080/post/findByUserid?userid=2');
+ expect(response.data).toEqual(mockData.data);
+ });
+
+ test('findPinnedPosts should fetch pinned posts', async () => {
+ const mockData = { data: [{ postid: 1, is_pinned: 1 }] };
+ axios.get.mockResolvedValue(mockData);
+
+ const response = await findPinnedPosts();
+
+ expect(axios.get).toHaveBeenCalledWith('http://localhost:8080/post/findPinned');
+ expect(response.data).toEqual(mockData.data);
+ });
+
+ test('getAllPostsSorted should fetch all posts sorted', async () => {
+ const mockData = { data: [{ postid: 1 }] };
+ axios.get.mockResolvedValue(mockData);
+
+ const response = await getAllPostsSorted();
+
+ expect(axios.get).toHaveBeenCalledWith('http://localhost:8080/post/all');
+ expect(response.data).toEqual(mockData.data);
+ });
+
+ test('getPostById should fetch post by ID', async () => {
+ const mockData = { data: { postid: 1 } };
+ axios.get.mockResolvedValue(mockData);
+
+ const response = await getPostById(1);
+
+ expect(axios.get).toHaveBeenCalledWith('http://localhost:8080/post/get/1');
+ expect(response.data).toEqual(mockData.data);
+ });
+});
diff --git a/src/api/post.js b/src/api/post.js
new file mode 100644
index 0000000..5891f99
--- /dev/null
+++ b/src/api/post.js
@@ -0,0 +1,128 @@
+const BASE_URL = 'http://localhost:8080/post';
+
+/**
+ * 创建帖子(带图片)
+ * @param {FormData} formData 包含 userid、post_title、post_content、tags、rannge、is_pinned、photo
+ */
+export const createPost = (formData) => {
+ return fetch(`${BASE_URL}/create`, {
+ method: 'POST',
+ body: formData,
+ }).then(res => res.json());
+};
+
+/**
+ * 切换置顶状态
+ * @param {number} postid 帖子 ID
+ */
+export const togglePinPost = (postid) => {
+ return fetch(`${BASE_URL}/togglePin/${postid}`, {
+ method: 'PUT',
+ }).then(res => res.json());
+};
+
+/**
+ * 删除帖子
+ * @param {number} postid 帖子 ID
+ */
+export const deletePost = (postid) => {
+ return fetch(`${BASE_URL}/delete/${postid}`, {
+ method: 'DELETE',
+ }).then(res => res.json());
+};
+
+/**
+ * 更新帖子(JSON 格式)
+ * @param {Object} post 帖子对象
+ */
+export const updatePost = (post) => {
+ return fetch(`${BASE_URL}/update`, {
+ method: 'PUT',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify(post),
+ }).then(res => res.json());
+};
+
+/**
+ * 关键词搜索帖子
+ * @param {string} keyword 搜索关键词
+ */
+export const searchPosts = (keyword) => {
+ return fetch(`${BASE_URL}/search?keyword=${encodeURIComponent(keyword)}`)
+ .then(res => res.json());
+};
+
+/**
+ * 点赞帖子
+ * @param {number} postid 帖子 ID
+ */
+export const likePost = (postid) => {
+ return fetch(`${BASE_URL}/like/${postid}`, {
+ method: 'PUT',
+ }).then(res => res.json());
+};
+
+/**
+ * 取消点赞帖子
+ * @param {number} postid 帖子 ID
+ */
+export const unlikePost = (postid) => {
+ return fetch(`${BASE_URL}/unlike/${postid}`, {
+ method: 'PUT',
+ }).then(res => res.json());
+};
+
+/**
+ * 置顶帖子
+ * @param {number} postid 帖子 ID
+ */
+export const pinPost = (postid) => {
+ return fetch(`${BASE_URL}/pin/${postid}`, {
+ method: 'PUT',
+ }).then(res => res.json());
+};
+
+/**
+ * 取消置顶帖子
+ * @param {number} postid 帖子 ID
+ */
+export const unpinPost = (postid) => {
+ return fetch(`${BASE_URL}/unpin/${postid}`, {
+ method: 'PUT',
+ }).then(res => res.json());
+};
+
+/**
+ * 获取某用户所有帖子
+ * @param {number} userid 用户 ID
+ */
+export const findPostsByUserId = (userid) => {
+ return fetch(`${BASE_URL}/findByUserid?userid=${userid}`)
+ .then(res => res.json());
+};
+
+/**
+ * 获取所有置顶帖子
+ */
+export const findPinnedPosts = () => {
+ return fetch(`${BASE_URL}/findPinned`)
+ .then(res => res.json());
+};
+
+/**
+ * 获取所有帖子(排序后)
+ */
+export const getAllPostsSorted = () => {
+ return fetch(`${BASE_URL}/all`)
+ .then(res => res.json());
+};
+
+/**
+ * 根据 postid 获取帖子详情(若你后期需要)
+ */
+export const getPostById = (postid) => {
+ return fetch(`${BASE_URL}/get/${postid}`)
+ .then(res => res.json());
+};