@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.
205 lines (170 loc) • 5.22 kB
text/typescript
import { describe, expect, it } from 'vitest';
import { ChatModelCard } from '@/types/llm';
import {
AddCustomModelCard,
DeleteCustomModelCard,
UpdateCustomModelCard,
customModelCardsReducer,
} from './customModelCard';
describe('customModelCardsReducer', () => {
const initialState: ChatModelCard[] = [
{
id: 'model1',
displayName: 'Model 1',
description: 'A helpful assistant',
files: true,
functionCall: false,
enabled: true,
isCustom: true,
legacy: false,
maxOutput: 1000,
contextWindowTokens: 2048,
vision: false,
},
{
id: 'model2',
displayName: 'Model 2',
description: 'A friendly chatbot',
files: false,
functionCall: true,
isCustom: true,
legacy: true,
maxOutput: 500,
contextWindowTokens: 1024,
vision: true,
},
];
it('should add a new custom model card', () => {
const newModelCard: ChatModelCard = {
id: 'model3',
displayName: 'Model 3',
description: 'A versatile assistant',
files: true,
functionCall: true,
enabled: true,
isCustom: true,
legacy: false,
maxOutput: 2000,
contextWindowTokens: 4096,
vision: false,
};
const action: AddCustomModelCard = {
type: 'add',
modelCard: newModelCard,
};
const newState = customModelCardsReducer(initialState, action);
expect(newState).toContainEqual(newModelCard);
expect(newState.length).toBe(initialState.length + 1);
});
it('should not add a duplicate custom model card', () => {
const duplicateModelCard: ChatModelCard = {
id: 'model1',
displayName: 'Duplicate Model 1',
description: 'A duplicate model',
files: true,
functionCall: false,
enabled: true,
isCustom: true,
legacy: false,
maxOutput: 1000,
contextWindowTokens: 2048,
vision: false,
};
const action: AddCustomModelCard = {
type: 'add',
modelCard: duplicateModelCard,
};
const newState = customModelCardsReducer(initialState, action);
expect(newState).toEqual(initialState);
});
it('should delete a custom model card', () => {
const action: DeleteCustomModelCard = {
type: 'delete',
id: 'model1',
};
const newState = customModelCardsReducer(initialState, action);
expect(newState).not.toContainEqual(initialState[0]);
expect(newState.length).toBe(initialState.length - 1);
});
it('should update a custom model card', () => {
const action: UpdateCustomModelCard = {
type: 'update',
id: 'model1',
value: { displayName: 'Updated Model 1' },
};
const newState = customModelCardsReducer(initialState, action);
expect(newState.find((card) => card.id === 'model1')?.displayName).toBe('Updated Model 1');
expect(newState.length).toBe(initialState.length);
});
it('should throw an error for unhandled action type', () => {
const invalidAction = {
type: 'invalid',
};
expect(() => customModelCardsReducer(initialState, invalidAction as any)).toThrowError(
'Unhandled action type in customModelCardsReducer',
);
});
it('should return the original state if the model card is not found during update', () => {
const action: UpdateCustomModelCard = {
type: 'update',
id: 'nonexistent',
value: { displayName: 'Updated Nonexistent Model' },
};
const newState = customModelCardsReducer(initialState, action);
expect(newState).toEqual(initialState);
});
it('should return the original state if the model card ID is missing during add', () => {
const newModelCard: ChatModelCard = {
id: '',
displayName: 'Model 4',
description: 'A new model',
files: false,
functionCall: false,
enabled: true,
isCustom: true,
legacy: false,
maxOutput: 1500,
contextWindowTokens: 2048,
vision: false,
};
const action: AddCustomModelCard = {
type: 'add',
modelCard: newModelCard,
};
const newState = customModelCardsReducer(initialState, action);
expect(newState).toEqual(initialState);
});
it('should handle optional properties correctly', () => {
const newModelCard: ChatModelCard = {
id: 'model4',
};
const action: AddCustomModelCard = {
type: 'add',
modelCard: newModelCard,
};
const newState = customModelCardsReducer(initialState, action);
expect(newState).toContainEqual(newModelCard);
});
it('should handle an undefined initial state', () => {
const newModelCard: ChatModelCard = {
id: 'model4',
displayName: 'Model 4',
description: 'A new model',
files: false,
functionCall: false,
enabled: true,
isCustom: true,
legacy: false,
maxOutput: 1500,
contextWindowTokens: 2048,
vision: false,
};
const action: AddCustomModelCard = {
type: 'add',
modelCard: newModelCard,
};
const newState = customModelCardsReducer(undefined, action);
expect(newState).toContainEqual(newModelCard);
expect(newState.length).toBe(1);
});
});