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('缺少必填字段'); }); }); });