@lobehub/chat
Version:
Lobe Chat - an open-source, high-performance chatbot framework that supports speech synthesis, multimodal, and extensible Function Call plugin system. Supports one-click free deployment of your private ChatGPT/LLM web application.
198 lines (156 loc) • 5.68 kB
text/typescript
import { describe, expect, it } from 'vitest';
import { UploadFileItem } from '@/types/files/upload';
import { uploadFileListReducer } from './uploadFileList';
// 创建测试用的文件项
const createMockFile = (id: string): UploadFileItem => ({
id,
file: new File(['test'], 'test.txt'),
status: 'pending',
uploadState: { speed: 2, restTime: 2, progress: 10 },
});
describe('uploadFileListReducer', () => {
describe('addFile action', () => {
it('should add a file at the end by default', () => {
const initialState: UploadFileItem[] = [createMockFile('1')];
const newFile = createMockFile('2');
const result = uploadFileListReducer(initialState, {
type: 'addFile',
file: newFile,
});
expect(result).toHaveLength(2);
expect(result[1]).toEqual(newFile);
});
it('should add a file at the start when atStart is true', () => {
const initialState: UploadFileItem[] = [createMockFile('1')];
const newFile = createMockFile('2');
const result = uploadFileListReducer(initialState, {
type: 'addFile',
file: newFile,
atStart: true,
});
expect(result).toHaveLength(2);
expect(result[0]).toEqual(newFile);
});
});
describe('addFiles action', () => {
it('should add multiple files at the end by default', () => {
const initialState: UploadFileItem[] = [createMockFile('1')];
const newFiles = [createMockFile('2'), createMockFile('3')];
const result = uploadFileListReducer(initialState, {
type: 'addFiles',
files: newFiles,
});
expect(result).toHaveLength(3);
expect(result.slice(1)).toEqual(newFiles);
});
it('should add multiple files at the start when atStart is true', () => {
const initialState: UploadFileItem[] = [createMockFile('1')];
const newFiles = [createMockFile('2'), createMockFile('3')];
const result = uploadFileListReducer(initialState, {
type: 'addFiles',
files: newFiles,
atStart: true,
});
expect(result).toHaveLength(3);
expect(result.slice(0, 2)).toEqual(newFiles.reverse());
});
});
describe('updateFile action', () => {
it('should update file properties', () => {
const initialState: UploadFileItem[] = [createMockFile('1')];
const updateValue = { name: 'updated.txt' } as File;
const result = uploadFileListReducer(initialState, {
type: 'updateFile',
id: '1',
value: { file: updateValue },
});
expect(result[0].file.name).toBe('updated.txt');
});
it('should not modify state if file id is not found', () => {
const initialState: UploadFileItem[] = [createMockFile('1')];
const result = uploadFileListReducer(initialState, {
type: 'updateFile',
id: 'non-existent',
value: { file: { name: 'updated.txt' } as File },
});
expect(result).toEqual(initialState);
});
});
describe('updateFileStatus action', () => {
it('should update file status', () => {
const initialState: UploadFileItem[] = [createMockFile('1')];
const result = uploadFileListReducer(initialState, {
type: 'updateFileStatus',
id: '1',
status: 'success',
});
expect(result[0].status).toBe('success');
});
});
describe('updateFileUploadState action', () => {
it('should update file upload state', () => {
const initialState: UploadFileItem[] = [createMockFile('1')];
const result = uploadFileListReducer(initialState, {
type: 'updateFileUploadState',
id: '1',
uploadState: { progress: 12, restTime: 12, speed: 12 },
});
expect(result[0].uploadState).toEqual({
progress: 12,
restTime: 12,
speed: 12,
});
});
});
describe('removeFile action', () => {
it('should remove a file by id', () => {
const initialState: UploadFileItem[] = [createMockFile('1'), createMockFile('2')];
const result = uploadFileListReducer(initialState, {
type: 'removeFile',
id: '1',
});
expect(result).toHaveLength(1);
expect(result[0].id).toBe('2');
});
it('should not modify state if file id is not found', () => {
const initialState: UploadFileItem[] = [createMockFile('1')];
const result = uploadFileListReducer(initialState, {
type: 'removeFile',
id: 'non-existent',
});
expect(result).toEqual(initialState);
});
});
describe('removeFiles action', () => {
it('should remove multiple files by ids', () => {
const initialState: UploadFileItem[] = [
createMockFile('1'),
createMockFile('2'),
createMockFile('3'),
];
const result = uploadFileListReducer(initialState, {
type: 'removeFiles',
ids: ['1', '2'],
});
expect(result).toHaveLength(1);
expect(result[0].id).toBe('3');
});
it('should not modify state if no file ids are found', () => {
const initialState: UploadFileItem[] = [createMockFile('1')];
const result = uploadFileListReducer(initialState, {
type: 'removeFiles',
ids: ['non-existent'],
});
expect(result).toEqual(initialState);
});
});
describe('error handling', () => {
it('should throw error for unhandled action type', () => {
const initialState: UploadFileItem[] = [];
// @ts-expect-error Testing invalid action type
expect(() => uploadFileListReducer(initialState, { type: 'invalid' })).toThrow(
'Unhandled action type',
);
});
});
});