mirror of
https://github.com/labring/FastGPT.git
synced 2025-07-24 22:03:54 +00:00
Add test (#4721)
* Add unit tests for Markdown utility functions and CodeClassNameEnum. (#4716) Co-authored-by: gru-agent[bot] <185149714+gru-agent[bot]@users.noreply.github.com> * Add unit tests for authChatCrud and authCollectionInChat functions in chat service. (#4718) Co-authored-by: gru-agent[bot] <185149714+gru-agent[bot]@users.noreply.github.com> --------- Co-authored-by: gru-agent[bot] <185149714+gru-agent[bot]@users.noreply.github.com>
This commit is contained in:
@@ -244,3 +244,5 @@ export const authCollectionInChat = async ({
|
||||
} catch (error) {}
|
||||
return Promise.reject(DatasetErrEnum.unAuthDatasetFile);
|
||||
};
|
||||
|
||||
export { defaultResponseShow };
|
||||
|
59
test/cases/components/Markdown/utils.test.ts
Normal file
59
test/cases/components/Markdown/utils.test.ts
Normal file
@@ -0,0 +1,59 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { mdTextFormat, CodeClassNameEnum } from '@/components/Markdown/utils';
|
||||
|
||||
describe('Markdown utils', () => {
|
||||
describe('mdTextFormat', () => {
|
||||
it('should format latex expressions correctly', () => {
|
||||
const input = 'Here is some math: \\[x^2 + y^2 = z^2\\] and inline \\(a+b=c\\)';
|
||||
const expected = 'Here is some math: $$x^2 + y^2 = z^2$$ and inline $a+b=c$';
|
||||
expect(mdTextFormat(input)).toBe(expected);
|
||||
});
|
||||
|
||||
it('should not format latex expressions inside code blocks', () => {
|
||||
const input = '```math\n\\[x^2\\]\n```\n`\\[y^2\\]`';
|
||||
expect(mdTextFormat(input)).toBe(input);
|
||||
});
|
||||
|
||||
it('should convert quote references to proper markdown links', () => {
|
||||
const input = '[123456789012345678901234]';
|
||||
const expected = '[123456789012345678901234](QUOTE)';
|
||||
expect(mdTextFormat(input)).toBe(expected);
|
||||
});
|
||||
|
||||
it('should not convert invalid quote references', () => {
|
||||
const input = '[12345] [abcdef] [123456789012345678901234](test)';
|
||||
expect(mdTextFormat(input)).toBe(input);
|
||||
});
|
||||
|
||||
it('should add spaces between URLs and Chinese punctuation', () => {
|
||||
const input = 'Check https://example.com,here。';
|
||||
const expected = 'Check https://example.com ,here。';
|
||||
expect(mdTextFormat(input)).toBe(expected);
|
||||
});
|
||||
|
||||
it('should handle complex text with multiple patterns', () => {
|
||||
const input =
|
||||
'Math \\[x^2\\] with link https://test.com,and quote [123456789012345678901234]';
|
||||
const expected =
|
||||
'Math $$x^2$$ with link https://test.com ,and quote [123456789012345678901234](QUOTE)';
|
||||
expect(mdTextFormat(input)).toBe(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('CodeClassNameEnum', () => {
|
||||
it('should have correct enum values', () => {
|
||||
expect(CodeClassNameEnum.guide).toBe('guide');
|
||||
expect(CodeClassNameEnum.questionguide).toBe('questionguide');
|
||||
expect(CodeClassNameEnum.mermaid).toBe('mermaid');
|
||||
expect(CodeClassNameEnum.echarts).toBe('echarts');
|
||||
expect(CodeClassNameEnum.quote).toBe('quote');
|
||||
expect(CodeClassNameEnum.files).toBe('files');
|
||||
expect(CodeClassNameEnum.latex).toBe('latex');
|
||||
expect(CodeClassNameEnum.iframe).toBe('iframe');
|
||||
expect(CodeClassNameEnum.html).toBe('html');
|
||||
expect(CodeClassNameEnum.svg).toBe('svg');
|
||||
expect(CodeClassNameEnum.video).toBe('video');
|
||||
expect(CodeClassNameEnum.audio).toBe('audio');
|
||||
});
|
||||
});
|
||||
});
|
254
test/cases/service/support/permission/auth/chat.test.ts
Normal file
254
test/cases/service/support/permission/auth/chat.test.ts
Normal file
@@ -0,0 +1,254 @@
|
||||
import { describe, expect, it, vi } from 'vitest';
|
||||
import { authChatCrud, authCollectionInChat } from '@/service/support/permission/auth/chat';
|
||||
import { MongoChat } from '@fastgpt/service/core/chat/chatSchema';
|
||||
import { MongoChatItem } from '@fastgpt/service/core/chat/chatItemSchema';
|
||||
import { AuthUserTypeEnum } from '@fastgpt/global/support/permission/constant';
|
||||
import { ChatErrEnum } from '@fastgpt/global/common/error/code/chat';
|
||||
import { DatasetErrEnum } from '@fastgpt/global/common/error/code/dataset';
|
||||
import { authApp } from '@fastgpt/service/support/permission/app/auth';
|
||||
import { authOutLink } from '@/service/support/permission/auth/outLink';
|
||||
|
||||
vi.mock('@fastgpt/service/core/chat/chatSchema', () => ({
|
||||
MongoChat: {
|
||||
findOne: vi.fn()
|
||||
}
|
||||
}));
|
||||
|
||||
vi.mock('@fastgpt/service/core/chat/chatItemSchema', () => ({
|
||||
MongoChatItem: {
|
||||
findOne: vi.fn()
|
||||
}
|
||||
}));
|
||||
|
||||
vi.mock('@fastgpt/service/support/permission/app/auth');
|
||||
vi.mock('@/service/support/permission/auth/outLink');
|
||||
|
||||
describe('authChatCrud', () => {
|
||||
it('should reject if no appId provided', async () => {
|
||||
await expect(authChatCrud({ appId: '' })).rejects.toBe(ChatErrEnum.unAuthChat);
|
||||
});
|
||||
|
||||
it('should auth outLink without chatId', async () => {
|
||||
vi.mocked(authOutLink).mockResolvedValue({
|
||||
outLinkConfig: {
|
||||
teamId: 'team1',
|
||||
tmbId: 'tmb1',
|
||||
responseDetail: true,
|
||||
showNodeStatus: true,
|
||||
showRawSource: true
|
||||
},
|
||||
uid: 'user1',
|
||||
appId: 'app1'
|
||||
});
|
||||
|
||||
const result = await authChatCrud({
|
||||
appId: 'app1',
|
||||
shareId: 'share1',
|
||||
outLinkUid: 'user1'
|
||||
});
|
||||
|
||||
expect(result).toMatchObject({
|
||||
teamId: 'team1',
|
||||
tmbId: 'tmb1',
|
||||
uid: 'user1',
|
||||
responseDetail: true,
|
||||
showNodeStatus: true,
|
||||
showRawSource: true,
|
||||
authType: AuthUserTypeEnum.outLink
|
||||
});
|
||||
});
|
||||
|
||||
it('should auth outLink with chatId', async () => {
|
||||
const mockChat = {
|
||||
appId: 'app1',
|
||||
outLinkUid: 'user1'
|
||||
};
|
||||
|
||||
vi.mocked(authOutLink).mockResolvedValue({
|
||||
outLinkConfig: {
|
||||
teamId: 'team1',
|
||||
tmbId: 'tmb1',
|
||||
responseDetail: true,
|
||||
showNodeStatus: true,
|
||||
showRawSource: true
|
||||
},
|
||||
uid: 'user1',
|
||||
appId: 'app1'
|
||||
});
|
||||
|
||||
vi.mocked(MongoChat.findOne).mockReturnValue({
|
||||
lean: () => mockChat
|
||||
} as any);
|
||||
|
||||
const result = await authChatCrud({
|
||||
appId: 'app1',
|
||||
chatId: 'chat1',
|
||||
shareId: 'share1',
|
||||
outLinkUid: 'user1'
|
||||
});
|
||||
|
||||
expect(result).toMatchObject({
|
||||
teamId: 'team1',
|
||||
tmbId: 'tmb1',
|
||||
uid: 'user1',
|
||||
chat: mockChat,
|
||||
responseDetail: true,
|
||||
showNodeStatus: true,
|
||||
showRawSource: true,
|
||||
authType: AuthUserTypeEnum.outLink
|
||||
});
|
||||
});
|
||||
|
||||
it('should reject if outLink appId does not match', async () => {
|
||||
vi.mocked(authOutLink).mockResolvedValue({
|
||||
outLinkConfig: {
|
||||
teamId: 'team1',
|
||||
tmbId: 'tmb1'
|
||||
},
|
||||
uid: 'user1',
|
||||
appId: 'different-app'
|
||||
});
|
||||
|
||||
await expect(
|
||||
authChatCrud({
|
||||
appId: 'app1',
|
||||
shareId: 'share1',
|
||||
outLinkUid: 'user1'
|
||||
})
|
||||
).rejects.toBe(ChatErrEnum.unAuthChat);
|
||||
});
|
||||
|
||||
it('should auth with cookie', async () => {
|
||||
vi.mocked(authApp).mockResolvedValue({
|
||||
teamId: 'team1',
|
||||
tmbId: 'tmb1',
|
||||
permission: {
|
||||
hasManagePer: true
|
||||
},
|
||||
authType: AuthUserTypeEnum.team
|
||||
});
|
||||
|
||||
const result = await authChatCrud({
|
||||
appId: 'app1',
|
||||
req: {} as any
|
||||
});
|
||||
|
||||
expect(result).toEqual({
|
||||
teamId: 'team1',
|
||||
tmbId: 'tmb1',
|
||||
uid: 'tmb1',
|
||||
responseDetail: true,
|
||||
showNodeStatus: true,
|
||||
showRawSource: true,
|
||||
authType: AuthUserTypeEnum.team
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('authCollectionInChat', () => {
|
||||
it('should reject if chat item not found', async () => {
|
||||
vi.mocked(MongoChatItem.findOne).mockReturnValue({
|
||||
lean: () => null
|
||||
} as any);
|
||||
|
||||
await expect(
|
||||
authCollectionInChat({
|
||||
collectionIds: ['col1'],
|
||||
appId: 'app1',
|
||||
chatId: 'chat1',
|
||||
chatItemDataId: 'item1'
|
||||
})
|
||||
).rejects.toBe(DatasetErrEnum.unAuthDatasetCollection);
|
||||
});
|
||||
|
||||
it('should auth collection ids in chat item', async () => {
|
||||
const mockChatItem = {
|
||||
time: new Date(),
|
||||
responseData: [
|
||||
{
|
||||
quoteList: [{ collectionId: 'col1' }, { collectionId: 'col2' }]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
vi.mocked(MongoChatItem.findOne).mockReturnValue({
|
||||
lean: () => mockChatItem
|
||||
} as any);
|
||||
|
||||
const result = await authCollectionInChat({
|
||||
collectionIds: ['col1', 'col2'],
|
||||
appId: 'app1',
|
||||
chatId: 'chat1',
|
||||
chatItemDataId: 'item1'
|
||||
});
|
||||
|
||||
expect(result).toEqual({
|
||||
chatItem: mockChatItem
|
||||
});
|
||||
});
|
||||
|
||||
it('should handle plugin, tool and loop details in response data', async () => {
|
||||
const mockChatItem = {
|
||||
time: new Date(),
|
||||
responseData: [
|
||||
{
|
||||
quoteList: [{ collectionId: 'col1' }],
|
||||
pluginDetail: [
|
||||
{
|
||||
quoteList: [{ collectionId: 'col2' }]
|
||||
}
|
||||
],
|
||||
toolDetail: [
|
||||
{
|
||||
quoteList: [{ collectionId: 'col3' }]
|
||||
}
|
||||
],
|
||||
loopDetail: [
|
||||
{
|
||||
quoteList: [{ collectionId: 'col4' }]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
vi.mocked(MongoChatItem.findOne).mockReturnValue({
|
||||
lean: () => mockChatItem
|
||||
} as any);
|
||||
|
||||
const result = await authCollectionInChat({
|
||||
collectionIds: ['col1', 'col2', 'col3', 'col4'],
|
||||
appId: 'app1',
|
||||
chatId: 'chat1',
|
||||
chatItemDataId: 'item1'
|
||||
});
|
||||
|
||||
expect(result).toEqual({
|
||||
chatItem: mockChatItem
|
||||
});
|
||||
});
|
||||
|
||||
it('should reject if collection ids not found in quotes', async () => {
|
||||
const mockChatItem = {
|
||||
time: new Date(),
|
||||
responseData: [
|
||||
{
|
||||
quoteList: [{ collectionId: 'col1' }]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
vi.mocked(MongoChatItem.findOne).mockReturnValue({
|
||||
lean: () => mockChatItem
|
||||
} as any);
|
||||
|
||||
await expect(
|
||||
authCollectionInChat({
|
||||
collectionIds: ['col2'],
|
||||
appId: 'app1',
|
||||
chatId: 'chat1',
|
||||
chatItemDataId: 'item1'
|
||||
})
|
||||
).rejects.toBe(DatasetErrEnum.unAuthDatasetFile);
|
||||
});
|
||||
});
|
Reference in New Issue
Block a user