@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.
295 lines (244 loc) • 8.06 kB
text/typescript
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
import { VARIABLE_GENERATORS, parsePlaceholderVariablesMessages } from './parserPlaceholder';
// Mock dependencies
vi.mock('@/utils/uuid', () => ({
uuid: () => 'mocked-uuid-12345',
}));
vi.mock('@/store/user', () => ({
useUserStore: {
getState: () => ({}),
},
}));
vi.mock('@/store/user/selectors', () => ({
userProfileSelectors: {
displayUserName: () => 'testuser',
nickName: () => 'Test User',
fullName: () => 'Test Full Name',
},
}));
describe('parsePlaceholderVariablesMessages', () => {
beforeEach(() => {
// Mock Date for consistent testing
vi.useFakeTimers();
vi.setSystemTime(new Date('2025-06-06T06:06:06.666Z'));
// Mock Math.random for consistent random values
vi.spyOn(Math, 'random').mockReturnValue(0.5);
});
afterEach(() => {
vi.useRealTimers();
vi.restoreAllMocks();
});
describe('string content messages', () => {
it('should replace template variables in string content', () => {
const messages = [
{
id: '1',
content: 'Hello {{username}}, today is {{date}}',
},
];
const result = parsePlaceholderVariablesMessages(messages);
expect(result[0].content).toContain('testuser');
expect(result[0].content).toContain(new Date().toLocaleDateString());
});
it('should handle multiple variables in one message', () => {
const messages = [
{
id: '1',
content: 'Time: {{time}}, Date: {{date}}, User: {{nickname}}',
},
];
const result = parsePlaceholderVariablesMessages(messages);
expect(result[0].content).toContain('Test User');
expect(result[0].content).toMatch(/Time: .+, Date: .+, User: Test User/);
});
it('should preserve message structure when replacing variables', () => {
const messages = [
{
id: '1',
role: 'user',
content: 'Hello {{username}}',
},
];
const result = parsePlaceholderVariablesMessages(messages);
expect(result[0]).toEqual({
id: '1',
role: 'user',
content: 'Hello testuser',
});
});
});
describe('array content messages', () => {
it('should replace variables in text type array elements', () => {
const messages = [
{
id: '1',
content: [
{
type: 'text',
text: 'Hello {{username}}',
},
{
type: 'image_url',
image_url: 'image.jpg',
},
],
},
];
const result = parsePlaceholderVariablesMessages(messages);
expect(result[0].content[0].text).toBe('Hello testuser');
expect(result[0].content[1]).toEqual({
type: 'image_url',
image_url: 'image.jpg',
});
});
it('should handle multiple text elements with variables', () => {
const messages = [
{
id: '1',
content: [
{
type: 'text',
text: 'Date: {{date}}',
},
{
type: 'text',
text: 'Time: {{time}}',
},
{
type: 'image_url',
image_url: 'test.jpg',
},
],
},
];
const result = parsePlaceholderVariablesMessages(messages);
expect(result[0].content[0].text).toContain(new Date().toLocaleDateString());
expect(result[0].content[1].text).toContain(new Date().toLocaleTimeString());
expect(result[0].content[2]).toEqual({
type: 'image_url',
image_url: 'test.jpg',
});
});
it('should preserve non-text array elements unchanged', () => {
const messages = [
{
id: '1',
content: [
{
type: 'image_url',
image_url: 'image.jpg',
},
{
type: 'image_url',
name: 'image2.jpg',
},
],
},
];
const result = parsePlaceholderVariablesMessages(messages);
expect(result[0].content).toEqual([
{
type: 'image_url',
image_url: 'image.jpg',
},
{
type: 'image_url',
name: 'image2.jpg',
},
]);
});
});
describe('edge cases', () => {
it('should handle empty messages array', () => {
const result = parsePlaceholderVariablesMessages([]);
expect(result).toEqual([]);
});
it('should handle messages without content', () => {
const messages = [{ id: '1' }, { id: '2', content: null }, { id: '3', content: undefined }];
const result = parsePlaceholderVariablesMessages(messages);
expect(result).toEqual([
{ id: '1' },
{ id: '2', content: null },
{ id: '3', content: undefined },
]);
});
it('should handle empty string content', () => {
const messages = [{ id: '1', content: '' }];
const result = parsePlaceholderVariablesMessages(messages);
expect(result[0].content).toBe('');
});
it('should handle content without variables', () => {
const messages = [
{ id: '1', content: 'Hello world!' },
{
id: '2',
content: [
{ type: 'text', text: 'No variables here' },
{ type: 'image_url', image_url: 'test.jpg' },
],
},
];
const result = parsePlaceholderVariablesMessages(messages);
expect(result[0].content).toBe('Hello world!');
expect(result[1].content[0].text).toBe('No variables here');
});
it('should handle unknown variable types', () => {
const messages = [{ id: '1', content: 'Hello {{unknown_variable}}!' }];
const result = parsePlaceholderVariablesMessages(messages);
// Unknown variables should remain unchanged
expect(result[0].content).toBe('Hello {{unknown_variable}}!');
});
});
describe('specific variable types', () => {
it('should handle time variables', () => {
const messages = [
{
id: '1',
content: 'Year: {{year}}, Month: {{month}}, Day: {{day}}',
},
];
const result = parsePlaceholderVariablesMessages(messages);
expect(result[0].content).toContain('Year: 2025');
expect(result[0].content).toContain('Month: 06');
expect(result[0].content).toContain('Day: 06');
});
it('should handle random variables', () => {
const messages = [
{
id: '1',
content: 'Random: {{random}}, Bool: {{random_bool}}, UUID: {{uuid}}',
},
];
const result = parsePlaceholderVariablesMessages(messages);
expect(result[0].content).toContain('Random: 500001'); // Math.random() * 1000000 + 1 with 0.5
expect(result[0].content).toContain('Bool: false'); // Math.random() > 0.5 with 0.5
expect(result[0].content).toContain('UUID: mocked-uuid-12345');
});
it('should handle user variables', () => {
const messages = [
{
id: '1',
content: 'User: {{username}}, Nickname: {{nickname}}',
},
];
const result = parsePlaceholderVariablesMessages(messages);
expect(result[0].content).toBe('User: testuser, Nickname: Test User');
});
});
describe('multiple messages', () => {
it('should process multiple messages correctly', () => {
const messages = [
{ id: '1', content: 'Hello {{username}}' },
{
id: '2',
content: [{ type: 'text', text: 'Today is {{date}}' }],
},
{ id: '3', content: 'Time: {{time}}' },
];
const result = parsePlaceholderVariablesMessages(messages);
expect(result[0].content).toBe('Hello testuser');
expect(result[1].content[0].text).toContain(new Date().toLocaleDateString());
expect(result[2].content).toContain(new Date().toLocaleTimeString());
});
});
});