@lobehub/lobehub 2.0.0-next.13 → 2.0.0-next.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +25 -0
- package/changelog/v1.json +9 -0
- package/package.json +1 -1
- package/packages/const/src/version.ts +3 -3
- package/packages/database/src/repositories/dataImporter/deprecated/__tests__/index.test.ts +2 -1
- package/packages/database/src/repositories/dataImporter/deprecated/index.ts +7 -1
- package/src/app/[variants]/(main)/(mobile)/me/(home)/__tests__/useCategory.test.tsx +9 -0
- package/src/app/[variants]/(main)/(mobile)/me/(home)/layout.tsx +0 -2
- package/src/app/[variants]/(main)/chat/@session/features/SessionListContent/List/Item/Actions.tsx +3 -28
- package/src/app/[variants]/(main)/chat/_layout/Desktop/index.tsx +0 -2
- package/src/app/[variants]/(main)/chat/_layout/Mobile.tsx +1 -5
- package/src/app/[variants]/(main)/chat/settings/features/HeaderContent.tsx +2 -62
- package/src/app/[variants]/(main)/image/page.tsx +0 -2
- package/src/app/[variants]/(main)/profile/_layout/Desktop/index.tsx +23 -24
- package/src/app/[variants]/(main)/profile/_layout/Mobile/index.tsx +5 -9
- package/src/app/[variants]/(main)/settings/_layout/Desktop/index.tsx +0 -2
- package/src/app/[variants]/(main)/settings/_layout/Mobile/index.tsx +0 -2
- package/src/app/[variants]/(main)/settings/provider/(list)/ProviderGrid/Card.tsx +1 -1
- package/src/app/[variants]/loading/index.tsx +1 -10
- package/src/components/Link.tsx +12 -0
- package/src/envs/app.ts +5 -8
- package/src/features/DataImporter/index.tsx +15 -60
- package/src/features/DevPanel/PostgresViewer/usePgTable.ts +3 -2
- package/src/hooks/useInterceptingRoutes.test.ts +21 -3
- package/src/libs/trpc/client/index.ts +0 -1
- package/src/libs/trpc/client/lambda.ts +8 -5
- package/src/server/routers/desktop/mcp.ts +1 -3
- package/src/server/routers/lambda/config/index.test.ts +2 -2
- package/src/server/routers/tools/mcp.ts +2 -3
- package/src/server/routers/tools/search.test.ts +1 -7
- package/src/server/routers/tools/search.ts +1 -4
- package/src/services/__tests__/tool.test.ts +0 -3
- package/src/services/aiModel/index.test.ts +0 -3
- package/src/services/aiModel/index.ts +1 -7
- package/src/services/aiProvider/index.test.ts +0 -3
- package/src/services/aiProvider/index.ts +1 -7
- package/src/services/chatGroup/index.ts +1 -10
- package/src/services/config.ts +1 -65
- package/src/services/export/index.ts +1 -4
- package/src/services/file/index.ts +1 -11
- package/src/services/import/index.ts +1 -7
- package/src/services/message/index.ts +1 -11
- package/src/services/plugin/index.ts +1 -11
- package/src/services/session/index.ts +1 -11
- package/src/services/tableViewer/client.ts +12 -15
- package/src/services/thread/index.ts +1 -7
- package/src/services/topic/index.ts +1 -11
- package/src/services/user/index.ts +1 -13
- package/src/store/chat/slices/aiChat/actions/__tests__/generateAIChat.test.ts +0 -241
- package/src/store/chat/slices/aiChat/actions/__tests__/generateAIChatV2.test.ts +26 -1
- package/src/store/chat/slices/aiChat/actions/__tests__/helpers.ts +3 -1
- package/src/store/chat/slices/aiChat/actions/generateAIChat.ts +1 -138
- package/src/store/user/slices/common/action.test.ts +1 -4
- package/src/app/(backend)/trpc/edge/[trpc]/route.ts +0 -26
- package/src/app/[variants]/(main)/(mobile)/me/data/features/Category.tsx +0 -48
- package/src/app/[variants]/(main)/(mobile)/me/data/features/Header.tsx +0 -33
- package/src/app/[variants]/(main)/(mobile)/me/data/layout.tsx +0 -13
- package/src/app/[variants]/(main)/(mobile)/me/data/loading.tsx +0 -5
- package/src/app/[variants]/(main)/(mobile)/me/data/page.tsx +0 -29
- package/src/app/[variants]/(main)/chat/features/Migration/DBReader.ts +0 -290
- package/src/app/[variants]/(main)/chat/features/Migration/ExportConfigButton.tsx +0 -35
- package/src/app/[variants]/(main)/chat/features/Migration/Failed.tsx +0 -120
- package/src/app/[variants]/(main)/chat/features/Migration/Modal.tsx +0 -81
- package/src/app/[variants]/(main)/chat/features/Migration/Start.tsx +0 -108
- package/src/app/[variants]/(main)/chat/features/Migration/UpgradeButton.tsx +0 -71
- package/src/app/[variants]/(main)/chat/features/Migration/const.ts +0 -15
- package/src/app/[variants]/(main)/chat/features/Migration/index.tsx +0 -50
- package/src/app/[variants]/loading/Client/Content.tsx +0 -48
- package/src/app/[variants]/loading/Client/Error.tsx +0 -27
- package/src/app/[variants]/loading/Client/Redirect.tsx +0 -47
- package/src/app/[variants]/loading/Client/index.tsx +0 -22
- package/src/components/InnerLink.tsx +0 -20
- package/src/database/_deprecated/core/__tests__/db-upgrade.test.ts +0 -42
- package/src/database/_deprecated/core/__tests__/db.test.ts +0 -79
- package/src/database/_deprecated/core/__tests__/model.test.ts +0 -55
- package/src/database/_deprecated/core/db.ts +0 -246
- package/src/database/_deprecated/core/index.ts +0 -2
- package/src/database/_deprecated/core/migrations/migrateSettingsToUser/fixtures/input.json +0 -55
- package/src/database/_deprecated/core/migrations/migrateSettingsToUser/fixtures/output.json +0 -60
- package/src/database/_deprecated/core/migrations/migrateSettingsToUser/index.test.ts +0 -14
- package/src/database/_deprecated/core/migrations/migrateSettingsToUser/index.ts +0 -22
- package/src/database/_deprecated/core/migrations/migrateSettingsToUser/type.ts +0 -105
- package/src/database/_deprecated/core/model.ts +0 -218
- package/src/database/_deprecated/core/schemas.ts +0 -88
- package/src/database/_deprecated/core/types/db.ts +0 -15
- package/src/database/_deprecated/models/__DEBUG.ts +0 -124
- package/src/database/_deprecated/models/__tests__/file.test.ts +0 -83
- package/src/database/_deprecated/models/__tests__/message.test.ts +0 -426
- package/src/database/_deprecated/models/__tests__/plugin.test.ts +0 -81
- package/src/database/_deprecated/models/__tests__/session.test.ts +0 -253
- package/src/database/_deprecated/models/__tests__/sessionGroup.test.ts +0 -220
- package/src/database/_deprecated/models/__tests__/topic.test.ts +0 -523
- package/src/database/_deprecated/models/__tests__/user.test.ts +0 -82
- package/src/database/_deprecated/models/file.ts +0 -51
- package/src/database/_deprecated/models/message.ts +0 -277
- package/src/database/_deprecated/models/plugin.ts +0 -62
- package/src/database/_deprecated/models/session.ts +0 -271
- package/src/database/_deprecated/models/sessionGroup.ts +0 -93
- package/src/database/_deprecated/models/topic.ts +0 -250
- package/src/database/_deprecated/models/user.ts +0 -69
- package/src/database/_deprecated/schemas/files.ts +0 -39
- package/src/database/_deprecated/schemas/message.ts +0 -50
- package/src/database/_deprecated/schemas/plugin.ts +0 -12
- package/src/database/_deprecated/schemas/session.ts +0 -54
- package/src/database/_deprecated/schemas/sessionGroup.ts +0 -8
- package/src/database/_deprecated/schemas/topic.ts +0 -12
- package/src/database/_deprecated/schemas/user.ts +0 -40
- package/src/features/DataImporter/_deprecated.ts +0 -43
- package/src/features/InitClientDB/EnableModal.tsx +0 -118
- package/src/features/InitClientDB/ErrorResult.tsx +0 -143
- package/src/features/InitClientDB/InitIndicator.tsx +0 -124
- package/src/features/InitClientDB/PGliteIcon.tsx +0 -28
- package/src/features/InitClientDB/features/DatabaseRepair/Backup.tsx +0 -75
- package/src/features/InitClientDB/features/DatabaseRepair/Diagnosis.tsx +0 -98
- package/src/features/InitClientDB/features/DatabaseRepair/Repair.tsx +0 -218
- package/src/features/InitClientDB/features/DatabaseRepair/index.tsx +0 -91
- package/src/features/InitClientDB/index.tsx +0 -37
- package/src/libs/trpc/client/edge.ts +0 -26
- package/src/libs/trpc/edge/context.ts +0 -71
- package/src/libs/trpc/edge/index.ts +0 -45
- package/src/libs/trpc/edge/init.ts +0 -26
- package/src/libs/trpc/edge/middleware/jwtPayload.test.ts +0 -75
- package/src/libs/trpc/edge/middleware/jwtPayload.ts +0 -14
- package/src/migrations/FromV0ToV1.ts +0 -10
- package/src/migrations/FromV1ToV2/fixtures/input-v1-session.json +0 -191
- package/src/migrations/FromV1ToV2/fixtures/output-v2.json +0 -202
- package/src/migrations/FromV1ToV2/index.ts +0 -82
- package/src/migrations/FromV1ToV2/migrations.test.ts +0 -224
- package/src/migrations/FromV1ToV2/types/v1.ts +0 -78
- package/src/migrations/FromV1ToV2/types/v2.ts +0 -52
- package/src/migrations/FromV2ToV3/fixtures/input-v2-session.json +0 -72
- package/src/migrations/FromV2ToV3/fixtures/output-v3-from-v1.json +0 -203
- package/src/migrations/FromV2ToV3/fixtures/output-v3.json +0 -74
- package/src/migrations/FromV2ToV3/index.ts +0 -30
- package/src/migrations/FromV2ToV3/migrations.test.ts +0 -42
- package/src/migrations/FromV2ToV3/types/v3.ts +0 -27
- package/src/migrations/FromV3ToV4/fixtures/azure-input-v3.json +0 -79
- package/src/migrations/FromV3ToV4/fixtures/azure-output-v4.json +0 -75
- package/src/migrations/FromV3ToV4/fixtures/ollama-input-v3.json +0 -85
- package/src/migrations/FromV3ToV4/fixtures/ollama-output-v4.json +0 -86
- package/src/migrations/FromV3ToV4/fixtures/openai-input-v3.json +0 -77
- package/src/migrations/FromV3ToV4/fixtures/openai-output-v4.json +0 -77
- package/src/migrations/FromV3ToV4/fixtures/openrouter-input-v3.json +0 -82
- package/src/migrations/FromV3ToV4/fixtures/openrouter-output-v4.json +0 -85
- package/src/migrations/FromV3ToV4/fixtures/output-v4-from-v1.json +0 -203
- package/src/migrations/FromV3ToV4/index.ts +0 -102
- package/src/migrations/FromV3ToV4/migrations.test.ts +0 -195
- package/src/migrations/FromV3ToV4/types/v3.ts +0 -52
- package/src/migrations/FromV3ToV4/types/v4.ts +0 -37
- package/src/migrations/FromV4ToV5/fixtures/from-v1-to-v5-output.json +0 -245
- package/src/migrations/FromV4ToV5/fixtures/function-input-v4.json +0 -96
- package/src/migrations/FromV4ToV5/fixtures/function-output-v5.json +0 -120
- package/src/migrations/FromV4ToV5/index.ts +0 -58
- package/src/migrations/FromV4ToV5/migrations.test.ts +0 -49
- package/src/migrations/FromV4ToV5/types/v4.ts +0 -21
- package/src/migrations/FromV4ToV5/types/v5.ts +0 -27
- package/src/migrations/FromV5ToV6/fixtures/from-v1-to-v6-output.json +0 -247
- package/src/migrations/FromV5ToV6/fixtures/session-input-v5.json +0 -81
- package/src/migrations/FromV5ToV6/fixtures/session-output-v6.json +0 -85
- package/src/migrations/FromV5ToV6/index.ts +0 -61
- package/src/migrations/FromV5ToV6/migrations.test.ts +0 -50
- package/src/migrations/FromV5ToV6/types/v5.ts +0 -48
- package/src/migrations/FromV5ToV6/types/v6.ts +0 -63
- package/src/migrations/FromV6ToV7/fixtures/output-v7-from-v1.json +0 -203
- package/src/migrations/FromV6ToV7/fixtures/provider-input-v6.json +0 -103
- package/src/migrations/FromV6ToV7/fixtures/provider-output-v7.json +0 -118
- package/src/migrations/FromV6ToV7/index.ts +0 -101
- package/src/migrations/FromV6ToV7/migrations.test.ts +0 -64
- package/src/migrations/FromV6ToV7/types/v6.ts +0 -61
- package/src/migrations/FromV6ToV7/types/v7.ts +0 -69
- package/src/migrations/VersionController.test.ts +0 -88
- package/src/migrations/VersionController.ts +0 -67
- package/src/migrations/index.ts +0 -61
- package/src/server/routers/edge/appStatus.ts +0 -3
- package/src/server/routers/edge/index.ts +0 -14
- package/src/server/routers/edge/upload.ts +0 -16
- package/src/services/aiModel/client.ts +0 -70
- package/src/services/aiProvider/client.ts +0 -58
- package/src/services/baseClientService/index.ts +0 -9
- package/src/services/chatGroup/client.ts +0 -63
- package/src/services/export/_deprecated.ts +0 -155
- package/src/services/export/client.ts +0 -15
- package/src/services/file/_deprecated.test.ts +0 -119
- package/src/services/file/_deprecated.ts +0 -80
- package/src/services/file/client.test.ts +0 -199
- package/src/services/file/client.ts +0 -85
- package/src/services/import/_deprecated.ts +0 -115
- package/src/services/import/client.test.ts +0 -1015
- package/src/services/import/client.ts +0 -64
- package/src/services/message/_deprecated.test.ts +0 -398
- package/src/services/message/_deprecated.ts +0 -168
- package/src/services/message/client.test.ts +0 -410
- package/src/services/message/client.ts +0 -192
- package/src/services/plugin/_deprecated.test.ts +0 -162
- package/src/services/plugin/_deprecated.ts +0 -42
- package/src/services/plugin/client.test.ts +0 -177
- package/src/services/plugin/client.ts +0 -46
- package/src/services/session/_deprecated.test.ts +0 -440
- package/src/services/session/_deprecated.ts +0 -190
- package/src/services/session/client.test.ts +0 -413
- package/src/services/session/client.ts +0 -193
- package/src/services/thread/client.ts +0 -51
- package/src/services/topic/_deprecated.test.ts +0 -245
- package/src/services/topic/_deprecated.ts +0 -75
- package/src/services/topic/client.ts +0 -89
- package/src/services/topic/pglite.test.ts +0 -212
- package/src/services/user/_deprecated.test.ts +0 -101
- package/src/services/user/_deprecated.ts +0 -70
- package/src/services/user/client.test.ts +0 -111
- package/src/services/user/client.ts +0 -104
|
@@ -1,245 +0,0 @@
|
|
|
1
|
-
import { Mock, beforeAll, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
2
|
-
|
|
3
|
-
import { SessionModel } from '@/database/_deprecated/models/session';
|
|
4
|
-
import { CreateTopicParams, TopicModel } from '@/database/_deprecated/models/topic';
|
|
5
|
-
import { ChatTopic } from '@/types/topic';
|
|
6
|
-
|
|
7
|
-
import { ClientService } from './_deprecated';
|
|
8
|
-
|
|
9
|
-
const topicService = new ClientService();
|
|
10
|
-
// Mock the TopicModel
|
|
11
|
-
vi.mock('@/database/_deprecated/models/topic', () => {
|
|
12
|
-
return {
|
|
13
|
-
TopicModel: {
|
|
14
|
-
create: vi.fn(),
|
|
15
|
-
query: vi.fn(),
|
|
16
|
-
delete: vi.fn(),
|
|
17
|
-
count: vi.fn(),
|
|
18
|
-
batchDeleteBySessionId: vi.fn(),
|
|
19
|
-
batchDelete: vi.fn(),
|
|
20
|
-
clearTable: vi.fn(),
|
|
21
|
-
toggleFavorite: vi.fn(),
|
|
22
|
-
batchCreate: vi.fn(),
|
|
23
|
-
update: vi.fn(),
|
|
24
|
-
queryAll: vi.fn(),
|
|
25
|
-
queryByKeyword: vi.fn(),
|
|
26
|
-
},
|
|
27
|
-
};
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
describe('TopicService', () => {
|
|
31
|
-
// Mock data
|
|
32
|
-
const mockTopicId = 'mock-topic-id';
|
|
33
|
-
const mockTopic: ChatTopic = {
|
|
34
|
-
createdAt: 100,
|
|
35
|
-
updatedAt: 100,
|
|
36
|
-
id: mockTopicId,
|
|
37
|
-
title: 'Mock Topic',
|
|
38
|
-
};
|
|
39
|
-
const mockTopics = [mockTopic];
|
|
40
|
-
|
|
41
|
-
beforeEach(() => {
|
|
42
|
-
// Reset all mocks before running each test case
|
|
43
|
-
vi.resetAllMocks();
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
describe('createTopic', () => {
|
|
47
|
-
it('should create a topic and return its id', async () => {
|
|
48
|
-
// Setup
|
|
49
|
-
const createParams: CreateTopicParams = {
|
|
50
|
-
title: 'New Topic',
|
|
51
|
-
sessionId: '1',
|
|
52
|
-
};
|
|
53
|
-
(TopicModel.create as Mock).mockResolvedValue(mockTopic);
|
|
54
|
-
|
|
55
|
-
// Execute
|
|
56
|
-
const topicId = await topicService.createTopic(createParams);
|
|
57
|
-
|
|
58
|
-
// Assert
|
|
59
|
-
expect(TopicModel.create).toHaveBeenCalledWith(createParams);
|
|
60
|
-
expect(topicId).toBe(mockTopicId);
|
|
61
|
-
});
|
|
62
|
-
it('should throw an error if topic creation fails', async () => {
|
|
63
|
-
// Setup
|
|
64
|
-
const createParams: CreateTopicParams = {
|
|
65
|
-
title: 'New Topic',
|
|
66
|
-
sessionId: '1',
|
|
67
|
-
};
|
|
68
|
-
|
|
69
|
-
(TopicModel.create as Mock).mockResolvedValue(null);
|
|
70
|
-
|
|
71
|
-
// Execute & Assert
|
|
72
|
-
await expect(topicService.createTopic(createParams)).rejects.toThrow('topic create Error');
|
|
73
|
-
});
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
describe('getTopics', () => {
|
|
77
|
-
// Example for getTopics
|
|
78
|
-
it('should query topics with given parameters', async () => {
|
|
79
|
-
// Setup
|
|
80
|
-
const queryParams = { containerId: 'session-id' };
|
|
81
|
-
(TopicModel.query as Mock).mockResolvedValue(mockTopics);
|
|
82
|
-
|
|
83
|
-
// Execute
|
|
84
|
-
const topics = await topicService.getTopics(queryParams);
|
|
85
|
-
|
|
86
|
-
// Assert
|
|
87
|
-
expect(TopicModel.query).toHaveBeenCalledWith(queryParams);
|
|
88
|
-
expect(topics).toBe(mockTopics);
|
|
89
|
-
});
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
describe('updateTopic', () => {
|
|
93
|
-
// Example for updateFavorite
|
|
94
|
-
it('should toggle favorite status of a topic', async () => {
|
|
95
|
-
// Setup
|
|
96
|
-
const newState = true;
|
|
97
|
-
|
|
98
|
-
// Execute
|
|
99
|
-
await topicService.updateTopic(mockTopicId, { favorite: newState });
|
|
100
|
-
|
|
101
|
-
// Assert
|
|
102
|
-
expect(TopicModel.update).toHaveBeenCalledWith(mockTopicId, { favorite: 1 });
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
it('should update the title of a topic', async () => {
|
|
106
|
-
// Setup
|
|
107
|
-
const newTitle = 'Updated Topic Title';
|
|
108
|
-
(TopicModel.update as Mock).mockResolvedValue({ ...mockTopic, title: newTitle });
|
|
109
|
-
|
|
110
|
-
// Execute
|
|
111
|
-
const result = await topicService.updateTopic(mockTopicId, { title: newTitle });
|
|
112
|
-
|
|
113
|
-
// Assert
|
|
114
|
-
expect(TopicModel.update).toHaveBeenCalledWith(mockTopicId, { title: newTitle });
|
|
115
|
-
expect(result).toEqual({ ...mockTopic, title: newTitle });
|
|
116
|
-
});
|
|
117
|
-
});
|
|
118
|
-
|
|
119
|
-
describe('removeTopic', () => {
|
|
120
|
-
it('should remove a topic by id', async () => {
|
|
121
|
-
// Setup
|
|
122
|
-
(TopicModel.delete as Mock).mockResolvedValue(true);
|
|
123
|
-
|
|
124
|
-
// Execute
|
|
125
|
-
const result = await topicService.removeTopic(mockTopicId);
|
|
126
|
-
|
|
127
|
-
// Assert
|
|
128
|
-
expect(TopicModel.delete).toHaveBeenCalledWith(mockTopicId);
|
|
129
|
-
expect(result).toBe(true);
|
|
130
|
-
});
|
|
131
|
-
});
|
|
132
|
-
|
|
133
|
-
describe('removeTopics', () => {
|
|
134
|
-
it('should remove all topics with a given session id', async () => {
|
|
135
|
-
// Setup
|
|
136
|
-
const sessionId = 'session-id';
|
|
137
|
-
(TopicModel.batchDeleteBySessionId as Mock).mockResolvedValue(true);
|
|
138
|
-
|
|
139
|
-
// Execute
|
|
140
|
-
const result = await topicService.removeTopics(sessionId);
|
|
141
|
-
|
|
142
|
-
// Assert
|
|
143
|
-
expect(TopicModel.batchDeleteBySessionId).toHaveBeenCalledWith(sessionId);
|
|
144
|
-
expect(result).toBe(true);
|
|
145
|
-
});
|
|
146
|
-
});
|
|
147
|
-
|
|
148
|
-
describe('batchRemoveTopics', () => {
|
|
149
|
-
it('should batch remove topics', async () => {
|
|
150
|
-
// Setup
|
|
151
|
-
const topicIds = [mockTopicId, 'another-topic-id'];
|
|
152
|
-
(TopicModel.batchDelete as Mock).mockResolvedValue(true);
|
|
153
|
-
|
|
154
|
-
// Execute
|
|
155
|
-
const result = await topicService.batchRemoveTopics(topicIds);
|
|
156
|
-
|
|
157
|
-
// Assert
|
|
158
|
-
expect(TopicModel.batchDelete).toHaveBeenCalledWith(topicIds);
|
|
159
|
-
expect(result).toBe(true);
|
|
160
|
-
});
|
|
161
|
-
});
|
|
162
|
-
|
|
163
|
-
describe('removeAllTopic', () => {
|
|
164
|
-
it('should clear all topics from the table', async () => {
|
|
165
|
-
// Setup
|
|
166
|
-
(TopicModel.clearTable as Mock).mockResolvedValue(true);
|
|
167
|
-
|
|
168
|
-
// Execute
|
|
169
|
-
const result = await topicService.removeAllTopic();
|
|
170
|
-
|
|
171
|
-
// Assert
|
|
172
|
-
expect(TopicModel.clearTable).toHaveBeenCalled();
|
|
173
|
-
expect(result).toBe(true);
|
|
174
|
-
});
|
|
175
|
-
});
|
|
176
|
-
|
|
177
|
-
describe('batchCreateTopics', () => {
|
|
178
|
-
it('should batch create topics', async () => {
|
|
179
|
-
// Setup
|
|
180
|
-
(TopicModel.batchCreate as Mock).mockResolvedValue(mockTopics);
|
|
181
|
-
|
|
182
|
-
// Execute
|
|
183
|
-
const result = await topicService.batchCreateTopics(mockTopics);
|
|
184
|
-
|
|
185
|
-
// Assert
|
|
186
|
-
expect(TopicModel.batchCreate).toHaveBeenCalledWith(mockTopics);
|
|
187
|
-
expect(result).toBe(mockTopics);
|
|
188
|
-
});
|
|
189
|
-
});
|
|
190
|
-
|
|
191
|
-
describe('getAllTopics', () => {
|
|
192
|
-
it('should retrieve all topics', async () => {
|
|
193
|
-
// Setup
|
|
194
|
-
(TopicModel.queryAll as Mock).mockResolvedValue(mockTopics);
|
|
195
|
-
|
|
196
|
-
// Execute
|
|
197
|
-
const result = await topicService.getAllTopics();
|
|
198
|
-
|
|
199
|
-
// Assert
|
|
200
|
-
expect(TopicModel.queryAll).toHaveBeenCalled();
|
|
201
|
-
expect(result).toBe(mockTopics);
|
|
202
|
-
});
|
|
203
|
-
});
|
|
204
|
-
|
|
205
|
-
describe('searchTopics', () => {
|
|
206
|
-
it('should return all topics that match the keyword', async () => {
|
|
207
|
-
// Setup
|
|
208
|
-
const keyword = 'search';
|
|
209
|
-
(TopicModel.queryByKeyword as Mock).mockResolvedValue(mockTopics);
|
|
210
|
-
|
|
211
|
-
// Execute
|
|
212
|
-
const result = await topicService.searchTopics(keyword, undefined);
|
|
213
|
-
|
|
214
|
-
// Assert
|
|
215
|
-
expect(TopicModel.queryByKeyword).toHaveBeenCalledWith(keyword, undefined);
|
|
216
|
-
expect(result).toBe(mockTopics);
|
|
217
|
-
});
|
|
218
|
-
});
|
|
219
|
-
|
|
220
|
-
describe('countTopics', () => {
|
|
221
|
-
it('should return false if no topics exist', async () => {
|
|
222
|
-
// Setup
|
|
223
|
-
(TopicModel.count as Mock).mockResolvedValue(0);
|
|
224
|
-
|
|
225
|
-
// Execute
|
|
226
|
-
const result = await topicService.countTopics();
|
|
227
|
-
|
|
228
|
-
// Assert
|
|
229
|
-
expect(TopicModel.count).toHaveBeenCalled();
|
|
230
|
-
expect(result).toBe(0);
|
|
231
|
-
});
|
|
232
|
-
|
|
233
|
-
it('should return true if topics exist', async () => {
|
|
234
|
-
// Setup
|
|
235
|
-
(TopicModel.count as Mock).mockResolvedValue(1);
|
|
236
|
-
|
|
237
|
-
// Execute
|
|
238
|
-
const result = await topicService.countTopics();
|
|
239
|
-
|
|
240
|
-
// Assert
|
|
241
|
-
expect(TopicModel.count).toHaveBeenCalled();
|
|
242
|
-
expect(result).toBe(1);
|
|
243
|
-
});
|
|
244
|
-
});
|
|
245
|
-
});
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
import { TopicModel } from '@/database/_deprecated/models/topic';
|
|
2
|
-
import { ChatTopic } from '@/types/topic';
|
|
3
|
-
|
|
4
|
-
import { CreateTopicParams, ITopicService, QueryTopicParams } from './type';
|
|
5
|
-
|
|
6
|
-
export class ClientService implements ITopicService {
|
|
7
|
-
async createTopic(params: CreateTopicParams): Promise<string> {
|
|
8
|
-
const item = await TopicModel.create(params as any);
|
|
9
|
-
|
|
10
|
-
if (!item) {
|
|
11
|
-
throw new Error('topic create Error');
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
return item.id;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
async batchCreateTopics(importTopics: ChatTopic[]) {
|
|
18
|
-
return TopicModel.batchCreate(importTopics as any);
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
async cloneTopic(id: string, newTitle?: string) {
|
|
22
|
-
return TopicModel.duplicateTopic(id, newTitle);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
async getTopics(params: QueryTopicParams): Promise<ChatTopic[]> {
|
|
26
|
-
return TopicModel.query(params);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
async searchTopics(keyword: string, sessionId?: string) {
|
|
30
|
-
return TopicModel.queryByKeyword(keyword, sessionId);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
async getAllTopics() {
|
|
34
|
-
return TopicModel.queryAll();
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
async countTopics() {
|
|
38
|
-
return TopicModel.count();
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
// @ts-ignore
|
|
42
|
-
async rankTopics() {
|
|
43
|
-
throw new Error('Method not implemented.');
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
async updateTopicFavorite(id: string, favorite?: boolean) {
|
|
47
|
-
return this.updateTopic(id, { favorite });
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
async updateTopicTitle(id: string, text: string) {
|
|
51
|
-
return this.updateTopic(id, { title: text });
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
async updateTopic(id: string, data: Partial<ChatTopic>) {
|
|
55
|
-
const favorite = typeof data.favorite !== 'undefined' ? (data.favorite ? 1 : 0) : undefined;
|
|
56
|
-
|
|
57
|
-
return TopicModel.update(id, { ...data, favorite });
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
async removeTopic(id: string) {
|
|
61
|
-
return TopicModel.delete(id);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
async removeTopics(sessionId: string) {
|
|
65
|
-
return TopicModel.batchDeleteBySessionId(sessionId);
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
async batchRemoveTopics(topics: string[]) {
|
|
69
|
-
return TopicModel.batchDelete(topics);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
async removeAllTopic() {
|
|
73
|
-
return TopicModel.clearTable();
|
|
74
|
-
}
|
|
75
|
-
}
|
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
import { INBOX_SESSION_ID } from '@/const/session';
|
|
2
|
-
import { clientDB } from '@/database/client/db';
|
|
3
|
-
import { TopicModel } from '@/database/models/topic';
|
|
4
|
-
import { BaseClientService } from '@/services/baseClientService';
|
|
5
|
-
import { ChatTopic } from '@/types/topic';
|
|
6
|
-
|
|
7
|
-
import { ITopicService } from './type';
|
|
8
|
-
|
|
9
|
-
export class ClientService extends BaseClientService implements ITopicService {
|
|
10
|
-
private get topicModel(): TopicModel {
|
|
11
|
-
return new TopicModel(clientDB as any, this.userId);
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
createTopic: ITopicService['createTopic'] = async (params) => {
|
|
15
|
-
const item = await this.topicModel.create({
|
|
16
|
-
...params,
|
|
17
|
-
sessionId: this.toDbSessionId(params.sessionId),
|
|
18
|
-
} as any);
|
|
19
|
-
|
|
20
|
-
if (!item) {
|
|
21
|
-
throw new Error('topic create Error');
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
return item.id;
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
batchCreateTopics: ITopicService['batchCreateTopics'] = async (importTopics) => {
|
|
28
|
-
const data = await this.topicModel.batchCreate(importTopics as any);
|
|
29
|
-
|
|
30
|
-
return { added: data.length, ids: [], skips: [], success: true };
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
cloneTopic: ITopicService['cloneTopic'] = async (id, newTitle) => {
|
|
34
|
-
const data = await this.topicModel.duplicate(id, newTitle);
|
|
35
|
-
return data.topic.id;
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
getTopics: ITopicService['getTopics'] = async (params) => {
|
|
39
|
-
const data = await this.topicModel.query({
|
|
40
|
-
...params,
|
|
41
|
-
containerId: this.toDbSessionId(params.containerId),
|
|
42
|
-
});
|
|
43
|
-
return data as unknown as Promise<ChatTopic[]>;
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
searchTopics: ITopicService['searchTopics'] = async (keyword, sessionId) => {
|
|
47
|
-
const data = await this.topicModel.queryByKeyword(keyword, this.toDbSessionId(sessionId));
|
|
48
|
-
|
|
49
|
-
return data as unknown as Promise<ChatTopic[]>;
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
getAllTopics: ITopicService['getAllTopics'] = async () => {
|
|
53
|
-
const data = await this.topicModel.queryAll();
|
|
54
|
-
|
|
55
|
-
return data as unknown as Promise<ChatTopic[]>;
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
countTopics: ITopicService['countTopics'] = async (params) => {
|
|
59
|
-
return this.topicModel.count(params);
|
|
60
|
-
};
|
|
61
|
-
|
|
62
|
-
rankTopics: ITopicService['rankTopics'] = async (limit) => {
|
|
63
|
-
return this.topicModel.rank(limit);
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
updateTopic: ITopicService['updateTopic'] = async (id, data) => {
|
|
67
|
-
return this.topicModel.update(id, data as any);
|
|
68
|
-
};
|
|
69
|
-
|
|
70
|
-
removeTopic: ITopicService['removeTopic'] = async (id) => {
|
|
71
|
-
return this.topicModel.delete(id);
|
|
72
|
-
};
|
|
73
|
-
|
|
74
|
-
removeTopics: ITopicService['removeTopics'] = async (sessionId) => {
|
|
75
|
-
return this.topicModel.batchDeleteBySessionId(this.toDbSessionId(sessionId));
|
|
76
|
-
};
|
|
77
|
-
|
|
78
|
-
batchRemoveTopics: ITopicService['batchRemoveTopics'] = async (topics) => {
|
|
79
|
-
return this.topicModel.batchDelete(topics);
|
|
80
|
-
};
|
|
81
|
-
|
|
82
|
-
removeAllTopic: ITopicService['removeAllTopic'] = async () => {
|
|
83
|
-
return this.topicModel.deleteAll();
|
|
84
|
-
};
|
|
85
|
-
|
|
86
|
-
private toDbSessionId(sessionId?: string | null) {
|
|
87
|
-
return sessionId === INBOX_SESSION_ID ? null : sessionId;
|
|
88
|
-
}
|
|
89
|
-
}
|
|
@@ -1,212 +0,0 @@
|
|
|
1
|
-
import { eq } from 'drizzle-orm';
|
|
2
|
-
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
3
|
-
|
|
4
|
-
import { clientDB, initializeDB } from '@/database/client/db';
|
|
5
|
-
import { sessions, topics, users } from '@/database/schemas';
|
|
6
|
-
import { ChatTopic } from '@/types/topic';
|
|
7
|
-
|
|
8
|
-
import { ClientService } from './client';
|
|
9
|
-
|
|
10
|
-
// Mock data
|
|
11
|
-
const userId = 'topic-user-test';
|
|
12
|
-
const sessionId = 'topic-session';
|
|
13
|
-
const mockTopicId = 'mock-topic-id';
|
|
14
|
-
|
|
15
|
-
const mockTopic = {
|
|
16
|
-
id: mockTopicId,
|
|
17
|
-
title: 'Mock Topic',
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
const topicService = new ClientService(userId);
|
|
21
|
-
|
|
22
|
-
beforeEach(async () => {
|
|
23
|
-
await initializeDB();
|
|
24
|
-
|
|
25
|
-
await clientDB.delete(users);
|
|
26
|
-
|
|
27
|
-
// 创建测试数据
|
|
28
|
-
await clientDB.transaction(async (tx) => {
|
|
29
|
-
await tx.insert(users).values({ id: userId }).onConflictDoNothing();
|
|
30
|
-
await tx.insert(sessions).values({ id: sessionId, userId });
|
|
31
|
-
await tx.insert(topics).values({ ...mockTopic, sessionId, userId });
|
|
32
|
-
});
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
describe('TopicService', () => {
|
|
36
|
-
describe('createTopic', () => {
|
|
37
|
-
it('should create a topic and return its id', async () => {
|
|
38
|
-
// Setup
|
|
39
|
-
const createParams = {
|
|
40
|
-
title: 'New Topic',
|
|
41
|
-
sessionId: sessionId,
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
// Execute
|
|
45
|
-
const topicId = await topicService.createTopic(createParams);
|
|
46
|
-
|
|
47
|
-
// Assert
|
|
48
|
-
expect(topicId).toBeDefined();
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
it('should throw an error if topic creation fails', async () => {
|
|
52
|
-
// Setup
|
|
53
|
-
const createParams = {
|
|
54
|
-
title: 'New Topic',
|
|
55
|
-
sessionId: 123 as any, // sessionId should be string
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
// Execute & Assert
|
|
59
|
-
await expect(topicService.createTopic(createParams)).rejects.toThrowError();
|
|
60
|
-
});
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
describe('getTopics', () => {
|
|
64
|
-
// Example for getTopics
|
|
65
|
-
it('should query topics with given parameters', async () => {
|
|
66
|
-
// Setup
|
|
67
|
-
const queryParams = { containerId: sessionId };
|
|
68
|
-
|
|
69
|
-
// Execute
|
|
70
|
-
const data = await topicService.getTopics(queryParams);
|
|
71
|
-
|
|
72
|
-
// Assert
|
|
73
|
-
expect(data[0]).toMatchObject(mockTopic);
|
|
74
|
-
});
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
describe('updateTopic', () => {
|
|
78
|
-
// Example for updateFavorite
|
|
79
|
-
it('should toggle favorite status of a topic', async () => {
|
|
80
|
-
// Execute
|
|
81
|
-
const result = await topicService.updateTopic(mockTopicId, { favorite: true });
|
|
82
|
-
|
|
83
|
-
// Assert
|
|
84
|
-
expect(result[0].favorite).toBeTruthy();
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
it('should update the title of a topic', async () => {
|
|
88
|
-
// Setup
|
|
89
|
-
const newTitle = 'Updated Topic Title';
|
|
90
|
-
|
|
91
|
-
// Execute
|
|
92
|
-
const result = await topicService.updateTopic(mockTopicId, { title: newTitle });
|
|
93
|
-
|
|
94
|
-
// Assert
|
|
95
|
-
expect(result[0].title).toEqual(newTitle);
|
|
96
|
-
});
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
describe('removeTopic', () => {
|
|
100
|
-
it('should remove a topic by id', async () => {
|
|
101
|
-
// Execute
|
|
102
|
-
await topicService.removeTopic(mockTopicId);
|
|
103
|
-
const result = await clientDB.query.topics.findFirst({ where: eq(topics.id, mockTopicId) });
|
|
104
|
-
|
|
105
|
-
// Assert
|
|
106
|
-
expect(result).toBeUndefined();
|
|
107
|
-
});
|
|
108
|
-
});
|
|
109
|
-
|
|
110
|
-
describe('removeTopics', () => {
|
|
111
|
-
it('should remove all topics with a given session id', async () => {
|
|
112
|
-
// Setup
|
|
113
|
-
const sessionId = 'session-id';
|
|
114
|
-
|
|
115
|
-
// Execute
|
|
116
|
-
await topicService.removeTopics(sessionId);
|
|
117
|
-
const result = await clientDB.query.topics.findMany({
|
|
118
|
-
where: eq(topics.sessionId, sessionId),
|
|
119
|
-
});
|
|
120
|
-
|
|
121
|
-
expect(result.length).toEqual(0);
|
|
122
|
-
});
|
|
123
|
-
});
|
|
124
|
-
|
|
125
|
-
describe('batchRemoveTopics', () => {
|
|
126
|
-
it('should batch remove topics', async () => {
|
|
127
|
-
await clientDB.insert(topics).values([{ id: 'topic-id-1', title: 'topic-title', userId }]);
|
|
128
|
-
// Setup
|
|
129
|
-
const topicIds = [mockTopicId, 'another-topic-id'];
|
|
130
|
-
|
|
131
|
-
// Execute
|
|
132
|
-
await topicService.batchRemoveTopics(topicIds);
|
|
133
|
-
|
|
134
|
-
const count = await clientDB.$count(topics);
|
|
135
|
-
|
|
136
|
-
// Assert
|
|
137
|
-
expect(count).toBe(1);
|
|
138
|
-
});
|
|
139
|
-
});
|
|
140
|
-
|
|
141
|
-
describe('removeAllTopic', () => {
|
|
142
|
-
it('should clear all topics from the table', async () => {
|
|
143
|
-
// Execute
|
|
144
|
-
await topicService.removeAllTopic();
|
|
145
|
-
|
|
146
|
-
const count = await clientDB.$count(topics);
|
|
147
|
-
// Assert
|
|
148
|
-
expect(count).toBe(0);
|
|
149
|
-
});
|
|
150
|
-
});
|
|
151
|
-
|
|
152
|
-
describe('batchCreateTopics', () => {
|
|
153
|
-
it('should batch create topics', async () => {
|
|
154
|
-
// Execute
|
|
155
|
-
const result = await topicService.batchCreateTopics([
|
|
156
|
-
{ id: 'topic-id-1', title: 'topic-title' },
|
|
157
|
-
{ id: 'topic-id-2', title: 'topic-title' },
|
|
158
|
-
] as ChatTopic[]);
|
|
159
|
-
|
|
160
|
-
// Assert
|
|
161
|
-
expect(result.success).toBeTruthy();
|
|
162
|
-
expect(result.added).toBe(2);
|
|
163
|
-
});
|
|
164
|
-
});
|
|
165
|
-
|
|
166
|
-
describe('getAllTopics', () => {
|
|
167
|
-
it('should retrieve all topics', async () => {
|
|
168
|
-
await clientDB.insert(topics).values([
|
|
169
|
-
{ id: 'topic-id-1', title: 'topic-title', userId },
|
|
170
|
-
{ id: 'topic-id-2', title: 'topic-title', userId },
|
|
171
|
-
]);
|
|
172
|
-
// Execute
|
|
173
|
-
const result = await topicService.getAllTopics();
|
|
174
|
-
|
|
175
|
-
// Assert
|
|
176
|
-
expect(result.length).toEqual(3);
|
|
177
|
-
});
|
|
178
|
-
});
|
|
179
|
-
|
|
180
|
-
describe('searchTopics', () => {
|
|
181
|
-
it('should return all topics that match the keyword', async () => {
|
|
182
|
-
// Setup
|
|
183
|
-
const keyword = 'Topic';
|
|
184
|
-
|
|
185
|
-
// Execute
|
|
186
|
-
const result = await topicService.searchTopics(keyword, sessionId);
|
|
187
|
-
|
|
188
|
-
// Assert
|
|
189
|
-
expect(result.length).toEqual(1);
|
|
190
|
-
});
|
|
191
|
-
it('should return empty topic if not match the keyword', async () => {
|
|
192
|
-
// Setup
|
|
193
|
-
const keyword = 'search';
|
|
194
|
-
|
|
195
|
-
// Execute
|
|
196
|
-
const result = await topicService.searchTopics(keyword, sessionId);
|
|
197
|
-
|
|
198
|
-
// Assert
|
|
199
|
-
expect(result.length).toEqual(0);
|
|
200
|
-
});
|
|
201
|
-
});
|
|
202
|
-
|
|
203
|
-
describe('countTopics', () => {
|
|
204
|
-
it('should return topic counts', async () => {
|
|
205
|
-
// Execute
|
|
206
|
-
const result = await topicService.countTopics();
|
|
207
|
-
|
|
208
|
-
// Assert
|
|
209
|
-
expect(result).toBe(1);
|
|
210
|
-
});
|
|
211
|
-
});
|
|
212
|
-
});
|