|
|
@@ -1,8 +1,8 @@
|
|
|
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
|
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
|
|
|
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
|
|
-import { AdvertisementManagement } from '../../src/components/AdvertisementManagement';
|
|
|
-import { advertisementClientManager } from '../../src/api/advertisementClient';
|
|
|
+import { SystemConfigManagement } from '../../src/components/SystemConfigManagement';
|
|
|
+import { systemConfigClientManager } from '../../src/api/systemConfigClient';
|
|
|
|
|
|
// 完整的mock响应对象
|
|
|
const createMockResponse = (status: number, data?: any) => ({
|
|
|
@@ -24,25 +24,21 @@ const createMockResponse = (status: number, data?: any) => ({
|
|
|
});
|
|
|
|
|
|
// Mock API client
|
|
|
-vi.mock('../../src/api/advertisementClient', () => {
|
|
|
- const mockAdvertisementClient = {
|
|
|
+vi.mock('../../src/api/systemConfigClient', () => {
|
|
|
+ const mockSystemConfigClient = {
|
|
|
index: {
|
|
|
$get: vi.fn(() => Promise.resolve(createMockResponse(200, {
|
|
|
data: [
|
|
|
{
|
|
|
id: 1,
|
|
|
- title: '测试广告',
|
|
|
- alias: 'test-ad',
|
|
|
- typeId: 1,
|
|
|
- imageUrl: 'https://example.com/image.jpg',
|
|
|
- linkUrl: 'https://example.com',
|
|
|
- status: 1,
|
|
|
- sortOrder: 1,
|
|
|
- remark: '测试备注',
|
|
|
- createdAt: '2024-01-01T00:00:00Z',
|
|
|
- updatedAt: '2024-01-01T00:00:00Z',
|
|
|
+ configKey: 'wx.mini.app.id',
|
|
|
+ configValue: 'wx1234567890',
|
|
|
+ description: '微信小程序AppID',
|
|
|
+ tenantId: 1,
|
|
|
createdBy: 1,
|
|
|
- updatedBy: 1
|
|
|
+ updatedBy: 1,
|
|
|
+ createdAt: '2024-01-01T00:00:00Z',
|
|
|
+ updatedAt: '2024-01-01T00:00:00Z'
|
|
|
}
|
|
|
],
|
|
|
pagination: {
|
|
|
@@ -52,21 +48,21 @@ vi.mock('../../src/api/advertisementClient', () => {
|
|
|
totalPages: 1
|
|
|
}
|
|
|
}))),
|
|
|
- $post: vi.fn(() => Promise.resolve(createMockResponse(201, { id: 2, title: '新广告' }))),
|
|
|
+ $post: vi.fn(() => Promise.resolve(createMockResponse(201, { id: 2, configKey: 'wx.mini.app.secret', configValue: 'secret123' }))),
|
|
|
},
|
|
|
':id': {
|
|
|
- $put: vi.fn(() => Promise.resolve(createMockResponse(200, { id: 1, title: '更新后的广告' }))),
|
|
|
+ $put: vi.fn(() => Promise.resolve(createMockResponse(200, { id: 1, configKey: 'wx.mini.app.id', configValue: 'updated_value' }))),
|
|
|
$delete: vi.fn(() => Promise.resolve(createMockResponse(204))),
|
|
|
},
|
|
|
};
|
|
|
|
|
|
- const mockAdvertisementClientManager = {
|
|
|
- get: vi.fn(() => mockAdvertisementClient),
|
|
|
+ const mockSystemConfigClientManager = {
|
|
|
+ get: vi.fn(() => mockSystemConfigClient),
|
|
|
};
|
|
|
|
|
|
return {
|
|
|
- advertisementClientManager: mockAdvertisementClientManager,
|
|
|
- advertisementClient: mockAdvertisementClient,
|
|
|
+ systemConfigClientManager: mockSystemConfigClientManager,
|
|
|
+ systemConfigClient: mockSystemConfigClient,
|
|
|
};
|
|
|
});
|
|
|
|
|
|
@@ -78,38 +74,6 @@ vi.mock('sonner', () => ({
|
|
|
},
|
|
|
}));
|
|
|
|
|
|
-// Mock FileSelector
|
|
|
-vi.mock('@d8d/file-management-ui', () => ({
|
|
|
- FileSelector: ({ value, onChange, testId, maxSize, uploadPath, previewSize, filterType, ...props }: any) => (
|
|
|
- <div data-testid="file-selector">
|
|
|
- <input
|
|
|
- type="number"
|
|
|
- value={value || ''}
|
|
|
- onChange={(e) => onChange?.(parseInt(e.target.value))}
|
|
|
- data-testid="file-selector-input"
|
|
|
- {...props}
|
|
|
- />
|
|
|
- </div>
|
|
|
- ),
|
|
|
-}));
|
|
|
-
|
|
|
-// Mock AdvertisementTypeSelector
|
|
|
-vi.mock('@d8d/advertisement-type-management-ui', () => ({
|
|
|
- AdvertisementTypeSelector: ({ value, onChange, testId, ...props }: any) => (
|
|
|
- <div data-testid="advertisement-type-selector">
|
|
|
- <select
|
|
|
- value={value?.toString() || ''}
|
|
|
- onChange={(e) => onChange?.(parseInt(e.target.value))}
|
|
|
- data-testid="type-selector"
|
|
|
- {...props}
|
|
|
- >
|
|
|
- <option value="1">首页轮播</option>
|
|
|
- <option value="2">侧边栏广告</option>
|
|
|
- </select>
|
|
|
- </div>
|
|
|
- ),
|
|
|
-}));
|
|
|
-
|
|
|
const createTestQueryClient = () =>
|
|
|
new QueryClient({
|
|
|
defaultOptions: {
|
|
|
@@ -128,27 +92,24 @@ const renderWithProviders = (component: React.ReactElement) => {
|
|
|
);
|
|
|
};
|
|
|
|
|
|
-describe('广告管理集成测试', () => {
|
|
|
+describe('系统配置管理集成测试', () => {
|
|
|
beforeEach(() => {
|
|
|
vi.clearAllMocks();
|
|
|
});
|
|
|
|
|
|
- it('应该完成完整的广告CRUD流程', async () => {
|
|
|
- const mockAdvertisements = {
|
|
|
+ it('应该完成完整的系统配置CRUD流程', async () => {
|
|
|
+ const mockSystemConfigs = {
|
|
|
data: [
|
|
|
{
|
|
|
id: 1,
|
|
|
- title: '测试广告',
|
|
|
- code: 'test-ad',
|
|
|
- typeId: 1,
|
|
|
- advertisementType: { id: 1, name: '首页轮播' },
|
|
|
- url: 'https://example.com',
|
|
|
- imageFileId: 1,
|
|
|
- imageFile: { id: 1, fullUrl: 'https://example.com/image.jpg' },
|
|
|
- sort: 1,
|
|
|
- status: 1,
|
|
|
- actionType: 1,
|
|
|
+ configKey: 'wx.mini.app.id',
|
|
|
+ configValue: 'wx1234567890',
|
|
|
+ description: '微信小程序AppID',
|
|
|
+ tenantId: 1,
|
|
|
+ createdBy: 1,
|
|
|
+ updatedBy: 1,
|
|
|
createdAt: '2024-01-01T00:00:00Z',
|
|
|
+ updatedAt: '2024-01-01T00:00:00Z'
|
|
|
},
|
|
|
],
|
|
|
pagination: {
|
|
|
@@ -160,35 +121,39 @@ describe('广告管理集成测试', () => {
|
|
|
|
|
|
const { toast } = await import('sonner');
|
|
|
|
|
|
- // Mock initial advertisement list
|
|
|
- const client = advertisementClientManager.get();
|
|
|
+ // Mock initial system config list
|
|
|
+ const client = systemConfigClientManager.get();
|
|
|
(client.index.$get as any).mockResolvedValue({
|
|
|
...createMockResponse(200),
|
|
|
- json: async () => mockAdvertisements
|
|
|
+ json: async () => mockSystemConfigs
|
|
|
});
|
|
|
|
|
|
- renderWithProviders(<AdvertisementManagement />);
|
|
|
+ renderWithProviders(<SystemConfigManagement />);
|
|
|
|
|
|
// Wait for initial data to load
|
|
|
await waitFor(() => {
|
|
|
- expect(screen.getByText('测试广告')).toBeInTheDocument();
|
|
|
+ expect(screen.getByText('wx.mini.app.id')).toBeInTheDocument();
|
|
|
});
|
|
|
|
|
|
- // Test create advertisement
|
|
|
- const createButton = screen.getByText('创建广告');
|
|
|
+ // Test create system config
|
|
|
+ const createButton = screen.getByText('创建配置');
|
|
|
fireEvent.click(createButton);
|
|
|
|
|
|
// Fill create form
|
|
|
- const titleInput = screen.getByTestId('title-input');
|
|
|
- const codeInput = screen.getByTestId('code-input');
|
|
|
- const typeSelector = screen.getByTestId('type-selector');
|
|
|
+ const configKeyInput = screen.getByTestId('config-key-input');
|
|
|
+ const configValueInput = screen.getByTestId('config-value-input');
|
|
|
+ const descriptionInput = screen.getByTestId('description-input');
|
|
|
|
|
|
- fireEvent.change(titleInput, { target: { value: '新广告' } });
|
|
|
- fireEvent.change(codeInput, { target: { value: 'new-ad' } });
|
|
|
- fireEvent.change(typeSelector, { target: { value: '1' } });
|
|
|
+ fireEvent.change(configKeyInput, { target: { value: 'wx.mini.app.secret' } });
|
|
|
+ fireEvent.change(configValueInput, { target: { value: 'secret123' } });
|
|
|
+ fireEvent.change(descriptionInput, { target: { value: '微信小程序AppSecret' } });
|
|
|
|
|
|
// Mock successful creation
|
|
|
- (client.index.$post as any).mockResolvedValue(createMockResponse(201, { id: 2, title: '新广告' }));
|
|
|
+ (client.index.$post as any).mockResolvedValue(createMockResponse(201, {
|
|
|
+ id: 2,
|
|
|
+ configKey: 'wx.mini.app.secret',
|
|
|
+ configValue: 'secret123'
|
|
|
+ }));
|
|
|
|
|
|
const submitButton = screen.getByTestId('create-submit-button');
|
|
|
fireEvent.click(submitButton);
|
|
|
@@ -196,31 +161,26 @@ describe('广告管理集成测试', () => {
|
|
|
await waitFor(() => {
|
|
|
expect(client.index.$post).toHaveBeenCalledWith({
|
|
|
json: {
|
|
|
- title: '新广告',
|
|
|
- code: 'new-ad',
|
|
|
- typeId: 1,
|
|
|
- url: '',
|
|
|
- imageFileId: undefined,
|
|
|
- sort: 0,
|
|
|
- status: 1,
|
|
|
- actionType: 1
|
|
|
+ configKey: 'wx.mini.app.secret',
|
|
|
+ configValue: 'secret123',
|
|
|
+ description: '微信小程序AppSecret'
|
|
|
},
|
|
|
});
|
|
|
- expect(toast.success).toHaveBeenCalledWith('广告创建成功');
|
|
|
+ expect(toast.success).toHaveBeenCalledWith('系统配置创建成功');
|
|
|
});
|
|
|
|
|
|
- // Test edit advertisement
|
|
|
+ // Test edit system config
|
|
|
const editButton = screen.getByTestId('edit-button-1');
|
|
|
fireEvent.click(editButton);
|
|
|
|
|
|
// Verify edit form is populated
|
|
|
await waitFor(() => {
|
|
|
- expect(screen.getByDisplayValue('测试广告')).toBeInTheDocument();
|
|
|
+ expect(screen.getByDisplayValue('wx.mini.app.id')).toBeInTheDocument();
|
|
|
});
|
|
|
|
|
|
- // Update advertisement
|
|
|
- const updateTitleInput = screen.getByDisplayValue('测试广告');
|
|
|
- fireEvent.change(updateTitleInput, { target: { value: '更新后的广告' } });
|
|
|
+ // Update system config
|
|
|
+ const updateConfigValueInput = screen.getByDisplayValue('wx1234567890');
|
|
|
+ fireEvent.change(updateConfigValueInput, { target: { value: 'updated_value' } });
|
|
|
|
|
|
// Mock successful update
|
|
|
(client[':id']['$put'] as any).mockResolvedValue(createMockResponse(200));
|
|
|
@@ -232,20 +192,15 @@ describe('广告管理集成测试', () => {
|
|
|
expect(client[':id']['$put']).toHaveBeenCalledWith({
|
|
|
param: { id: 1 },
|
|
|
json: {
|
|
|
- title: '更新后的广告',
|
|
|
- typeId: 1,
|
|
|
- code: 'test-ad',
|
|
|
- url: 'https://example.com',
|
|
|
- imageFileId: 1,
|
|
|
- sort: 1,
|
|
|
- status: 1,
|
|
|
- actionType: 1
|
|
|
+ configKey: 'wx.mini.app.id',
|
|
|
+ configValue: 'updated_value',
|
|
|
+ description: '微信小程序AppID'
|
|
|
},
|
|
|
});
|
|
|
- expect(toast.success).toHaveBeenCalledWith('广告更新成功');
|
|
|
+ expect(toast.success).toHaveBeenCalledWith('系统配置更新成功');
|
|
|
});
|
|
|
|
|
|
- // Test delete advertisement
|
|
|
+ // Test delete system config
|
|
|
const deleteButton = screen.getByTestId('delete-button-1');
|
|
|
fireEvent.click(deleteButton);
|
|
|
|
|
|
@@ -278,33 +233,33 @@ describe('广告管理集成测试', () => {
|
|
|
expect(client[':id']['$delete']).toHaveBeenCalledWith({
|
|
|
param: { id: 1 },
|
|
|
});
|
|
|
- expect(toast.success).toHaveBeenCalledWith('广告删除成功');
|
|
|
+ expect(toast.success).toHaveBeenCalledWith('系统配置删除成功');
|
|
|
});
|
|
|
});
|
|
|
|
|
|
it('应该优雅处理API错误', async () => {
|
|
|
- const client = advertisementClientManager.get();
|
|
|
+ const client = systemConfigClientManager.get();
|
|
|
const { toast } = await import('sonner');
|
|
|
|
|
|
// Mock API error
|
|
|
(client.index.$get as any).mockRejectedValue(new Error('API Error'));
|
|
|
|
|
|
- renderWithProviders(<AdvertisementManagement />);
|
|
|
+ renderWithProviders(<SystemConfigManagement />);
|
|
|
|
|
|
// Should handle error without crashing
|
|
|
await waitFor(() => {
|
|
|
- expect(screen.getByText('广告管理')).toBeInTheDocument();
|
|
|
+ expect(screen.getByText('系统配置管理')).toBeInTheDocument();
|
|
|
});
|
|
|
|
|
|
- // Test create advertisement error
|
|
|
- const createButton = screen.getByText('创建广告');
|
|
|
+ // Test create system config error
|
|
|
+ const createButton = screen.getByText('创建配置');
|
|
|
fireEvent.click(createButton);
|
|
|
|
|
|
- const titleInput = screen.getByTestId('title-input');
|
|
|
- const codeInput = screen.getByTestId('code-input');
|
|
|
+ const configKeyInput = screen.getByTestId('config-key-input');
|
|
|
+ const configValueInput = screen.getByTestId('config-value-input');
|
|
|
|
|
|
- fireEvent.change(titleInput, { target: { value: '测试广告' } });
|
|
|
- fireEvent.change(codeInput, { target: { value: 'test-ad' } });
|
|
|
+ fireEvent.change(configKeyInput, { target: { value: 'wx.mini.app.id' } });
|
|
|
+ fireEvent.change(configValueInput, { target: { value: 'test_value' } });
|
|
|
|
|
|
// Mock creation error
|
|
|
(client.index.$post as any).mockRejectedValue(new Error('Creation failed'));
|
|
|
@@ -318,19 +273,19 @@ describe('广告管理集成测试', () => {
|
|
|
});
|
|
|
|
|
|
it('应该处理搜索功能', async () => {
|
|
|
- const client = advertisementClientManager.get();
|
|
|
- const mockAdvertisements = {
|
|
|
+ const client = systemConfigClientManager.get();
|
|
|
+ const mockSystemConfigs = {
|
|
|
data: [],
|
|
|
pagination: { total: 0, page: 1, pageSize: 10 },
|
|
|
};
|
|
|
|
|
|
- (client.index.$get as any).mockResolvedValue(createMockResponse(200, mockAdvertisements));
|
|
|
+ (client.index.$get as any).mockResolvedValue(createMockResponse(200, mockSystemConfigs));
|
|
|
|
|
|
- renderWithProviders(<AdvertisementManagement />);
|
|
|
+ renderWithProviders(<SystemConfigManagement />);
|
|
|
|
|
|
// Test search
|
|
|
const searchInput = screen.getByTestId('search-input');
|
|
|
- fireEvent.change(searchInput, { target: { value: '搜索关键词' } });
|
|
|
+ fireEvent.change(searchInput, { target: { value: '微信' } });
|
|
|
|
|
|
const searchButton = screen.getByText('搜索');
|
|
|
fireEvent.click(searchButton);
|
|
|
@@ -340,7 +295,7 @@ describe('广告管理集成测试', () => {
|
|
|
query: {
|
|
|
page: 1,
|
|
|
pageSize: 10,
|
|
|
- keyword: '搜索关键词',
|
|
|
+ keyword: '微信',
|
|
|
},
|
|
|
});
|
|
|
});
|