lobe-chat
195 строк · 6.3 Кб
1import { describe } from 'vitest';
2
3import { MigrationData, VersionController } from '@/migrations/VersionController';
4
5import { MigrationV1ToV2 } from '../FromV1ToV2';
6import inputV1Data from '../FromV1ToV2/fixtures/input-v1-session.json';
7import { MigrationV2ToV3 } from '../FromV2ToV3';
8import azureInputV3 from './fixtures/azure-input-v3.json';
9import azureOutputV4 from './fixtures/azure-output-v4.json';
10import ollamaInputV3 from './fixtures/ollama-input-v3.json';
11import ollamaOutputV4 from './fixtures/ollama-output-v4.json';
12import openaiInputV3 from './fixtures/openai-input-v3.json';
13import openaiOutputV4 from './fixtures/openai-output-v4.json';
14import openrouterInputV3 from './fixtures/openrouter-input-v3.json';
15import openrouterOutputV4 from './fixtures/openrouter-output-v4.json';
16import outputV4Data from './fixtures/output-v4-from-v1.json';
17import { MigrationV3ToV4 } from './index';
18
19describe('MigrationV3ToV4', () => {
20let migrations;
21let versionController: VersionController<any>;
22
23beforeEach(() => {
24migrations = [MigrationV3ToV4];
25versionController = new VersionController(migrations, 4);
26});
27
28describe('should migrate data correctly from previous versions', () => {
29it('openai', () => {
30const data: MigrationData = openaiInputV3;
31
32const migratedData = versionController.migrate(data);
33
34expect(migratedData.version).toEqual(openaiOutputV4.version);
35expect(migratedData.state.settings.languageModel).toEqual(
36openaiOutputV4.state.settings.languageModel,
37);
38});
39
40it('azure', () => {
41const data: MigrationData = azureInputV3;
42
43const migratedData = versionController.migrate(data);
44
45expect(migratedData.version).toEqual(azureOutputV4.version);
46expect(migratedData.state.settings.languageModel).toEqual(
47azureOutputV4.state.settings.languageModel,
48);
49});
50
51it('openrouter', () => {
52const data: MigrationData = openrouterInputV3;
53
54const migratedData = versionController.migrate(data);
55
56expect(migratedData.version).toEqual(openrouterOutputV4.version);
57expect(migratedData.state.settings.languageModel).toEqual(
58openrouterOutputV4.state.settings.languageModel,
59);
60});
61
62it('ollama', () => {
63const data: MigrationData = ollamaInputV3;
64
65const migratedData = versionController.migrate(data);
66
67expect(migratedData.version).toEqual(ollamaOutputV4.version);
68expect(migratedData.state.settings.languageModel).toEqual(
69ollamaOutputV4.state.settings.languageModel,
70);
71});
72});
73
74it('should work correct from v1 to v4', () => {
75const data: MigrationData = inputV1Data;
76
77versionController = new VersionController(
78[MigrationV3ToV4, MigrationV2ToV3, MigrationV1ToV2],
794,
80);
81
82const migratedData = versionController.migrate(data);
83
84expect(migratedData.version).toEqual(outputV4Data.version);
85// expect(migratedData.state.sessions).toEqual(outputV3DataFromV1.state.sessions);
86// expect(migratedData.state.topics).toEqual(outputV3DataFromV1.state.topics);
87// expect(migratedData.state.messages).toEqual(outputV3DataFromV1.state.messages);
88});
89
90describe('Edge Case', () => {
91it('should handle undefined settings or languageModel', () => {
92const data: MigrationData = {
93version: 3,
94state: {
95// settings undefined
96},
97};
98
99const migratedData = versionController.migrate(data);
100
101expect(migratedData.version).toEqual(4);
102expect(migratedData.state.settings).toBeUndefined();
103});
104
105it('should handle undefined languageModel', () => {
106const data: MigrationData = {
107version: 3,
108state: {
109settings: {
110// languageModel undefined
111},
112},
113};
114
115const migratedData = versionController.migrate(data);
116
117expect(migratedData.version).toEqual(4);
118expect(migratedData.state.settings.languageModel).toBeUndefined();
119});
120
121it('should handle missing provider configurations', () => {
122const data: MigrationData = {
123version: 3,
124state: {
125settings: {
126languageModel: {
127// missing togetherai、openrouter 、 ollama
128openAI: {
129// openAI
130},
131},
132},
133},
134};
135
136const migratedData = versionController.migrate(data);
137
138expect(migratedData.version).toEqual(4);
139expect(migratedData.state.settings.languageModel.togetherai).toBeUndefined();
140expect(migratedData.state.settings.languageModel.openrouter).toBeUndefined();
141expect(migratedData.state.settings.languageModel.ollama).toBeUndefined();
142});
143
144it('should success for invalid data format', () => {
145const data: MigrationData = {
146version: 3,
147state: {
148settings: {
149languageModel: {
150openAI: 'invalid-config', // 错误的配置格式
151},
152},
153},
154};
155
156const migratedData = versionController.migrate(data);
157
158expect(migratedData.version).toEqual(4);
159expect(migratedData.state.settings.languageModel.openai).toEqual({ enabled: true });
160expect(migratedData.state.settings.languageModel.togetherai).toBeUndefined();
161expect(migratedData.state.settings.languageModel.openrouter).toBeUndefined();
162expect(migratedData.state.settings.languageModel.ollama).toBeUndefined();
163});
164
165it('should handle empty strings and empty objects', () => {
166const data: MigrationData = {
167version: 3,
168state: {
169settings: {
170languageModel: {
171openAI: undefined,
172togetherai: {
173apiKey: '',
174endpoint: '',
175customModelName: '',
176},
177},
178},
179},
180};
181
182const migratedData = versionController.migrate(data);
183
184expect(migratedData.version).toEqual(4);
185expect(migratedData.state.settings.languageModel.openai).toEqual({
186apiKey: '',
187enabled: true,
188});
189
190expect(migratedData.state.settings.languageModel.togetherai.apiKey).toEqual('');
191expect(migratedData.state.settings.languageModel.togetherai.endpoint).toEqual('');
192expect(migratedData.state.settings.languageModel.togetherai.customModelCards).toBeUndefined();
193});
194});
195});
196