mirror of
https://gitee.com/newgateway/vtj.git
synced 2026-06-24 04:03:38 +08:00
- 为加密工具(MD5、RSA、base64、AES)添加完整加解密测试,支持中文及空字符串 - 新增日期格式化工具 dateFormat 的多种格式及类型测试 - lodash 工具函数增加类型判断、字符串转换、对象操作、深拷贝和合并等测试覆盖 - 添加 lz-string 压缩解压工具的多场景测试,含中文和特殊字符 - mitt 事件总线工具新增事件监听、触发、取消、多次触发及通配符测试 - 优化数字格式化工具 numberFormat 和 toFixed 的边界及四舍五入测试 - 添加 path-to-regexp 路径匹配及参数捕获相关测试 - Queue 队列工具新增任务顺序执行、去重、缓存及结果查询的全覆盖测试 - 增补正则校验工具(URL、邮箱、身份证、手机号、车牌)及正则常量匹配测试 - utils 包中基础工具 uid 生成唯一 ID 及版本号的测试补充 - 新增 browser-patch 中 addEventListener 补丁覆盖及调用测试 - clientInfo 工具丰富各主流浏览器、操作系统及移动设备的检测测试覆盖 - cookie 工具新增增删改查测试及多 cookie 互不影响的保证 - download 工具中 URL 下载及 Blob 下载功能测试初始化补充保证运行环境兼容性
219 lines
6.3 KiB
TypeScript
219 lines
6.3 KiB
TypeScript
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
import { Request, createRequest, createApi, createApis, useApi } from '../src';
|
|
|
|
vi.mock('axios', () => {
|
|
const requestFn = vi.fn();
|
|
const instance: any = requestFn;
|
|
instance.defaults = { headers: { common: {} } };
|
|
instance.interceptors = {
|
|
request: { use: vi.fn(() => 1), eject: vi.fn() },
|
|
response: { use: vi.fn(() => 1), eject: vi.fn() }
|
|
};
|
|
instance.request = requestFn;
|
|
instance.get = vi.fn();
|
|
instance.post = vi.fn();
|
|
instance.put = vi.fn();
|
|
instance.delete = vi.fn();
|
|
instance.patch = vi.fn();
|
|
const cancelSource = { token: 'mock-token', cancel: vi.fn() };
|
|
return {
|
|
default: {
|
|
create: vi.fn(() => instance),
|
|
CancelToken: { source: vi.fn(() => cancelSource) }
|
|
},
|
|
CancelToken: { source: vi.fn(() => cancelSource) }
|
|
};
|
|
});
|
|
|
|
describe('Request 请求工具', () => {
|
|
let request: Request;
|
|
let axiosMock: any;
|
|
|
|
beforeEach(() => {
|
|
vi.clearAllMocks();
|
|
request = new Request({
|
|
baseURL: 'https://api.example.com',
|
|
settings: {
|
|
type: 'form',
|
|
failMessage: false
|
|
}
|
|
});
|
|
axiosMock = (request as any).axios;
|
|
});
|
|
|
|
describe('send', () => {
|
|
it('应发送 GET 请求', async () => {
|
|
axiosMock.request.mockResolvedValueOnce({
|
|
data: { data: { id: 1, name: 'test' } },
|
|
headers: { 'content-type': 'text/plain' },
|
|
status: 200
|
|
});
|
|
|
|
const result = await request.send({ url: '/users' });
|
|
expect(result).toEqual({ id: 1, name: 'test' });
|
|
});
|
|
|
|
it('应支持 originResponse 选项', async () => {
|
|
axiosMock.request.mockResolvedValueOnce({
|
|
data: { data: { id: 1 } },
|
|
headers: {},
|
|
status: 200,
|
|
statusText: 'OK'
|
|
});
|
|
|
|
const result = await request.send({
|
|
url: '/users',
|
|
settings: { originResponse: true }
|
|
});
|
|
expect((result as any).status).toBe(200);
|
|
});
|
|
|
|
it('应处理请求失败', async () => {
|
|
axiosMock.request.mockRejectedValueOnce(new Error('Network Error'));
|
|
await expect(request.send({ url: '/fail' })).rejects.toThrow(
|
|
'Network Error'
|
|
);
|
|
});
|
|
|
|
it('应处理 validSuccess 校验失败', async () => {
|
|
axiosMock.request.mockResolvedValueOnce({
|
|
data: { code: 500, msg: 'error', data: null },
|
|
headers: {}
|
|
});
|
|
|
|
await expect(
|
|
request.send({
|
|
url: '/fail',
|
|
settings: {
|
|
validSuccess: true,
|
|
validate: (res: any) => res.data.code === 200
|
|
}
|
|
})
|
|
).rejects.toBeDefined();
|
|
});
|
|
});
|
|
|
|
describe('cancel', () => {
|
|
it('应取消指定 ID 的请求', () => {
|
|
const cancelFn = vi.fn();
|
|
(request as any).records['test-id'] = {
|
|
settings: {},
|
|
config: {},
|
|
source: { cancel: cancelFn }
|
|
};
|
|
request.cancel('test-id');
|
|
expect(cancelFn).toHaveBeenCalled();
|
|
});
|
|
|
|
it('应取消所有请求', () => {
|
|
const cancelFn1 = vi.fn();
|
|
const cancelFn2 = vi.fn();
|
|
(request as any).records = {
|
|
a: { settings: {}, config: {}, source: { cancel: cancelFn1 } },
|
|
b: { settings: {}, config: {}, source: { cancel: cancelFn2 } }
|
|
};
|
|
request.cancel();
|
|
expect(cancelFn1).toHaveBeenCalled();
|
|
expect(cancelFn2).toHaveBeenCalled();
|
|
});
|
|
});
|
|
|
|
describe('setConfig', () => {
|
|
it('应更新配置', () => {
|
|
request.setConfig({
|
|
baseURL: 'https://new-api.example.com',
|
|
settings: { type: 'json' }
|
|
});
|
|
expect((request as any).settings.type).toBe('json');
|
|
});
|
|
});
|
|
|
|
describe('useResponse', () => {
|
|
it('应注册响应拦截器', () => {
|
|
const fn = vi.fn();
|
|
const dispose = request.useResponse(fn);
|
|
expect(typeof dispose).toBe('function');
|
|
});
|
|
});
|
|
|
|
describe('useRequest', () => {
|
|
it('应注册请求拦截器', () => {
|
|
const fn = vi.fn();
|
|
const dispose = request.useRequest(fn);
|
|
expect(typeof dispose).toBe('function');
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('createRequest', () => {
|
|
it('应创建可调用对象', () => {
|
|
const req = createRequest({ settings: { type: 'form' } });
|
|
expect(typeof req).toBe('function');
|
|
expect(req.cancel).toBeInstanceOf(Function);
|
|
expect(req.setConfig).toBeInstanceOf(Function);
|
|
expect(req.useRequest).toBeInstanceOf(Function);
|
|
expect(req.useResponse).toBeInstanceOf(Function);
|
|
});
|
|
});
|
|
|
|
describe('createApi', () => {
|
|
it('应使用字符串创建 API 函数', () => {
|
|
const mockReq = { send: vi.fn().mockResolvedValue({ id: 1 }) } as any;
|
|
const api = createApi('/users', mockReq);
|
|
expect(typeof api).toBe('function');
|
|
});
|
|
|
|
it('应使用配置对象创建 API 函数', () => {
|
|
const mockReq = { send: vi.fn().mockResolvedValue({ id: 1 }) } as any;
|
|
const api = createApi({ url: '/users', method: 'post' }, mockReq);
|
|
expect(typeof api).toBe('function');
|
|
});
|
|
});
|
|
|
|
describe('createApis', () => {
|
|
it('应从映射创建多个 API', () => {
|
|
const mockReq = { send: vi.fn().mockResolvedValue({}) } as any;
|
|
const apis = createApis(
|
|
{ getUser: '/user/get', saveUser: '/user/save' },
|
|
mockReq
|
|
);
|
|
expect(apis.getUser).toBeInstanceOf(Function);
|
|
expect(apis.saveUser).toBeInstanceOf(Function);
|
|
});
|
|
});
|
|
|
|
describe('useApi', () => {
|
|
it('应返回响应式数据', async () => {
|
|
const loader = () => Promise.resolve({ id: 1, name: 'test' });
|
|
const result = useApi(loader);
|
|
expect(result.data.value).toBeNull();
|
|
expect(result.loading.value).toBe(true);
|
|
expect(result.error.value).toBeUndefined();
|
|
expect(result.reload).toBeInstanceOf(Function);
|
|
|
|
await vi.waitFor(() => {
|
|
expect(result.data.value).toEqual({ id: 1, name: 'test' });
|
|
expect(result.loading.value).toBe(false);
|
|
});
|
|
});
|
|
|
|
it('应处理加载失败', async () => {
|
|
const loader = () => Promise.reject(new Error('load failed'));
|
|
const result = useApi(loader);
|
|
|
|
await vi.waitFor(() => {
|
|
expect(result.error.value).toBeInstanceOf(Error);
|
|
expect(result.loading.value).toBe(false);
|
|
});
|
|
});
|
|
|
|
it('应支持 transform 转换', async () => {
|
|
const loader = () => Promise.resolve({ data: { id: 1 } });
|
|
const result = useApi(loader, (res: any) => res.data);
|
|
|
|
await vi.waitFor(() => {
|
|
expect(result.data.value).toEqual({ id: 1 });
|
|
});
|
|
});
|
|
});
|