- Raise use-swipe-gesture mutation score to 66.13% (target 65%+) - Maintain use-reduced-motion mutation score at 76.32% (target 50%+) - Fix use-reduced-motion.ts ESLint set-state-in-effect warning - Add UJ-10 deep searcher journey (category browse → article read → content discovery) - Add 40 new test files (analytics, detail, sections, ui, lib components) - Update test-strategy-plan.md to v2.0 (sync test count to 1591) - Sync README.md with final release metrics Quality gates: TS 0 errors, ESLint 0 errors, 121 suites / 1591 tests passed
182 lines
5.9 KiB
TypeScript
182 lines
5.9 KiB
TypeScript
// @ts-nocheck
|
|
import { describe, it, expect, jest, beforeEach } from '@jest/globals';
|
|
import {
|
|
unauthorized,
|
|
forbidden,
|
|
notFound,
|
|
validationError,
|
|
badRequest,
|
|
internalError,
|
|
success,
|
|
handleApiError,
|
|
} from './api-response';
|
|
|
|
describe('unauthorized', () => {
|
|
it('返回默认错误消息和 401 状态码', async () => {
|
|
const res = unauthorized();
|
|
expect(res.status).toBe(401);
|
|
const body = await res.json();
|
|
expect(body).toEqual({ error: '未授权,请先登录', code: 'UNAUTHORIZED' });
|
|
});
|
|
|
|
it('返回自定义错误消息和 401 状态码', async () => {
|
|
const res = unauthorized('自定义未授权消息');
|
|
expect(res.status).toBe(401);
|
|
const body = await res.json();
|
|
expect(body).toEqual({ error: '自定义未授权消息', code: 'UNAUTHORIZED' });
|
|
});
|
|
});
|
|
|
|
describe('forbidden', () => {
|
|
it('返回默认错误消息和 403 状态码', async () => {
|
|
const res = forbidden();
|
|
expect(res.status).toBe(403);
|
|
const body = await res.json();
|
|
expect(body).toEqual({ error: '无权限执行此操作', code: 'FORBIDDEN' });
|
|
});
|
|
|
|
it('返回自定义错误消息和 403 状态码', async () => {
|
|
const res = forbidden('自定义无权限消息');
|
|
expect(res.status).toBe(403);
|
|
const body = await res.json();
|
|
expect(body).toEqual({ error: '自定义无权限消息', code: 'FORBIDDEN' });
|
|
});
|
|
});
|
|
|
|
describe('notFound', () => {
|
|
it('返回默认错误消息和 404 状态码', async () => {
|
|
const res = notFound();
|
|
expect(res.status).toBe(404);
|
|
const body = await res.json();
|
|
expect(body).toEqual({ error: '请求的资源不存在', code: 'NOT_FOUND' });
|
|
});
|
|
|
|
it('返回自定义错误消息和 404 状态码', async () => {
|
|
const res = notFound('自定义不存在消息');
|
|
expect(res.status).toBe(404);
|
|
const body = await res.json();
|
|
expect(body).toEqual({ error: '自定义不存在消息', code: 'NOT_FOUND' });
|
|
});
|
|
});
|
|
|
|
describe('validationError', () => {
|
|
it('返回错误消息和 400 状态码', async () => {
|
|
const res = validationError('数据验证失败');
|
|
expect(res.status).toBe(400);
|
|
const body = await res.json();
|
|
expect(body).toEqual({ error: '数据验证失败', code: 'VALIDATION_ERROR' });
|
|
});
|
|
|
|
it('返回包含 details 的错误响应', async () => {
|
|
const details = { field: 'email', reason: '格式不正确' };
|
|
const res = validationError('数据验证失败', details);
|
|
expect(res.status).toBe(400);
|
|
const body = await res.json();
|
|
expect(body).toEqual({
|
|
error: '数据验证失败',
|
|
code: 'VALIDATION_ERROR',
|
|
details,
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('badRequest', () => {
|
|
it('返回错误消息和 400 状态码', async () => {
|
|
const res = badRequest('请求参数错误');
|
|
expect(res.status).toBe(400);
|
|
const body = await res.json();
|
|
expect(body).toEqual({ error: '请求参数错误', code: 'BAD_REQUEST' });
|
|
});
|
|
});
|
|
|
|
describe('internalError', () => {
|
|
beforeEach(() => {
|
|
jest.clearAllMocks();
|
|
});
|
|
|
|
it('返回默认错误消息和 500 状态码', async () => {
|
|
const res = internalError();
|
|
expect(res.status).toBe(500);
|
|
const body = await res.json();
|
|
expect(body).toEqual({ error: '服务器内部错误', code: 'INTERNAL_ERROR' });
|
|
});
|
|
|
|
it('使用自定义消息调用 console.error', () => {
|
|
internalError('自定义服务器错误');
|
|
expect(console.error).toHaveBeenCalledWith('自定义服务器错误');
|
|
});
|
|
|
|
it('当未传入消息时使用默认参数调用 console.error', () => {
|
|
internalError();
|
|
expect(console.error).toHaveBeenCalledWith('服务器错误');
|
|
});
|
|
});
|
|
|
|
describe('success', () => {
|
|
it('返回数据和默认 200 状态码', async () => {
|
|
const data = { id: 1, name: 'test' };
|
|
const res = success(data);
|
|
expect(res.status).toBe(200);
|
|
const body = await res.json();
|
|
expect(body).toEqual(data);
|
|
});
|
|
|
|
it('返回数据和自定义状态码', async () => {
|
|
const data = { message: 'created' };
|
|
const res = success(data, 201);
|
|
expect(res.status).toBe(201);
|
|
const body = await res.json();
|
|
expect(body).toEqual(data);
|
|
});
|
|
});
|
|
|
|
describe('handleApiError', () => {
|
|
beforeEach(() => {
|
|
jest.clearAllMocks();
|
|
});
|
|
|
|
it('包含 "未授权" 的 Error 返回 unauthorized 响应', async () => {
|
|
const error = new Error('未授权,请先登录');
|
|
const res = handleApiError(error);
|
|
expect(res.status).toBe(401);
|
|
const body = await res.json();
|
|
expect(body).toEqual({ error: '未授权,请先登录', code: 'UNAUTHORIZED' });
|
|
});
|
|
|
|
it('包含 "无权限" 的 Error 返回 forbidden 响应', async () => {
|
|
const error = new Error('无权限执行此操作');
|
|
const res = handleApiError(error);
|
|
expect(res.status).toBe(403);
|
|
const body = await res.json();
|
|
expect(body).toEqual({ error: '无权限执行此操作', code: 'FORBIDDEN' });
|
|
});
|
|
|
|
it('包含 "不存在" 的 Error 返回 notFound 响应', async () => {
|
|
const error = new Error('资源不存在');
|
|
const res = handleApiError(error);
|
|
expect(res.status).toBe(404);
|
|
const body = await res.json();
|
|
expect(body).toEqual({ error: '资源不存在', code: 'NOT_FOUND' });
|
|
});
|
|
|
|
it('普通的 Error 返回 internalError 响应', async () => {
|
|
const error = new Error('未知错误');
|
|
const res = handleApiError(error);
|
|
expect(res.status).toBe(500);
|
|
const body = await res.json();
|
|
expect(body).toEqual({ error: '服务器内部错误', code: 'INTERNAL_ERROR' });
|
|
});
|
|
|
|
it('非 Error 类型返回 internalError 响应', async () => {
|
|
const res = handleApiError('字符串错误');
|
|
expect(res.status).toBe(500);
|
|
const body = await res.json();
|
|
expect(body).toEqual({ error: '服务器内部错误', code: 'INTERNAL_ERROR' });
|
|
});
|
|
|
|
it('打印 API Error 日志', () => {
|
|
const error = new Error('测试错误');
|
|
handleApiError(error);
|
|
expect(console.error).toHaveBeenCalledWith('API Error:', error);
|
|
});
|
|
}); |