@nocobase/test 1.6.0-alpha.2 → 1.6.0-alpha.20
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/es/e2e/e2eUtils.d.ts +4 -2
- package/es/server/index.d.ts +1 -0
- package/es/server/mock-server.d.ts +4 -3
- package/lib/client/formItemChecker/icon.js +0 -1
- package/lib/e2e/e2eUtils.d.ts +4 -2
- package/lib/e2e/e2eUtils.js +124 -20
- package/lib/e2e/templatesOfPage.js +3 -3
- package/lib/server/index.d.ts +1 -0
- package/lib/server/index.js +3 -0
- package/lib/server/mock-server.d.ts +4 -3
- package/lib/server/mock-server.js +39 -5
- package/package.json +3 -3
package/es/e2e/e2eUtils.d.ts
CHANGED
|
@@ -117,7 +117,7 @@ interface AclRoleSetting {
|
|
|
117
117
|
*/
|
|
118
118
|
default?: boolean;
|
|
119
119
|
key?: string;
|
|
120
|
-
|
|
120
|
+
desktopRoutes?: number[];
|
|
121
121
|
dataSourceKey?: string;
|
|
122
122
|
}
|
|
123
123
|
interface DatabaseSetting {
|
|
@@ -289,6 +289,7 @@ export declare class NocoPage {
|
|
|
289
289
|
protected page?: Page;
|
|
290
290
|
protected url: string;
|
|
291
291
|
protected uid: string | undefined;
|
|
292
|
+
protected desktopRouteId: number | undefined;
|
|
292
293
|
protected collectionsName: string[] | undefined;
|
|
293
294
|
protected _waitForInit: Promise<void>;
|
|
294
295
|
constructor(options?: PageConfig, page?: Page);
|
|
@@ -296,6 +297,7 @@ export declare class NocoPage {
|
|
|
296
297
|
goto(): Promise<void>;
|
|
297
298
|
getUrl(): Promise<string>;
|
|
298
299
|
getUid(): Promise<string>;
|
|
300
|
+
getDesktopRouteId(): Promise<number>;
|
|
299
301
|
/**
|
|
300
302
|
* If you are using mockRecords, then you need to use this method.
|
|
301
303
|
* Wait until the mockRecords create the records successfully before navigating to the page.
|
|
@@ -308,7 +310,7 @@ export declare class NocoPage {
|
|
|
308
310
|
export declare class NocoMobilePage extends NocoPage {
|
|
309
311
|
protected options?: MobilePageConfig;
|
|
310
312
|
protected page?: Page;
|
|
311
|
-
protected
|
|
313
|
+
protected mobileRouteId: number;
|
|
312
314
|
protected title: string;
|
|
313
315
|
constructor(options?: MobilePageConfig, page?: Page);
|
|
314
316
|
getTitle(): string;
|
package/es/server/index.d.ts
CHANGED
|
@@ -14,6 +14,7 @@ export * from './mock-isolated-cluster';
|
|
|
14
14
|
export * from './mock-server';
|
|
15
15
|
export declare const pgOnly: () => any;
|
|
16
16
|
export declare const isPg: () => boolean;
|
|
17
|
+
export declare const isMysql: () => boolean;
|
|
17
18
|
export declare function randomStr(): string;
|
|
18
19
|
export declare function sleep(ms?: number): Promise<unknown>;
|
|
19
20
|
export declare const waitSecond: typeof sleep;
|
|
@@ -57,8 +57,9 @@ interface Resource {
|
|
|
57
57
|
[name: string]: (params?: ActionParams) => Promise<supertest.Response>;
|
|
58
58
|
}
|
|
59
59
|
interface ExtendedAgent extends SuperAgentTest {
|
|
60
|
-
login: (user: any) => ExtendedAgent;
|
|
61
|
-
loginUsingId: (userId: number) => ExtendedAgent;
|
|
60
|
+
login: (user: any, roleName?: string) => ExtendedAgent;
|
|
61
|
+
loginUsingId: (userId: number, roleName?: string) => ExtendedAgent;
|
|
62
|
+
loginWithJti: (user: any, roleName?: string) => Promise<ExtendedAgent>;
|
|
62
63
|
resource: (name: string, resourceOf?: any) => Resource;
|
|
63
64
|
}
|
|
64
65
|
export declare class MockServer extends Application {
|
|
@@ -69,7 +70,7 @@ export declare class MockServer extends Application {
|
|
|
69
70
|
clean?: boolean;
|
|
70
71
|
}): Promise<void>;
|
|
71
72
|
destroy(options?: any): Promise<void>;
|
|
72
|
-
agent(): ExtendedAgent;
|
|
73
|
+
agent(callback?: any): ExtendedAgent;
|
|
73
74
|
protected createDatabase(options: ApplicationOptions): import("@nocobase/database").MockDatabase;
|
|
74
75
|
}
|
|
75
76
|
export declare function mockServer(options?: ApplicationOptions): MockServer;
|
|
@@ -53,7 +53,6 @@ async function iconChecker(options) {
|
|
|
53
53
|
await import_user_event.default.click(formItem.querySelector("span[role=img]") || formItem.querySelector("button"));
|
|
54
54
|
await (0, import_react.waitFor)(() => {
|
|
55
55
|
(0, import_utils.expectNoTsError)(import_react.screen.queryByRole("tooltip")).toBeInTheDocument();
|
|
56
|
-
(0, import_utils.expectNoTsError)(import_react.screen.getByRole("tooltip").querySelector(".ant-popover-title")).toHaveTextContent("Icon");
|
|
57
56
|
});
|
|
58
57
|
await import_user_event.default.click(import_react.screen.getByRole("tooltip").querySelector(`span[aria-label="${options.newValue}"]`));
|
|
59
58
|
await (0, import_react.waitFor)(() => {
|
package/lib/e2e/e2eUtils.d.ts
CHANGED
|
@@ -117,7 +117,7 @@ interface AclRoleSetting {
|
|
|
117
117
|
*/
|
|
118
118
|
default?: boolean;
|
|
119
119
|
key?: string;
|
|
120
|
-
|
|
120
|
+
desktopRoutes?: number[];
|
|
121
121
|
dataSourceKey?: string;
|
|
122
122
|
}
|
|
123
123
|
interface DatabaseSetting {
|
|
@@ -289,6 +289,7 @@ export declare class NocoPage {
|
|
|
289
289
|
protected page?: Page;
|
|
290
290
|
protected url: string;
|
|
291
291
|
protected uid: string | undefined;
|
|
292
|
+
protected desktopRouteId: number | undefined;
|
|
292
293
|
protected collectionsName: string[] | undefined;
|
|
293
294
|
protected _waitForInit: Promise<void>;
|
|
294
295
|
constructor(options?: PageConfig, page?: Page);
|
|
@@ -296,6 +297,7 @@ export declare class NocoPage {
|
|
|
296
297
|
goto(): Promise<void>;
|
|
297
298
|
getUrl(): Promise<string>;
|
|
298
299
|
getUid(): Promise<string>;
|
|
300
|
+
getDesktopRouteId(): Promise<number>;
|
|
299
301
|
/**
|
|
300
302
|
* If you are using mockRecords, then you need to use this method.
|
|
301
303
|
* Wait until the mockRecords create the records successfully before navigating to the page.
|
|
@@ -308,7 +310,7 @@ export declare class NocoPage {
|
|
|
308
310
|
export declare class NocoMobilePage extends NocoPage {
|
|
309
311
|
protected options?: MobilePageConfig;
|
|
310
312
|
protected page?: Page;
|
|
311
|
-
protected
|
|
313
|
+
protected mobileRouteId: number;
|
|
312
314
|
protected title: string;
|
|
313
315
|
constructor(options?: MobilePageConfig, page?: Page);
|
|
314
316
|
getTitle(): string;
|
package/lib/e2e/e2eUtils.js
CHANGED
|
@@ -68,6 +68,7 @@ const _NocoPage = class _NocoPage {
|
|
|
68
68
|
}
|
|
69
69
|
url;
|
|
70
70
|
uid;
|
|
71
|
+
desktopRouteId;
|
|
71
72
|
collectionsName;
|
|
72
73
|
_waitForInit;
|
|
73
74
|
async init() {
|
|
@@ -89,7 +90,9 @@ const _NocoPage = class _NocoPage {
|
|
|
89
90
|
})
|
|
90
91
|
);
|
|
91
92
|
const result = await Promise.all(waitList);
|
|
92
|
-
|
|
93
|
+
const { schemaUid, routeId } = result[result.length - 1] || {};
|
|
94
|
+
this.uid = schemaUid;
|
|
95
|
+
this.desktopRouteId = routeId;
|
|
93
96
|
this.url = `${((_i = this.options) == null ? void 0 : _i.basePath) || "/admin/"}${this.uid}`;
|
|
94
97
|
}
|
|
95
98
|
async goto() {
|
|
@@ -105,6 +108,10 @@ const _NocoPage = class _NocoPage {
|
|
|
105
108
|
await this._waitForInit;
|
|
106
109
|
return this.uid;
|
|
107
110
|
}
|
|
111
|
+
async getDesktopRouteId() {
|
|
112
|
+
await this._waitForInit;
|
|
113
|
+
return this.desktopRouteId;
|
|
114
|
+
}
|
|
108
115
|
/**
|
|
109
116
|
* If you are using mockRecords, then you need to use this method.
|
|
110
117
|
* Wait until the mockRecords create the records successfully before navigating to the page.
|
|
@@ -119,8 +126,9 @@ const _NocoPage = class _NocoPage {
|
|
|
119
126
|
var _a;
|
|
120
127
|
const waitList = [];
|
|
121
128
|
if (this.uid) {
|
|
122
|
-
waitList.push(deletePage(this.uid));
|
|
129
|
+
waitList.push(deletePage(this.uid, this.desktopRouteId));
|
|
123
130
|
this.uid = void 0;
|
|
131
|
+
this.desktopRouteId = void 0;
|
|
124
132
|
}
|
|
125
133
|
if ((_a = this.collectionsName) == null ? void 0 : _a.length) {
|
|
126
134
|
waitList.push(deleteCollections(this.collectionsName));
|
|
@@ -137,7 +145,7 @@ const _NocoMobilePage = class _NocoMobilePage extends NocoPage {
|
|
|
137
145
|
this.options = options;
|
|
138
146
|
this.page = page;
|
|
139
147
|
}
|
|
140
|
-
|
|
148
|
+
mobileRouteId;
|
|
141
149
|
title;
|
|
142
150
|
getTitle() {
|
|
143
151
|
return this.title;
|
|
@@ -154,7 +162,7 @@ const _NocoMobilePage = class _NocoMobilePage extends NocoPage {
|
|
|
154
162
|
const result = await Promise.all(waitList);
|
|
155
163
|
const { url, pageSchemaUid, routeId, title } = result[result.length - 1];
|
|
156
164
|
this.title = title;
|
|
157
|
-
this.
|
|
165
|
+
this.mobileRouteId = routeId;
|
|
158
166
|
this.uid = pageSchemaUid;
|
|
159
167
|
if (((_c = this.options) == null ? void 0 : _c.type) == "link") {
|
|
160
168
|
if (url == null ? void 0 : url.startsWith("/")) {
|
|
@@ -167,7 +175,7 @@ const _NocoMobilePage = class _NocoMobilePage extends NocoPage {
|
|
|
167
175
|
}
|
|
168
176
|
}
|
|
169
177
|
async mobileDestroy() {
|
|
170
|
-
await deleteMobileRoutes(this.
|
|
178
|
+
await deleteMobileRoutes(this.mobileRouteId);
|
|
171
179
|
await this.destroy();
|
|
172
180
|
}
|
|
173
181
|
};
|
|
@@ -379,6 +387,7 @@ const updateUidOfPageSchema = /* @__PURE__ */ __name((uiSchema) => {
|
|
|
379
387
|
return uiSchema;
|
|
380
388
|
}, "updateUidOfPageSchema");
|
|
381
389
|
const createPage = /* @__PURE__ */ __name(async (options) => {
|
|
390
|
+
var _a, _b, _c, _d;
|
|
382
391
|
const { type = "page", url, name, pageSchema, keepUid, pageUid: pageUidFromOptions } = options || {};
|
|
383
392
|
const api = await import_test.request.newContext({
|
|
384
393
|
storageState: process.env.PLAYWRIGHT_AUTH_FILE
|
|
@@ -401,8 +410,79 @@ const createPage = /* @__PURE__ */ __name(async (options) => {
|
|
|
401
410
|
};
|
|
402
411
|
const state = await api.storageState();
|
|
403
412
|
const headers = getHeaders(state);
|
|
404
|
-
const
|
|
405
|
-
const
|
|
413
|
+
const menuSchemaUid = pageUidFromOptions || (0, import_shared.uid)();
|
|
414
|
+
const pageSchemaUid = (0, import_shared.uid)();
|
|
415
|
+
const tabSchemaUid = (0, import_shared.uid)();
|
|
416
|
+
const tabSchemaName = (0, import_shared.uid)();
|
|
417
|
+
const title = name || menuSchemaUid;
|
|
418
|
+
const newPageSchema = keepUid ? pageSchema : updateUidOfPageSchema(pageSchema);
|
|
419
|
+
let routeId;
|
|
420
|
+
let schemaUid;
|
|
421
|
+
if (type === "group") {
|
|
422
|
+
const result2 = await api.post("/api/desktopRoutes:create", {
|
|
423
|
+
headers,
|
|
424
|
+
data: {
|
|
425
|
+
type: "group",
|
|
426
|
+
title,
|
|
427
|
+
schemaUid: menuSchemaUid,
|
|
428
|
+
hideInMenu: false
|
|
429
|
+
}
|
|
430
|
+
});
|
|
431
|
+
if (!result2.ok()) {
|
|
432
|
+
throw new Error(await result2.text());
|
|
433
|
+
}
|
|
434
|
+
const data = await result2.json();
|
|
435
|
+
routeId = (_a = data.data) == null ? void 0 : _a.id;
|
|
436
|
+
schemaUid = menuSchemaUid;
|
|
437
|
+
}
|
|
438
|
+
if (type === "page") {
|
|
439
|
+
const result2 = await api.post("/api/desktopRoutes:create", {
|
|
440
|
+
headers,
|
|
441
|
+
data: {
|
|
442
|
+
type: "page",
|
|
443
|
+
title,
|
|
444
|
+
schemaUid: (newPageSchema == null ? void 0 : newPageSchema["x-uid"]) || pageSchemaUid,
|
|
445
|
+
menuSchemaUid,
|
|
446
|
+
hideInMenu: false,
|
|
447
|
+
enableTabs: !!((_b = newPageSchema == null ? void 0 : newPageSchema["x-component-props"]) == null ? void 0 : _b.enablePageTabs),
|
|
448
|
+
children: newPageSchema ? schemaToRoutes(newPageSchema) : [
|
|
449
|
+
{
|
|
450
|
+
type: "tabs",
|
|
451
|
+
title: '{{t("Unnamed")}}',
|
|
452
|
+
schemaUid: tabSchemaUid,
|
|
453
|
+
tabSchemaName,
|
|
454
|
+
hideInMenu: false
|
|
455
|
+
}
|
|
456
|
+
]
|
|
457
|
+
}
|
|
458
|
+
});
|
|
459
|
+
if (!result2.ok()) {
|
|
460
|
+
throw new Error(await result2.text());
|
|
461
|
+
}
|
|
462
|
+
const data = await result2.json();
|
|
463
|
+
routeId = (_c = data.data) == null ? void 0 : _c.id;
|
|
464
|
+
schemaUid = menuSchemaUid;
|
|
465
|
+
}
|
|
466
|
+
if (type === "link") {
|
|
467
|
+
const result2 = await api.post("/api/desktopRoutes:create", {
|
|
468
|
+
headers,
|
|
469
|
+
data: {
|
|
470
|
+
type: "link",
|
|
471
|
+
title,
|
|
472
|
+
schemaUid: menuSchemaUid,
|
|
473
|
+
hideInMenu: false,
|
|
474
|
+
options: {
|
|
475
|
+
href: url
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
});
|
|
479
|
+
if (!result2.ok()) {
|
|
480
|
+
throw new Error(await result2.text());
|
|
481
|
+
}
|
|
482
|
+
const data = await result2.json();
|
|
483
|
+
routeId = (_d = data.data) == null ? void 0 : _d.id;
|
|
484
|
+
schemaUid = menuSchemaUid;
|
|
485
|
+
}
|
|
406
486
|
const result = await api.post(`/api/uiSchemas:insertAdjacent/nocobase-admin-menu?position=beforeEnd`, {
|
|
407
487
|
headers,
|
|
408
488
|
data: {
|
|
@@ -410,37 +490,33 @@ const createPage = /* @__PURE__ */ __name(async (options) => {
|
|
|
410
490
|
_isJSONSchemaObject: true,
|
|
411
491
|
version: "2.0",
|
|
412
492
|
type: "void",
|
|
413
|
-
title
|
|
493
|
+
title,
|
|
414
494
|
...typeToSchema[type],
|
|
415
495
|
"x-decorator": "ACLMenuItemProvider",
|
|
416
|
-
"x-server-hooks": [
|
|
417
|
-
{ type: "onSelfCreate", method: "bindMenuToRole" },
|
|
418
|
-
{ type: "onSelfSave", method: "extractTextToLocale" }
|
|
419
|
-
],
|
|
420
496
|
properties: {
|
|
421
|
-
page:
|
|
497
|
+
page: newPageSchema || {
|
|
422
498
|
_isJSONSchemaObject: true,
|
|
423
499
|
version: "2.0",
|
|
424
500
|
type: "void",
|
|
425
501
|
"x-component": "Page",
|
|
426
502
|
"x-async": true,
|
|
427
503
|
properties: {
|
|
428
|
-
[
|
|
504
|
+
[tabSchemaName]: {
|
|
429
505
|
_isJSONSchemaObject: true,
|
|
430
506
|
version: "2.0",
|
|
431
507
|
type: "void",
|
|
432
508
|
"x-component": "Grid",
|
|
433
509
|
"x-initializer": "page:addBlock",
|
|
434
|
-
"x-uid":
|
|
435
|
-
name:
|
|
510
|
+
"x-uid": tabSchemaUid,
|
|
511
|
+
name: tabSchemaName
|
|
436
512
|
}
|
|
437
513
|
},
|
|
438
|
-
"x-uid":
|
|
514
|
+
"x-uid": pageSchemaUid,
|
|
439
515
|
name: "page"
|
|
440
516
|
}
|
|
441
517
|
},
|
|
442
518
|
name: (0, import_shared.uid)(),
|
|
443
|
-
"x-uid":
|
|
519
|
+
"x-uid": menuSchemaUid
|
|
444
520
|
},
|
|
445
521
|
wrap: null
|
|
446
522
|
}
|
|
@@ -448,7 +524,7 @@ const createPage = /* @__PURE__ */ __name(async (options) => {
|
|
|
448
524
|
if (!result.ok()) {
|
|
449
525
|
throw new Error(await result.text());
|
|
450
526
|
}
|
|
451
|
-
return
|
|
527
|
+
return { schemaUid, routeId };
|
|
452
528
|
}, "createPage");
|
|
453
529
|
const createMobilePage = /* @__PURE__ */ __name(async (options) => {
|
|
454
530
|
const { type = "page", url, name, pageSchema, keepUid } = options || {};
|
|
@@ -614,12 +690,20 @@ const deleteMobileRoutes = /* @__PURE__ */ __name(async (mobileRouteId) => {
|
|
|
614
690
|
throw new Error(await result2.text());
|
|
615
691
|
}
|
|
616
692
|
}, "deleteMobileRoutes");
|
|
617
|
-
const deletePage = /* @__PURE__ */ __name(async (pageUid) => {
|
|
693
|
+
const deletePage = /* @__PURE__ */ __name(async (pageUid, routeId) => {
|
|
618
694
|
const api = await import_test.request.newContext({
|
|
619
695
|
storageState: process.env.PLAYWRIGHT_AUTH_FILE
|
|
620
696
|
});
|
|
621
697
|
const state = await api.storageState();
|
|
622
698
|
const headers = getHeaders(state);
|
|
699
|
+
if (routeId !== void 0) {
|
|
700
|
+
const routeResult = await api.post(`/api/desktopRoutes:destroy?filterByTk=${routeId}`, {
|
|
701
|
+
headers
|
|
702
|
+
});
|
|
703
|
+
if (!routeResult.ok()) {
|
|
704
|
+
throw new Error(await routeResult.text());
|
|
705
|
+
}
|
|
706
|
+
}
|
|
623
707
|
const result = await api.post(`/api/uiSchemas:remove/${pageUid}`, {
|
|
624
708
|
headers
|
|
625
709
|
});
|
|
@@ -921,6 +1005,26 @@ async function expectSupportedVariables(page, variables) {
|
|
|
921
1005
|
}
|
|
922
1006
|
}
|
|
923
1007
|
__name(expectSupportedVariables, "expectSupportedVariables");
|
|
1008
|
+
function schemaToRoutes(schema) {
|
|
1009
|
+
const schemaKeys = Object.keys(schema.properties || {});
|
|
1010
|
+
if (schemaKeys.length === 0) {
|
|
1011
|
+
return [];
|
|
1012
|
+
}
|
|
1013
|
+
const result = schemaKeys.map((key) => {
|
|
1014
|
+
var _a;
|
|
1015
|
+
const item = schema.properties[key];
|
|
1016
|
+
return {
|
|
1017
|
+
type: "tabs",
|
|
1018
|
+
title: item.title || '{{t("Unnamed")}}',
|
|
1019
|
+
icon: (_a = item["x-component-props"]) == null ? void 0 : _a.icon,
|
|
1020
|
+
schemaUid: item["x-uid"],
|
|
1021
|
+
tabSchemaName: key,
|
|
1022
|
+
hideInMenu: false
|
|
1023
|
+
};
|
|
1024
|
+
});
|
|
1025
|
+
return result;
|
|
1026
|
+
}
|
|
1027
|
+
__name(schemaToRoutes, "schemaToRoutes");
|
|
924
1028
|
// Annotate the CommonJS export names for ESM import in node:
|
|
925
1029
|
0 && (module.exports = {
|
|
926
1030
|
NocoMobilePage,
|
|
@@ -12313,7 +12313,7 @@ const oneFilterFormBlockWithAllAssociationFieldsV1333Beta = {
|
|
|
12313
12313
|
"x-use-decorator-props": "useFormItemProps",
|
|
12314
12314
|
"x-collection-field": "general.oneToOneBelongsTo",
|
|
12315
12315
|
"x-component-props": {
|
|
12316
|
-
multiple:
|
|
12316
|
+
multiple: true,
|
|
12317
12317
|
fieldNames: {
|
|
12318
12318
|
label: "id",
|
|
12319
12319
|
value: "id"
|
|
@@ -12360,7 +12360,7 @@ const oneFilterFormBlockWithAllAssociationFieldsV1333Beta = {
|
|
|
12360
12360
|
"x-use-decorator-props": "useFormItemProps",
|
|
12361
12361
|
"x-collection-field": "general.oneToOneHasOne",
|
|
12362
12362
|
"x-component-props": {
|
|
12363
|
-
multiple:
|
|
12363
|
+
multiple: true,
|
|
12364
12364
|
fieldNames: {
|
|
12365
12365
|
label: "id",
|
|
12366
12366
|
value: "id"
|
|
@@ -12454,7 +12454,7 @@ const oneFilterFormBlockWithAllAssociationFieldsV1333Beta = {
|
|
|
12454
12454
|
"x-use-decorator-props": "useFormItemProps",
|
|
12455
12455
|
"x-collection-field": "general.manyToOne",
|
|
12456
12456
|
"x-component-props": {
|
|
12457
|
-
multiple:
|
|
12457
|
+
multiple: true,
|
|
12458
12458
|
fieldNames: {
|
|
12459
12459
|
label: "id",
|
|
12460
12460
|
value: "id"
|
package/lib/server/index.d.ts
CHANGED
|
@@ -14,6 +14,7 @@ export * from './mock-isolated-cluster';
|
|
|
14
14
|
export * from './mock-server';
|
|
15
15
|
export declare const pgOnly: () => any;
|
|
16
16
|
export declare const isPg: () => boolean;
|
|
17
|
+
export declare const isMysql: () => boolean;
|
|
17
18
|
export declare function randomStr(): string;
|
|
18
19
|
export declare function sleep(ms?: number): Promise<unknown>;
|
|
19
20
|
export declare const waitSecond: typeof sleep;
|
package/lib/server/index.js
CHANGED
|
@@ -40,6 +40,7 @@ var server_exports = {};
|
|
|
40
40
|
__export(server_exports, {
|
|
41
41
|
MockDatabase: () => import_database.MockDatabase,
|
|
42
42
|
createWsClient: () => createWsClient,
|
|
43
|
+
isMysql: () => isMysql,
|
|
43
44
|
isPg: () => isPg,
|
|
44
45
|
mockDatabase: () => import_database.mockDatabase,
|
|
45
46
|
pgOnly: () => pgOnly,
|
|
@@ -59,6 +60,7 @@ __reExport(server_exports, require("./mock-isolated-cluster"), module.exports);
|
|
|
59
60
|
__reExport(server_exports, require("./mock-server"), module.exports);
|
|
60
61
|
const pgOnly = /* @__PURE__ */ __name(() => process.env.DB_DIALECT == "postgres" ? import_vitest.describe : import_vitest.describe.skip, "pgOnly");
|
|
61
62
|
const isPg = /* @__PURE__ */ __name(() => process.env.DB_DIALECT == "postgres", "isPg");
|
|
63
|
+
const isMysql = /* @__PURE__ */ __name(() => process.env.DB_DIALECT == "mysql", "isMysql");
|
|
62
64
|
function randomStr() {
|
|
63
65
|
return Math.random().toString(36).substring(2);
|
|
64
66
|
}
|
|
@@ -112,6 +114,7 @@ const createWsClient = /* @__PURE__ */ __name(async ({ serverPort, options = {}
|
|
|
112
114
|
0 && (module.exports = {
|
|
113
115
|
MockDatabase,
|
|
114
116
|
createWsClient,
|
|
117
|
+
isMysql,
|
|
115
118
|
isPg,
|
|
116
119
|
mockDatabase,
|
|
117
120
|
pgOnly,
|
|
@@ -57,8 +57,9 @@ interface Resource {
|
|
|
57
57
|
[name: string]: (params?: ActionParams) => Promise<supertest.Response>;
|
|
58
58
|
}
|
|
59
59
|
interface ExtendedAgent extends SuperAgentTest {
|
|
60
|
-
login: (user: any) => ExtendedAgent;
|
|
61
|
-
loginUsingId: (userId: number) => ExtendedAgent;
|
|
60
|
+
login: (user: any, roleName?: string) => ExtendedAgent;
|
|
61
|
+
loginUsingId: (userId: number, roleName?: string) => ExtendedAgent;
|
|
62
|
+
loginWithJti: (user: any, roleName?: string) => Promise<ExtendedAgent>;
|
|
62
63
|
resource: (name: string, resourceOf?: any) => Resource;
|
|
63
64
|
}
|
|
64
65
|
export declare class MockServer extends Application {
|
|
@@ -69,7 +70,7 @@ export declare class MockServer extends Application {
|
|
|
69
70
|
clean?: boolean;
|
|
70
71
|
}): Promise<void>;
|
|
71
72
|
destroy(options?: any): Promise<void>;
|
|
72
|
-
agent(): ExtendedAgent;
|
|
73
|
+
agent(callback?: any): ExtendedAgent;
|
|
73
74
|
protected createDatabase(options: ApplicationOptions): import("@nocobase/database").MockDatabase;
|
|
74
75
|
}
|
|
75
76
|
export declare function mockServer(options?: ApplicationOptions): MockServer;
|
|
@@ -53,6 +53,9 @@ var import_qs = __toESM(require("qs"));
|
|
|
53
53
|
var import_supertest = __toESM(require("supertest"));
|
|
54
54
|
var import_memory_pub_sub_adapter = require("./memory-pub-sub-adapter");
|
|
55
55
|
var import_mock_data_source = require("./mock-data-source");
|
|
56
|
+
var import_path = __toESM(require("path"));
|
|
57
|
+
var import_node_process = __toESM(require("node:process"));
|
|
58
|
+
var import_fs = require("fs");
|
|
56
59
|
const _MockServer = class _MockServer extends import_server.Application {
|
|
57
60
|
registerMockDataSource() {
|
|
58
61
|
this.dataSourceManager.factory.register("mock", import_mock_data_source.MockDataSource);
|
|
@@ -87,20 +90,22 @@ const _MockServer = class _MockServer extends import_server.Application {
|
|
|
87
90
|
import_server.Gateway.getInstance().destroy();
|
|
88
91
|
await import_server.AppSupervisor.getInstance().destroy();
|
|
89
92
|
}
|
|
90
|
-
agent() {
|
|
91
|
-
const agent = import_supertest.default.agent(this.callback());
|
|
93
|
+
agent(callback) {
|
|
94
|
+
const agent = import_supertest.default.agent(callback || this.callback());
|
|
92
95
|
const prefix = this.resourcer.options.prefix;
|
|
96
|
+
const authManager = this.authManager;
|
|
93
97
|
const proxy = new Proxy(agent, {
|
|
94
98
|
get(target, method, receiver) {
|
|
95
99
|
if (["login", "loginUsingId"].includes(method)) {
|
|
96
|
-
return (userOrId) => {
|
|
100
|
+
return (userOrId, roleName) => {
|
|
97
101
|
return proxy.auth(
|
|
98
102
|
import_jsonwebtoken.default.sign(
|
|
99
103
|
{
|
|
100
104
|
userId: typeof userOrId === "number" ? userOrId : userOrId == null ? void 0 : userOrId.id,
|
|
101
|
-
temp: true
|
|
105
|
+
temp: true,
|
|
106
|
+
roleName
|
|
102
107
|
},
|
|
103
|
-
|
|
108
|
+
import_node_process.default.env.APP_KEY,
|
|
104
109
|
{
|
|
105
110
|
expiresIn: "1d"
|
|
106
111
|
}
|
|
@@ -109,6 +114,29 @@ const _MockServer = class _MockServer extends import_server.Application {
|
|
|
109
114
|
).set("X-Authenticator", "basic");
|
|
110
115
|
};
|
|
111
116
|
}
|
|
117
|
+
if (method === "loginWithJti") {
|
|
118
|
+
return async (userOrId, roleName) => {
|
|
119
|
+
const userId = typeof userOrId === "number" ? userOrId : userOrId == null ? void 0 : userOrId.id;
|
|
120
|
+
const tokenInfo = await authManager.tokenController.add({ userId });
|
|
121
|
+
const expiresIn = (await authManager.tokenController.getConfig()).tokenExpirationTime;
|
|
122
|
+
return proxy.auth(
|
|
123
|
+
import_jsonwebtoken.default.sign(
|
|
124
|
+
{
|
|
125
|
+
userId,
|
|
126
|
+
temp: true,
|
|
127
|
+
roleName,
|
|
128
|
+
signInTime: Date.now()
|
|
129
|
+
},
|
|
130
|
+
import_node_process.default.env.APP_KEY,
|
|
131
|
+
{
|
|
132
|
+
jwtid: tokenInfo.jti,
|
|
133
|
+
expiresIn
|
|
134
|
+
}
|
|
135
|
+
),
|
|
136
|
+
{ type: "bearer" }
|
|
137
|
+
).set("X-Authenticator", "basic");
|
|
138
|
+
};
|
|
139
|
+
}
|
|
112
140
|
if (method === "resource") {
|
|
113
141
|
return (name, resourceOf) => {
|
|
114
142
|
const keys = name.split(".");
|
|
@@ -252,6 +280,12 @@ async function createMockCluster({
|
|
|
252
280
|
}
|
|
253
281
|
__name(createMockCluster, "createMockCluster");
|
|
254
282
|
async function createMockServer(options = {}) {
|
|
283
|
+
const cachePath = import_path.default.join(import_node_process.default.cwd(), "storage", "cache");
|
|
284
|
+
try {
|
|
285
|
+
await import_fs.promises.rm(cachePath, { recursive: true, force: true });
|
|
286
|
+
await import_fs.promises.mkdir(cachePath, { recursive: true });
|
|
287
|
+
} catch (e) {
|
|
288
|
+
}
|
|
255
289
|
const { version, beforeInstall, skipInstall, skipStart, ...others } = options;
|
|
256
290
|
const app = mockServer(others);
|
|
257
291
|
if (!skipInstall) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nocobase/test",
|
|
3
|
-
"version": "1.6.0-alpha.
|
|
3
|
+
"version": "1.6.0-alpha.20",
|
|
4
4
|
"main": "lib/index.js",
|
|
5
5
|
"module": "./src/index.ts",
|
|
6
6
|
"types": "./lib/index.d.ts",
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
},
|
|
52
52
|
"dependencies": {
|
|
53
53
|
"@faker-js/faker": "8.1.0",
|
|
54
|
-
"@nocobase/server": "1.6.0-alpha.
|
|
54
|
+
"@nocobase/server": "1.6.0-alpha.20",
|
|
55
55
|
"@playwright/test": "^1.45.3",
|
|
56
56
|
"@testing-library/jest-dom": "^6.4.2",
|
|
57
57
|
"@testing-library/react": "^14.0.0",
|
|
@@ -76,5 +76,5 @@
|
|
|
76
76
|
"vitest-dom": "^0.1.1",
|
|
77
77
|
"ws": "^8.13.0"
|
|
78
78
|
},
|
|
79
|
-
"gitHead": "
|
|
79
|
+
"gitHead": "c127664eb2b900edd5c18c9344046cd663a06c3b"
|
|
80
80
|
}
|