@payloadcms/ui 4.0.0-canary.35 → 4.0.0-canary.37
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/Banner/index.css +4 -0
- package/dist/elements/Banner/index.d.ts.map +1 -1
- package/dist/elements/Banner/index.js +1 -0
- package/dist/elements/Banner/index.js.map +1 -1
- 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/getNavPrefs.d.ts.map +1 -1
- package/dist/elements/Nav/getNavPrefs.js +2 -0
- package/dist/elements/Nav/getNavPrefs.js.map +1 -1
- 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/PublishButton/index.d.ts.map +1 -1
- package/dist/elements/PublishButton/index.js +11 -25
- package/dist/elements/PublishButton/index.js.map +1 -1
- 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/layouts/Root/index.d.ts +3 -6
- package/dist/layouts/Root/index.d.ts.map +1 -1
- package/dist/layouts/Root/index.js +2 -4
- package/dist/layouts/Root/index.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/getDocPreferences.d.ts.map +1 -1
- package/dist/utilities/getDocPreferences.js +1 -0
- package/dist/utilities/getDocPreferences.js.map +1 -1
- package/dist/utilities/getPreferences.d.ts.map +1 -1
- package/dist/utilities/getPreferences.js +1 -0
- package/dist/utilities/getPreferences.js.map +1 -1
- package/dist/utilities/getVersions.d.ts.map +1 -1
- package/dist/utilities/getVersions.js +8 -0
- package/dist/utilities/getVersions.js.map +1 -1
- 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/utilities/schedulePublishHandler.d.ts.map +1 -1
- package/dist/utilities/schedulePublishHandler.js +2 -0
- package/dist/utilities/schedulePublishHandler.js.map +1 -1
- package/dist/utilities/upsertPreferences.d.ts.map +1 -1
- package/dist/utilities/upsertPreferences.js +3 -0
- package/dist/utilities/upsertPreferences.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/Document/handleServerFunction.d.ts.map +1 -1
- package/dist/views/Document/handleServerFunction.js +1 -0
- package/dist/views/Document/handleServerFunction.js.map +1 -1
- 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/enrichDocsWithVersionStatus.d.ts.map +1 -1
- package/dist/views/List/enrichDocsWithVersionStatus.js +1 -0
- package/dist/views/List/enrichDocsWithVersionStatus.js.map +1 -1
- package/dist/views/List/handleServerFunction.d.ts.map +1 -1
- package/dist/views/List/handleServerFunction.js +1 -0
- package/dist/views/List/handleServerFunction.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/NotFound/client.d.ts +2 -0
- package/dist/views/NotFound/client.d.ts.map +1 -0
- package/dist/views/NotFound/client.js +4 -0
- package/dist/views/NotFound/client.js.map +1 -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/generateLabelFromValue.d.ts.map +1 -1
- package/dist/views/Version/RenderFieldsToDiff/fields/Relationship/generateLabelFromValue.js +1 -0
- package/dist/views/Version/RenderFieldsToDiff/fields/Relationship/generateLabelFromValue.js.map +1 -1
- 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 +11 -6
- 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/getRequestLocale.d.ts +0 -7
- package/dist/utilities/getRequestLocale.d.ts.map +0 -1
- package/dist/utilities/getRequestLocale.js +0 -20
- package/dist/utilities/getRequestLocale.js.map +0 -1
- package/dist/utilities/initReq.d.ts +0 -16
- package/dist/utilities/initReq.d.ts.map +0 -1
- package/dist/utilities/initReq.js +0 -146
- package/dist/utilities/initReq.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/utilities/selectiveCache.d.ts +0 -12
- package/dist/utilities/selectiveCache.d.ts.map +0 -1
- package/dist/utilities/selectiveCache.js +0 -37
- package/dist/utilities/selectiveCache.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,311 +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 { getAuthSessionTiming } from './sessionTiming.js';
|
|
6
|
-
import { useAuthSessionTimers } from './useAuthSessionTimers.js';
|
|
7
|
-
const timerCleanups = [];
|
|
8
|
-
beforeEach(() => {
|
|
9
|
-
vi.useFakeTimers();
|
|
10
|
-
vi.setSystemTime(new Date('2026-01-01T00:00:00.000Z'));
|
|
11
|
-
});
|
|
12
|
-
afterEach(() => {
|
|
13
|
-
for (const cleanup of timerCleanups.splice(0)) {
|
|
14
|
-
cleanup();
|
|
15
|
-
}
|
|
16
|
-
vi.useRealTimers();
|
|
17
|
-
});
|
|
18
|
-
describe('useAuthSessionTimers', () => {
|
|
19
|
-
it('should scale session timing for tokens shorter than two minutes', () => {
|
|
20
|
-
const nowMs = Date.now();
|
|
21
|
-
const expirationMs = nowMs + 30_000;
|
|
22
|
-
expect(getAuthSessionTiming({
|
|
23
|
-
expirationMs,
|
|
24
|
-
nowMs
|
|
25
|
-
})).toEqual({
|
|
26
|
-
activityTrackingStartsAt: nowMs,
|
|
27
|
-
expiresAt: expirationMs,
|
|
28
|
-
refreshStartsAt: nowMs,
|
|
29
|
-
reminderStartsAt: nowMs + 15_000
|
|
30
|
-
});
|
|
31
|
-
});
|
|
32
|
-
it('should return the lifecycle timing when setting an expiration', () => {
|
|
33
|
-
const timers = renderAuthSessionTimers();
|
|
34
|
-
const expirationMs = Date.now() + 300_000;
|
|
35
|
-
expect(timers.setExpiration(expirationMs)).toEqual({
|
|
36
|
-
activityTrackingStartsAt: expirationMs - 240_000,
|
|
37
|
-
expiresAt: expirationMs,
|
|
38
|
-
refreshStartsAt: expirationMs - 120_000,
|
|
39
|
-
reminderStartsAt: expirationMs - 60_000
|
|
40
|
-
});
|
|
41
|
-
});
|
|
42
|
-
it('should refresh at the checkpoint when activity occurred in the tracking window', () => {
|
|
43
|
-
const onActivity = vi.fn();
|
|
44
|
-
const onActivityRefresh = vi.fn();
|
|
45
|
-
const timers = renderAuthSessionTimers({
|
|
46
|
-
onActivity,
|
|
47
|
-
onActivityRefresh
|
|
48
|
-
});
|
|
49
|
-
timers.setExpiration(Date.now() + 300_000);
|
|
50
|
-
act(() => {
|
|
51
|
-
vi.advanceTimersByTime(120_000);
|
|
52
|
-
window.dispatchEvent(new MouseEvent('mousemove'));
|
|
53
|
-
vi.advanceTimersByTime(1_000);
|
|
54
|
-
window.dispatchEvent(new KeyboardEvent('keydown'));
|
|
55
|
-
vi.advanceTimersByTime(59_000);
|
|
56
|
-
vi.advanceTimersByTime(1_000);
|
|
57
|
-
});
|
|
58
|
-
expect(onActivity).toHaveBeenCalledOnce();
|
|
59
|
-
expect(onActivityRefresh).toHaveBeenCalledTimes(1);
|
|
60
|
-
});
|
|
61
|
-
it('should ignore activity once the expiration reminder opens', () => {
|
|
62
|
-
const onActivityRefresh = vi.fn();
|
|
63
|
-
const timers = renderAuthSessionTimers({
|
|
64
|
-
onActivityRefresh
|
|
65
|
-
});
|
|
66
|
-
const sessionStartedAt = Date.now();
|
|
67
|
-
timers.setExpiration(sessionStartedAt + 300_000);
|
|
68
|
-
act(() => {
|
|
69
|
-
vi.advanceTimersByTime(60_000);
|
|
70
|
-
});
|
|
71
|
-
vi.setSystemTime(sessionStartedAt + 240_000);
|
|
72
|
-
expect(timers.recordActivity('route')).toBe(false);
|
|
73
|
-
expect(onActivityRefresh).not.toHaveBeenCalled();
|
|
74
|
-
});
|
|
75
|
-
it('should clear timers and listeners on logout', () => {
|
|
76
|
-
const onActivityRefresh = vi.fn();
|
|
77
|
-
const onExpire = vi.fn();
|
|
78
|
-
const timers = renderAuthSessionTimers({
|
|
79
|
-
onActivityRefresh,
|
|
80
|
-
onExpire
|
|
81
|
-
});
|
|
82
|
-
timers.setExpiration(Date.now() + 300_000);
|
|
83
|
-
timers.clear();
|
|
84
|
-
act(() => {
|
|
85
|
-
window.dispatchEvent(new MouseEvent('mousemove'));
|
|
86
|
-
vi.advanceTimersByTime(300_000);
|
|
87
|
-
});
|
|
88
|
-
expect(onActivityRefresh).not.toHaveBeenCalled();
|
|
89
|
-
expect(onExpire).not.toHaveBeenCalled();
|
|
90
|
-
});
|
|
91
|
-
it('should schedule the reminder and expiration from the current expiration', () => {
|
|
92
|
-
const onExpire = vi.fn();
|
|
93
|
-
const onReminder = vi.fn();
|
|
94
|
-
const timers = renderAuthSessionTimers({
|
|
95
|
-
onExpire,
|
|
96
|
-
onReminder
|
|
97
|
-
});
|
|
98
|
-
const expirationMs = Date.now() + 300_000;
|
|
99
|
-
timers.setExpiration(expirationMs);
|
|
100
|
-
act(() => {
|
|
101
|
-
vi.advanceTimersByTime(240_000);
|
|
102
|
-
});
|
|
103
|
-
expect(onReminder).toHaveBeenCalledTimes(1);
|
|
104
|
-
expect(onExpire).not.toHaveBeenCalled();
|
|
105
|
-
act(() => {
|
|
106
|
-
vi.advanceTimersByTime(60_000);
|
|
107
|
-
});
|
|
108
|
-
expect(onExpire).toHaveBeenCalledWith(expirationMs);
|
|
109
|
-
});
|
|
110
|
-
it('should respect expirations beyond the maximum browser timeout', () => {
|
|
111
|
-
const onExpire = vi.fn();
|
|
112
|
-
const timers = renderAuthSessionTimers({
|
|
113
|
-
onExpire
|
|
114
|
-
});
|
|
115
|
-
const thirtyDaysMs = 2_592_000_000;
|
|
116
|
-
const maximumBrowserTimeoutMs = 2_147_483_647;
|
|
117
|
-
const expirationMs = Date.now() + thirtyDaysMs;
|
|
118
|
-
timers.setExpiration(expirationMs);
|
|
119
|
-
act(() => {
|
|
120
|
-
vi.advanceTimersByTime(maximumBrowserTimeoutMs);
|
|
121
|
-
});
|
|
122
|
-
expect(onExpire).not.toHaveBeenCalled();
|
|
123
|
-
act(() => {
|
|
124
|
-
vi.advanceTimersByTime(thirtyDaysMs - maximumBrowserTimeoutMs - 1);
|
|
125
|
-
});
|
|
126
|
-
expect(onExpire).not.toHaveBeenCalled();
|
|
127
|
-
act(() => {
|
|
128
|
-
vi.advanceTimersByTime(1);
|
|
129
|
-
});
|
|
130
|
-
expect(onExpire).toHaveBeenCalledOnce();
|
|
131
|
-
expect(onExpire).toHaveBeenCalledWith(expirationMs);
|
|
132
|
-
});
|
|
133
|
-
it('should schedule expiration when the token expires exactly now', () => {
|
|
134
|
-
const onActivityRefresh = vi.fn();
|
|
135
|
-
const onExpire = vi.fn();
|
|
136
|
-
const onReminder = vi.fn();
|
|
137
|
-
const timers = renderAuthSessionTimers({
|
|
138
|
-
isAuthenticated: false,
|
|
139
|
-
onActivityRefresh,
|
|
140
|
-
onExpire,
|
|
141
|
-
onReminder
|
|
142
|
-
});
|
|
143
|
-
const expirationMs = Date.now();
|
|
144
|
-
timers.setExpiration(expirationMs);
|
|
145
|
-
expect(onExpire).not.toHaveBeenCalled();
|
|
146
|
-
act(() => {
|
|
147
|
-
vi.advanceTimersByTime(0);
|
|
148
|
-
});
|
|
149
|
-
expect(onExpire).toHaveBeenCalledOnce();
|
|
150
|
-
expect(onExpire).toHaveBeenCalledWith(expirationMs);
|
|
151
|
-
expect(onActivityRefresh).not.toHaveBeenCalled();
|
|
152
|
-
expect(onReminder).not.toHaveBeenCalled();
|
|
153
|
-
});
|
|
154
|
-
it('should schedule expiration when the token is already past', () => {
|
|
155
|
-
const onActivityRefresh = vi.fn();
|
|
156
|
-
const onExpire = vi.fn();
|
|
157
|
-
const onReminder = vi.fn();
|
|
158
|
-
const timers = renderAuthSessionTimers({
|
|
159
|
-
isAuthenticated: false,
|
|
160
|
-
onActivityRefresh,
|
|
161
|
-
onExpire,
|
|
162
|
-
onReminder
|
|
163
|
-
});
|
|
164
|
-
const expirationMs = Date.now() - 1;
|
|
165
|
-
timers.setExpiration(expirationMs);
|
|
166
|
-
act(() => {
|
|
167
|
-
vi.advanceTimersByTime(0);
|
|
168
|
-
});
|
|
169
|
-
expect(onExpire).toHaveBeenCalledOnce();
|
|
170
|
-
expect(onExpire).toHaveBeenCalledWith(expirationMs);
|
|
171
|
-
expect(onActivityRefresh).not.toHaveBeenCalled();
|
|
172
|
-
expect(onReminder).not.toHaveBeenCalled();
|
|
173
|
-
});
|
|
174
|
-
it('should reject a non-finite expiration without activating the session', () => {
|
|
175
|
-
const onActivityRefresh = vi.fn();
|
|
176
|
-
const onExpire = vi.fn();
|
|
177
|
-
const timers = renderAuthSessionTimers({
|
|
178
|
-
isAuthenticated: false,
|
|
179
|
-
onActivityRefresh,
|
|
180
|
-
onExpire
|
|
181
|
-
});
|
|
182
|
-
timers.setExpiration(Number.NaN);
|
|
183
|
-
timers.scheduleRefresh(true);
|
|
184
|
-
act(() => {
|
|
185
|
-
vi.advanceTimersByTime(1_000);
|
|
186
|
-
});
|
|
187
|
-
expect(timers.getCurrentExpirationMs()).toBeUndefined();
|
|
188
|
-
expect(onActivityRefresh).not.toHaveBeenCalled();
|
|
189
|
-
expect(onExpire).not.toHaveBeenCalled();
|
|
190
|
-
});
|
|
191
|
-
it('should synchronously activate on apply and deactivate on clear', () => {
|
|
192
|
-
const onActivityRefresh = vi.fn();
|
|
193
|
-
const timers = renderAuthSessionTimers({
|
|
194
|
-
isAuthenticated: false,
|
|
195
|
-
onActivityRefresh
|
|
196
|
-
});
|
|
197
|
-
timers.clear();
|
|
198
|
-
timers.setExpiration(Date.now() + 300_000);
|
|
199
|
-
timers.scheduleRefresh(true);
|
|
200
|
-
act(() => {
|
|
201
|
-
vi.advanceTimersByTime(1_000);
|
|
202
|
-
});
|
|
203
|
-
expect(onActivityRefresh).toHaveBeenCalledOnce();
|
|
204
|
-
timers.clear();
|
|
205
|
-
timers.scheduleRefresh(true);
|
|
206
|
-
act(() => {
|
|
207
|
-
vi.advanceTimersByTime(1_000);
|
|
208
|
-
});
|
|
209
|
-
expect(onActivityRefresh).toHaveBeenCalledOnce();
|
|
210
|
-
});
|
|
211
|
-
it('should reset tracked activity when replacing the expiration', () => {
|
|
212
|
-
const onActivity = vi.fn();
|
|
213
|
-
const onActivityRefresh = vi.fn();
|
|
214
|
-
const timers = renderAuthSessionTimers({
|
|
215
|
-
onActivity,
|
|
216
|
-
onActivityRefresh
|
|
217
|
-
});
|
|
218
|
-
const expirationMs = Date.now() + 300_000;
|
|
219
|
-
timers.setExpiration(expirationMs);
|
|
220
|
-
act(() => {
|
|
221
|
-
vi.advanceTimersByTime(60_000);
|
|
222
|
-
});
|
|
223
|
-
expect(timers.recordActivity('route')).toBe(true);
|
|
224
|
-
expect(onActivity).toHaveBeenCalledOnce();
|
|
225
|
-
timers.setExpiration(expirationMs);
|
|
226
|
-
expect(timers.recordActivity('route')).toBe(true);
|
|
227
|
-
expect(onActivity).toHaveBeenCalledTimes(2);
|
|
228
|
-
act(() => {
|
|
229
|
-
vi.advanceTimersByTime(120_000);
|
|
230
|
-
vi.advanceTimersByTime(1_000);
|
|
231
|
-
});
|
|
232
|
-
expect(onActivityRefresh).toHaveBeenCalledOnce();
|
|
233
|
-
});
|
|
234
|
-
it('should keep its controller and activity throttle across rerenders', () => {
|
|
235
|
-
const onActivityRefresh = vi.fn();
|
|
236
|
-
const timers = renderAuthSessionTimers({
|
|
237
|
-
onActivityRefresh
|
|
238
|
-
});
|
|
239
|
-
const initialController = timers.getController();
|
|
240
|
-
timers.setExpiration(Date.now() + 300_000);
|
|
241
|
-
act(() => {
|
|
242
|
-
vi.advanceTimersByTime(238_000);
|
|
243
|
-
window.dispatchEvent(new MouseEvent('mousemove'));
|
|
244
|
-
});
|
|
245
|
-
timers.rerender();
|
|
246
|
-
expect(timers.getController()).toBe(initialController);
|
|
247
|
-
act(() => {
|
|
248
|
-
vi.advanceTimersByTime(1);
|
|
249
|
-
window.dispatchEvent(new MouseEvent('mousemove'));
|
|
250
|
-
vi.advanceTimersByTime(999);
|
|
251
|
-
});
|
|
252
|
-
expect(onActivityRefresh).toHaveBeenCalledTimes(1);
|
|
253
|
-
});
|
|
254
|
-
it('should synchronously replace the current expiration', () => {
|
|
255
|
-
const timers = renderAuthSessionTimers();
|
|
256
|
-
const firstExpirationMs = Date.now() + 300_000;
|
|
257
|
-
const replacementExpirationMs = Date.now() + 600_000;
|
|
258
|
-
timers.setExpiration(firstExpirationMs);
|
|
259
|
-
timers.setExpiration(replacementExpirationMs);
|
|
260
|
-
expect(timers.getCurrentExpirationMs()).toBe(replacementExpirationMs);
|
|
261
|
-
});
|
|
262
|
-
});
|
|
263
|
-
function renderAuthSessionTimers({
|
|
264
|
-
isAuthenticated = true,
|
|
265
|
-
onActivity = vi.fn(),
|
|
266
|
-
onActivityRefresh = vi.fn(),
|
|
267
|
-
onExpire = vi.fn(),
|
|
268
|
-
onReminder = vi.fn()
|
|
269
|
-
} = {}) {
|
|
270
|
-
let controller;
|
|
271
|
-
const container = document.createElement('div');
|
|
272
|
-
const root = createRoot(container);
|
|
273
|
-
function SessionTimers() {
|
|
274
|
-
controller = useAuthSessionTimers({
|
|
275
|
-
isAuthenticated,
|
|
276
|
-
onActivity,
|
|
277
|
-
onActivityRefresh,
|
|
278
|
-
onExpire,
|
|
279
|
-
onReminder
|
|
280
|
-
});
|
|
281
|
-
return null;
|
|
282
|
-
}
|
|
283
|
-
act(() => {
|
|
284
|
-
root.render(React.createElement(SessionTimers));
|
|
285
|
-
});
|
|
286
|
-
timerCleanups.push(() => {
|
|
287
|
-
act(() => {
|
|
288
|
-
root.unmount();
|
|
289
|
-
});
|
|
290
|
-
});
|
|
291
|
-
const getController = () => {
|
|
292
|
-
if (!controller) {
|
|
293
|
-
throw new Error('Expected auth session timers.');
|
|
294
|
-
}
|
|
295
|
-
return controller;
|
|
296
|
-
};
|
|
297
|
-
return {
|
|
298
|
-
clear: () => getController().clear(),
|
|
299
|
-
getController,
|
|
300
|
-
getCurrentExpirationMs: () => getController().getCurrentExpirationMs(),
|
|
301
|
-
rerender: () => {
|
|
302
|
-
act(() => {
|
|
303
|
-
root.render(React.createElement(SessionTimers));
|
|
304
|
-
});
|
|
305
|
-
},
|
|
306
|
-
recordActivity: source => getController().recordActivity(source),
|
|
307
|
-
scheduleRefresh: forceRefresh => getController().scheduleRefresh(forceRefresh),
|
|
308
|
-
setExpiration: expirationMs => getController().setExpiration(expirationMs)
|
|
309
|
-
};
|
|
310
|
-
}
|
|
311
|
-
//# sourceMappingURL=useAuthSessionTimers.spec.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"useAuthSessionTimers.spec.js","names":["React","act","createRoot","afterEach","beforeEach","describe","expect","it","vi","getAuthSessionTiming","useAuthSessionTimers","timerCleanups","useFakeTimers","setSystemTime","Date","cleanup","splice","useRealTimers","nowMs","now","expirationMs","toEqual","activityTrackingStartsAt","expiresAt","refreshStartsAt","reminderStartsAt","timers","renderAuthSessionTimers","setExpiration","onActivity","fn","onActivityRefresh","advanceTimersByTime","window","dispatchEvent","MouseEvent","KeyboardEvent","toHaveBeenCalledOnce","toHaveBeenCalledTimes","sessionStartedAt","recordActivity","toBe","not","toHaveBeenCalled","onExpire","clear","onReminder","toHaveBeenCalledWith","thirtyDaysMs","maximumBrowserTimeoutMs","isAuthenticated","Number","NaN","scheduleRefresh","getCurrentExpirationMs","toBeUndefined","initialController","getController","rerender","firstExpirationMs","replacementExpirationMs","controller","container","document","createElement","root","SessionTimers","render","push","unmount","Error","source","forceRefresh"],"sources":["../../../src/providers/Auth/useAuthSessionTimers.spec.ts"],"sourcesContent":["// @vitest-environment jsdom\nimport React, { act } from 'react'\nimport { createRoot } from 'react-dom/client'\nimport { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'\n\nimport type { AuthSessionTimers } from './useAuthSessionTimers.js'\n\nimport { getAuthSessionTiming } from './sessionTiming.js'\nimport { useAuthSessionTimers } from './useAuthSessionTimers.js'\n\nconst timerCleanups: Array<() => void> = []\n\nbeforeEach(() => {\n vi.useFakeTimers()\n vi.setSystemTime(new Date('2026-01-01T00:00:00.000Z'))\n})\n\nafterEach(() => {\n for (const cleanup of timerCleanups.splice(0)) {\n cleanup()\n }\n\n vi.useRealTimers()\n})\n\ndescribe('useAuthSessionTimers', () => {\n it('should scale session timing for tokens shorter than two minutes', () => {\n const nowMs = Date.now()\n const expirationMs = nowMs + 30_000\n\n expect(getAuthSessionTiming({ expirationMs, nowMs })).toEqual({\n activityTrackingStartsAt: nowMs,\n expiresAt: expirationMs,\n refreshStartsAt: nowMs,\n reminderStartsAt: nowMs + 15_000,\n })\n })\n\n it('should return the lifecycle timing when setting an expiration', () => {\n const timers = renderAuthSessionTimers()\n const expirationMs = Date.now() + 300_000\n\n expect(timers.setExpiration(expirationMs)).toEqual({\n activityTrackingStartsAt: expirationMs - 240_000,\n expiresAt: expirationMs,\n refreshStartsAt: expirationMs - 120_000,\n reminderStartsAt: expirationMs - 60_000,\n })\n })\n\n it('should refresh at the checkpoint when activity occurred in the tracking window', () => {\n const onActivity = vi.fn()\n const onActivityRefresh = vi.fn()\n const timers = renderAuthSessionTimers({ onActivity, onActivityRefresh })\n\n timers.setExpiration(Date.now() + 300_000)\n act(() => {\n vi.advanceTimersByTime(120_000)\n window.dispatchEvent(new MouseEvent('mousemove'))\n vi.advanceTimersByTime(1_000)\n window.dispatchEvent(new KeyboardEvent('keydown'))\n vi.advanceTimersByTime(59_000)\n vi.advanceTimersByTime(1_000)\n })\n\n expect(onActivity).toHaveBeenCalledOnce()\n expect(onActivityRefresh).toHaveBeenCalledTimes(1)\n })\n\n it('should ignore activity once the expiration reminder opens', () => {\n const onActivityRefresh = vi.fn()\n const timers = renderAuthSessionTimers({ onActivityRefresh })\n const sessionStartedAt = Date.now()\n\n timers.setExpiration(sessionStartedAt + 300_000)\n act(() => {\n vi.advanceTimersByTime(60_000)\n })\n vi.setSystemTime(sessionStartedAt + 240_000)\n\n expect(timers.recordActivity('route')).toBe(false)\n expect(onActivityRefresh).not.toHaveBeenCalled()\n })\n\n it('should clear timers and listeners on logout', () => {\n const onActivityRefresh = vi.fn()\n const onExpire = vi.fn()\n const timers = renderAuthSessionTimers({ onActivityRefresh, onExpire })\n\n timers.setExpiration(Date.now() + 300_000)\n timers.clear()\n act(() => {\n window.dispatchEvent(new MouseEvent('mousemove'))\n vi.advanceTimersByTime(300_000)\n })\n\n expect(onActivityRefresh).not.toHaveBeenCalled()\n expect(onExpire).not.toHaveBeenCalled()\n })\n\n it('should schedule the reminder and expiration from the current expiration', () => {\n const onExpire = vi.fn()\n const onReminder = vi.fn()\n const timers = renderAuthSessionTimers({ onExpire, onReminder })\n const expirationMs = Date.now() + 300_000\n\n timers.setExpiration(expirationMs)\n act(() => {\n vi.advanceTimersByTime(240_000)\n })\n\n expect(onReminder).toHaveBeenCalledTimes(1)\n expect(onExpire).not.toHaveBeenCalled()\n\n act(() => {\n vi.advanceTimersByTime(60_000)\n })\n\n expect(onExpire).toHaveBeenCalledWith(expirationMs)\n })\n\n it('should respect expirations beyond the maximum browser timeout', () => {\n const onExpire = vi.fn()\n const timers = renderAuthSessionTimers({ onExpire })\n const thirtyDaysMs = 2_592_000_000\n const maximumBrowserTimeoutMs = 2_147_483_647\n const expirationMs = Date.now() + thirtyDaysMs\n\n timers.setExpiration(expirationMs)\n\n act(() => {\n vi.advanceTimersByTime(maximumBrowserTimeoutMs)\n })\n\n expect(onExpire).not.toHaveBeenCalled()\n\n act(() => {\n vi.advanceTimersByTime(thirtyDaysMs - maximumBrowserTimeoutMs - 1)\n })\n\n expect(onExpire).not.toHaveBeenCalled()\n\n act(() => {\n vi.advanceTimersByTime(1)\n })\n\n expect(onExpire).toHaveBeenCalledOnce()\n expect(onExpire).toHaveBeenCalledWith(expirationMs)\n })\n\n it('should schedule expiration when the token expires exactly now', () => {\n const onActivityRefresh = vi.fn()\n const onExpire = vi.fn()\n const onReminder = vi.fn()\n const timers = renderAuthSessionTimers({\n isAuthenticated: false,\n onActivityRefresh,\n onExpire,\n onReminder,\n })\n const expirationMs = Date.now()\n\n timers.setExpiration(expirationMs)\n\n expect(onExpire).not.toHaveBeenCalled()\n\n act(() => {\n vi.advanceTimersByTime(0)\n })\n\n expect(onExpire).toHaveBeenCalledOnce()\n expect(onExpire).toHaveBeenCalledWith(expirationMs)\n expect(onActivityRefresh).not.toHaveBeenCalled()\n expect(onReminder).not.toHaveBeenCalled()\n })\n\n it('should schedule expiration when the token is already past', () => {\n const onActivityRefresh = vi.fn()\n const onExpire = vi.fn()\n const onReminder = vi.fn()\n const timers = renderAuthSessionTimers({\n isAuthenticated: false,\n onActivityRefresh,\n onExpire,\n onReminder,\n })\n const expirationMs = Date.now() - 1\n\n timers.setExpiration(expirationMs)\n\n act(() => {\n vi.advanceTimersByTime(0)\n })\n\n expect(onExpire).toHaveBeenCalledOnce()\n expect(onExpire).toHaveBeenCalledWith(expirationMs)\n expect(onActivityRefresh).not.toHaveBeenCalled()\n expect(onReminder).not.toHaveBeenCalled()\n })\n\n it('should reject a non-finite expiration without activating the session', () => {\n const onActivityRefresh = vi.fn()\n const onExpire = vi.fn()\n const timers = renderAuthSessionTimers({\n isAuthenticated: false,\n onActivityRefresh,\n onExpire,\n })\n\n timers.setExpiration(Number.NaN)\n timers.scheduleRefresh(true)\n act(() => {\n vi.advanceTimersByTime(1_000)\n })\n\n expect(timers.getCurrentExpirationMs()).toBeUndefined()\n expect(onActivityRefresh).not.toHaveBeenCalled()\n expect(onExpire).not.toHaveBeenCalled()\n })\n\n it('should synchronously activate on apply and deactivate on clear', () => {\n const onActivityRefresh = vi.fn()\n const timers = renderAuthSessionTimers({ isAuthenticated: false, onActivityRefresh })\n\n timers.clear()\n timers.setExpiration(Date.now() + 300_000)\n timers.scheduleRefresh(true)\n act(() => {\n vi.advanceTimersByTime(1_000)\n })\n\n expect(onActivityRefresh).toHaveBeenCalledOnce()\n\n timers.clear()\n timers.scheduleRefresh(true)\n act(() => {\n vi.advanceTimersByTime(1_000)\n })\n\n expect(onActivityRefresh).toHaveBeenCalledOnce()\n })\n\n it('should reset tracked activity when replacing the expiration', () => {\n const onActivity = vi.fn()\n const onActivityRefresh = vi.fn()\n const timers = renderAuthSessionTimers({ onActivity, onActivityRefresh })\n const expirationMs = Date.now() + 300_000\n\n timers.setExpiration(expirationMs)\n act(() => {\n vi.advanceTimersByTime(60_000)\n })\n expect(timers.recordActivity('route')).toBe(true)\n expect(onActivity).toHaveBeenCalledOnce()\n\n timers.setExpiration(expirationMs)\n\n expect(timers.recordActivity('route')).toBe(true)\n expect(onActivity).toHaveBeenCalledTimes(2)\n\n act(() => {\n vi.advanceTimersByTime(120_000)\n vi.advanceTimersByTime(1_000)\n })\n\n expect(onActivityRefresh).toHaveBeenCalledOnce()\n })\n\n it('should keep its controller and activity throttle across rerenders', () => {\n const onActivityRefresh = vi.fn()\n const timers = renderAuthSessionTimers({ onActivityRefresh })\n const initialController = timers.getController()\n\n timers.setExpiration(Date.now() + 300_000)\n act(() => {\n vi.advanceTimersByTime(238_000)\n window.dispatchEvent(new MouseEvent('mousemove'))\n })\n timers.rerender()\n\n expect(timers.getController()).toBe(initialController)\n\n act(() => {\n vi.advanceTimersByTime(1)\n window.dispatchEvent(new MouseEvent('mousemove'))\n vi.advanceTimersByTime(999)\n })\n\n expect(onActivityRefresh).toHaveBeenCalledTimes(1)\n })\n\n it('should synchronously replace the current expiration', () => {\n const timers = renderAuthSessionTimers()\n const firstExpirationMs = Date.now() + 300_000\n const replacementExpirationMs = Date.now() + 600_000\n\n timers.setExpiration(firstExpirationMs)\n timers.setExpiration(replacementExpirationMs)\n\n expect(timers.getCurrentExpirationMs()).toBe(replacementExpirationMs)\n })\n})\n\nfunction renderAuthSessionTimers({\n isAuthenticated = true,\n onActivity = vi.fn(),\n onActivityRefresh = vi.fn(),\n onExpire = vi.fn(),\n onReminder = vi.fn(),\n}: {\n isAuthenticated?: boolean\n onActivity?: () => void\n onActivityRefresh?: () => void\n onExpire?: (expirationMs: number) => void\n onReminder?: () => void\n} = {}): RenderedAuthSessionTimers {\n let controller: AuthSessionTimers | undefined\n const container = document.createElement('div')\n const root = createRoot(container)\n\n function SessionTimers() {\n controller = useAuthSessionTimers({\n isAuthenticated,\n onActivity,\n onActivityRefresh,\n onExpire,\n onReminder,\n })\n\n return null\n }\n\n act(() => {\n root.render(React.createElement(SessionTimers))\n })\n\n timerCleanups.push(() => {\n act(() => {\n root.unmount()\n })\n })\n\n const getController = (): AuthSessionTimers => {\n if (!controller) {\n throw new Error('Expected auth session timers.')\n }\n\n return controller\n }\n\n return {\n clear: () => getController().clear(),\n getController,\n getCurrentExpirationMs: () => getController().getCurrentExpirationMs(),\n rerender: () => {\n act(() => {\n root.render(React.createElement(SessionTimers))\n })\n },\n recordActivity: (source) => getController().recordActivity(source),\n scheduleRefresh: (forceRefresh) => getController().scheduleRefresh(forceRefresh),\n setExpiration: (expirationMs) => getController().setExpiration(expirationMs),\n }\n}\n\ntype RenderedAuthSessionTimers = AuthSessionTimers & {\n getController: () => AuthSessionTimers\n recordActivity: (source: 'focus' | 'keydown' | 'mousemove' | 'route') => boolean\n rerender: () => void\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
// @vitest-environment happy-dom
|
|
2
|
-
import { act, createElement, useEffect } from 'react';
|
|
3
|
-
import { createRoot } from 'react-dom/client';
|
|
4
|
-
import { afterEach, beforeEach, expect, test, vi } from 'vitest';
|
|
5
|
-
import { RouteTransitionProvider, useRouteTransition } from '../index.js';
|
|
6
|
-
import { ProgressBar } from './index.js';
|
|
7
|
-
let container;
|
|
8
|
-
let root;
|
|
9
|
-
beforeEach(() => {
|
|
10
|
-
globalThis.IS_REACT_ACT_ENVIRONMENT = true;
|
|
11
|
-
container = document.createElement('div');
|
|
12
|
-
document.body.appendChild(container);
|
|
13
|
-
root = createRoot(container);
|
|
14
|
-
});
|
|
15
|
-
afterEach(() => {
|
|
16
|
-
act(() => root.unmount());
|
|
17
|
-
container.remove();
|
|
18
|
-
vi.useRealTimers();
|
|
19
|
-
});
|
|
20
|
-
test('does not show progress for transitions that finish before the initial delay', async () => {
|
|
21
|
-
vi.useFakeTimers();
|
|
22
|
-
const FastTransition = () => {
|
|
23
|
-
const {
|
|
24
|
-
holdRouteTransition
|
|
25
|
-
} = useRouteTransition();
|
|
26
|
-
useEffect(() => {
|
|
27
|
-
const releaseRouteTransition = holdRouteTransition();
|
|
28
|
-
const timeout = setTimeout(releaseRouteTransition, 50);
|
|
29
|
-
return () => {
|
|
30
|
-
clearTimeout(timeout);
|
|
31
|
-
releaseRouteTransition();
|
|
32
|
-
};
|
|
33
|
-
}, [holdRouteTransition]);
|
|
34
|
-
return null;
|
|
35
|
-
};
|
|
36
|
-
await act(async () => {
|
|
37
|
-
root.render(createElement(RouteTransitionProvider, null, createElement(ProgressBar), createElement(FastTransition)));
|
|
38
|
-
});
|
|
39
|
-
await act(async () => {
|
|
40
|
-
await vi.advanceTimersByTimeAsync(50);
|
|
41
|
-
});
|
|
42
|
-
expect(container.querySelector('.progress-bar')).toBeNull();
|
|
43
|
-
});
|
|
44
|
-
//# sourceMappingURL=index.spec.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.spec.js","names":["act","createElement","useEffect","createRoot","afterEach","beforeEach","expect","test","vi","RouteTransitionProvider","useRouteTransition","ProgressBar","container","root","globalThis","IS_REACT_ACT_ENVIRONMENT","document","body","appendChild","unmount","remove","useRealTimers","useFakeTimers","FastTransition","holdRouteTransition","releaseRouteTransition","timeout","setTimeout","clearTimeout","render","advanceTimersByTimeAsync","querySelector","toBeNull"],"sources":["../../../../src/providers/RouteTransition/ProgressBar/index.spec.ts"],"sourcesContent":["// @vitest-environment happy-dom\n\nimport { act, createElement, useEffect } from 'react'\nimport { createRoot, type Root } from 'react-dom/client'\nimport { afterEach, beforeEach, expect, test, vi } from 'vitest'\n\nimport { RouteTransitionProvider, useRouteTransition } from '../index.js'\nimport { ProgressBar } from './index.js'\n\nlet container: HTMLDivElement\nlet root: Root\n\nbeforeEach(() => {\n globalThis.IS_REACT_ACT_ENVIRONMENT = true\n container = document.createElement('div')\n document.body.appendChild(container)\n root = createRoot(container)\n})\n\nafterEach(() => {\n act(() => root.unmount())\n container.remove()\n vi.useRealTimers()\n})\n\ntest('does not show progress for transitions that finish before the initial delay', async () => {\n vi.useFakeTimers()\n\n const FastTransition = () => {\n const { holdRouteTransition } = useRouteTransition()\n\n useEffect(() => {\n const releaseRouteTransition = holdRouteTransition()\n const timeout = setTimeout(releaseRouteTransition, 50)\n\n return () => {\n clearTimeout(timeout)\n releaseRouteTransition()\n }\n }, [holdRouteTransition])\n\n return null\n }\n\n await act(async () => {\n root.render(\n createElement(\n RouteTransitionProvider,\n null,\n createElement(ProgressBar),\n createElement(FastTransition),\n ),\n )\n })\n\n await act(async () => {\n await vi.advanceTimersByTimeAsync(50)\n })\n\n expect(container.querySelector('.progress-bar')).toBeNull()\n})\n"],"mappings":"AAAA;AAEA,SAASA,GAAG,EAAEC,aAAa,EAAEC,SAAS,QAAQ;AAC9C,SAASC,UAAU,QAAmB;AACtC,SAASC,SAAS,EAAEC,UAAU,EAAEC,MAAM,EAAEC,IAAI,EAAEC,EAAE,QAAQ;AAExD,SAASC,uBAAuB,EAAEC,kBAAkB,QAAQ;AAC5D,SAASC,WAAW,QAAQ;AAE5B,IAAIC,SAAA;AACJ,IAAIC,IAAA;AAEJR,UAAA,CAAW;EACTS,UAAA,CAAWC,wBAAwB,GAAG;EACtCH,SAAA,GAAYI,QAAA,CAASf,aAAa,CAAC;EACnCe,QAAA,CAASC,IAAI,CAACC,WAAW,CAACN,SAAA;EAC1BC,IAAA,GAAOV,UAAA,CAAWS,SAAA;AACpB;AAEAR,SAAA,CAAU;EACRJ,GAAA,CAAI,MAAMa,IAAA,CAAKM,OAAO;EACtBP,SAAA,CAAUQ,MAAM;EAChBZ,EAAA,CAAGa,aAAa;AAClB;AAEAd,IAAA,CAAK,+EAA+E;EAClFC,EAAA,CAAGc,aAAa;EAEhB,MAAMC,cAAA,GAAiBA,CAAA;IACrB,MAAM;MAAEC;IAAmB,CAAE,GAAGd,kBAAA;IAEhCR,SAAA,CAAU;MACR,MAAMuB,sBAAA,GAAyBD,mBAAA;MAC/B,MAAME,OAAA,GAAUC,UAAA,CAAWF,sBAAA,EAAwB;MAEnD,OAAO;QACLG,YAAA,CAAaF,OAAA;QACbD,sBAAA;MACF;IACF,GAAG,CAACD,mBAAA,CAAoB;IAExB,OAAO;EACT;EAEA,MAAMxB,GAAA,CAAI;IACRa,IAAA,CAAKgB,MAAM,CACT5B,aAAA,CACEQ,uBAAA,EACA,MACAR,aAAA,CAAcU,WAAA,GACdV,aAAA,CAAcsB,cAAA;EAGpB;EAEA,MAAMvB,GAAA,CAAI;IACR,MAAMQ,EAAA,CAAGsB,wBAAwB,CAAC;EACpC;EAEAxB,MAAA,CAAOM,SAAA,CAAUmB,aAAa,CAAC,kBAAkBC,QAAQ;AAC3D","ignoreList":[]}
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it, vi } from 'vitest';
|
|
2
|
-
import { buildColumnState } from './index.js';
|
|
3
|
-
vi.mock('../../../exports/client/index.js', () => ({
|
|
4
|
-
SortColumn: () => null
|
|
5
|
-
}));
|
|
6
|
-
describe('buildColumnState', () => {
|
|
7
|
-
it('should handle fields with admin components explicitly set to undefined', () => {
|
|
8
|
-
const clientField = {
|
|
9
|
-
name: 'title',
|
|
10
|
-
type: 'text'
|
|
11
|
-
};
|
|
12
|
-
const serverField = {
|
|
13
|
-
name: 'title',
|
|
14
|
-
type: 'text',
|
|
15
|
-
admin: {
|
|
16
|
-
components: undefined
|
|
17
|
-
}
|
|
18
|
-
};
|
|
19
|
-
const columns = buildColumnState({
|
|
20
|
-
clientFields: [clientField],
|
|
21
|
-
collectionSlug: 'posts',
|
|
22
|
-
customCellProps: {},
|
|
23
|
-
dataType: 'monomorphic',
|
|
24
|
-
docs: [],
|
|
25
|
-
enableRowSelections: false,
|
|
26
|
-
fieldPermissions: true,
|
|
27
|
-
i18n: {
|
|
28
|
-
t: vi.fn()
|
|
29
|
-
},
|
|
30
|
-
payload: {
|
|
31
|
-
importMap: {}
|
|
32
|
-
},
|
|
33
|
-
serverFields: [serverField],
|
|
34
|
-
useAsTitle: 'title'
|
|
35
|
-
});
|
|
36
|
-
expect(columns).toHaveLength(1);
|
|
37
|
-
expect(columns[0].CustomLabel).toBeUndefined();
|
|
38
|
-
});
|
|
39
|
-
});
|
|
40
|
-
//# sourceMappingURL=index.spec.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.spec.js","names":["describe","expect","it","vi","buildColumnState","mock","SortColumn","clientField","name","type","serverField","admin","components","undefined","columns","clientFields","collectionSlug","customCellProps","dataType","docs","enableRowSelections","fieldPermissions","i18n","t","fn","payload","importMap","serverFields","useAsTitle","toHaveLength","CustomLabel","toBeUndefined"],"sources":["../../../../src/providers/TableColumns/buildColumnState/index.spec.ts"],"sourcesContent":["import type { I18nClient } from '@payloadcms/translations'\nimport type { ClientField, Field, Payload } from 'payload'\n\nimport { describe, expect, it, vi } from 'vitest'\n\nimport { buildColumnState } from './index.js'\n\nvi.mock('../../../exports/client/index.js', () => ({\n SortColumn: () => null,\n}))\n\ndescribe('buildColumnState', () => {\n it('should handle fields with admin components explicitly set to undefined', () => {\n const clientField: ClientField = {\n name: 'title',\n type: 'text',\n }\n const serverField: Field = {\n name: 'title',\n type: 'text',\n admin: {\n components: undefined,\n },\n }\n\n const columns = buildColumnState({\n clientFields: [clientField],\n collectionSlug: 'posts',\n customCellProps: {},\n dataType: 'monomorphic',\n docs: [],\n enableRowSelections: false,\n fieldPermissions: true,\n i18n: {\n t: vi.fn(),\n } as unknown as I18nClient,\n payload: {\n importMap: {},\n } as unknown as Payload,\n serverFields: [serverField],\n useAsTitle: 'title',\n })\n\n expect(columns).toHaveLength(1)\n expect(columns[0].CustomLabel).toBeUndefined()\n })\n})\n"],"mappings":"AAGA,SAASA,QAAQ,EAAEC,MAAM,EAAEC,EAAE,EAAEC,EAAE,QAAQ;AAEzC,SAASC,gBAAgB,QAAQ;AAEjCD,EAAA,CAAGE,IAAI,CAAC,oCAAoC,OAAO;EACjDC,UAAA,EAAYA,CAAA,KAAM;AACpB;AAEAN,QAAA,CAAS,oBAAoB;EAC3BE,EAAA,CAAG,0EAA0E;IAC3E,MAAMK,WAAA,GAA2B;MAC/BC,IAAA,EAAM;MACNC,IAAA,EAAM;IACR;IACA,MAAMC,WAAA,GAAqB;MACzBF,IAAA,EAAM;MACNC,IAAA,EAAM;MACNE,KAAA,EAAO;QACLC,UAAA,EAAYC;MACd;IACF;IAEA,MAAMC,OAAA,GAAUV,gBAAA,CAAiB;MAC/BW,YAAA,EAAc,CAACR,WAAA,CAAY;MAC3BS,cAAA,EAAgB;MAChBC,eAAA,EAAiB,CAAC;MAClBC,QAAA,EAAU;MACVC,IAAA,EAAM,EAAE;MACRC,mBAAA,EAAqB;MACrBC,gBAAA,EAAkB;MAClBC,IAAA,EAAM;QACJC,CAAA,EAAGpB,EAAA,CAAGqB,EAAE;MACV;MACAC,OAAA,EAAS;QACPC,SAAA,EAAW,CAAC;MACd;MACAC,YAAA,EAAc,CAACjB,WAAA,CAAY;MAC3BkB,UAAA,EAAY;IACd;IAEA3B,MAAA,CAAOa,OAAA,EAASe,YAAY,CAAC;IAC7B5B,MAAA,CAAOa,OAAO,CAAC,EAAE,CAACgB,WAAW,EAAEC,aAAa;EAC9C;AACF","ignoreList":[]}
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest';
|
|
2
|
-
import { appendCacheTag } from './appendCacheTag.js';
|
|
3
|
-
describe('appendCacheTag', () => {
|
|
4
|
-
it('should return the url unchanged when cacheTag is undefined', () => {
|
|
5
|
-
expect(appendCacheTag('https://example.com/image.jpg', undefined)).toBe('https://example.com/image.jpg');
|
|
6
|
-
});
|
|
7
|
-
it('should return the url unchanged when cacheTag is false', () => {
|
|
8
|
-
expect(appendCacheTag('https://example.com/image.jpg', false)).toBe('https://example.com/image.jpg');
|
|
9
|
-
});
|
|
10
|
-
it('should return the url unchanged when cacheTag is empty string', () => {
|
|
11
|
-
expect(appendCacheTag('https://example.com/image.jpg', '')).toBe('https://example.com/image.jpg');
|
|
12
|
-
});
|
|
13
|
-
it('should append the cache tag with ? when the url has no query string', () => {
|
|
14
|
-
const result = appendCacheTag('https://example.com/image.jpg', '2024-01-01T00:00:00.000Z');
|
|
15
|
-
expect(result).toBe('https://example.com/image.jpg?2024-01-01T00%3A00%3A00.000Z');
|
|
16
|
-
});
|
|
17
|
-
it('should append the cache tag with & when the url already has a query string', () => {
|
|
18
|
-
const result = appendCacheTag('https://example.com/image.jpg?w=800&q=75', '2024-01-01T00:00:00.000Z');
|
|
19
|
-
expect(result).toBe('https://example.com/image.jpg?w=800&q=75&2024-01-01T00%3A00%3A00.000Z');
|
|
20
|
-
});
|
|
21
|
-
it('should URI-encode the cache tag value', () => {
|
|
22
|
-
const result = appendCacheTag('/image.jpg', '2024-06-15T12:30:00.000Z');
|
|
23
|
-
expect(result).toBe('/image.jpg?2024-06-15T12%3A30%3A00.000Z');
|
|
24
|
-
});
|
|
25
|
-
it('should work with relative urls', () => {
|
|
26
|
-
const result = appendCacheTag('/uploads/photo.png', '2024-01-01T00:00:00.000Z');
|
|
27
|
-
expect(result).toBe('/uploads/photo.png?2024-01-01T00%3A00%3A00.000Z');
|
|
28
|
-
});
|
|
29
|
-
it('should work with relative urls that already have a query string', () => {
|
|
30
|
-
const result = appendCacheTag('/uploads/photo.png?size=large', '2024-01-01T00:00:00.000Z');
|
|
31
|
-
expect(result).toBe('/uploads/photo.png?size=large&2024-01-01T00%3A00%3A00.000Z');
|
|
32
|
-
});
|
|
33
|
-
});
|
|
34
|
-
//# sourceMappingURL=appendCacheTag.spec.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"appendCacheTag.spec.js","names":["describe","expect","it","appendCacheTag","undefined","toBe","result"],"sources":["../../src/utilities/appendCacheTag.spec.ts"],"sourcesContent":["import { describe, expect, it } from 'vitest'\n\nimport { appendCacheTag } from './appendCacheTag.js'\n\ndescribe('appendCacheTag', () => {\n it('should return the url unchanged when cacheTag is undefined', () => {\n expect(appendCacheTag('https://example.com/image.jpg', undefined)).toBe(\n 'https://example.com/image.jpg',\n )\n })\n\n it('should return the url unchanged when cacheTag is false', () => {\n expect(appendCacheTag('https://example.com/image.jpg', false)).toBe(\n 'https://example.com/image.jpg',\n )\n })\n\n it('should return the url unchanged when cacheTag is empty string', () => {\n expect(appendCacheTag('https://example.com/image.jpg', '')).toBe(\n 'https://example.com/image.jpg',\n )\n })\n\n it('should append the cache tag with ? when the url has no query string', () => {\n const result = appendCacheTag('https://example.com/image.jpg', '2024-01-01T00:00:00.000Z')\n expect(result).toBe('https://example.com/image.jpg?2024-01-01T00%3A00%3A00.000Z')\n })\n\n it('should append the cache tag with & when the url already has a query string', () => {\n const result = appendCacheTag(\n 'https://example.com/image.jpg?w=800&q=75',\n '2024-01-01T00:00:00.000Z',\n )\n expect(result).toBe('https://example.com/image.jpg?w=800&q=75&2024-01-01T00%3A00%3A00.000Z')\n })\n\n it('should URI-encode the cache tag value', () => {\n const result = appendCacheTag('/image.jpg', '2024-06-15T12:30:00.000Z')\n expect(result).toBe('/image.jpg?2024-06-15T12%3A30%3A00.000Z')\n })\n\n it('should work with relative urls', () => {\n const result = appendCacheTag('/uploads/photo.png', '2024-01-01T00:00:00.000Z')\n expect(result).toBe('/uploads/photo.png?2024-01-01T00%3A00%3A00.000Z')\n })\n\n it('should work with relative urls that already have a query string', () => {\n const result = appendCacheTag('/uploads/photo.png?size=large', '2024-01-01T00:00:00.000Z')\n expect(result).toBe('/uploads/photo.png?size=large&2024-01-01T00%3A00%3A00.000Z')\n })\n})\n"],"mappings":"AAAA,SAASA,QAAQ,EAAEC,MAAM,EAAEC,EAAE,QAAQ;AAErC,SAASC,cAAc,QAAQ;AAE/BH,QAAA,CAAS,kBAAkB;EACzBE,EAAA,CAAG,8DAA8D;IAC/DD,MAAA,CAAOE,cAAA,CAAe,iCAAiCC,SAAA,GAAYC,IAAI,CACrE;EAEJ;EAEAH,EAAA,CAAG,0DAA0D;IAC3DD,MAAA,CAAOE,cAAA,CAAe,iCAAiC,QAAQE,IAAI,CACjE;EAEJ;EAEAH,EAAA,CAAG,iEAAiE;IAClED,MAAA,CAAOE,cAAA,CAAe,iCAAiC,KAAKE,IAAI,CAC9D;EAEJ;EAEAH,EAAA,CAAG,uEAAuE;IACxE,MAAMI,MAAA,GAASH,cAAA,CAAe,iCAAiC;IAC/DF,MAAA,CAAOK,MAAA,EAAQD,IAAI,CAAC;EACtB;EAEAH,EAAA,CAAG,8EAA8E;IAC/E,MAAMI,MAAA,GAASH,cAAA,CACb,4CACA;IAEFF,MAAA,CAAOK,MAAA,EAAQD,IAAI,CAAC;EACtB;EAEAH,EAAA,CAAG,yCAAyC;IAC1C,MAAMI,MAAA,GAASH,cAAA,CAAe,cAAc;IAC5CF,MAAA,CAAOK,MAAA,EAAQD,IAAI,CAAC;EACtB;EAEAH,EAAA,CAAG,kCAAkC;IACnC,MAAMI,MAAA,GAASH,cAAA,CAAe,sBAAsB;IACpDF,MAAA,CAAOK,MAAA,EAAQD,IAAI,CAAC;EACtB;EAEAH,EAAA,CAAG,mEAAmE;IACpE,MAAMI,MAAA,GAASH,cAAA,CAAe,iCAAiC;IAC/DF,MAAA,CAAOK,MAAA,EAAQD,IAAI,CAAC;EACtB;AACF","ignoreList":[]}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
2
|
-
import { formatAbsoluteURL } from './formatAbsoluteURL.js';
|
|
3
|
-
describe('formatAbsoluteURL', () => {
|
|
4
|
-
beforeEach(() => {
|
|
5
|
-
vi.stubGlobal('window', {
|
|
6
|
-
location: {
|
|
7
|
-
origin: 'https://admin.example.com'
|
|
8
|
-
}
|
|
9
|
-
});
|
|
10
|
-
});
|
|
11
|
-
afterEach(() => {
|
|
12
|
-
vi.unstubAllGlobals();
|
|
13
|
-
});
|
|
14
|
-
it.each([['/preview', 'https://admin.example.com/preview'], ['preview?draft=true', 'https://admin.example.com/preview?draft=true'], ['../preview', 'https://admin.example.com/preview'], ['?draft=true', 'https://admin.example.com/?draft=true'], ['#preview', 'https://admin.example.com/#preview'], ['//preview.example.com/page', 'https://preview.example.com/page'], ['', 'https://admin.example.com/']])('should resolve relative URL %s against the admin origin', (input, expected) => {
|
|
15
|
-
expect(formatAbsoluteURL(input)).toBe(expected);
|
|
16
|
-
});
|
|
17
|
-
it.each(['http://preview.example.com', 'https://preview.example.com', 'https://preview.example.com:443/one/../two?draft=true#preview'])('should preserve absolute HTTP(S) URL %s', input => {
|
|
18
|
-
expect(formatAbsoluteURL(input)).toBe(input);
|
|
19
|
-
});
|
|
20
|
-
it.each(['mailto:editor@example.com', 'file:///preview.html'])('should return undefined for unsupported URL %s', input => {
|
|
21
|
-
expect(formatAbsoluteURL(input)).toBeUndefined();
|
|
22
|
-
});
|
|
23
|
-
it.each(['http://', 'https://', 'https://[invalid'])('should return undefined for invalid URL %s', input => {
|
|
24
|
-
expect(formatAbsoluteURL(input)).toBeUndefined();
|
|
25
|
-
});
|
|
26
|
-
});
|
|
27
|
-
//# sourceMappingURL=formatAbsoluteURL.spec.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"formatAbsoluteURL.spec.js","names":["afterEach","beforeEach","describe","expect","it","vi","formatAbsoluteURL","stubGlobal","location","origin","unstubAllGlobals","each","input","expected","toBe","toBeUndefined"],"sources":["../../src/utilities/formatAbsoluteURL.spec.ts"],"sourcesContent":["import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'\n\nimport { formatAbsoluteURL } from './formatAbsoluteURL.js'\n\ndescribe('formatAbsoluteURL', () => {\n beforeEach(() => {\n vi.stubGlobal('window', {\n location: { origin: 'https://admin.example.com' },\n })\n })\n\n afterEach(() => {\n vi.unstubAllGlobals()\n })\n\n it.each([\n ['/preview', 'https://admin.example.com/preview'],\n ['preview?draft=true', 'https://admin.example.com/preview?draft=true'],\n ['../preview', 'https://admin.example.com/preview'],\n ['?draft=true', 'https://admin.example.com/?draft=true'],\n ['#preview', 'https://admin.example.com/#preview'],\n ['//preview.example.com/page', 'https://preview.example.com/page'],\n ['', 'https://admin.example.com/'],\n ])('should resolve relative URL %s against the admin origin', (input, expected) => {\n expect(formatAbsoluteURL(input)).toBe(expected)\n })\n\n it.each([\n 'http://preview.example.com',\n 'https://preview.example.com',\n 'https://preview.example.com:443/one/../two?draft=true#preview',\n ])('should preserve absolute HTTP(S) URL %s', (input) => {\n expect(formatAbsoluteURL(input)).toBe(input)\n })\n\n it.each(['mailto:editor@example.com', 'file:///preview.html'])(\n 'should return undefined for unsupported URL %s',\n (input) => {\n expect(formatAbsoluteURL(input)).toBeUndefined()\n },\n )\n\n it.each(['http://', 'https://', 'https://[invalid'])(\n 'should return undefined for invalid URL %s',\n (input) => {\n expect(formatAbsoluteURL(input)).toBeUndefined()\n },\n )\n})\n"],"mappings":"AAAA,SAASA,SAAS,EAAEC,UAAU,EAAEC,QAAQ,EAAEC,MAAM,EAAEC,EAAE,EAAEC,EAAE,QAAQ;AAEhE,SAASC,iBAAiB,QAAQ;AAElCJ,QAAA,CAAS,qBAAqB;EAC5BD,UAAA,CAAW;IACTI,EAAA,CAAGE,UAAU,CAAC,UAAU;MACtBC,QAAA,EAAU;QAAEC,MAAA,EAAQ;MAA4B;IAClD;EACF;EAEAT,SAAA,CAAU;IACRK,EAAA,CAAGK,gBAAgB;EACrB;EAEAN,EAAA,CAAGO,IAAI,CAAC,CACN,CAAC,YAAY,oCAAoC,EACjD,CAAC,sBAAsB,+CAA+C,EACtE,CAAC,cAAc,oCAAoC,EACnD,CAAC,eAAe,wCAAwC,EACxD,CAAC,YAAY,qCAAqC,EAClD,CAAC,8BAA8B,mCAAmC,EAClE,CAAC,IAAI,6BAA6B,CACnC,EAAE,2DAA2D,CAACC,KAAA,EAAOC,QAAA;IACpEV,MAAA,CAAOG,iBAAA,CAAkBM,KAAA,GAAQE,IAAI,CAACD,QAAA;EACxC;EAEAT,EAAA,CAAGO,IAAI,CAAC,CACN,8BACA,+BACA,gEACD,EAAE,2CAA4CC,KAAA;IAC7CT,MAAA,CAAOG,iBAAA,CAAkBM,KAAA,GAAQE,IAAI,CAACF,KAAA;EACxC;EAEAR,EAAA,CAAGO,IAAI,CAAC,CAAC,6BAA6B,uBAAuB,EAC3D,kDACCC,KAAA;IACCT,MAAA,CAAOG,iBAAA,CAAkBM,KAAA,GAAQG,aAAa;EAChD;EAGFX,EAAA,CAAGO,IAAI,CAAC,CAAC,WAAW,YAAY,mBAAmB,EACjD,8CACCC,KAAA;IACCT,MAAA,CAAOG,iBAAA,CAAkBM,KAAA,GAAQG,aAAa;EAChD;AAEJ","ignoreList":[]}
|
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest';
|
|
2
|
-
import { formatMetadata } from './formatMetadata.js';
|
|
3
|
-
describe('formatMetadata', () => {
|
|
4
|
-
it('should handle a string title with titleSuffix', async () => {
|
|
5
|
-
const result = await formatMetadata({
|
|
6
|
-
serverURL: 'http://localhost:3000',
|
|
7
|
-
title: 'Dashboard',
|
|
8
|
-
titleSuffix: '- My CMS'
|
|
9
|
-
});
|
|
10
|
-
expect(result.title).toBe('Dashboard - My CMS');
|
|
11
|
-
});
|
|
12
|
-
it('should apply titleSuffix to default and template fields of a TemplateString title object', async () => {
|
|
13
|
-
const result = await formatMetadata({
|
|
14
|
-
serverURL: 'http://localhost:3000',
|
|
15
|
-
title: {
|
|
16
|
-
default: 'Dashboard',
|
|
17
|
-
template: '%s | Dashboard'
|
|
18
|
-
},
|
|
19
|
-
titleSuffix: '- My CMS'
|
|
20
|
-
});
|
|
21
|
-
expect(typeof result.title).toBe('object');
|
|
22
|
-
expect(result.title.default).toBe('Dashboard - My CMS');
|
|
23
|
-
expect(result.title.template).toBe('%s | Dashboard - My CMS');
|
|
24
|
-
});
|
|
25
|
-
it('should use the TemplateString default for ogTitle when title is a TemplateString object', async () => {
|
|
26
|
-
const result = await formatMetadata({
|
|
27
|
-
serverURL: 'http://localhost:3000',
|
|
28
|
-
title: {
|
|
29
|
-
default: 'My CMS',
|
|
30
|
-
template: '%s | My CMS'
|
|
31
|
-
},
|
|
32
|
-
titleSuffix: '- Payload'
|
|
33
|
-
});
|
|
34
|
-
// OG title must be a plain string — extract from TemplateString.default and append titleSuffix
|
|
35
|
-
expect(result.openGraph?.title).toBe('My CMS - Payload');
|
|
36
|
-
});
|
|
37
|
-
it('should use the TemplateString absolute for ogTitle when title has absolute property', async () => {
|
|
38
|
-
const result = await formatMetadata({
|
|
39
|
-
serverURL: 'http://localhost:3000',
|
|
40
|
-
title: {
|
|
41
|
-
absolute: 'My CMS Absolute'
|
|
42
|
-
},
|
|
43
|
-
titleSuffix: '- Payload'
|
|
44
|
-
});
|
|
45
|
-
expect(result.openGraph?.title).toBe('My CMS Absolute - Payload');
|
|
46
|
-
});
|
|
47
|
-
it('should apply titleSuffix to the absolute field of a TemplateString title object', async () => {
|
|
48
|
-
const result = await formatMetadata({
|
|
49
|
-
serverURL: 'http://localhost:3000',
|
|
50
|
-
title: {
|
|
51
|
-
absolute: 'My CMS Absolute'
|
|
52
|
-
},
|
|
53
|
-
titleSuffix: '- Payload'
|
|
54
|
-
});
|
|
55
|
-
expect(typeof result.title).toBe('object');
|
|
56
|
-
expect(result.title.absolute).toBe('My CMS Absolute - Payload');
|
|
57
|
-
});
|
|
58
|
-
it('should use openGraph.title string over incomingMetadata.title for ogTitle', async () => {
|
|
59
|
-
const result = await formatMetadata({
|
|
60
|
-
serverURL: 'http://localhost:3000',
|
|
61
|
-
title: 'My CMS',
|
|
62
|
-
titleSuffix: '- Payload',
|
|
63
|
-
openGraph: {
|
|
64
|
-
title: 'Custom OG Title'
|
|
65
|
-
}
|
|
66
|
-
});
|
|
67
|
-
expect(result.openGraph?.title).toBe('Custom OG Title');
|
|
68
|
-
});
|
|
69
|
-
it('should return undefined for metaTitle when no title and no titleSuffix are set', async () => {
|
|
70
|
-
const result = await formatMetadata({
|
|
71
|
-
serverURL: 'http://localhost:3000'
|
|
72
|
-
});
|
|
73
|
-
expect(result.title).toBeUndefined();
|
|
74
|
-
});
|
|
75
|
-
it('should return just the title when no titleSuffix is set', async () => {
|
|
76
|
-
const result = await formatMetadata({
|
|
77
|
-
serverURL: 'http://localhost:3000',
|
|
78
|
-
title: 'My CMS'
|
|
79
|
-
});
|
|
80
|
-
expect(result.title).toBe('My CMS');
|
|
81
|
-
});
|
|
82
|
-
});
|
|
83
|
-
//# sourceMappingURL=formatMetadata.spec.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"formatMetadata.spec.js","names":["describe","expect","it","formatMetadata","result","serverURL","title","titleSuffix","toBe","default","template","openGraph","absolute","toBeUndefined"],"sources":["../../src/utilities/formatMetadata.spec.ts"],"sourcesContent":["import { describe, expect, it } from 'vitest'\n\nimport { formatMetadata } from './formatMetadata.js'\n\ndescribe('formatMetadata', () => {\n it('should handle a string title with titleSuffix', async () => {\n const result = await formatMetadata({\n serverURL: 'http://localhost:3000',\n title: 'Dashboard',\n titleSuffix: '- My CMS',\n })\n\n expect(result.title).toBe('Dashboard - My CMS')\n })\n\n it('should apply titleSuffix to default and template fields of a TemplateString title object', async () => {\n const result = await formatMetadata({\n serverURL: 'http://localhost:3000',\n title: { default: 'Dashboard', template: '%s | Dashboard' },\n titleSuffix: '- My CMS',\n })\n\n expect(typeof result.title).toBe('object')\n expect((result.title as { default: string; template: string }).default).toBe(\n 'Dashboard - My CMS',\n )\n expect((result.title as { default: string; template: string }).template).toBe(\n '%s | Dashboard - My CMS',\n )\n })\n\n it('should use the TemplateString default for ogTitle when title is a TemplateString object', async () => {\n const result = await formatMetadata({\n serverURL: 'http://localhost:3000',\n title: { default: 'My CMS', template: '%s | My CMS' },\n titleSuffix: '- Payload',\n })\n\n // OG title must be a plain string — extract from TemplateString.default and append titleSuffix\n expect(result.openGraph?.title).toBe('My CMS - Payload')\n })\n\n it('should use the TemplateString absolute for ogTitle when title has absolute property', async () => {\n const result = await formatMetadata({\n serverURL: 'http://localhost:3000',\n title: { absolute: 'My CMS Absolute' },\n titleSuffix: '- Payload',\n })\n\n expect(result.openGraph?.title).toBe('My CMS Absolute - Payload')\n })\n\n it('should apply titleSuffix to the absolute field of a TemplateString title object', async () => {\n const result = await formatMetadata({\n serverURL: 'http://localhost:3000',\n title: { absolute: 'My CMS Absolute' },\n titleSuffix: '- Payload',\n })\n\n expect(typeof result.title).toBe('object')\n expect((result.title as { absolute: string }).absolute).toBe('My CMS Absolute - Payload')\n })\n\n it('should use openGraph.title string over incomingMetadata.title for ogTitle', async () => {\n const result = await formatMetadata({\n serverURL: 'http://localhost:3000',\n title: 'My CMS',\n titleSuffix: '- Payload',\n openGraph: { title: 'Custom OG Title' },\n })\n\n expect(result.openGraph?.title).toBe('Custom OG Title')\n })\n\n it('should return undefined for metaTitle when no title and no titleSuffix are set', async () => {\n const result = await formatMetadata({\n serverURL: 'http://localhost:3000',\n })\n\n expect(result.title).toBeUndefined()\n })\n\n it('should return just the title when no titleSuffix is set', async () => {\n const result = await formatMetadata({\n serverURL: 'http://localhost:3000',\n title: 'My CMS',\n })\n\n expect(result.title).toBe('My CMS')\n })\n})\n"],"mappings":"AAAA,SAASA,QAAQ,EAAEC,MAAM,EAAEC,EAAE,QAAQ;AAErC,SAASC,cAAc,QAAQ;AAE/BH,QAAA,CAAS,kBAAkB;EACzBE,EAAA,CAAG,iDAAiD;IAClD,MAAME,MAAA,GAAS,MAAMD,cAAA,CAAe;MAClCE,SAAA,EAAW;MACXC,KAAA,EAAO;MACPC,WAAA,EAAa;IACf;IAEAN,MAAA,CAAOG,MAAA,CAAOE,KAAK,EAAEE,IAAI,CAAC;EAC5B;EAEAN,EAAA,CAAG,4FAA4F;IAC7F,MAAME,MAAA,GAAS,MAAMD,cAAA,CAAe;MAClCE,SAAA,EAAW;MACXC,KAAA,EAAO;QAAEG,OAAA,EAAS;QAAaC,QAAA,EAAU;MAAiB;MAC1DH,WAAA,EAAa;IACf;IAEAN,MAAA,CAAO,OAAOG,MAAA,CAAOE,KAAK,EAAEE,IAAI,CAAC;IACjCP,MAAA,CAAOG,MAAC,CAAOE,KAAK,CAA2CG,OAAO,EAAED,IAAI,CAC1E;IAEFP,MAAA,CAAOG,MAAC,CAAOE,KAAK,CAA2CI,QAAQ,EAAEF,IAAI,CAC3E;EAEJ;EAEAN,EAAA,CAAG,2FAA2F;IAC5F,MAAME,MAAA,GAAS,MAAMD,cAAA,CAAe;MAClCE,SAAA,EAAW;MACXC,KAAA,EAAO;QAAEG,OAAA,EAAS;QAAUC,QAAA,EAAU;MAAc;MACpDH,WAAA,EAAa;IACf;IAEA;IACAN,MAAA,CAAOG,MAAA,CAAOO,SAAS,EAAEL,KAAA,EAAOE,IAAI,CAAC;EACvC;EAEAN,EAAA,CAAG,uFAAuF;IACxF,MAAME,MAAA,GAAS,MAAMD,cAAA,CAAe;MAClCE,SAAA,EAAW;MACXC,KAAA,EAAO;QAAEM,QAAA,EAAU;MAAkB;MACrCL,WAAA,EAAa;IACf;IAEAN,MAAA,CAAOG,MAAA,CAAOO,SAAS,EAAEL,KAAA,EAAOE,IAAI,CAAC;EACvC;EAEAN,EAAA,CAAG,mFAAmF;IACpF,MAAME,MAAA,GAAS,MAAMD,cAAA,CAAe;MAClCE,SAAA,EAAW;MACXC,KAAA,EAAO;QAAEM,QAAA,EAAU;MAAkB;MACrCL,WAAA,EAAa;IACf;IAEAN,MAAA,CAAO,OAAOG,MAAA,CAAOE,KAAK,EAAEE,IAAI,CAAC;IACjCP,MAAA,CAAOG,MAAC,CAAOE,KAAK,CAA0BM,QAAQ,EAAEJ,IAAI,CAAC;EAC/D;EAEAN,EAAA,CAAG,6EAA6E;IAC9E,MAAME,MAAA,GAAS,MAAMD,cAAA,CAAe;MAClCE,SAAA,EAAW;MACXC,KAAA,EAAO;MACPC,WAAA,EAAa;MACbI,SAAA,EAAW;QAAEL,KAAA,EAAO;MAAkB;IACxC;IAEAL,MAAA,CAAOG,MAAA,CAAOO,SAAS,EAAEL,KAAA,EAAOE,IAAI,CAAC;EACvC;EAEAN,EAAA,CAAG,kFAAkF;IACnF,MAAME,MAAA,GAAS,MAAMD,cAAA,CAAe;MAClCE,SAAA,EAAW;IACb;IAEAJ,MAAA,CAAOG,MAAA,CAAOE,KAAK,EAAEO,aAAa;EACpC;EAEAX,EAAA,CAAG,2DAA2D;IAC5D,MAAME,MAAA,GAAS,MAAMD,cAAA,CAAe;MAClCE,SAAA,EAAW;MACXC,KAAA,EAAO;IACT;IAEAL,MAAA,CAAOG,MAAA,CAAOE,KAAK,EAAEE,IAAI,CAAC;EAC5B;AACF","ignoreList":[]}
|