@payloadcms/ui 4.0.0-canary.34 → 4.0.0-canary.36
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/dist/css/app.css +1 -0
- package/dist/css/preflight.css +1 -0
- package/dist/css/spacing.css +3 -0
- package/dist/elements/AppHeader/index.css +3 -0
- package/dist/elements/BulkUpload/ActionsBar/index.css +1 -0
- package/dist/elements/BulkUpload/AddingFilesView/index.css +2 -4
- package/dist/elements/BulkUpload/FileSidebar/index.css +1 -0
- package/dist/elements/BulkUpload/FormsManager/index.d.ts.map +1 -1
- package/dist/elements/BulkUpload/FormsManager/index.js +12 -7
- package/dist/elements/BulkUpload/FormsManager/index.js.map +1 -1
- package/dist/elements/BulkUpload/index.css +2 -0
- package/dist/elements/Collapsible/index.css +1 -0
- package/dist/elements/DatePicker/index.css +2 -0
- package/dist/elements/Dialog/index.css +1 -0
- package/dist/elements/DocumentControls/index.css +1 -0
- package/dist/elements/DocumentFields/index.css +2 -0
- package/dist/elements/DocumentHeader/Tabs/index.css +1 -0
- package/dist/elements/DocumentHeader/index.css +1 -0
- package/dist/elements/EditUpload/index.css +1 -1
- package/dist/elements/FieldDiffContainer/index.css +1 -0
- package/dist/elements/FieldDiffLabel/index.css +1 -0
- package/dist/elements/FileDetails/StaticFileDetails/index.css +2 -0
- package/dist/elements/HTMLDiff/index.css +1 -0
- package/dist/elements/ItemsDrawer/index.css +3 -0
- package/dist/elements/ListControls/index.css +1 -0
- package/dist/elements/ListControls/index.d.ts.map +1 -1
- package/dist/elements/ListControls/index.js +7 -1
- package/dist/elements/ListControls/index.js.map +1 -1
- package/dist/elements/ListControls/types.d.ts +3 -1
- package/dist/elements/ListControls/types.d.ts.map +1 -1
- package/dist/elements/ListControls/types.js.map +1 -1
- package/dist/elements/ListControlsBar/index.css +1 -0
- package/dist/elements/ListHeader/TitleActions/ListEmptyTrashButton.js +1 -1
- package/dist/elements/ListHeader/TitleActions/ListEmptyTrashButton.js.map +1 -1
- package/dist/elements/LivePreview/Window/index.css +1 -0
- package/dist/elements/Nav/index.css +2 -0
- package/dist/elements/PageControls/index.css +1 -0
- package/dist/elements/PillSelector/index.css +1 -0
- package/dist/elements/PreviewSizes/index.css +2 -0
- package/dist/elements/PublishButton/index.css +1 -0
- package/dist/elements/QueryPresets/fields/Heading/index.css +1 -0
- package/dist/elements/RenderTitle/index.css +1 -0
- package/dist/elements/Table/index.css +1 -0
- package/dist/elements/TableSection/index.css +1 -0
- package/dist/elements/Tabs/index.css +1 -0
- package/dist/elements/Thumbnail/index.css +1 -0
- package/dist/elements/TimezonePicker/index.css +1 -0
- package/dist/elements/Tooltip/index.css +7 -0
- package/dist/elements/WhereBuilder/Condition/index.css +1 -0
- package/dist/elements/WhereBuilder/index.css +2 -0
- package/dist/fields/Array/index.css +1 -0
- package/dist/fields/Blocks/index.css +1 -0
- package/dist/fields/Group/index.css +1 -0
- package/dist/fields/Row/index.css +2 -0
- package/dist/fields/Tabs/index.css +1 -0
- package/dist/forms/RenderFields/index.css +1 -0
- package/dist/hooks/useControllableState.js +3 -3
- package/dist/hooks/useControllableState.js.map +1 -1
- package/dist/providers/DocumentInfo/index.d.ts.map +1 -1
- package/dist/providers/DocumentInfo/index.js +30 -19
- package/dist/providers/DocumentInfo/index.js.map +1 -1
- package/dist/providers/Locale/index.d.ts.map +1 -1
- package/dist/providers/Locale/index.js +6 -7
- package/dist/providers/Locale/index.js.map +1 -1
- package/dist/styles.css +5 -1
- package/dist/templates/Default/Wrapper/index.css +2 -0
- package/dist/templates/Default/index.css +1 -0
- package/dist/utilities/handleAuthRedirect.d.ts.map +1 -1
- package/dist/utilities/handleAuthRedirect.js +4 -1
- package/dist/utilities/handleAuthRedirect.js.map +1 -1
- package/dist/utilities/isPathMatchingRoute.d.ts.map +1 -1
- package/dist/utilities/isPathMatchingRoute.js +7 -5
- package/dist/utilities/isPathMatchingRoute.js.map +1 -1
- package/dist/views/API/index.css +1 -0
- package/dist/views/Dashboard/Default/ModularDashboard/index.css +2 -0
- package/dist/views/Edit/index.css +1 -0
- package/dist/views/HierarchyList/HierarchyTable/SlotTable.css +1 -0
- package/dist/views/HierarchyList/index.css +1 -0
- package/dist/views/List/ListHeader/index.css +1 -0
- package/dist/views/List/ListHeader/index.d.ts +0 -1
- package/dist/views/List/ListHeader/index.d.ts.map +1 -1
- package/dist/views/List/ListHeader/index.js +2 -6
- package/dist/views/List/ListHeader/index.js.map +1 -1
- package/dist/views/List/index.client.d.ts.map +1 -1
- package/dist/views/List/index.client.js +3 -2
- package/dist/views/List/index.client.js.map +1 -1
- package/dist/views/List/index.css +2 -0
- package/dist/views/Root/index.d.ts.map +1 -1
- package/dist/views/Root/index.js +26 -19
- package/dist/views/Root/index.js.map +1 -1
- package/dist/views/Version/Default/index.css +2 -0
- package/dist/views/Version/RenderFieldsToDiff/fields/Date/index.css +8 -0
- package/dist/views/Version/RenderFieldsToDiff/fields/Relationship/index.css +1 -0
- package/dist/views/Version/RenderFieldsToDiff/fields/Upload/index.css +1 -0
- package/dist/views/Version/RenderFieldsToDiff/index.css +2 -0
- package/dist/views/Version/Restore/index.d.ts.map +1 -1
- package/dist/views/Version/Restore/index.js +9 -6
- package/dist/views/Version/Restore/index.js.map +1 -1
- package/dist/views/Versions/VersionPillLabel/index.css +1 -0
- package/dist/views/Versions/index.css +1 -0
- package/dist/widgets/CollectionCards/index.css +4 -0
- package/package.json +5 -5
- package/dist/elements/ClipboardAction/clipboardUtilities.spec.js +0 -120
- package/dist/elements/ClipboardAction/clipboardUtilities.spec.js.map +0 -1
- package/dist/elements/ClipboardAction/isClipboardDataValid.spec.js +0 -144
- package/dist/elements/ClipboardAction/isClipboardDataValid.spec.js.map +0 -1
- package/dist/elements/ClipboardAction/mergeFormStateFromClipboard.spec.js +0 -885
- package/dist/elements/ClipboardAction/mergeFormStateFromClipboard.spec.js.map +0 -1
- package/dist/elements/ColumnSelection/matchesColumnSearch.spec.js +0 -87
- package/dist/elements/ColumnSelection/matchesColumnSearch.spec.js.map +0 -1
- package/dist/elements/CommandPalette/buildActions.spec.js +0 -158
- package/dist/elements/CommandPalette/buildActions.spec.js.map +0 -1
- package/dist/elements/CommandPalette/highlightLabel.spec.js +0 -78
- package/dist/elements/CommandPalette/highlightLabel.spec.js.map +0 -1
- package/dist/elements/FieldSelect/reduceFieldOptions.spec.js +0 -143
- package/dist/elements/FieldSelect/reduceFieldOptions.spec.js.map +0 -1
- package/dist/elements/Toasts/fieldErrors.spec.js +0 -46
- package/dist/elements/Toasts/fieldErrors.spec.js.map +0 -1
- package/dist/elements/WhereBuilder/Condition/Relationship/optionsReducer.spec.js +0 -152
- package/dist/elements/WhereBuilder/Condition/Relationship/optionsReducer.spec.js.map +0 -1
- package/dist/elements/WhereBuilder/conditionValue.spec.js +0 -65
- package/dist/elements/WhereBuilder/conditionValue.spec.js.map +0 -1
- package/dist/fields/Upload/Input.spec.js +0 -242
- package/dist/fields/Upload/Input.spec.js.map +0 -1
- package/dist/forms/fieldSchemasToFormState/fieldSchemasToFormState.spec.d.ts +0 -2
- package/dist/forms/fieldSchemasToFormState/fieldSchemasToFormState.spec.d.ts.map +0 -1
- package/dist/forms/fieldSchemasToFormState/fieldSchemasToFormState.spec.js +0 -67
- package/dist/forms/fieldSchemasToFormState/fieldSchemasToFormState.spec.js.map +0 -1
- package/dist/forms/fieldSchemasToFormState/serverFunctions/renderFieldServerFn.spec.js +0 -150
- package/dist/forms/fieldSchemasToFormState/serverFunctions/renderFieldServerFn.spec.js.map +0 -1
- package/dist/layouts/Root/index.spec.js +0 -20
- package/dist/layouts/Root/index.spec.js.map +0 -1
- package/dist/providers/Auth/authSessionRequests.spec.js +0 -121
- package/dist/providers/Auth/authSessionRequests.spec.js.map +0 -1
- package/dist/providers/Auth/sessionActivity.spec.js +0 -44
- package/dist/providers/Auth/sessionActivity.spec.js.map +0 -1
- package/dist/providers/Auth/tabSessionSync/index.spec.js +0 -463
- package/dist/providers/Auth/tabSessionSync/index.spec.js.map +0 -1
- package/dist/providers/Auth/useAuthSessionTimers.spec.js +0 -311
- package/dist/providers/Auth/useAuthSessionTimers.spec.js.map +0 -1
- package/dist/providers/RouteTransition/ProgressBar/index.spec.js +0 -44
- package/dist/providers/RouteTransition/ProgressBar/index.spec.js.map +0 -1
- package/dist/providers/TableColumns/buildColumnState/index.spec.js +0 -40
- package/dist/providers/TableColumns/buildColumnState/index.spec.js.map +0 -1
- package/dist/utilities/appendCacheTag.spec.js +0 -34
- package/dist/utilities/appendCacheTag.spec.js.map +0 -1
- package/dist/utilities/formatAbsoluteURL.spec.js +0 -27
- package/dist/utilities/formatAbsoluteURL.spec.js.map +0 -1
- package/dist/utilities/formatMetadata.spec.js +0 -83
- package/dist/utilities/formatMetadata.spec.js.map +0 -1
- package/dist/utilities/fuzzyMatch.spec.js +0 -38
- package/dist/utilities/fuzzyMatch.spec.js.map +0 -1
- package/dist/utilities/initReq.spec.js +0 -226
- package/dist/utilities/initReq.spec.js.map +0 -1
- package/dist/utilities/isAbsoluteURL.spec.js +0 -11
- package/dist/utilities/isAbsoluteURL.spec.js.map +0 -1
- package/dist/utilities/isCustomAdminView.spec.js +0 -90
- package/dist/utilities/isCustomAdminView.spec.js.map +0 -1
- package/dist/utilities/isHttpURL.spec.js +0 -25
- package/dist/utilities/isHttpURL.spec.js.map +0 -1
- package/dist/utilities/isPathMatchingRoute.spec.js +0 -178
- package/dist/utilities/isPathMatchingRoute.spec.js.map +0 -1
- package/dist/utilities/isPublicAdminRoute.spec.js +0 -34
- package/dist/utilities/isPublicAdminRoute.spec.js.map +0 -1
- package/dist/utilities/normalizeRelationshipValue.spec.js +0 -373
- package/dist/utilities/normalizeRelationshipValue.spec.js.map +0 -1
- package/dist/utilities/recentlyViewed.spec.js +0 -92
- package/dist/utilities/recentlyViewed.spec.js.map +0 -1
- package/dist/views/Root/getCustomCollectionViewByRoute.spec.js +0 -168
- package/dist/views/Root/getCustomCollectionViewByRoute.spec.js.map +0 -1
- package/dist/views/Version/RenderFieldsToDiff/buildVersionFields.spec.js +0 -258
- package/dist/views/Version/RenderFieldsToDiff/buildVersionFields.spec.js.map +0 -1
- package/dist/views/Version/RenderFieldsToDiff/utilities/countChangedFields.spec.js +0 -915
- package/dist/views/Version/RenderFieldsToDiff/utilities/countChangedFields.spec.js.map +0 -1
- package/dist/views/Version/RenderFieldsToDiff/utilities/fieldHasChanges.spec.js +0 -47
- package/dist/views/Version/RenderFieldsToDiff/utilities/fieldHasChanges.spec.js.map +0 -1
- package/dist/views/Version/RenderFieldsToDiff/utilities/getFieldsForRowComparison.spec.js +0 -125
- package/dist/views/Version/RenderFieldsToDiff/utilities/getFieldsForRowComparison.spec.js.map +0 -1
- package/dist/widgets/CollectionQuery/getCollectionFieldPaths.spec.js +0 -100
- package/dist/widgets/CollectionQuery/getCollectionFieldPaths.spec.js.map +0 -1
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest';
|
|
2
|
-
import { createErrorsFromMessage } from './fieldErrors.js';
|
|
3
|
-
describe('createErrorsFromMessage', () => {
|
|
4
|
-
it('should return the full message when there is no colon', () => {
|
|
5
|
-
const result = createErrorsFromMessage('Something went wrong');
|
|
6
|
-
expect(result).toEqual({
|
|
7
|
-
message: 'Something went wrong'
|
|
8
|
-
});
|
|
9
|
-
});
|
|
10
|
-
it('should split a single field error after the colon', () => {
|
|
11
|
-
const result = createErrorsFromMessage('Validation failed: email');
|
|
12
|
-
expect(result).toEqual({
|
|
13
|
-
errors: ['email'],
|
|
14
|
-
message: 'Validation failed: '
|
|
15
|
-
});
|
|
16
|
-
});
|
|
17
|
-
it('should split multiple comma-separated field errors after the colon', () => {
|
|
18
|
-
const result = createErrorsFromMessage('The following fields are invalid: email, name');
|
|
19
|
-
expect(result).toEqual({
|
|
20
|
-
errors: ['email', 'name'],
|
|
21
|
-
message: 'The following fields are invalid (2):'
|
|
22
|
-
});
|
|
23
|
-
});
|
|
24
|
-
it('should preserve the full message when it contains multiple colons', () => {
|
|
25
|
-
const result = createErrorsFromMessage('With: multiple: colons');
|
|
26
|
-
expect(result).toEqual({
|
|
27
|
-
errors: ['multiple: colons'],
|
|
28
|
-
message: 'With: '
|
|
29
|
-
});
|
|
30
|
-
});
|
|
31
|
-
it('should replace " > " with " → " in error paths', () => {
|
|
32
|
-
const result = createErrorsFromMessage('Invalid: parent > child');
|
|
33
|
-
expect(result).toEqual({
|
|
34
|
-
errors: ['parent → child'],
|
|
35
|
-
message: 'Invalid: '
|
|
36
|
-
});
|
|
37
|
-
});
|
|
38
|
-
it('should group similar errors and count them', () => {
|
|
39
|
-
const result = createErrorsFromMessage('Invalid: blocks > 0, blocks > 1, other');
|
|
40
|
-
expect(result).toEqual({
|
|
41
|
-
errors: ['blocks → 0', 'blocks → 1', 'other'],
|
|
42
|
-
message: 'Invalid (3):'
|
|
43
|
-
});
|
|
44
|
-
});
|
|
45
|
-
});
|
|
46
|
-
//# sourceMappingURL=fieldErrors.spec.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"fieldErrors.spec.js","names":["describe","expect","it","createErrorsFromMessage","result","toEqual","message","errors"],"sources":["../../../src/elements/Toasts/fieldErrors.spec.ts"],"sourcesContent":["import { describe, expect, it } from 'vitest'\n\nimport { createErrorsFromMessage } from './fieldErrors.js'\n\ndescribe('createErrorsFromMessage', () => {\n it('should return the full message when there is no colon', () => {\n const result = createErrorsFromMessage('Something went wrong')\n\n expect(result).toEqual({ message: 'Something went wrong' })\n })\n\n it('should split a single field error after the colon', () => {\n const result = createErrorsFromMessage('Validation failed: email')\n\n expect(result).toEqual({ errors: ['email'], message: 'Validation failed: ' })\n })\n\n it('should split multiple comma-separated field errors after the colon', () => {\n const result = createErrorsFromMessage('The following fields are invalid: email, name')\n\n expect(result).toEqual({\n errors: ['email', 'name'],\n message: 'The following fields are invalid (2):',\n })\n })\n\n it('should preserve the full message when it contains multiple colons', () => {\n const result = createErrorsFromMessage('With: multiple: colons')\n\n expect(result).toEqual({ errors: ['multiple: colons'], message: 'With: ' })\n })\n\n it('should replace \" > \" with \" → \" in error paths', () => {\n const result = createErrorsFromMessage('Invalid: parent > child')\n\n expect(result).toEqual({ errors: ['parent → child'], message: 'Invalid: ' })\n })\n\n it('should group similar errors and count them', () => {\n const result = createErrorsFromMessage('Invalid: blocks > 0, blocks > 1, other')\n\n expect(result).toEqual({\n errors: ['blocks → 0', 'blocks → 1', 'other'],\n message: 'Invalid (3):',\n })\n })\n})\n"],"mappings":"AAAA,SAASA,QAAQ,EAAEC,MAAM,EAAEC,EAAE,QAAQ;AAErC,SAASC,uBAAuB,QAAQ;AAExCH,QAAA,CAAS,2BAA2B;EAClCE,EAAA,CAAG,yDAAyD;IAC1D,MAAME,MAAA,GAASD,uBAAA,CAAwB;IAEvCF,MAAA,CAAOG,MAAA,EAAQC,OAAO,CAAC;MAAEC,OAAA,EAAS;IAAuB;EAC3D;EAEAJ,EAAA,CAAG,qDAAqD;IACtD,MAAME,MAAA,GAASD,uBAAA,CAAwB;IAEvCF,MAAA,CAAOG,MAAA,EAAQC,OAAO,CAAC;MAAEE,MAAA,EAAQ,CAAC,QAAQ;MAAED,OAAA,EAAS;IAAsB;EAC7E;EAEAJ,EAAA,CAAG,sEAAsE;IACvE,MAAME,MAAA,GAASD,uBAAA,CAAwB;IAEvCF,MAAA,CAAOG,MAAA,EAAQC,OAAO,CAAC;MACrBE,MAAA,EAAQ,CAAC,SAAS,OAAO;MACzBD,OAAA,EAAS;IACX;EACF;EAEAJ,EAAA,CAAG,qEAAqE;IACtE,MAAME,MAAA,GAASD,uBAAA,CAAwB;IAEvCF,MAAA,CAAOG,MAAA,EAAQC,OAAO,CAAC;MAAEE,MAAA,EAAQ,CAAC,mBAAmB;MAAED,OAAA,EAAS;IAAS;EAC3E;EAEAJ,EAAA,CAAG,kDAAkD;IACnD,MAAME,MAAA,GAASD,uBAAA,CAAwB;IAEvCF,MAAA,CAAOG,MAAA,EAAQC,OAAO,CAAC;MAAEE,MAAA,EAAQ,CAAC,iBAAiB;MAAED,OAAA,EAAS;IAAY;EAC5E;EAEAJ,EAAA,CAAG,8CAA8C;IAC/C,MAAME,MAAA,GAASD,uBAAA,CAAwB;IAEvCF,MAAA,CAAOG,MAAA,EAAQC,OAAO,CAAC;MACrBE,MAAA,EAAQ,CAAC,cAAc,cAAc,QAAQ;MAC7CD,OAAA,EAAS;IACX;EACF;AACF","ignoreList":[]}
|
|
@@ -1,152 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest';
|
|
2
|
-
import optionsReducer from './optionsReducer.js';
|
|
3
|
-
const mockI18n = {
|
|
4
|
-
t: key => key
|
|
5
|
-
};
|
|
6
|
-
const mockCollection = {
|
|
7
|
-
admin: {
|
|
8
|
-
useAsTitle: 'title'
|
|
9
|
-
},
|
|
10
|
-
labels: {
|
|
11
|
-
plural: 'Posts'
|
|
12
|
-
}
|
|
13
|
-
};
|
|
14
|
-
describe('optionsReducer', () => {
|
|
15
|
-
describe('ADD — single relation', () => {
|
|
16
|
-
it('deduplicates options when the same doc is loaded twice', () => {
|
|
17
|
-
const initial = [{
|
|
18
|
-
label: 'Post A',
|
|
19
|
-
value: 'id-1'
|
|
20
|
-
}];
|
|
21
|
-
const result = optionsReducer(initial, {
|
|
22
|
-
type: 'ADD',
|
|
23
|
-
collection: mockCollection,
|
|
24
|
-
data: {
|
|
25
|
-
docs: [{
|
|
26
|
-
id: 'id-1',
|
|
27
|
-
title: 'Post A'
|
|
28
|
-
}, {
|
|
29
|
-
id: 'id-2',
|
|
30
|
-
title: 'Post B'
|
|
31
|
-
}],
|
|
32
|
-
totalDocs: 2,
|
|
33
|
-
limit: 10,
|
|
34
|
-
totalPages: 1,
|
|
35
|
-
page: 1,
|
|
36
|
-
pagingCounter: 1,
|
|
37
|
-
hasPrevPage: false,
|
|
38
|
-
hasNextPage: false,
|
|
39
|
-
prevPage: null,
|
|
40
|
-
nextPage: null
|
|
41
|
-
},
|
|
42
|
-
hasMultipleRelations: false,
|
|
43
|
-
i18n: mockI18n,
|
|
44
|
-
relation: 'posts'
|
|
45
|
-
});
|
|
46
|
-
expect(result).toHaveLength(2);
|
|
47
|
-
expect(result.map(o => o.value)).toEqual(['id-1', 'id-2']);
|
|
48
|
-
});
|
|
49
|
-
it('appends all docs when state is empty', () => {
|
|
50
|
-
const result = optionsReducer([], {
|
|
51
|
-
type: 'ADD',
|
|
52
|
-
collection: mockCollection,
|
|
53
|
-
data: {
|
|
54
|
-
docs: [{
|
|
55
|
-
id: 'id-1',
|
|
56
|
-
title: 'Post A'
|
|
57
|
-
}, {
|
|
58
|
-
id: 'id-2',
|
|
59
|
-
title: 'Post B'
|
|
60
|
-
}],
|
|
61
|
-
totalDocs: 2,
|
|
62
|
-
limit: 10,
|
|
63
|
-
totalPages: 1,
|
|
64
|
-
page: 1,
|
|
65
|
-
pagingCounter: 1,
|
|
66
|
-
hasPrevPage: false,
|
|
67
|
-
hasNextPage: false,
|
|
68
|
-
prevPage: null,
|
|
69
|
-
nextPage: null
|
|
70
|
-
},
|
|
71
|
-
hasMultipleRelations: false,
|
|
72
|
-
i18n: mockI18n,
|
|
73
|
-
relation: 'posts'
|
|
74
|
-
});
|
|
75
|
-
expect(result).toHaveLength(2);
|
|
76
|
-
});
|
|
77
|
-
});
|
|
78
|
-
describe('ADD — multiple relations (grouped options)', () => {
|
|
79
|
-
it('deduplicates sub-options within a group when the same doc is loaded twice', () => {
|
|
80
|
-
const initial = [{
|
|
81
|
-
label: 'Posts',
|
|
82
|
-
value: undefined,
|
|
83
|
-
options: [{
|
|
84
|
-
label: 'Post A',
|
|
85
|
-
value: 'id-1',
|
|
86
|
-
relationTo: 'posts'
|
|
87
|
-
}]
|
|
88
|
-
}];
|
|
89
|
-
const result = optionsReducer(initial, {
|
|
90
|
-
type: 'ADD',
|
|
91
|
-
collection: {
|
|
92
|
-
...mockCollection,
|
|
93
|
-
labels: {
|
|
94
|
-
plural: 'Posts'
|
|
95
|
-
}
|
|
96
|
-
},
|
|
97
|
-
data: {
|
|
98
|
-
docs: [{
|
|
99
|
-
id: 'id-1',
|
|
100
|
-
title: 'Post A'
|
|
101
|
-
}, {
|
|
102
|
-
id: 'id-2',
|
|
103
|
-
title: 'Post B'
|
|
104
|
-
}],
|
|
105
|
-
totalDocs: 2,
|
|
106
|
-
limit: 10,
|
|
107
|
-
totalPages: 1,
|
|
108
|
-
page: 1,
|
|
109
|
-
pagingCounter: 1,
|
|
110
|
-
hasPrevPage: false,
|
|
111
|
-
hasNextPage: false,
|
|
112
|
-
prevPage: null,
|
|
113
|
-
nextPage: null
|
|
114
|
-
},
|
|
115
|
-
hasMultipleRelations: true,
|
|
116
|
-
i18n: {
|
|
117
|
-
t: () => 'Posts'
|
|
118
|
-
},
|
|
119
|
-
relation: 'posts'
|
|
120
|
-
});
|
|
121
|
-
const group = result.find(o => o.options);
|
|
122
|
-
expect(group?.options).toHaveLength(2);
|
|
123
|
-
expect(group?.options?.map(o => o.value)).toEqual(['id-1', 'id-2']);
|
|
124
|
-
});
|
|
125
|
-
});
|
|
126
|
-
describe('CLEAR', () => {
|
|
127
|
-
it('returns empty array when field is required', () => {
|
|
128
|
-
const result = optionsReducer([{
|
|
129
|
-
label: 'Post A',
|
|
130
|
-
value: 'id-1'
|
|
131
|
-
}], {
|
|
132
|
-
type: 'CLEAR',
|
|
133
|
-
required: true,
|
|
134
|
-
i18n: mockI18n
|
|
135
|
-
});
|
|
136
|
-
expect(result).toEqual([]);
|
|
137
|
-
});
|
|
138
|
-
it('returns none option when field is not required', () => {
|
|
139
|
-
const result = optionsReducer([{
|
|
140
|
-
label: 'Post A',
|
|
141
|
-
value: 'id-1'
|
|
142
|
-
}], {
|
|
143
|
-
type: 'CLEAR',
|
|
144
|
-
required: false,
|
|
145
|
-
i18n: mockI18n
|
|
146
|
-
});
|
|
147
|
-
expect(result).toHaveLength(1);
|
|
148
|
-
expect(result[0]?.value).toBe('null');
|
|
149
|
-
});
|
|
150
|
-
});
|
|
151
|
-
});
|
|
152
|
-
//# sourceMappingURL=optionsReducer.spec.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"optionsReducer.spec.js","names":["describe","expect","it","optionsReducer","mockI18n","t","key","mockCollection","admin","useAsTitle","labels","plural","initial","label","value","result","type","collection","data","docs","id","title","totalDocs","limit","totalPages","page","pagingCounter","hasPrevPage","hasNextPage","prevPage","nextPage","hasMultipleRelations","i18n","relation","toHaveLength","map","o","toEqual","undefined","options","relationTo","group","find","required","toBe"],"sources":["../../../../../src/elements/WhereBuilder/Condition/Relationship/optionsReducer.spec.ts"],"sourcesContent":["import { describe, expect, it } from 'vitest'\n\nimport optionsReducer from './optionsReducer.js'\nimport type { Option } from './types.js'\n\nconst mockI18n = {\n t: (key: string) => key,\n} as any\n\nconst mockCollection = {\n admin: { useAsTitle: 'title' },\n labels: { plural: 'Posts' },\n} as any\n\ndescribe('optionsReducer', () => {\n describe('ADD — single relation', () => {\n it('deduplicates options when the same doc is loaded twice', () => {\n const initial: Option[] = [{ label: 'Post A', value: 'id-1' }]\n\n const result = optionsReducer(initial, {\n type: 'ADD',\n collection: mockCollection,\n data: {\n docs: [\n { id: 'id-1', title: 'Post A' }, // already in state\n { id: 'id-2', title: 'Post B' }, // new\n ],\n totalDocs: 2,\n limit: 10,\n totalPages: 1,\n page: 1,\n pagingCounter: 1,\n hasPrevPage: false,\n hasNextPage: false,\n prevPage: null,\n nextPage: null,\n },\n hasMultipleRelations: false,\n i18n: mockI18n,\n relation: 'posts',\n })\n\n expect(result).toHaveLength(2)\n expect(result.map((o) => o.value)).toEqual(['id-1', 'id-2'])\n })\n\n it('appends all docs when state is empty', () => {\n const result = optionsReducer([], {\n type: 'ADD',\n collection: mockCollection,\n data: {\n docs: [\n { id: 'id-1', title: 'Post A' },\n { id: 'id-2', title: 'Post B' },\n ],\n totalDocs: 2,\n limit: 10,\n totalPages: 1,\n page: 1,\n pagingCounter: 1,\n hasPrevPage: false,\n hasNextPage: false,\n prevPage: null,\n nextPage: null,\n },\n hasMultipleRelations: false,\n i18n: mockI18n,\n relation: 'posts',\n })\n\n expect(result).toHaveLength(2)\n })\n })\n\n describe('ADD — multiple relations (grouped options)', () => {\n it('deduplicates sub-options within a group when the same doc is loaded twice', () => {\n const initial: Option[] = [\n {\n label: 'Posts',\n value: undefined as any,\n options: [{ label: 'Post A', value: 'id-1', relationTo: 'posts' }],\n },\n ]\n\n const result = optionsReducer(initial, {\n type: 'ADD',\n collection: { ...mockCollection, labels: { plural: 'Posts' } },\n data: {\n docs: [\n { id: 'id-1', title: 'Post A' }, // duplicate\n { id: 'id-2', title: 'Post B' }, // new\n ],\n totalDocs: 2,\n limit: 10,\n totalPages: 1,\n page: 1,\n pagingCounter: 1,\n hasPrevPage: false,\n hasNextPage: false,\n prevPage: null,\n nextPage: null,\n },\n hasMultipleRelations: true,\n i18n: { t: () => 'Posts' } as any,\n relation: 'posts',\n })\n\n const group = result.find((o) => o.options)\n expect(group?.options).toHaveLength(2)\n expect(group?.options?.map((o) => o.value)).toEqual(['id-1', 'id-2'])\n })\n })\n\n describe('CLEAR', () => {\n it('returns empty array when field is required', () => {\n const result = optionsReducer([{ label: 'Post A', value: 'id-1' }], {\n type: 'CLEAR',\n required: true,\n i18n: mockI18n,\n })\n expect(result).toEqual([])\n })\n\n it('returns none option when field is not required', () => {\n const result = optionsReducer([{ label: 'Post A', value: 'id-1' }], {\n type: 'CLEAR',\n required: false,\n i18n: mockI18n,\n })\n expect(result).toHaveLength(1)\n expect(result[0]?.value).toBe('null')\n })\n })\n})\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest';
|
|
2
|
-
import { getDisplayedConditionValue, isEmptyConditionValue, isNoOpConditionValueUpdate } from './conditionValue.js';
|
|
3
|
-
describe('isEmptyConditionValue', () => {
|
|
4
|
-
it.each([['undefined', undefined], ['null', null], ['an empty string', '']])('should treat %s as empty', (_label, value) => {
|
|
5
|
-
expect(isEmptyConditionValue({
|
|
6
|
-
value
|
|
7
|
-
})).toBe(true);
|
|
8
|
-
});
|
|
9
|
-
it.each([['a string', 'option1'], ['zero', 0], ['false', false]])('should treat %s as a real value', (_label, value) => {
|
|
10
|
-
expect(isEmptyConditionValue({
|
|
11
|
-
value
|
|
12
|
-
})).toBe(false);
|
|
13
|
-
});
|
|
14
|
-
});
|
|
15
|
-
describe('getDisplayedConditionValue', () => {
|
|
16
|
-
it.each([['undefined', undefined], ['null', null]])('should display %s as no value', (_label, value) => {
|
|
17
|
-
expect(getDisplayedConditionValue({
|
|
18
|
-
value
|
|
19
|
-
})).toBeUndefined();
|
|
20
|
-
});
|
|
21
|
-
it.each([['zero', 0], ['false', false], ['an empty string', ''], ['a string', 'option1']])('should display %s as itself', (_label, value) => {
|
|
22
|
-
expect(getDisplayedConditionValue({
|
|
23
|
-
value
|
|
24
|
-
})).toBe(value);
|
|
25
|
-
});
|
|
26
|
-
});
|
|
27
|
-
describe('isNoOpConditionValueUpdate', () => {
|
|
28
|
-
it('should skip the empty value a row reports back for a stored empty string', () => {
|
|
29
|
-
// The row this covers comes from a URL such as `?where[or][0][and][0][field][equals]=`.
|
|
30
|
-
expect(isNoOpConditionValueUpdate({
|
|
31
|
-
incomingValue: undefined,
|
|
32
|
-
storedValue: '',
|
|
33
|
-
type: 'value'
|
|
34
|
-
})).toBe(true);
|
|
35
|
-
});
|
|
36
|
-
it.each([['undefined', 'an empty string', undefined, ''], ['null', 'undefined', null, undefined], ['undefined', 'undefined', undefined, undefined]])('should skip a %s value stored as %s', (_incomingLabel, _storedLabel, incomingValue, storedValue) => {
|
|
37
|
-
expect(isNoOpConditionValueUpdate({
|
|
38
|
-
incomingValue,
|
|
39
|
-
storedValue,
|
|
40
|
-
type: 'value'
|
|
41
|
-
})).toBe(true);
|
|
42
|
-
});
|
|
43
|
-
it('should commit a value typed into an empty row', () => {
|
|
44
|
-
expect(isNoOpConditionValueUpdate({
|
|
45
|
-
incomingValue: 'option1',
|
|
46
|
-
storedValue: '',
|
|
47
|
-
type: 'value'
|
|
48
|
-
})).toBe(false);
|
|
49
|
-
});
|
|
50
|
-
it('should commit a row the user cleared', () => {
|
|
51
|
-
expect(isNoOpConditionValueUpdate({
|
|
52
|
-
incomingValue: undefined,
|
|
53
|
-
storedValue: 'option1',
|
|
54
|
-
type: 'value'
|
|
55
|
-
})).toBe(false);
|
|
56
|
-
});
|
|
57
|
-
it.each([['field'], ['operator']])('should commit a %s edit on a row that holds no value', type => {
|
|
58
|
-
expect(isNoOpConditionValueUpdate({
|
|
59
|
-
incomingValue: undefined,
|
|
60
|
-
storedValue: '',
|
|
61
|
-
type
|
|
62
|
-
})).toBe(false);
|
|
63
|
-
});
|
|
64
|
-
});
|
|
65
|
-
//# sourceMappingURL=conditionValue.spec.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"conditionValue.spec.js","names":["describe","expect","it","getDisplayedConditionValue","isEmptyConditionValue","isNoOpConditionValueUpdate","each","undefined","_label","value","toBe","toBeUndefined","incomingValue","storedValue","type","_incomingLabel","_storedLabel"],"sources":["../../../src/elements/WhereBuilder/conditionValue.spec.ts"],"sourcesContent":["import { describe, expect, it } from 'vitest'\n\nimport {\n getDisplayedConditionValue,\n isEmptyConditionValue,\n isNoOpConditionValueUpdate,\n} from './conditionValue.js'\n\ndescribe('isEmptyConditionValue', () => {\n it.each([\n ['undefined', undefined],\n ['null', null],\n ['an empty string', ''],\n ])('should treat %s as empty', (_label, value) => {\n expect(isEmptyConditionValue({ value })).toBe(true)\n })\n\n it.each([\n ['a string', 'option1'],\n ['zero', 0],\n ['false', false],\n ])('should treat %s as a real value', (_label, value) => {\n expect(isEmptyConditionValue({ value })).toBe(false)\n })\n})\n\ndescribe('getDisplayedConditionValue', () => {\n it.each([\n ['undefined', undefined],\n ['null', null],\n ])('should display %s as no value', (_label, value) => {\n expect(getDisplayedConditionValue({ value })).toBeUndefined()\n })\n\n it.each([\n ['zero', 0],\n ['false', false],\n ['an empty string', ''],\n ['a string', 'option1'],\n ])('should display %s as itself', (_label, value) => {\n expect(getDisplayedConditionValue({ value })).toBe(value)\n })\n})\n\ndescribe('isNoOpConditionValueUpdate', () => {\n it('should skip the empty value a row reports back for a stored empty string', () => {\n // The row this covers comes from a URL such as `?where[or][0][and][0][field][equals]=`.\n expect(\n isNoOpConditionValueUpdate({ incomingValue: undefined, storedValue: '', type: 'value' }),\n ).toBe(true)\n })\n\n it.each([\n ['undefined', 'an empty string', undefined, ''],\n ['null', 'undefined', null, undefined],\n ['undefined', 'undefined', undefined, undefined],\n ])(\n 'should skip a %s value stored as %s',\n (_incomingLabel, _storedLabel, incomingValue, storedValue) => {\n expect(isNoOpConditionValueUpdate({ incomingValue, storedValue, type: 'value' })).toBe(true)\n },\n )\n\n it('should commit a value typed into an empty row', () => {\n expect(\n isNoOpConditionValueUpdate({ incomingValue: 'option1', storedValue: '', type: 'value' }),\n ).toBe(false)\n })\n\n it('should commit a row the user cleared', () => {\n expect(\n isNoOpConditionValueUpdate({\n incomingValue: undefined,\n storedValue: 'option1',\n type: 'value',\n }),\n ).toBe(false)\n })\n\n it.each([['field'], ['operator']] as const)(\n 'should commit a %s edit on a row that holds no value',\n (type) => {\n expect(isNoOpConditionValueUpdate({ incomingValue: undefined, storedValue: '', type })).toBe(\n false,\n )\n },\n )\n})\n"],"mappings":"AAAA,SAASA,QAAQ,EAAEC,MAAM,EAAEC,EAAE,QAAQ;AAErC,SACEC,0BAA0B,EAC1BC,qBAAqB,EACrBC,0BAA0B,QACrB;AAEPL,QAAA,CAAS,yBAAyB;EAChCE,EAAA,CAAGI,IAAI,CAAC,CACN,CAAC,aAAaC,SAAA,CAAU,EACxB,CAAC,QAAQ,KAAK,EACd,CAAC,mBAAmB,GAAG,CACxB,EAAE,4BAA4B,CAACC,MAAA,EAAQC,KAAA;IACtCR,MAAA,CAAOG,qBAAA,CAAsB;MAAEK;IAAM,IAAIC,IAAI,CAAC;EAChD;EAEAR,EAAA,CAAGI,IAAI,CAAC,CACN,CAAC,YAAY,UAAU,EACvB,CAAC,QAAQ,EAAE,EACX,CAAC,SAAS,MAAM,CACjB,EAAE,mCAAmC,CAACE,MAAA,EAAQC,KAAA;IAC7CR,MAAA,CAAOG,qBAAA,CAAsB;MAAEK;IAAM,IAAIC,IAAI,CAAC;EAChD;AACF;AAEAV,QAAA,CAAS,8BAA8B;EACrCE,EAAA,CAAGI,IAAI,CAAC,CACN,CAAC,aAAaC,SAAA,CAAU,EACxB,CAAC,QAAQ,KAAK,CACf,EAAE,iCAAiC,CAACC,MAAA,EAAQC,KAAA;IAC3CR,MAAA,CAAOE,0BAAA,CAA2B;MAAEM;IAAM,IAAIE,aAAa;EAC7D;EAEAT,EAAA,CAAGI,IAAI,CAAC,CACN,CAAC,QAAQ,EAAE,EACX,CAAC,SAAS,MAAM,EAChB,CAAC,mBAAmB,GAAG,EACvB,CAAC,YAAY,UAAU,CACxB,EAAE,+BAA+B,CAACE,MAAA,EAAQC,KAAA;IACzCR,MAAA,CAAOE,0BAAA,CAA2B;MAAEM;IAAM,IAAIC,IAAI,CAACD,KAAA;EACrD;AACF;AAEAT,QAAA,CAAS,8BAA8B;EACrCE,EAAA,CAAG,4EAA4E;IAC7E;IACAD,MAAA,CACEI,0BAAA,CAA2B;MAAEO,aAAA,EAAeL,SAAA;MAAWM,WAAA,EAAa;MAAIC,IAAA,EAAM;IAAQ,IACtFJ,IAAI,CAAC;EACT;EAEAR,EAAA,CAAGI,IAAI,CAAC,CACN,CAAC,aAAa,mBAAmBC,SAAA,EAAW,GAAG,EAC/C,CAAC,QAAQ,aAAa,MAAMA,SAAA,CAAU,EACtC,CAAC,aAAa,aAAaA,SAAA,EAAWA,SAAA,CAAU,CACjD,EACC,uCACA,CAACQ,cAAA,EAAgBC,YAAA,EAAcJ,aAAA,EAAeC,WAAA;IAC5CZ,MAAA,CAAOI,0BAAA,CAA2B;MAAEO,aAAA;MAAeC,WAAA;MAAaC,IAAA,EAAM;IAAQ,IAAIJ,IAAI,CAAC;EACzF;EAGFR,EAAA,CAAG,iDAAiD;IAClDD,MAAA,CACEI,0BAAA,CAA2B;MAAEO,aAAA,EAAe;MAAWC,WAAA,EAAa;MAAIC,IAAA,EAAM;IAAQ,IACtFJ,IAAI,CAAC;EACT;EAEAR,EAAA,CAAG,wCAAwC;IACzCD,MAAA,CACEI,0BAAA,CAA2B;MACzBO,aAAA,EAAeL,SAAA;MACfM,WAAA,EAAa;MACbC,IAAA,EAAM;IACR,IACAJ,IAAI,CAAC;EACT;EAEAR,EAAA,CAAGI,IAAI,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,WAAW,CAAC,EAC/B,wDACCQ,IAAA;IACCb,MAAA,CAAOI,0BAAA,CAA2B;MAAEO,aAAA,EAAeL,SAAA;MAAWM,WAAA,EAAa;MAAIC;IAAK,IAAIJ,IAAI,CAC1F;EAEJ;AAEJ","ignoreList":[]}
|
|
@@ -1,242 +0,0 @@
|
|
|
1
|
-
// @vitest-environment jsdom
|
|
2
|
-
import React, { act } from 'react';
|
|
3
|
-
import { createRoot } from 'react-dom/client';
|
|
4
|
-
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
5
|
-
import { UploadInput } from './Input.js';
|
|
6
|
-
vi.mock('@faceless-ui/modal', () => ({
|
|
7
|
-
useModal: () => ({
|
|
8
|
-
openModal: vi.fn()
|
|
9
|
-
})
|
|
10
|
-
}));
|
|
11
|
-
vi.mock('../../elements/BulkUpload/index.js', () => ({
|
|
12
|
-
useBulkUpload: () => ({
|
|
13
|
-
modalSlug: 'bulk-upload',
|
|
14
|
-
setCollectionSlug: vi.fn(),
|
|
15
|
-
setInitialFiles: vi.fn(),
|
|
16
|
-
setMaxFiles: vi.fn(),
|
|
17
|
-
setOnSuccess: vi.fn(),
|
|
18
|
-
setSelectableCollections: vi.fn()
|
|
19
|
-
})
|
|
20
|
-
}));
|
|
21
|
-
vi.mock('../../elements/DocumentDrawer/index.js', () => ({
|
|
22
|
-
useDocumentDrawer: () => [() => null, () => null, {
|
|
23
|
-
closeDrawer: vi.fn(),
|
|
24
|
-
openDrawer: vi.fn()
|
|
25
|
-
}]
|
|
26
|
-
}));
|
|
27
|
-
vi.mock('../../elements/ListDrawer/index.js', () => ({
|
|
28
|
-
useListDrawer: () => [() => null, () => null, {
|
|
29
|
-
closeDrawer: vi.fn(),
|
|
30
|
-
openDrawer: vi.fn()
|
|
31
|
-
}]
|
|
32
|
-
}));
|
|
33
|
-
vi.mock('../../providers/Auth/index.js', () => ({
|
|
34
|
-
useAuth: () => ({
|
|
35
|
-
permissions: {}
|
|
36
|
-
})
|
|
37
|
-
}));
|
|
38
|
-
vi.mock('../../providers/Locale/index.js', () => ({
|
|
39
|
-
useLocale: () => ({
|
|
40
|
-
code: 'en',
|
|
41
|
-
label: 'English'
|
|
42
|
-
})
|
|
43
|
-
}));
|
|
44
|
-
vi.mock('../../providers/Translation/index.js', () => ({
|
|
45
|
-
useTranslation: () => ({
|
|
46
|
-
i18n: {
|
|
47
|
-
language: 'en'
|
|
48
|
-
},
|
|
49
|
-
t: key => key
|
|
50
|
-
})
|
|
51
|
-
}));
|
|
52
|
-
vi.mock('./HasMany/index.js', () => ({
|
|
53
|
-
UploadComponentHasMany: props => React.createElement('div', {
|
|
54
|
-
'data-testid': 'has-many'
|
|
55
|
-
}, JSON.stringify(props.fileDocs))
|
|
56
|
-
}));
|
|
57
|
-
vi.mock('./HasOne/index.js', () => ({
|
|
58
|
-
UploadComponentHasOne: () => null
|
|
59
|
-
}));
|
|
60
|
-
const rootCleanups = [];
|
|
61
|
-
beforeEach(() => {
|
|
62
|
-
vi.stubGlobal('fetch', vi.fn());
|
|
63
|
-
});
|
|
64
|
-
afterEach(() => {
|
|
65
|
-
for (const cleanup of rootCleanups.splice(0)) {
|
|
66
|
-
cleanup();
|
|
67
|
-
}
|
|
68
|
-
vi.unstubAllGlobals();
|
|
69
|
-
});
|
|
70
|
-
describe('UploadInput populateDocs race', () => {
|
|
71
|
-
it('aborts an in-flight populateDocs() request when value changes', async () => {
|
|
72
|
-
let oldRequest;
|
|
73
|
-
let newRequest;
|
|
74
|
-
const fetchMock = fetch;
|
|
75
|
-
fetchMock.mockImplementation((_url, options) => {
|
|
76
|
-
const deferred = createDeferred();
|
|
77
|
-
if (options.signal) {
|
|
78
|
-
if (options.signal.aborted) {
|
|
79
|
-
return Promise.reject(new DOMException('The operation was aborted.', 'AbortError'));
|
|
80
|
-
}
|
|
81
|
-
options.signal.addEventListener('abort', () => {
|
|
82
|
-
deferred.reject(new DOMException('The operation was aborted.', 'AbortError'));
|
|
83
|
-
});
|
|
84
|
-
}
|
|
85
|
-
if (options.body.includes('old-id')) {
|
|
86
|
-
oldRequest = deferred;
|
|
87
|
-
} else {
|
|
88
|
-
newRequest = deferred;
|
|
89
|
-
}
|
|
90
|
-
return deferred.promise;
|
|
91
|
-
});
|
|
92
|
-
const {
|
|
93
|
-
container,
|
|
94
|
-
rerender
|
|
95
|
-
} = renderUploadInput({
|
|
96
|
-
value: ['old-id']
|
|
97
|
-
});
|
|
98
|
-
// First render fires populateDocs() for the older value; do not resolve it yet.
|
|
99
|
-
await act(async () => {
|
|
100
|
-
await Promise.resolve();
|
|
101
|
-
});
|
|
102
|
-
expect(oldRequest).toBeDefined();
|
|
103
|
-
// A newer value supersedes it before the older request resolves.
|
|
104
|
-
rerender({
|
|
105
|
-
value: ['new-id']
|
|
106
|
-
});
|
|
107
|
-
await act(async () => {
|
|
108
|
-
await Promise.resolve();
|
|
109
|
-
});
|
|
110
|
-
expect(newRequest).toBeDefined();
|
|
111
|
-
await expect(oldRequest.promise).rejects.toMatchObject({
|
|
112
|
-
name: 'AbortError'
|
|
113
|
-
});
|
|
114
|
-
// The newer request resolves and is applied.
|
|
115
|
-
await act(async () => {
|
|
116
|
-
newRequest.resolve(jsonResponse([{
|
|
117
|
-
id: 'new-id',
|
|
118
|
-
filename: 'new.jpg'
|
|
119
|
-
}]));
|
|
120
|
-
await Promise.resolve();
|
|
121
|
-
await Promise.resolve();
|
|
122
|
-
});
|
|
123
|
-
expect(container.querySelector('[data-testid="has-many"]')?.textContent).toContain('new-id');
|
|
124
|
-
expect(container.querySelector('[data-testid="has-many"]')?.textContent).not.toContain('old-id');
|
|
125
|
-
});
|
|
126
|
-
it('applies the result normally when requests resolve in order', async () => {
|
|
127
|
-
let oldRequest;
|
|
128
|
-
let newRequest;
|
|
129
|
-
const fetchMock = fetch;
|
|
130
|
-
fetchMock.mockImplementation((_url, options) => {
|
|
131
|
-
const deferred = createDeferred();
|
|
132
|
-
if (options.signal) {
|
|
133
|
-
if (options.signal.aborted) {
|
|
134
|
-
return Promise.reject(new DOMException('The operation was aborted.', 'AbortError'));
|
|
135
|
-
}
|
|
136
|
-
options.signal.addEventListener('abort', () => {
|
|
137
|
-
deferred.reject(new DOMException('The operation was aborted.', 'AbortError'));
|
|
138
|
-
});
|
|
139
|
-
}
|
|
140
|
-
if (options.body.includes('old-id')) {
|
|
141
|
-
oldRequest = deferred;
|
|
142
|
-
} else {
|
|
143
|
-
newRequest = deferred;
|
|
144
|
-
}
|
|
145
|
-
return deferred.promise;
|
|
146
|
-
});
|
|
147
|
-
const {
|
|
148
|
-
container,
|
|
149
|
-
rerender
|
|
150
|
-
} = renderUploadInput({
|
|
151
|
-
value: ['old-id']
|
|
152
|
-
});
|
|
153
|
-
await act(async () => {
|
|
154
|
-
await Promise.resolve();
|
|
155
|
-
});
|
|
156
|
-
await act(async () => {
|
|
157
|
-
oldRequest.resolve(jsonResponse([{
|
|
158
|
-
id: 'old-id',
|
|
159
|
-
filename: 'old.jpg'
|
|
160
|
-
}]));
|
|
161
|
-
await Promise.resolve();
|
|
162
|
-
await Promise.resolve();
|
|
163
|
-
});
|
|
164
|
-
expect(container.querySelector('[data-testid="has-many"]')?.textContent).toContain('old-id');
|
|
165
|
-
rerender({
|
|
166
|
-
value: ['new-id']
|
|
167
|
-
});
|
|
168
|
-
await act(async () => {
|
|
169
|
-
await Promise.resolve();
|
|
170
|
-
});
|
|
171
|
-
await act(async () => {
|
|
172
|
-
newRequest.resolve(jsonResponse([{
|
|
173
|
-
id: 'new-id',
|
|
174
|
-
filename: 'new.jpg'
|
|
175
|
-
}]));
|
|
176
|
-
await Promise.resolve();
|
|
177
|
-
await Promise.resolve();
|
|
178
|
-
});
|
|
179
|
-
expect(container.querySelector('[data-testid="has-many"]')?.textContent).toContain('new-id');
|
|
180
|
-
});
|
|
181
|
-
});
|
|
182
|
-
function renderUploadInput({
|
|
183
|
-
value
|
|
184
|
-
}) {
|
|
185
|
-
const container = document.createElement('div');
|
|
186
|
-
const root = createRoot(container);
|
|
187
|
-
const props = {
|
|
188
|
-
api: '/api',
|
|
189
|
-
hasMany: true,
|
|
190
|
-
onChange: vi.fn(),
|
|
191
|
-
path: 'upload',
|
|
192
|
-
relationTo: 'uploads',
|
|
193
|
-
serverURL: ''
|
|
194
|
-
};
|
|
195
|
-
act(() => {
|
|
196
|
-
root.render(React.createElement(UploadInput, {
|
|
197
|
-
...props,
|
|
198
|
-
value
|
|
199
|
-
}));
|
|
200
|
-
});
|
|
201
|
-
rootCleanups.push(() => {
|
|
202
|
-
act(() => {
|
|
203
|
-
root.unmount();
|
|
204
|
-
});
|
|
205
|
-
});
|
|
206
|
-
return {
|
|
207
|
-
container,
|
|
208
|
-
rerender: next => {
|
|
209
|
-
act(() => {
|
|
210
|
-
root.render(React.createElement(UploadInput, {
|
|
211
|
-
...props,
|
|
212
|
-
value: next.value
|
|
213
|
-
}));
|
|
214
|
-
});
|
|
215
|
-
}
|
|
216
|
-
};
|
|
217
|
-
}
|
|
218
|
-
function jsonResponse(docs) {
|
|
219
|
-
return {
|
|
220
|
-
json: async () => ({
|
|
221
|
-
docs
|
|
222
|
-
}),
|
|
223
|
-
ok: true
|
|
224
|
-
};
|
|
225
|
-
}
|
|
226
|
-
function createDeferred() {
|
|
227
|
-
let resolve;
|
|
228
|
-
let reject;
|
|
229
|
-
const promise = new Promise((resolvePromise, rejectPromise) => {
|
|
230
|
-
resolve = resolvePromise;
|
|
231
|
-
reject = rejectPromise;
|
|
232
|
-
});
|
|
233
|
-
if (!resolve || !reject) {
|
|
234
|
-
throw new Error('Expected deferred promise resolver.');
|
|
235
|
-
}
|
|
236
|
-
return {
|
|
237
|
-
promise,
|
|
238
|
-
reject,
|
|
239
|
-
resolve
|
|
240
|
-
};
|
|
241
|
-
}
|
|
242
|
-
//# sourceMappingURL=Input.spec.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Input.spec.js","names":["React","act","createRoot","afterEach","beforeEach","describe","expect","it","vi","UploadInput","mock","useModal","openModal","fn","useBulkUpload","modalSlug","setCollectionSlug","setInitialFiles","setMaxFiles","setOnSuccess","setSelectableCollections","useDocumentDrawer","closeDrawer","openDrawer","useListDrawer","useAuth","permissions","useLocale","code","label","useTranslation","i18n","language","t","key","UploadComponentHasMany","props","createElement","JSON","stringify","fileDocs","UploadComponentHasOne","rootCleanups","stubGlobal","cleanup","splice","unstubAllGlobals","oldRequest","newRequest","fetchMock","fetch","mockImplementation","_url","options","deferred","createDeferred","signal","aborted","Promise","reject","DOMException","addEventListener","body","includes","promise","container","rerender","renderUploadInput","value","resolve","toBeDefined","rejects","toMatchObject","name","jsonResponse","id","filename","querySelector","textContent","toContain","not","document","root","api","hasMany","onChange","path","relationTo","serverURL","render","push","unmount","next","docs","json","ok","resolvePromise","rejectPromise","Error"],"sources":["../../../src/fields/Upload/Input.spec.ts"],"sourcesContent":["// @vitest-environment jsdom\nimport type { Locale } from 'payload'\n\nimport React, { act } from 'react'\nimport { createRoot, type Root } from 'react-dom/client'\nimport { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'\n\nimport { UploadInput } from './Input.js'\n\nvi.mock('@faceless-ui/modal', () => ({\n useModal: () => ({ openModal: vi.fn() }),\n}))\n\nvi.mock('../../elements/BulkUpload/index.js', () => ({\n useBulkUpload: () => ({\n modalSlug: 'bulk-upload',\n setCollectionSlug: vi.fn(),\n setInitialFiles: vi.fn(),\n setMaxFiles: vi.fn(),\n setOnSuccess: vi.fn(),\n setSelectableCollections: vi.fn(),\n }),\n}))\n\nvi.mock('../../elements/DocumentDrawer/index.js', () => ({\n useDocumentDrawer: () => [() => null, () => null, { closeDrawer: vi.fn(), openDrawer: vi.fn() }],\n}))\n\nvi.mock('../../elements/ListDrawer/index.js', () => ({\n useListDrawer: () => [() => null, () => null, { closeDrawer: vi.fn(), openDrawer: vi.fn() }],\n}))\n\nvi.mock('../../providers/Auth/index.js', () => ({\n useAuth: () => ({ permissions: {} }),\n}))\n\nvi.mock('../../providers/Locale/index.js', () => ({\n useLocale: (): Locale | null => ({ code: 'en', label: 'English' }),\n}))\n\nvi.mock('../../providers/Translation/index.js', () => ({\n useTranslation: () => ({ i18n: { language: 'en' }, t: (key: string) => key }),\n}))\n\nvi.mock('./HasMany/index.js', () => ({\n UploadComponentHasMany: (props: { fileDocs: unknown }) =>\n React.createElement('div', { 'data-testid': 'has-many' }, JSON.stringify(props.fileDocs)),\n}))\n\nvi.mock('./HasOne/index.js', () => ({\n UploadComponentHasOne: () => null,\n}))\n\nconst rootCleanups: Array<() => void> = []\n\nbeforeEach(() => {\n vi.stubGlobal('fetch', vi.fn())\n})\n\nafterEach(() => {\n for (const cleanup of rootCleanups.splice(0)) {\n cleanup()\n }\n vi.unstubAllGlobals()\n})\n\ndescribe('UploadInput populateDocs race', () => {\n it('aborts an in-flight populateDocs() request when value changes', async () => {\n let oldRequest: ReturnType<typeof createDeferred<Response>> | undefined\n let newRequest: ReturnType<typeof createDeferred<Response>> | undefined\n\n const fetchMock = fetch as unknown as ReturnType<typeof vi.fn>\n fetchMock.mockImplementation(\n (_url: string, options: { body: string; signal?: AbortSignal }) => {\n const deferred = createDeferred<Response>()\n\n if (options.signal) {\n if (options.signal.aborted) {\n return Promise.reject(new DOMException('The operation was aborted.', 'AbortError'))\n }\n\n options.signal.addEventListener('abort', () => {\n deferred.reject(new DOMException('The operation was aborted.', 'AbortError'))\n })\n }\n\n if (options.body.includes('old-id')) {\n oldRequest = deferred\n } else {\n newRequest = deferred\n }\n\n return deferred.promise\n },\n )\n\n const { container, rerender } = renderUploadInput({ value: ['old-id'] })\n\n // First render fires populateDocs() for the older value; do not resolve it yet.\n await act(async () => {\n await Promise.resolve()\n })\n expect(oldRequest).toBeDefined()\n\n // A newer value supersedes it before the older request resolves.\n rerender({ value: ['new-id'] })\n await act(async () => {\n await Promise.resolve()\n })\n expect(newRequest).toBeDefined()\n await expect(oldRequest!.promise).rejects.toMatchObject({ name: 'AbortError' })\n\n // The newer request resolves and is applied.\n await act(async () => {\n newRequest!.resolve(jsonResponse([{ id: 'new-id', filename: 'new.jpg' }]))\n await Promise.resolve()\n await Promise.resolve()\n })\n expect(container.querySelector('[data-testid=\"has-many\"]')?.textContent).toContain('new-id')\n expect(container.querySelector('[data-testid=\"has-many\"]')?.textContent).not.toContain('old-id')\n })\n\n it('applies the result normally when requests resolve in order', async () => {\n let oldRequest: ReturnType<typeof createDeferred<Response>> | undefined\n let newRequest: ReturnType<typeof createDeferred<Response>> | undefined\n\n const fetchMock = fetch as unknown as ReturnType<typeof vi.fn>\n fetchMock.mockImplementation(\n (_url: string, options: { body: string; signal?: AbortSignal }) => {\n const deferred = createDeferred<Response>()\n\n if (options.signal) {\n if (options.signal.aborted) {\n return Promise.reject(new DOMException('The operation was aborted.', 'AbortError'))\n }\n\n options.signal.addEventListener('abort', () => {\n deferred.reject(new DOMException('The operation was aborted.', 'AbortError'))\n })\n }\n\n if (options.body.includes('old-id')) {\n oldRequest = deferred\n } else {\n newRequest = deferred\n }\n\n return deferred.promise\n },\n )\n\n const { container, rerender } = renderUploadInput({ value: ['old-id'] })\n\n await act(async () => {\n await Promise.resolve()\n })\n\n await act(async () => {\n oldRequest!.resolve(jsonResponse([{ id: 'old-id', filename: 'old.jpg' }]))\n await Promise.resolve()\n await Promise.resolve()\n })\n expect(container.querySelector('[data-testid=\"has-many\"]')?.textContent).toContain('old-id')\n\n rerender({ value: ['new-id'] })\n await act(async () => {\n await Promise.resolve()\n })\n\n await act(async () => {\n newRequest!.resolve(jsonResponse([{ id: 'new-id', filename: 'new.jpg' }]))\n await Promise.resolve()\n await Promise.resolve()\n })\n expect(container.querySelector('[data-testid=\"has-many\"]')?.textContent).toContain('new-id')\n })\n})\n\nfunction renderUploadInput({ value }: { value: (number | string)[] }): {\n container: HTMLElement\n rerender: (next: { value: (number | string)[] }) => void\n} {\n const container = document.createElement('div')\n const root: Root = createRoot(container)\n\n const props = {\n api: '/api',\n hasMany: true,\n onChange: vi.fn(),\n path: 'upload',\n relationTo: 'uploads',\n serverURL: '',\n }\n\n act(() => {\n root.render(React.createElement(UploadInput, { ...props, value }))\n })\n\n rootCleanups.push(() => {\n act(() => {\n root.unmount()\n })\n })\n\n return {\n container,\n rerender: (next) => {\n act(() => {\n root.render(React.createElement(UploadInput, { ...props, value: next.value }))\n })\n },\n }\n}\n\nfunction jsonResponse(docs: unknown[]): Response {\n return {\n json: async () => ({ docs }),\n ok: true,\n } as unknown as Response\n}\n\nfunction createDeferred<Value>(): {\n promise: Promise<Value>\n reject: (reason?: unknown) => void\n resolve: (value: Value | PromiseLike<Value>) => void\n} {\n let resolve: ((value: Value | PromiseLike<Value>) => void) | undefined\n let reject: ((reason?: unknown) => void) | undefined\n const promise = new Promise<Value>((resolvePromise, rejectPromise) => {\n resolve = resolvePromise\n reject = rejectPromise\n })\n\n if (!resolve || !reject) {\n throw new Error('Expected deferred promise resolver.')\n }\n\n return { promise, reject, resolve }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"fieldSchemasToFormState.spec.d.ts","sourceRoot":"","sources":["../../../src/forms/fieldSchemasToFormState/fieldSchemasToFormState.spec.js"],"names":[],"mappings":""}
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from 'vitest';
|
|
2
|
-
import { fieldSchemasToFormState } from './index.js';
|
|
3
|
-
describe('Form - fieldSchemasToFormState', () => {
|
|
4
|
-
const defaultValue = 'Default';
|
|
5
|
-
it('populates default value - normal fields', async () => {
|
|
6
|
-
const fieldSchema = [{
|
|
7
|
-
name: 'text',
|
|
8
|
-
type: 'text',
|
|
9
|
-
defaultValue,
|
|
10
|
-
label: 'Text'
|
|
11
|
-
}];
|
|
12
|
-
const state = await fieldSchemasToFormState({
|
|
13
|
-
req: {},
|
|
14
|
-
fields: fieldSchema
|
|
15
|
-
});
|
|
16
|
-
expect(state.text.value).toBe(defaultValue);
|
|
17
|
-
});
|
|
18
|
-
it('field value overrides defaultValue - normal fields', async () => {
|
|
19
|
-
const value = 'value';
|
|
20
|
-
const data = {
|
|
21
|
-
text: value
|
|
22
|
-
};
|
|
23
|
-
const fieldSchema = [{
|
|
24
|
-
name: 'text',
|
|
25
|
-
type: 'text',
|
|
26
|
-
defaultValue,
|
|
27
|
-
label: 'Text'
|
|
28
|
-
}];
|
|
29
|
-
const state = await fieldSchemasToFormState({
|
|
30
|
-
req: {},
|
|
31
|
-
data,
|
|
32
|
-
fields: fieldSchema
|
|
33
|
-
});
|
|
34
|
-
expect(state.text.value).toBe(value);
|
|
35
|
-
});
|
|
36
|
-
it('populates default value from a function - normal fields', async () => {
|
|
37
|
-
const user = {
|
|
38
|
-
email: 'user@example.com'
|
|
39
|
-
};
|
|
40
|
-
const locale = 'en';
|
|
41
|
-
const fieldSchema = [{
|
|
42
|
-
name: 'text',
|
|
43
|
-
type: 'text',
|
|
44
|
-
defaultValue: args => {
|
|
45
|
-
if (!args.locale) {
|
|
46
|
-
return 'missing locale';
|
|
47
|
-
}
|
|
48
|
-
if (!args.user) {
|
|
49
|
-
return 'missing user';
|
|
50
|
-
}
|
|
51
|
-
return 'Default';
|
|
52
|
-
},
|
|
53
|
-
label: 'Text'
|
|
54
|
-
}];
|
|
55
|
-
const state = await fieldSchemasToFormState({
|
|
56
|
-
req: {
|
|
57
|
-
locale: 'en',
|
|
58
|
-
user: {}
|
|
59
|
-
},
|
|
60
|
-
fields: fieldSchema,
|
|
61
|
-
locale,
|
|
62
|
-
user
|
|
63
|
-
});
|
|
64
|
-
expect(state.text.value).toBe(defaultValue);
|
|
65
|
-
});
|
|
66
|
-
});
|
|
67
|
-
//# sourceMappingURL=fieldSchemasToFormState.spec.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"fieldSchemasToFormState.spec.js","names":["describe","it","expect","fieldSchemasToFormState","defaultValue","fieldSchema","name","type","label","state","req","fields","text","value","toBe","data","user","email","locale","args"],"sources":["../../../src/forms/fieldSchemasToFormState/fieldSchemasToFormState.spec.js"],"sourcesContent":["import { describe, it, expect } from 'vitest'\nimport { fieldSchemasToFormState } from './index.js'\n\ndescribe('Form - fieldSchemasToFormState', () => {\n const defaultValue = 'Default'\n it('populates default value - normal fields', async () => {\n const fieldSchema = [\n {\n name: 'text',\n type: 'text',\n defaultValue,\n label: 'Text',\n },\n ]\n const state = await fieldSchemasToFormState({ req: {}, fields: fieldSchema })\n expect(state.text.value).toBe(defaultValue)\n })\n it('field value overrides defaultValue - normal fields', async () => {\n const value = 'value'\n const data = { text: value }\n const fieldSchema = [\n {\n name: 'text',\n type: 'text',\n defaultValue,\n label: 'Text',\n },\n ]\n const state = await fieldSchemasToFormState({ req: {}, data, fields: fieldSchema })\n expect(state.text.value).toBe(value)\n })\n it('populates default value from a function - normal fields', async () => {\n const user = { email: 'user@example.com' }\n const locale = 'en'\n const fieldSchema = [\n {\n name: 'text',\n type: 'text',\n defaultValue: (args) => {\n if (!args.locale) {\n return 'missing locale'\n }\n if (!args.user) {\n return 'missing user'\n }\n return 'Default'\n },\n label: 'Text',\n },\n ]\n const state = await fieldSchemasToFormState({\n req: { locale: 'en', user: {} },\n fields: fieldSchema,\n locale,\n user,\n })\n expect(state.text.value).toBe(defaultValue)\n })\n})\n"],"mappings":"AAAA,SAASA,QAAQ,EAAEC,EAAE,EAAEC,MAAM,QAAQ;AACrC,SAASC,uBAAuB,QAAQ;AAExCH,QAAA,CAAS,kCAAkC;EACzC,MAAMI,YAAA,GAAe;EACrBH,EAAA,CAAG,2CAA2C;IAC5C,MAAMI,WAAA,GAAc,CAClB;MACEC,IAAA,EAAM;MACNC,IAAA,EAAM;MACNH,YAAA;MACAI,KAAA,EAAO;IACT,EACD;IACD,MAAMC,KAAA,GAAQ,MAAMN,uBAAA,CAAwB;MAAEO,GAAA,EAAK,CAAC;MAAGC,MAAA,EAAQN;IAAY;IAC3EH,MAAA,CAAOO,KAAA,CAAMG,IAAI,CAACC,KAAK,EAAEC,IAAI,CAACV,YAAA;EAChC;EACAH,EAAA,CAAG,sDAAsD;IACvD,MAAMY,KAAA,GAAQ;IACd,MAAME,IAAA,GAAO;MAAEH,IAAA,EAAMC;IAAM;IAC3B,MAAMR,WAAA,GAAc,CAClB;MACEC,IAAA,EAAM;MACNC,IAAA,EAAM;MACNH,YAAA;MACAI,KAAA,EAAO;IACT,EACD;IACD,MAAMC,KAAA,GAAQ,MAAMN,uBAAA,CAAwB;MAAEO,GAAA,EAAK,CAAC;MAAGK,IAAA;MAAMJ,MAAA,EAAQN;IAAY;IACjFH,MAAA,CAAOO,KAAA,CAAMG,IAAI,CAACC,KAAK,EAAEC,IAAI,CAACD,KAAA;EAChC;EACAZ,EAAA,CAAG,2DAA2D;IAC5D,MAAMe,IAAA,GAAO;MAAEC,KAAA,EAAO;IAAmB;IACzC,MAAMC,MAAA,GAAS;IACf,MAAMb,WAAA,GAAc,CAClB;MACEC,IAAA,EAAM;MACNC,IAAA,EAAM;MACNH,YAAA,EAAee,IAAA;QACb,IAAI,CAACA,IAAA,CAAKD,MAAM,EAAE;UAChB,OAAO;QACT;QACA,IAAI,CAACC,IAAA,CAAKH,IAAI,EAAE;UACd,OAAO;QACT;QACA,OAAO;MACT;MACAR,KAAA,EAAO;IACT,EACD;IACD,MAAMC,KAAA,GAAQ,MAAMN,uBAAA,CAAwB;MAC1CO,GAAA,EAAK;QAAEQ,MAAA,EAAQ;QAAMF,IAAA,EAAM,CAAC;MAAE;MAC9BL,MAAA,EAAQN,WAAA;MACRa,MAAA;MACAF;IACF;IACAd,MAAA,CAAOO,KAAA,CAAMG,IAAI,CAACC,KAAK,EAAEC,IAAI,CAACV,YAAA;EAChC;AACF","ignoreList":[]}
|