Files
novalon-website/src/app/api/admin/users/route.test.ts
T
张翔 b207bfa7af feat: 增加测试覆盖率并优化代码质量
test: 添加单元测试和端到端测试
refactor: 重构登录页面和上传模块
ci: 更新测试覆盖率阈值至42%
build: 添加测试相关依赖
docs: 更新测试文档
style: 修复代码格式问题
2026-03-11 11:14:37 +08:00

136 lines
3.6 KiB
TypeScript

import { describe, it, expect, jest, beforeAll, beforeEach } from '@jest/globals';
import { NextRequest } from 'next/server';
import '@testing-library/jest-dom';
const mockAuth = jest.fn();
const mockHasPermission = jest.fn();
const mockDbSelect = jest.fn();
const mockDbInsert = jest.fn();
jest.mock('@/lib/auth', () => ({
auth: mockAuth,
}));
jest.mock('@/lib/auth/permissions', () => ({
hasPermission: mockHasPermission,
}));
jest.mock('@/db', () => ({
db: {
select: () => ({
from: () => ({
where: () => ({
limit: mockDbSelect,
}),
orderBy: mockDbSelect,
}),
}),
insert: () => ({
values: () => ({
returning: mockDbInsert,
}),
}),
},
}));
jest.mock('drizzle-orm', () => ({
eq: jest.fn(),
}));
jest.mock('nanoid', () => ({
nanoid: () => 'test-id-123',
}));
jest.mock('bcryptjs', () => ({
hash: jest.fn().mockResolvedValue('hashed-password'),
}));
jest.mock('@/db/schema', () => ({
users: {},
}));
import { GET, POST } from './route';
describe('/api/admin/users', () => {
beforeEach(() => {
jest.clearAllMocks();
});
describe('GET', () => {
it('should return 401 when not authenticated', async () => {
mockAuth.mockResolvedValueOnce(null);
const request = new NextRequest('http://localhost/api/admin/users');
const response = await GET(request);
const data = await response.json();
expect(response.status).toBe(401);
expect(data.error).toBe('未授权');
});
it('should return 403 when user lacks permission', async () => {
mockAuth.mockResolvedValueOnce({
user: { id: '1', role: 'viewer' },
});
mockHasPermission.mockReturnValueOnce(false);
const request = new NextRequest('http://localhost/api/admin/users');
const response = await GET(request);
const data = await response.json();
expect(response.status).toBe(403);
expect(data.error).toBe('无权限');
});
it('should return users list when authorized', async () => {
mockAuth.mockResolvedValueOnce({
user: { id: '1', role: 'admin' },
});
mockHasPermission.mockReturnValueOnce(true);
mockDbSelect.mockResolvedValueOnce([
{ id: '1', email: 'admin@example.com', name: 'Admin', role: 'admin' },
]);
const request = new NextRequest('http://localhost/api/admin/users');
const response = await GET(request);
const data = await response.json();
expect(response.status).toBe(200);
expect(data.users).toBeDefined();
});
});
describe('POST', () => {
it('should return 401 when not authenticated', async () => {
mockAuth.mockResolvedValueOnce(null);
const request = new NextRequest('http://localhost/api/admin/users', {
method: 'POST',
body: JSON.stringify({ email: 'test@example.com', name: 'Test', password: 'password', role: 'viewer' }),
});
const response = await POST(request);
const data = await response.json();
expect(response.status).toBe(401);
expect(data.error).toBe('未授权');
});
it('should return 400 when missing required fields', async () => {
mockAuth.mockResolvedValueOnce({
user: { id: '1', role: 'admin' },
});
mockHasPermission.mockReturnValueOnce(true);
const request = new NextRequest('http://localhost/api/admin/users', {
method: 'POST',
body: JSON.stringify({ email: 'test@example.com' }),
});
const response = await POST(request);
const data = await response.json();
expect(response.status).toBe(400);
expect(data.error).toBe('缺少必填字段');
});
});
});