修改论坛、促销、登录,增加测试

Change-Id: I71883fc1da46a94db47f90a4cd61474c274a5b2c
diff --git a/src/__tests__/CreatePost.test.js b/src/__tests__/CreatePost.test.js
new file mode 100644
index 0000000..2695c5e
--- /dev/null
+++ b/src/__tests__/CreatePost.test.js
@@ -0,0 +1,106 @@
+
+import React from 'react';
+import { render, screen, fireEvent, waitFor } from '@testing-library/react';
+import CreatePost from '../pages/Forum/posts-create/CreatePost';
+import axios from 'axios';
+
+// mock axios
+jest.mock('axios');
+
+describe('CreatePost Component', () => {
+  const mockUserId = 123;
+
+  beforeEach(() => {
+    axios.post.mockClear();
+  });
+
+  test('renders form inputs and button', () => {
+    render(<CreatePost user_id={mockUserId} />);
+
+    expect(screen.getByLabelText(/标题/)).toBeInTheDocument();
+    expect(screen.getByLabelText(/内容/)).toBeInTheDocument();
+    expect(screen.getByLabelText(/图片链接/)).toBeInTheDocument();
+    expect(screen.getByRole('button', { name: '发布' })).toBeInTheDocument();
+  });
+
+  test('shows error when title and content are empty', async () => {
+    render(<CreatePost user_id={mockUserId} />);
+
+    fireEvent.click(screen.getByRole('button', { name: '发布' }));
+
+    expect(await screen.findByText('标题和内容不能为空')).toBeInTheDocument();
+  });
+
+  test('submits post and shows success message', async () => {
+    axios.post.mockResolvedValueOnce({
+      data: { post_id: 456 },
+    });
+
+    render(<CreatePost user_id={mockUserId} />);
+
+    fireEvent.change(screen.getByLabelText(/标题/), {
+      target: { value: '测试标题' },
+    });
+    fireEvent.change(screen.getByLabelText(/内容/), {
+      target: { value: '测试内容' },
+    });
+    fireEvent.change(screen.getByLabelText(/图片链接/), {
+      target: { value: 'http://example.com/image.jpg' },
+    });
+
+    fireEvent.click(screen.getByRole('button', { name: '发布' }));
+
+    await waitFor(() =>
+      expect(axios.post).toHaveBeenCalledWith(
+        `http://localhost:8080/echo/forum/posts/${mockUserId}/createPost`,
+        {
+          title: '测试标题',
+          post_content: '测试内容',
+          image_url: 'http://example.com/image.jpg',
+        }
+      )
+    );
+
+    expect(await screen.findByText(/发帖成功,帖子ID:456/)).toBeInTheDocument();
+  });
+
+  test('shows error message on submission failure', async () => {
+    axios.post.mockRejectedValueOnce({
+      response: {
+        data: {
+          error: '服务器内部错误',
+        },
+      },
+    });
+
+    render(<CreatePost user_id={mockUserId} />);
+
+    fireEvent.change(screen.getByLabelText(/标题/), {
+      target: { value: '测试标题' },
+    });
+    fireEvent.change(screen.getByLabelText(/内容/), {
+      target: { value: '测试内容' },
+    });
+
+    fireEvent.click(screen.getByRole('button', { name: '发布' }));
+
+    expect(await screen.findByText('服务器内部错误')).toBeInTheDocument();
+  });
+
+  test('shows fallback error message when no response', async () => {
+    axios.post.mockRejectedValueOnce(new Error('Network error'));
+
+    render(<CreatePost user_id={mockUserId} />);
+
+    fireEvent.change(screen.getByLabelText(/标题/), {
+      target: { value: '测试标题' },
+    });
+    fireEvent.change(screen.getByLabelText(/内容/), {
+      target: { value: '测试内容' },
+    });
+
+    fireEvent.click(screen.getByRole('button', { name: '发布' }));
+
+    expect(await screen.findByText('发帖失败,请稍后重试')).toBeInTheDocument();
+  });
+});