Skip to content

Commit

Permalink
4.8.11 test (#2794)
Browse files Browse the repository at this point in the history
* perf: version list type

* perf: add node default value

* perf: snapshot status

* fix: version detail auth

* fix: export defalt
  • Loading branch information
c121914yu authored Sep 26, 2024
1 parent e31d6ec commit 86436d5
Show file tree
Hide file tree
Showing 24 changed files with 750 additions and 488 deletions.
68 changes: 68 additions & 0 deletions .vscode/nextapi.code-snippets
Original file line number Diff line number Diff line change
Expand Up @@ -50,5 +50,73 @@
"export default ContextProvider"
],
"description": "FastGPT usecontext template"
},

"Jest test template": {
"scope": "typescriptreact",
"prefix": "jesttest",
"body": [
"import '@/pages/api/__mocks__/base';",
"import { root } from '@/pages/api/__mocks__/db/init';",
"import { getTestRequest } from '@/test/utils';",
"import { AppErrEnum } from '@fastgpt/global/common/error/code/app';",
"import handler from './demo';",
"",
"// Import the schema",
"import { MongoOutLink } from '@fastgpt/service/support/outLink/schema';",
"",
"beforeAll(async () => {",
" // await MongoOutLink.create({",
" // shareId: 'aaa',",
" // appId: root.appId,",
" // tmbId: root.tmbId,",
" // teamId: root.teamId,",
" // type: 'share',",
" // name: 'aaa'",
" // })",
"});",
"",
"test('Should return a list of outLink', async () => {",
" // Mock request",
" const res = (await handler(",
" ...getTestRequest({",
" query: {",
" appId: root.appId,",
" type: 'share'",
" },",
" user: root",
" })",
" )) as any;",
"",
" expect(res.code).toBe(200);",
" expect(res.data.length).toBe(2);",
"});",
"",
"test('appId is required', async () => {",
" const res = (await handler(",
" ...getTestRequest({",
" query: {",
" type: 'share'",
" },",
" user: root",
" })",
" )) as any;",
" expect(res.code).toBe(500);",
" expect(res.error).toBe(AppErrEnum.unExist);",
"});",
"",
"test('if type is not provided, return nothing', async () => {",
" const res = (await handler(",
" ...getTestRequest({",
" query: {",
" appId: root.appId",
" },",
" user: root",
" })",
" )) as any;",
" expect(res.code).toBe(200);",
" expect(res.data.length).toBe(0);",
"});"
]
}
}
4 changes: 4 additions & 0 deletions dev.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ Note: If the Node version is >= 20, you need to pass the `--no-node-snapshot` pa
NODE_OPTIONS=--no-node-snapshot pnpm i
```

### Jest

https://fael3z0zfze.feishu.cn/docx/ZOI1dABpxoGhS7xzhkXcKPxZnDL

## I18N

### Install i18n-ally Plugin
Expand Down
9 changes: 9 additions & 0 deletions packages/global/core/app/version.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,12 @@ export type AppVersionSchemaType = {
versionName: string;
tmbId: string;
};

export type VersionListItemType = {
_id: string;
appId: string;
versionName: string;
time: Date;
isPublish: boolean | undefined;
tmbId: string;
};
11 changes: 6 additions & 5 deletions packages/web/i18n/en/app.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@
"app.Version name": "Version Name",
"app.modules.click to update": "Click to Refresh",
"app.modules.has new version": "New Version Available",
"app.version_back": "Revert to Original State",
"app.version_copy": "Duplicate",
"version_back": "Revert to Original State",
"version_copy": "Duplicate",
"app.version_current": "Current Version",
"app.version_initial": "Initial Version",
"app.version_initial_copy": "Duplicate - Original State",
"version_initial_copy": "Duplicate - Original State",
"app.version_name_tips": "Version name cannot be empty",
"app.version_past": "Previously Published",
"app.version_publish_tips": "This version will be saved to the team cloud, synchronized with the entire team, and update the app version on all release channels.",
Expand Down Expand Up @@ -51,6 +51,7 @@
"import_configs": "Import Configurations",
"import_configs_failed": "Import configuration failed, please ensure the configuration is correct!",
"import_configs_success": "Import Successful",
"initial_form": "initial state",
"interval.12_hours": "Every 12 Hours",
"interval.2_hours": "Every 2 Hours",
"interval.3_hours": "Every 3 Hours",
Expand Down Expand Up @@ -87,11 +88,11 @@
"search_app": "Search Application",
"setting_app": "Application Settings",
"setting_plugin": "Plugin Settings",
"template.simple_robot": "Simple robot",
"template.hard_strict": "Strict Q&A template",
"template.hard_strict_des": "Based on the question and answer template, stricter requirements are imposed on the model's answers.",
"template.qa_template": "Q&A template",
"template.qa_template_des": "A knowledge base suitable for QA question and answer structure, which allows AI to answer strictly according to preset content",
"template.simple_robot": "Simple robot",
"template.standard_strict": "Standard strict template",
"template.standard_strict_des": "Based on the standard template, stricter requirements are imposed on the model's answers.",
"template.standard_template": "Standard template",
Expand Down Expand Up @@ -154,4 +155,4 @@
"workflow.user_file_input_desc": "Links to documents and images uploaded by users.",
"workflow.user_select": "User Selection",
"workflow.user_select_tip": "This module can configure multiple options for selection during the dialogue. Different options can lead to different workflow branches."
}
}
7 changes: 4 additions & 3 deletions packages/web/i18n/zh/app.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@
"app.Version name": "版本名称",
"app.modules.click to update": "点击更新",
"app.modules.has new version": "有新版本",
"app.version_back": "回到初始状态",
"app.version_copy": "副本",
"version_back": "回到初始状态",
"version_copy": "副本",
"app.version_current": "当前版本",
"app.version_initial": "初始版本",
"app.version_initial_copy": "副本-初始状态",
"version_initial_copy": "副本-初始状态",
"app.version_name_tips": "版本名称不能为空",
"app.version_past": "发布过",
"app.version_publish_tips": "该版本将被保存至团队云端,同步给整个团队,同时更新所有发布渠道的应用版本",
Expand Down Expand Up @@ -51,6 +51,7 @@
"import_configs": "导入配置",
"import_configs_failed": "导入配置失败,请确保配置正常!",
"import_configs_success": "导入成功",
"initial_form": "初始状态",
"interval.12_hours": "每12小时",
"interval.2_hours": "每2小时",
"interval.3_hours": "每3小时",
Expand Down
2 changes: 0 additions & 2 deletions projects/app/src/pages/api/__mocks__/db/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,4 @@ export const initMockData = async () => {
root.tmbId = rootTeamMember._id;
root.teamId = rootTeam._id;
root.appId = rootApp._id;

await Promise.all([rootUser.save(), rootTeam.save(), rootTeamMember.save(), rootApp.save()]);
};
61 changes: 61 additions & 0 deletions projects/app/src/pages/api/__mocks__/demo/demo.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import '@/pages/api/__mocks__/base';
import { root } from '@/pages/api/__mocks__/db/init';
import { getTestRequest } from '@/test/utils';
import { AppErrEnum } from '@fastgpt/global/common/error/code/app';
import handler from './demo';

// Import the schema
import { MongoOutLink } from '@fastgpt/service/support/outLink/schema';

beforeAll(async () => {
// await MongoOutLink.create({
// shareId: 'aaa',
// appId: root.appId,
// tmbId: root.tmbId,
// teamId: root.teamId,
// type: 'share',
// name: 'aaa'
// })
});

test('Should return a list of outLink', async () => {
// Mock request
const res = (await handler(
...getTestRequest({
query: {
appId: root.appId,
type: 'share'
},
user: root
})
)) as any;

expect(res.code).toBe(200);
expect(res.data.length).toBe(2);
});

test('appId is required', async () => {
const res = (await handler(
...getTestRequest({
query: {
type: 'share'
},
user: root
})
)) as any;
expect(res.code).toBe(500);
expect(res.error).toBe(AppErrEnum.unExist);
});

test('if type is not provided, return nothing', async () => {
const res = (await handler(
...getTestRequest({
query: {
appId: root.appId
},
user: root
})
)) as any;
expect(res.code).toBe(200);
expect(res.data.length).toBe(0);
});
17 changes: 17 additions & 0 deletions projects/app/src/pages/api/__mocks__/demo/demo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import type { ApiRequestProps, ApiResponseType } from '@fastgpt/service/type/next';
import { NextAPI } from '@/service/middleware/entry';

export type demoQuery = {};

export type demoBody = {};

export type demoResponse = {};

async function handler(
req: ApiRequestProps<demoBody, demoQuery>,
res: ApiResponseType<any>
): Promise<demoResponse> {
return {};
}

export default NextAPI(handler);
22 changes: 17 additions & 5 deletions projects/app/src/pages/api/core/app/version/detail.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,32 @@ import type { NextApiRequest, NextApiResponse } from 'next';
import { NextAPI } from '@/service/middleware/entry';
import { MongoAppVersion } from '@fastgpt/service/core/app/version/schema';
import { authApp } from '@fastgpt/service/support/permission/app/auth';
import { ReadPermissionVal } from '@fastgpt/global/support/permission/constant';
import { WritePermissionVal } from '@fastgpt/global/support/permission/constant';
import { AppVersionSchemaType } from '@fastgpt/global/core/app/version';
import { formatTime2YMDHM } from '@fastgpt/global/common/string/time';

type Props = {
versionId: string;
appId: string;
};

async function handler(req: NextApiRequest, res: NextApiResponse<any>) {
async function handler(
req: NextApiRequest,
res: NextApiResponse<any>
): Promise<AppVersionSchemaType> {
const { versionId, appId } = req.query as Props;

await authApp({ req, authToken: true, appId, per: ReadPermissionVal });
const result = await MongoAppVersion.findById(versionId);
await authApp({ req, authToken: true, appId, per: WritePermissionVal });
const result = await MongoAppVersion.findById(versionId).lean();

return result;
if (!result) {
return Promise.reject('version not found');
}

return {
...result,
versionName: result?.versionName || formatTime2YMDHM(result?.time)
};
}

export default NextAPI(handler);
69 changes: 69 additions & 0 deletions projects/app/src/pages/api/core/app/version/lis.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import '@/pages/api/__mocks__/base';
import { root } from '@/pages/api/__mocks__/db/init';
import { getTestRequest } from '@/test/utils';
import handler, { versionListBody, versionListResponse } from './list';

// Import the schema
import { MongoAppVersion } from '@fastgpt/service/core/app/version/schema';

const total = 22;

beforeAll(async () => {
const arr = new Array(total).fill(0);
await MongoAppVersion.insertMany(
arr.map((_, index) => ({
appId: root.appId,
nodes: [],
edges: [],
chatConfig: {},
isPublish: index % 2 === 0,
versionName: `v` + index,
tmbId: root.tmbId,
time: new Date(index * 1000)
}))
);
});

test('Get version list and check', async () => {
const offset = 0;
const pageSize = 10;

const _res = (await handler(
...getTestRequest<{}, versionListBody>({
body: {
offset,
pageSize,
appId: root.appId
},
user: root
})
)) as any;
const res = _res.data as versionListResponse;

expect(res.total).toBe(total);
expect(res.list.length).toBe(pageSize);
expect(res.list[0].versionName).toBe('v21');
expect(res.list[9].versionName).toBe('v12');
});

test('Get version list with offset 20', async () => {
const offset = 20;
const pageSize = 10;

const _res = (await handler(
...getTestRequest<{}, versionListBody>({
body: {
offset,
pageSize,
appId: root.appId
},
user: root
})
)) as any;
const res = _res.data as versionListResponse;

expect(res.total).toBe(total);
expect(res.list.length).toBe(2);
expect(res.list[0].versionName).toBe('v1');
expect(res.list[1].versionName).toBe('v0');
});
Original file line number Diff line number Diff line change
@@ -1,27 +1,26 @@
import type { NextApiRequest, NextApiResponse } from 'next';
import type { NextApiResponse } from 'next';
import { NextAPI } from '@/service/middleware/entry';
import { MongoAppVersion } from '@fastgpt/service/core/app/version/schema';
import { PaginationProps, PaginationResponse } from '@fastgpt/web/common/fetch/type';
import { ApiRequestProps } from '@fastgpt/service/type/next';
import { authApp } from '@fastgpt/service/support/permission/app/auth';
import { WritePermissionVal } from '@fastgpt/global/support/permission/constant';
import { VersionListItemType } from '@fastgpt/global/core/app/version';

type Props = PaginationProps<{
export type versionListBody = PaginationProps<{
appId: string;
}>;

export type versionListResponse = {
_id: string;
appId: string;
versionName: string;
time: Date;
isPublish: boolean | undefined;
tmbId: string;
};

type Response = PaginationResponse<versionListResponse>;
export type versionListResponse = PaginationResponse<VersionListItemType>;

async function handler(req: ApiRequestProps<Props>, res: NextApiResponse<any>): Promise<Response> {
async function handler(
req: ApiRequestProps<versionListBody>,
res: NextApiResponse<any>
): Promise<versionListResponse> {
const { offset, pageSize, appId } = req.body;

await authApp({ appId, req, per: WritePermissionVal, authToken: true });

const [result, total] = await Promise.all([
MongoAppVersion.find(
{
Expand Down
Loading

0 comments on commit 86436d5

Please sign in to comment.