f5dec95a83
refactor: 重构页面导航和滚动逻辑,提升用户体验 test: 更新测试配置和用例,增加覆盖率和稳定性 perf: 优化性能指标和阈值,适应开发环境需求 ci: 添加Lighthouse CI工作流,集成性能测试 docs: 更新API文档和健康检查端点 fix: 修复登录页面和表单提交问题 style: 调整响应式布局和可访问性改进 chore: 更新依赖项和脚本配置
180 lines
5.6 KiB
TypeScript
180 lines
5.6 KiB
TypeScript
import { GET, POST, PUT } from './route';
|
|
import { NextRequest } from 'next/server';
|
|
|
|
jest.mock('@/lib/auth', () => ({
|
|
auth: jest.fn(),
|
|
}));
|
|
|
|
jest.mock('@/lib/auth/permissions', () => ({
|
|
hasPermission: jest.fn(),
|
|
}));
|
|
|
|
jest.mock('@/lib/auth/check-permission', () => ({
|
|
checkIsAdmin: jest.fn(),
|
|
getAdminUserId: jest.fn(),
|
|
}));
|
|
|
|
jest.mock('@/db', () => {
|
|
const mockSelect = jest.fn().mockReturnValue({
|
|
from: jest.fn().mockReturnValue({
|
|
where: jest.fn().mockReturnValue({
|
|
limit: jest.fn().mockResolvedValue([]),
|
|
orderBy: jest.fn().mockResolvedValue([]),
|
|
}),
|
|
}),
|
|
});
|
|
|
|
const mockUpdate = jest.fn().mockReturnValue({
|
|
set: jest.fn().mockReturnValue({
|
|
where: jest.fn().mockReturnValue({
|
|
returning: jest.fn().mockResolvedValue([{
|
|
id: 'test-id',
|
|
key: 'test_key',
|
|
value: 'test_value',
|
|
category: 'general',
|
|
}]),
|
|
}),
|
|
}),
|
|
});
|
|
|
|
return {
|
|
db: {
|
|
select: mockSelect,
|
|
update: mockUpdate,
|
|
insert: jest.fn().mockReturnValue({
|
|
values: jest.fn().mockReturnValue({
|
|
returning: jest.fn().mockResolvedValue([{
|
|
id: 'test-id',
|
|
key: 'test_key',
|
|
value: 'test_value',
|
|
category: 'general',
|
|
}]),
|
|
}),
|
|
}),
|
|
},
|
|
};
|
|
});
|
|
|
|
const { checkIsAdmin: mockCheckIsAdmin, getAdminUserId: mockGetAdminUserId } = require('@/lib/auth/check-permission');
|
|
|
|
describe('/api/admin/config', () => {
|
|
beforeEach(() => {
|
|
jest.clearAllMocks();
|
|
});
|
|
|
|
describe('GET', () => {
|
|
it('should return 401 if not authenticated', async () => {
|
|
mockCheckIsAdmin.mockResolvedValueOnce({ isAdmin: false });
|
|
|
|
const request = new NextRequest('http://localhost/api/admin/config');
|
|
const response = await GET(request);
|
|
const data = await response.json();
|
|
|
|
expect(response.status).toBe(403);
|
|
expect(data.error).toBe('无权限执行此操作');
|
|
});
|
|
|
|
it('should return 403 if no permission', async () => {
|
|
mockCheckIsAdmin.mockResolvedValueOnce({ isAdmin: false });
|
|
|
|
const request = new NextRequest('http://localhost/api/admin/config');
|
|
const response = await GET(request);
|
|
const data = await response.json();
|
|
|
|
expect(response.status).toBe(403);
|
|
expect(data.error).toBe('无权限执行此操作');
|
|
});
|
|
|
|
it('should return configs if authenticated and has permission', async () => {
|
|
mockCheckIsAdmin.mockResolvedValueOnce({ isAdmin: true, userId: '1' });
|
|
|
|
const request = new NextRequest('http://localhost/api/admin/config');
|
|
const response = await GET(request);
|
|
const data = await response.json();
|
|
|
|
expect(response.status).toBe(200);
|
|
expect(data.configs).toBeDefined();
|
|
expect(Array.isArray(data.configs)).toBe(true);
|
|
});
|
|
});
|
|
|
|
describe('POST', () => {
|
|
it('should return 401 if not authenticated', async () => {
|
|
mockCheckIsAdmin.mockResolvedValueOnce({ isAdmin: false });
|
|
mockGetAdminUserId.mockResolvedValueOnce(null);
|
|
|
|
const request = new NextRequest('http://localhost/api/admin/config', {
|
|
method: 'POST',
|
|
body: JSON.stringify({ key: 'test', value: {} }),
|
|
});
|
|
const response = await POST(request);
|
|
const data = await response.json();
|
|
|
|
expect(response.status).toBe(403);
|
|
expect(data.error).toBe('无权限执行此操作');
|
|
});
|
|
|
|
it('should return 400 if missing required fields', async () => {
|
|
mockCheckIsAdmin.mockResolvedValueOnce({ isAdmin: true, userId: '1' });
|
|
mockGetAdminUserId.mockResolvedValueOnce('1');
|
|
|
|
const request = new NextRequest('http://localhost/api/admin/config', {
|
|
method: 'POST',
|
|
body: JSON.stringify({ key: 'test' }),
|
|
});
|
|
const response = await POST(request);
|
|
const data = await response.json();
|
|
|
|
expect(response.status).toBe(400);
|
|
expect(data.error).toBe('缺少必要字段');
|
|
});
|
|
});
|
|
|
|
describe('PUT', () => {
|
|
it('should return 401 if not authenticated', async () => {
|
|
mockCheckIsAdmin.mockResolvedValueOnce({ isAdmin: false });
|
|
mockGetAdminUserId.mockResolvedValueOnce(null);
|
|
|
|
const request = new NextRequest('http://localhost/api/admin/config', {
|
|
method: 'PUT',
|
|
body: JSON.stringify({ configs: [] }),
|
|
});
|
|
const response = await PUT(request);
|
|
const data = await response.json();
|
|
|
|
expect(response.status).toBe(403);
|
|
expect(data.error).toBe('无权限执行此操作');
|
|
});
|
|
|
|
it('should return 403 if no permission', async () => {
|
|
mockCheckIsAdmin.mockResolvedValueOnce({ isAdmin: false });
|
|
mockGetAdminUserId.mockResolvedValueOnce(null);
|
|
|
|
const request = new NextRequest('http://localhost/api/admin/config', {
|
|
method: 'PUT',
|
|
body: JSON.stringify({ configs: [] }),
|
|
});
|
|
const response = await PUT(request);
|
|
const data = await response.json();
|
|
|
|
expect(response.status).toBe(403);
|
|
expect(data.error).toBe('无权限执行此操作');
|
|
});
|
|
|
|
it('should return 400 if configs is not an array', async () => {
|
|
mockCheckIsAdmin.mockResolvedValueOnce({ isAdmin: true, userId: '1' });
|
|
mockGetAdminUserId.mockResolvedValueOnce('1');
|
|
|
|
const request = new NextRequest('http://localhost/api/admin/config', {
|
|
method: 'PUT',
|
|
body: JSON.stringify({ configs: 'not-array' }),
|
|
});
|
|
const response = await PUT(request);
|
|
const data = await response.json();
|
|
|
|
expect(response.status).toBe(400);
|
|
expect(data.error).toBe('无效的数据格式');
|
|
});
|
|
});
|
|
});
|