You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
185 lines
6.5 KiB
185 lines
6.5 KiB
/**
|
|
* config.ts 配置解析模块单元测试
|
|
*/
|
|
import { describe, it, expect } from 'vitest';
|
|
import { parseConfig } from '../src/config';
|
|
|
|
const validConfig = {
|
|
integrateId: '123',
|
|
requestDomain: 'https://api.example.com',
|
|
};
|
|
|
|
describe('parseConfig - 必传参数校验', () => {
|
|
it('缺少 integrateId 返回 null', () => {
|
|
expect(parseConfig({ requestDomain: 'https://api.example.com' } as never)).toBeNull();
|
|
});
|
|
|
|
it('integrateId 为空字符串返回 null', () => {
|
|
expect(parseConfig({ integrateId: '', requestDomain: 'https://api.example.com' })).toBeNull();
|
|
});
|
|
|
|
it('缺少 requestDomain 返回 null', () => {
|
|
expect(parseConfig({ integrateId: '123' } as never)).toBeNull();
|
|
});
|
|
|
|
it('requestDomain 不是合法 URL 返回 null', () => {
|
|
expect(parseConfig({ integrateId: '123', requestDomain: 'not-a-url' })).toBeNull();
|
|
});
|
|
|
|
it('合法配置正常解析', () => {
|
|
const result = parseConfig(validConfig);
|
|
expect(result).not.toBeNull();
|
|
expect(result!.integrateId).toBe('123');
|
|
expect(result!.requestDomain).toBe('https://api.example.com');
|
|
});
|
|
|
|
it('数字 integrateId 转为字符串', () => {
|
|
const result = parseConfig({ integrateId: 42, requestDomain: 'https://api.example.com' });
|
|
expect(result!.integrateId).toBe('42');
|
|
});
|
|
});
|
|
|
|
describe('parseConfig - 默认值填充', () => {
|
|
it('width 默认 500', () => {
|
|
const result = parseConfig(validConfig);
|
|
expect(result!.width).toBe(500);
|
|
});
|
|
|
|
it('height 默认 520', () => {
|
|
const result = parseConfig(validConfig);
|
|
expect(result!.height).toBe(520);
|
|
});
|
|
|
|
it('height 最小值 400', () => {
|
|
const result = parseConfig({ ...validConfig, height: 100 });
|
|
expect(result!.height).toBe(400);
|
|
});
|
|
|
|
it('title 默认 "AI 智能助手"', () => {
|
|
const result = parseConfig(validConfig);
|
|
expect(result!.title).toBe('AI 智能助手');
|
|
});
|
|
|
|
it('theme 默认 light', () => {
|
|
const result = parseConfig(validConfig);
|
|
expect(result!.theme).toBe('light');
|
|
});
|
|
|
|
it('theme dark 正常解析', () => {
|
|
const result = parseConfig({ ...validConfig, theme: 'dark' });
|
|
expect(result!.theme).toBe('dark');
|
|
});
|
|
|
|
it('streaming 默认 true', () => {
|
|
const result = parseConfig(validConfig);
|
|
expect(result!.streaming).toBe(true);
|
|
});
|
|
|
|
it('debug 默认 true', () => {
|
|
const result = parseConfig(validConfig);
|
|
expect(result!.debug).toBe(true);
|
|
});
|
|
|
|
it('sound 默认 false', () => {
|
|
const result = parseConfig(validConfig);
|
|
expect(result!.sound).toBe(false);
|
|
});
|
|
|
|
it('notification 默认 false', () => {
|
|
const result = parseConfig(validConfig);
|
|
expect(result!.notification).toBe(false);
|
|
});
|
|
|
|
it('quickReplies 默认空数组', () => {
|
|
const result = parseConfig(validConfig);
|
|
expect(result!.quickReplies).toEqual([]);
|
|
});
|
|
|
|
it('quickReplies 过滤空字符串', () => {
|
|
const result = parseConfig({ ...validConfig, quickReplies: ['你好', '', ' ', '世界'] });
|
|
expect(result!.quickReplies).toEqual(['你好', '世界']);
|
|
});
|
|
|
|
it('requestDomain 去除末尾斜杠', () => {
|
|
const result = parseConfig({ ...validConfig, requestDomain: 'https://api.example.com///' });
|
|
expect(result!.requestDomain).toBe('https://api.example.com');
|
|
});
|
|
|
|
it('position 仅接受两个合法值', () => {
|
|
expect(parseConfig({ ...validConfig, position: 'left-bottom' })!.position).toBe('left-bottom');
|
|
expect(parseConfig({ ...validConfig, position: 'right-bottom' })!.position).toBe('right-bottom');
|
|
expect(parseConfig({ ...validConfig, position: 'top' as never })!.position).toBe('right-bottom');
|
|
});
|
|
});
|
|
|
|
describe('parseConfig - 回调函数', () => {
|
|
it('onError 回调正常保留', () => {
|
|
const onError = () => {};
|
|
const result = parseConfig({ ...validConfig, onError });
|
|
expect(result!.onError).toBe(onError);
|
|
});
|
|
|
|
it('非函数的 onError 被忽略', () => {
|
|
const result = parseConfig({ ...validConfig, onError: 'not-a-function' as never });
|
|
expect(result!.onError).toBeUndefined();
|
|
});
|
|
|
|
it('onReady / onMessage 回调正常保留', () => {
|
|
const onReady = () => {};
|
|
const onMessage = () => {};
|
|
const result = parseConfig({ ...validConfig, onReady, onMessage });
|
|
expect(result!.onReady).toBe(onReady);
|
|
expect(result!.onMessage).toBe(onMessage);
|
|
});
|
|
});
|
|
|
|
describe('parseConfig - 鉴权参数(token / expiresIn / getToken / tokenStrategy / tokenUrl)', () => {
|
|
it('合法的 token 与 expiresIn 正常保留', () => {
|
|
const result = parseConfig({ ...validConfig, token: ' eyJhbGci ', expiresIn: 7200 });
|
|
expect(result!.token).toBe('eyJhbGci'); // 去除首尾空白
|
|
expect(result!.expiresIn).toBe(7200);
|
|
});
|
|
|
|
it('token 非字符串时忽略', () => {
|
|
const result = parseConfig({ ...validConfig, token: 123 as never });
|
|
expect(result!.token).toBeUndefined();
|
|
});
|
|
|
|
it('token 为空白串时忽略', () => {
|
|
const result = parseConfig({ ...validConfig, token: ' ' });
|
|
expect(result!.token).toBeUndefined();
|
|
});
|
|
|
|
it('expiresIn 非正数或非数字时忽略', () => {
|
|
expect(parseConfig({ ...validConfig, expiresIn: 0 })!.expiresIn).toBeUndefined();
|
|
expect(parseConfig({ ...validConfig, expiresIn: -5 })!.expiresIn).toBeUndefined();
|
|
expect(parseConfig({ ...validConfig, expiresIn: '7200' as never })!.expiresIn).toBeUndefined();
|
|
});
|
|
|
|
it('getToken 非函数时忽略', () => {
|
|
const result = parseConfig({ ...validConfig, getToken: 'not-a-function' as never });
|
|
expect(result!.getToken).toBeUndefined();
|
|
});
|
|
|
|
it('tokenStrategy 默认 expiry', () => {
|
|
expect(parseConfig(validConfig)!.tokenStrategy).toBe('expiry');
|
|
});
|
|
|
|
it('tokenStrategy 接受 always,非法值回退 expiry', () => {
|
|
expect(parseConfig({ ...validConfig, tokenStrategy: 'always' })!.tokenStrategy).toBe('always');
|
|
expect(parseConfig({ ...validConfig, tokenStrategy: 'everyRequest' as never })!.tokenStrategy).toBe('expiry');
|
|
});
|
|
|
|
it('tokenUrl 去空白保留,非法值忽略', () => {
|
|
expect(parseConfig({ ...validConfig, tokenUrl: ' /api/sdk-token ' })!.tokenUrl).toBe('/api/sdk-token');
|
|
expect(parseConfig({ ...validConfig, tokenUrl: ' ' })!.tokenUrl).toBeUndefined();
|
|
expect(parseConfig({ ...validConfig, tokenUrl: 42 as never })!.tokenUrl).toBeUndefined();
|
|
});
|
|
|
|
it('getToken 与 tokenUrl 同时配置时 getToken 优先,tokenUrl 被忽略', () => {
|
|
const getToken = async () => 'token';
|
|
const result = parseConfig({ ...validConfig, getToken, tokenUrl: '/api/sdk-token' });
|
|
expect(result!.getToken).toBe(getToken);
|
|
expect(result!.tokenUrl).toBeUndefined();
|
|
});
|
|
});
|