@wordpress/editor 14.50.0 → 14.51.1-next.v.202607070741.0
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/CHANGELOG.md +10 -0
- package/build/components/collab-sidebar/format.cjs +83 -0
- package/build/components/collab-sidebar/format.cjs.map +7 -0
- package/build/components/collab-sidebar/hooks.cjs +117 -16
- package/build/components/collab-sidebar/hooks.cjs.map +2 -2
- package/build/components/collab-sidebar/index.cjs +18 -2
- package/build/components/collab-sidebar/index.cjs.map +2 -2
- package/build/components/collab-sidebar/note-highlight-styles.cjs +67 -0
- package/build/components/collab-sidebar/note-highlight-styles.cjs.map +7 -0
- package/build/components/collab-sidebar/utils.cjs +139 -0
- package/build/components/collab-sidebar/utils.cjs.map +2 -2
- package/build/components/collaborators-presence/use-collaborator-notifications.cjs +55 -30
- package/build/components/collaborators-presence/use-collaborator-notifications.cjs.map +2 -2
- package/build/components/commands/index.cjs +99 -3
- package/build/components/commands/index.cjs.map +2 -2
- package/build/components/document-bar/index.cjs +28 -34
- package/build/components/document-bar/index.cjs.map +2 -2
- package/build/components/entities-saved-states/index.cjs +1 -4
- package/build/components/entities-saved-states/index.cjs.map +2 -2
- package/build/components/media-categories/index.cjs +92 -6
- package/build/components/media-categories/index.cjs.map +2 -2
- package/build/components/page-attributes/parent.cjs +0 -1
- package/build/components/page-attributes/parent.cjs.map +2 -2
- package/build/components/post-author/combobox.cjs +0 -1
- package/build/components/post-author/combobox.cjs.map +2 -2
- package/build/components/post-author/select.cjs +0 -1
- package/build/components/post-author/select.cjs.map +2 -2
- package/build/components/post-preview-button/index.cjs +29 -2
- package/build/components/post-preview-button/index.cjs.map +2 -2
- package/build/components/post-publish-panel/maybe-upload-media.cjs +15 -26
- package/build/components/post-publish-panel/maybe-upload-media.cjs.map +3 -3
- package/build/components/post-revisions-preview/revisions-slider.cjs +3 -1
- package/build/components/post-revisions-preview/revisions-slider.cjs.map +2 -2
- package/build/components/post-taxonomies/flat-term-selector.cjs +0 -1
- package/build/components/post-taxonomies/flat-term-selector.cjs.map +2 -2
- package/build/components/post-taxonomies/hierarchical-term-selector.cjs +0 -2
- package/build/components/post-taxonomies/hierarchical-term-selector.cjs.map +2 -2
- package/build/components/post-template/classic-theme.cjs +0 -1
- package/build/components/post-template/classic-theme.cjs.map +2 -2
- package/build/components/preferences-modal/index.cjs +54 -28
- package/build/components/preferences-modal/index.cjs.map +2 -2
- package/build/components/preview-dropdown/index.cjs +3 -3
- package/build/components/preview-dropdown/index.cjs.map +2 -2
- package/build/components/provider/use-block-editor-settings.cjs +23 -3
- package/build/components/provider/use-block-editor-settings.cjs.map +3 -3
- package/build/components/sidebar/dataform-post-summary.cjs +5 -1
- package/build/components/sidebar/dataform-post-summary.cjs.map +3 -3
- package/build/components/sidebar/index.cjs +29 -38
- package/build/components/sidebar/index.cjs.map +3 -3
- package/build/components/sidebar/post-summary.cjs +0 -13
- package/build/components/sidebar/post-summary.cjs.map +3 -3
- package/build/dataviews/store/private-actions.cjs +24 -19
- package/build/dataviews/store/private-actions.cjs.map +2 -2
- package/build/store/private-actions.cjs +5 -2
- package/build/store/private-actions.cjs.map +2 -2
- package/build/utils/media-sideload-from-url/index.cjs +63 -0
- package/build/utils/media-sideload-from-url/index.cjs.map +7 -0
- package/build-module/components/collab-sidebar/format.mjs +57 -0
- package/build-module/components/collab-sidebar/format.mjs.map +7 -0
- package/build-module/components/collab-sidebar/hooks.mjs +121 -16
- package/build-module/components/collab-sidebar/hooks.mjs.map +2 -2
- package/build-module/components/collab-sidebar/index.mjs +21 -5
- package/build-module/components/collab-sidebar/index.mjs.map +2 -2
- package/build-module/components/collab-sidebar/note-highlight-styles.mjs +41 -0
- package/build-module/components/collab-sidebar/note-highlight-styles.mjs.map +7 -0
- package/build-module/components/collab-sidebar/utils.mjs +133 -0
- package/build-module/components/collab-sidebar/utils.mjs.map +2 -2
- package/build-module/components/collaborators-presence/use-collaborator-notifications.mjs +55 -30
- package/build-module/components/collaborators-presence/use-collaborator-notifications.mjs.map +2 -2
- package/build-module/components/commands/index.mjs +99 -3
- package/build-module/components/commands/index.mjs.map +2 -2
- package/build-module/components/document-bar/index.mjs +28 -34
- package/build-module/components/document-bar/index.mjs.map +2 -2
- package/build-module/components/entities-saved-states/index.mjs +1 -4
- package/build-module/components/entities-saved-states/index.mjs.map +2 -2
- package/build-module/components/media-categories/index.mjs +93 -7
- package/build-module/components/media-categories/index.mjs.map +2 -2
- package/build-module/components/page-attributes/parent.mjs +0 -1
- package/build-module/components/page-attributes/parent.mjs.map +2 -2
- package/build-module/components/post-author/combobox.mjs +0 -1
- package/build-module/components/post-author/combobox.mjs.map +2 -2
- package/build-module/components/post-author/select.mjs +0 -1
- package/build-module/components/post-author/select.mjs.map +2 -2
- package/build-module/components/post-preview-button/index.mjs +29 -2
- package/build-module/components/post-preview-button/index.mjs.map +2 -2
- package/build-module/components/post-publish-panel/maybe-upload-media.mjs +19 -27
- package/build-module/components/post-publish-panel/maybe-upload-media.mjs.map +2 -2
- package/build-module/components/post-revisions-preview/revisions-slider.mjs +3 -1
- package/build-module/components/post-revisions-preview/revisions-slider.mjs.map +2 -2
- package/build-module/components/post-taxonomies/flat-term-selector.mjs +0 -1
- package/build-module/components/post-taxonomies/flat-term-selector.mjs.map +2 -2
- package/build-module/components/post-taxonomies/hierarchical-term-selector.mjs +0 -2
- package/build-module/components/post-taxonomies/hierarchical-term-selector.mjs.map +2 -2
- package/build-module/components/post-template/classic-theme.mjs +0 -1
- package/build-module/components/post-template/classic-theme.mjs.map +2 -2
- package/build-module/components/preferences-modal/index.mjs +54 -28
- package/build-module/components/preferences-modal/index.mjs.map +2 -2
- package/build-module/components/preview-dropdown/index.mjs +3 -3
- package/build-module/components/preview-dropdown/index.mjs.map +2 -2
- package/build-module/components/provider/use-block-editor-settings.mjs +23 -3
- package/build-module/components/provider/use-block-editor-settings.mjs.map +2 -2
- package/build-module/components/sidebar/dataform-post-summary.mjs +6 -2
- package/build-module/components/sidebar/dataform-post-summary.mjs.map +2 -2
- package/build-module/components/sidebar/index.mjs +29 -42
- package/build-module/components/sidebar/index.mjs.map +2 -2
- package/build-module/components/sidebar/post-summary.mjs +0 -13
- package/build-module/components/sidebar/post-summary.mjs.map +2 -2
- package/build-module/dataviews/store/private-actions.mjs +26 -19
- package/build-module/dataviews/store/private-actions.mjs.map +2 -2
- package/build-module/store/private-actions.mjs +5 -2
- package/build-module/store/private-actions.mjs.map +2 -2
- package/build-module/utils/media-sideload-from-url/index.mjs +32 -0
- package/build-module/utils/media-sideload-from-url/index.mjs.map +7 -0
- package/build-style/style-rtl.css +65 -33
- package/build-style/style.css +65 -33
- package/build-types/components/collab-sidebar/format.d.ts +17 -0
- package/build-types/components/collab-sidebar/format.d.ts.map +1 -0
- package/build-types/components/collab-sidebar/hooks.d.ts.map +1 -1
- package/build-types/components/collab-sidebar/index.d.ts.map +1 -1
- package/build-types/components/collab-sidebar/note-highlight-styles.d.ts +31 -0
- package/build-types/components/collab-sidebar/note-highlight-styles.d.ts.map +1 -0
- package/build-types/components/collab-sidebar/utils.d.ts +82 -2
- package/build-types/components/collab-sidebar/utils.d.ts.map +1 -1
- package/build-types/components/collaborators-presence/use-collaborator-notifications.d.ts.map +1 -1
- package/build-types/components/commands/index.d.ts.map +1 -1
- package/build-types/components/document-bar/index.d.ts.map +1 -1
- package/build-types/components/entities-saved-states/index.d.ts.map +1 -1
- package/build-types/components/media-categories/index.d.ts +12 -3
- package/build-types/components/media-categories/index.d.ts.map +1 -1
- package/build-types/components/page-attributes/parent.d.ts.map +1 -1
- package/build-types/components/post-author/combobox.d.ts.map +1 -1
- package/build-types/components/post-author/select.d.ts.map +1 -1
- package/build-types/components/post-preview-button/index.d.ts.map +1 -1
- package/build-types/components/post-publish-panel/maybe-upload-media.d.ts.map +1 -1
- package/build-types/components/post-revisions-preview/revisions-slider.d.ts.map +1 -1
- package/build-types/components/post-taxonomies/flat-term-selector.d.ts.map +1 -1
- package/build-types/components/post-taxonomies/hierarchical-term-selector.d.ts.map +1 -1
- package/build-types/components/post-template/classic-theme.d.ts.map +1 -1
- package/build-types/components/provider/use-block-editor-settings.d.ts.map +1 -1
- package/build-types/components/sidebar/dataform-post-summary.d.ts.map +1 -1
- package/build-types/components/sidebar/index.d.ts.map +1 -1
- package/build-types/components/sidebar/post-summary.d.ts.map +1 -1
- package/build-types/dataviews/store/private-actions.d.ts.map +1 -1
- package/build-types/store/private-actions.d.ts.map +1 -1
- package/build-types/store/selectors.d.ts.map +1 -1
- package/build-types/utils/get-template-part-icon.d.ts.map +1 -1
- package/build-types/utils/media-sideload-from-url/index.d.ts +18 -0
- package/build-types/utils/media-sideload-from-url/index.d.ts.map +1 -0
- package/package.json +48 -46
- package/src/components/collab-sidebar/format.js +72 -0
- package/src/components/collab-sidebar/hooks.js +203 -22
- package/src/components/collab-sidebar/index.js +19 -5
- package/src/components/collab-sidebar/note-highlight-styles.js +83 -0
- package/src/components/collab-sidebar/style.scss +9 -0
- package/src/components/collab-sidebar/test/note-highlight-styles.js +106 -0
- package/src/components/collab-sidebar/test/utils.js +471 -0
- package/src/components/collab-sidebar/utils.js +225 -2
- package/src/components/collaborators-presence/test/use-collaborator-notifications.ts +265 -262
- package/src/components/collaborators-presence/use-collaborator-notifications.ts +70 -34
- package/src/components/commands/index.js +142 -0
- package/src/components/document-bar/index.js +0 -9
- package/src/components/document-bar/style.scss +0 -17
- package/src/components/entities-saved-states/index.js +1 -5
- package/src/components/header/style.scss +7 -3
- package/src/components/media-categories/index.js +160 -6
- package/src/components/media-categories/test/index.js +202 -0
- package/src/components/page-attributes/parent.js +0 -1
- package/src/components/post-author/combobox.js +0 -1
- package/src/components/post-author/select.js +0 -1
- package/src/components/post-preview-button/index.js +68 -2
- package/src/components/post-publish-panel/maybe-upload-media.js +25 -30
- package/src/components/post-publish-panel/style.scss +1 -1
- package/src/components/post-publish-panel/test/__snapshots__/index.js.snap +11 -127
- package/src/components/post-revisions-preview/revisions-slider.js +4 -1
- package/src/components/post-revisions-preview/test/block-diff.js +2 -2
- package/src/components/post-taxonomies/flat-term-selector.js +0 -1
- package/src/components/post-taxonomies/hierarchical-term-selector.js +0 -2
- package/src/components/post-template/classic-theme.js +0 -1
- package/src/components/preferences-modal/index.js +40 -22
- package/src/components/preferences-modal/test/index.js +83 -0
- package/src/components/preview-dropdown/index.js +3 -3
- package/src/components/provider/use-block-editor-settings.js +42 -1
- package/src/components/sidebar/dataform-post-summary.js +13 -1
- package/src/components/sidebar/index.js +32 -47
- package/src/components/sidebar/post-summary.js +0 -17
- package/src/dataviews/store/private-actions.ts +30 -26
- package/src/store/private-actions.js +6 -2
- package/src/utils/media-sideload-from-url/index.js +54 -0
- package/src/utils/media-sideload-from-url/test/index.js +162 -0
- package/build/components/post-publish-panel/media-util.cjs +0 -72
- package/build/components/post-publish-panel/media-util.cjs.map +0 -7
- package/build-module/components/post-publish-panel/media-util.mjs +0 -46
- package/build-module/components/post-publish-panel/media-util.mjs.map +0 -7
- package/build-types/components/post-publish-panel/media-util.d.ts +0 -20
- package/build-types/components/post-publish-panel/media-util.d.ts.map +0 -1
- package/src/components/post-publish-panel/media-util.js +0 -87
- package/src/components/post-publish-panel/test/media-util.js +0 -118
|
@@ -14,145 +14,163 @@ import { useDispatch, useSelect } from '@wordpress/data';
|
|
|
14
14
|
import { useCollaboratorNotifications } from '../use-collaborator-notifications';
|
|
15
15
|
|
|
16
16
|
// --- Mocks ---
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
let mockOnPostSaveCallback: Function | null = null;
|
|
22
|
-
let lastJoinPostId: unknown;
|
|
23
|
-
let lastLeavePostId: unknown;
|
|
24
|
-
let lastSavePostId: unknown;
|
|
25
|
-
let mockEditorState = {
|
|
26
|
-
postStatus: 'draft',
|
|
27
|
-
isCollaborationEnabled: true,
|
|
28
|
-
showCollaborationNotifications: true,
|
|
29
|
-
};
|
|
17
|
+
//
|
|
18
|
+
// These mocks isolate the hook from `@wordpress/data`, the editor store, and
|
|
19
|
+
// the core-data private APIs it unlocks, so tests can drive the join/leave/
|
|
20
|
+
// save callbacks directly instead of simulating real awareness events.
|
|
30
21
|
|
|
31
22
|
jest.mock( '@wordpress/data', () => ( {
|
|
32
23
|
useSelect: jest.fn(),
|
|
33
24
|
useDispatch: jest.fn(),
|
|
34
25
|
} ) );
|
|
35
26
|
|
|
36
|
-
jest.mock( '@wordpress/notices', () => ( {
|
|
37
|
-
|
|
38
|
-
} ) );
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
27
|
+
jest.mock( '@wordpress/notices', () => ( { store: 'core/notices' } ) );
|
|
28
|
+
|
|
29
|
+
jest.mock( '@wordpress/preferences', () => ( { store: 'core/preferences' } ) );
|
|
30
|
+
|
|
31
|
+
// Avoids pulling in the full editor store (blocks, rich-text, etc.).
|
|
32
|
+
jest.mock( '../../../store', () => ( { store: 'core/editor' } ) );
|
|
33
|
+
|
|
34
|
+
jest.mock( '@wordpress/core-data', () => ( { privateApis: {} } ) );
|
|
35
|
+
|
|
36
|
+
// Captures the callbacks and postIds the hook registers with each of the
|
|
37
|
+
// three core-data subscriptions it unlocks. Must be prefixed with `mock`
|
|
38
|
+
// so jest's module factory hoisting allows referencing it below.
|
|
39
|
+
const mockRegistered: {
|
|
40
|
+
join: Function | null;
|
|
41
|
+
leave: Function | null;
|
|
42
|
+
save: Function | null;
|
|
43
|
+
joinPostId: unknown;
|
|
44
|
+
leavePostId: unknown;
|
|
45
|
+
savePostId: unknown;
|
|
46
|
+
} = {
|
|
47
|
+
join: null,
|
|
48
|
+
leave: null,
|
|
49
|
+
save: null,
|
|
50
|
+
joinPostId: undefined,
|
|
51
|
+
leavePostId: undefined,
|
|
52
|
+
savePostId: undefined,
|
|
53
|
+
};
|
|
53
54
|
|
|
54
55
|
jest.mock( '../../../lock-unlock', () => ( {
|
|
55
56
|
unlock: jest.fn( ( value: unknown ) => ( {
|
|
56
57
|
...( value as object ),
|
|
57
|
-
useOnCollaboratorJoin:
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
58
|
+
useOnCollaboratorJoin: (
|
|
59
|
+
postId: unknown,
|
|
60
|
+
_t: unknown,
|
|
61
|
+
cb: Function
|
|
62
|
+
) => {
|
|
63
|
+
mockRegistered.joinPostId = postId;
|
|
64
|
+
mockRegistered.join = cb;
|
|
65
|
+
},
|
|
66
|
+
useOnCollaboratorLeave: (
|
|
67
|
+
postId: unknown,
|
|
68
|
+
_t: unknown,
|
|
69
|
+
cb: Function
|
|
70
|
+
) => {
|
|
71
|
+
mockRegistered.leavePostId = postId;
|
|
72
|
+
mockRegistered.leave = cb;
|
|
73
|
+
},
|
|
74
|
+
useOnPostSave: ( postId: unknown, _t: unknown, cb: Function ) => {
|
|
75
|
+
mockRegistered.savePostId = postId;
|
|
76
|
+
mockRegistered.save = cb;
|
|
77
|
+
},
|
|
75
78
|
} ) ),
|
|
76
79
|
} ) );
|
|
77
80
|
|
|
78
|
-
// ---
|
|
81
|
+
// --- Fixtures ---
|
|
79
82
|
|
|
80
83
|
const BASE_ENTERED_AT = 1704067200000;
|
|
81
84
|
|
|
82
|
-
function makeCollaborator(
|
|
85
|
+
function makeCollaborator(
|
|
86
|
+
id: number,
|
|
87
|
+
name: string,
|
|
88
|
+
enteredAt: number,
|
|
89
|
+
overrides: Record< string, unknown > = {}
|
|
90
|
+
) {
|
|
83
91
|
return {
|
|
84
|
-
clientId:
|
|
92
|
+
clientId: id,
|
|
85
93
|
isMe: false,
|
|
86
94
|
isConnected: true,
|
|
87
95
|
collaboratorInfo: {
|
|
88
|
-
id
|
|
89
|
-
name
|
|
90
|
-
slug:
|
|
96
|
+
id,
|
|
97
|
+
name,
|
|
98
|
+
slug: name.toLowerCase(),
|
|
91
99
|
avatar_urls: {},
|
|
92
100
|
browserType: 'Chrome',
|
|
93
|
-
enteredAt
|
|
101
|
+
enteredAt,
|
|
94
102
|
},
|
|
95
103
|
...overrides,
|
|
96
104
|
};
|
|
97
105
|
}
|
|
98
106
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
name: 'Me',
|
|
106
|
-
slug: 'me',
|
|
107
|
-
avatar_urls: {},
|
|
108
|
-
browserType: 'Chrome',
|
|
109
|
-
enteredAt: BASE_ENTERED_AT + 5000, // joined later than Alice
|
|
110
|
-
},
|
|
111
|
-
...overrides,
|
|
112
|
-
} );
|
|
113
|
-
}
|
|
107
|
+
// "me" is the current user; Alice entered before "me", Bob after.
|
|
108
|
+
const me = makeCollaborator( 1, 'Me', BASE_ENTERED_AT + 5000, {
|
|
109
|
+
isMe: true,
|
|
110
|
+
} );
|
|
111
|
+
const alice = makeCollaborator( 100, 'Alice', BASE_ENTERED_AT + 1000 );
|
|
112
|
+
const bob = makeCollaborator( 200, 'Bob', BASE_ENTERED_AT + 10000 );
|
|
114
113
|
|
|
115
114
|
// --- Setup ---
|
|
116
115
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
116
|
+
const mockCreateNotice = jest.fn();
|
|
117
|
+
|
|
118
|
+
type PreferenceState = {
|
|
119
|
+
postStatus: string | undefined;
|
|
120
|
+
isCollaborationEnabled: boolean;
|
|
121
|
+
showCollaborationJoinNotifications: boolean;
|
|
122
|
+
showCollaborationLeaveNotifications: boolean;
|
|
123
|
+
showCollaborationPostSaveNotifications: boolean;
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
const DEFAULT_STATE: PreferenceState = {
|
|
127
|
+
postStatus: 'draft',
|
|
128
|
+
isCollaborationEnabled: true,
|
|
129
|
+
showCollaborationJoinNotifications: true,
|
|
130
|
+
showCollaborationLeaveNotifications: true,
|
|
131
|
+
showCollaborationPostSaveNotifications: true,
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
let state: PreferenceState = { ...DEFAULT_STATE };
|
|
135
|
+
|
|
136
|
+
function mockSelect( storeKey: string ) {
|
|
137
|
+
if ( storeKey === 'core/preferences' ) {
|
|
132
138
|
return {
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
139
|
+
get: ( scope: string, name: string ) =>
|
|
140
|
+
scope === 'core' && name in state
|
|
141
|
+
? ( state as unknown as Record< string, boolean > )[ name ]
|
|
142
|
+
: undefined,
|
|
137
143
|
};
|
|
144
|
+
}
|
|
145
|
+
return {
|
|
146
|
+
getCurrentPostAttribute: ( attr: string ) =>
|
|
147
|
+
attr === 'status' ? state.postStatus : undefined,
|
|
148
|
+
isCollaborationEnabledForCurrentPost: () =>
|
|
149
|
+
state.isCollaborationEnabled,
|
|
138
150
|
};
|
|
139
151
|
}
|
|
140
152
|
|
|
153
|
+
/**
|
|
154
|
+
* Renders the hook under test with the given preference/state overrides
|
|
155
|
+
* applied on top of the defaults (everything enabled, status: 'draft').
|
|
156
|
+
*
|
|
157
|
+
* @param overrides Partial preference/state overrides.
|
|
158
|
+
*/
|
|
159
|
+
function renderNotifications( overrides: Partial< PreferenceState > = {} ) {
|
|
160
|
+
state = { ...DEFAULT_STATE, ...overrides };
|
|
161
|
+
return renderHook( () => useCollaboratorNotifications( 123, 'post' ) );
|
|
162
|
+
}
|
|
163
|
+
|
|
141
164
|
beforeEach( () => {
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
mockEditorState = {
|
|
149
|
-
postStatus: 'draft',
|
|
150
|
-
isCollaborationEnabled: true,
|
|
151
|
-
showCollaborationNotifications: true,
|
|
152
|
-
};
|
|
165
|
+
mockRegistered.join = null;
|
|
166
|
+
mockRegistered.leave = null;
|
|
167
|
+
mockRegistered.save = null;
|
|
168
|
+
mockRegistered.joinPostId = undefined;
|
|
169
|
+
mockRegistered.leavePostId = undefined;
|
|
170
|
+
mockRegistered.savePostId = undefined;
|
|
153
171
|
mockCreateNotice.mockClear();
|
|
154
172
|
( useSelect as jest.Mock ).mockImplementation( ( selector: Function ) =>
|
|
155
|
-
selector(
|
|
173
|
+
selector( mockSelect )
|
|
156
174
|
);
|
|
157
175
|
( useDispatch as jest.Mock ).mockReturnValue( {
|
|
158
176
|
createNotice: mockCreateNotice,
|
|
@@ -163,235 +181,220 @@ beforeEach( () => {
|
|
|
163
181
|
|
|
164
182
|
describe( 'useCollaboratorNotifications', () => {
|
|
165
183
|
describe( 'collaborator join notifications', () => {
|
|
166
|
-
it( 'fires
|
|
167
|
-
|
|
168
|
-
const bobJoinedAfter = makeCollaborator( {
|
|
169
|
-
clientId: 2,
|
|
170
|
-
collaboratorInfo: {
|
|
171
|
-
id: 200,
|
|
172
|
-
name: 'Bob',
|
|
173
|
-
slug: 'bob',
|
|
174
|
-
avatar_urls: {},
|
|
175
|
-
browserType: 'Firefox',
|
|
176
|
-
enteredAt: BASE_ENTERED_AT + 10000, // joined after me
|
|
177
|
-
},
|
|
178
|
-
} );
|
|
179
|
-
|
|
180
|
-
renderHook( () => useCollaboratorNotifications( 123, 'post' ) );
|
|
184
|
+
it( 'fires when the collaborator entered after the current user', () => {
|
|
185
|
+
renderNotifications();
|
|
181
186
|
|
|
182
|
-
|
|
183
|
-
mockOnJoinCallback?.( bobJoinedAfter, me );
|
|
187
|
+
mockRegistered.join?.( bob, me );
|
|
184
188
|
|
|
185
189
|
expect( mockCreateNotice ).toHaveBeenCalledWith(
|
|
186
190
|
'info',
|
|
187
191
|
'Bob has joined the post.',
|
|
188
192
|
expect.objectContaining( {
|
|
189
193
|
id: 'collab-user-entered-200',
|
|
194
|
+
type: 'snackbar',
|
|
195
|
+
isDismissible: false,
|
|
190
196
|
} )
|
|
191
197
|
);
|
|
192
198
|
} );
|
|
193
199
|
|
|
194
|
-
it( '
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
200
|
+
it( 'is skipped when the collaborator entered before the current user', () => {
|
|
201
|
+
renderNotifications();
|
|
202
|
+
|
|
203
|
+
mockRegistered.join?.( alice, me );
|
|
204
|
+
|
|
205
|
+
expect( mockCreateNotice ).not.toHaveBeenCalled();
|
|
206
|
+
} );
|
|
207
|
+
|
|
208
|
+
it( 'does not fire when join notifications are disabled', () => {
|
|
209
|
+
renderNotifications( {
|
|
210
|
+
showCollaborationJoinNotifications: false,
|
|
205
211
|
} );
|
|
206
212
|
|
|
207
|
-
|
|
213
|
+
// The hook unsubscribes by passing a null postId...
|
|
214
|
+
expect( mockRegistered.joinPostId ).toBeNull();
|
|
208
215
|
|
|
209
|
-
//
|
|
210
|
-
|
|
216
|
+
// ...while the other two hooks stay wired to the real post id,
|
|
217
|
+
// proving this preference doesn't accidentally couple with them.
|
|
218
|
+
expect( mockRegistered.leavePostId ).toBe( 123 );
|
|
219
|
+
expect( mockRegistered.savePostId ).toBe( 123 );
|
|
220
|
+
|
|
221
|
+
// ...and the callback itself guards against any queued event.
|
|
222
|
+
mockRegistered.join?.( bob, me );
|
|
223
|
+
expect( mockCreateNotice ).not.toHaveBeenCalled();
|
|
224
|
+
} );
|
|
225
|
+
|
|
226
|
+
it( 'stops firing once join notifications are toggled off mid-session', () => {
|
|
227
|
+
const { rerender } = renderNotifications();
|
|
228
|
+
|
|
229
|
+
state = {
|
|
230
|
+
...state,
|
|
231
|
+
showCollaborationJoinNotifications: false,
|
|
232
|
+
};
|
|
233
|
+
rerender();
|
|
234
|
+
|
|
235
|
+
mockRegistered.join?.( bob, me );
|
|
211
236
|
|
|
212
237
|
expect( mockCreateNotice ).not.toHaveBeenCalled();
|
|
213
238
|
} );
|
|
214
239
|
} );
|
|
215
240
|
|
|
216
241
|
describe( 'collaborator leave notifications', () => {
|
|
217
|
-
it( 'fires
|
|
218
|
-
|
|
219
|
-
renderHook( () => useCollaboratorNotifications( 123, 'post' ) );
|
|
242
|
+
it( 'fires when a collaborator leaves', () => {
|
|
243
|
+
renderNotifications();
|
|
220
244
|
|
|
221
|
-
|
|
222
|
-
mockOnLeaveCallback?.( alice );
|
|
245
|
+
mockRegistered.leave?.( alice );
|
|
223
246
|
|
|
224
247
|
expect( mockCreateNotice ).toHaveBeenCalledWith(
|
|
225
248
|
'info',
|
|
226
249
|
'Alice has left the post.',
|
|
227
250
|
expect.objectContaining( {
|
|
251
|
+
id: 'collab-user-exited-100',
|
|
228
252
|
type: 'snackbar',
|
|
229
253
|
isDismissible: false,
|
|
230
|
-
id: 'collab-user-exited-100',
|
|
231
254
|
} )
|
|
232
255
|
);
|
|
233
256
|
} );
|
|
234
|
-
} );
|
|
235
257
|
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
258
|
+
it( 'does not fire when leave notifications are disabled', () => {
|
|
259
|
+
renderNotifications( {
|
|
260
|
+
showCollaborationLeaveNotifications: false,
|
|
261
|
+
} );
|
|
240
262
|
|
|
241
|
-
|
|
242
|
-
mockOnPostSaveCallback?.(
|
|
243
|
-
{
|
|
244
|
-
savedAt: Date.now(),
|
|
245
|
-
savedByClientId: alice.clientId,
|
|
246
|
-
postStatus: undefined,
|
|
247
|
-
},
|
|
248
|
-
alice,
|
|
249
|
-
null
|
|
250
|
-
);
|
|
263
|
+
expect( mockRegistered.leavePostId ).toBeNull();
|
|
251
264
|
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
id: 'collab-post-updated-100',
|
|
259
|
-
} )
|
|
260
|
-
);
|
|
265
|
+
// The other two hooks stay wired to the real post id.
|
|
266
|
+
expect( mockRegistered.joinPostId ).toBe( 123 );
|
|
267
|
+
expect( mockRegistered.savePostId ).toBe( 123 );
|
|
268
|
+
|
|
269
|
+
mockRegistered.leave?.( alice );
|
|
270
|
+
expect( mockCreateNotice ).not.toHaveBeenCalled();
|
|
261
271
|
} );
|
|
262
272
|
|
|
263
|
-
it( '
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
273
|
+
it( 'stops firing once leave notifications are toggled off mid-session', () => {
|
|
274
|
+
const { rerender } = renderNotifications();
|
|
275
|
+
|
|
276
|
+
state = {
|
|
277
|
+
...state,
|
|
278
|
+
showCollaborationLeaveNotifications: false,
|
|
267
279
|
};
|
|
268
|
-
|
|
269
|
-
renderHook( () => useCollaboratorNotifications( 123, 'post' ) );
|
|
280
|
+
rerender();
|
|
270
281
|
|
|
271
|
-
|
|
272
|
-
{
|
|
273
|
-
savedAt: Date.now(),
|
|
274
|
-
savedByClientId: alice.clientId,
|
|
275
|
-
postStatus: 'publish',
|
|
276
|
-
},
|
|
277
|
-
alice,
|
|
278
|
-
null
|
|
279
|
-
);
|
|
282
|
+
mockRegistered.leave?.( alice );
|
|
280
283
|
|
|
281
|
-
expect( mockCreateNotice ).
|
|
282
|
-
'info',
|
|
283
|
-
'Post updated by Alice.',
|
|
284
|
-
expect.objectContaining( {
|
|
285
|
-
id: 'collab-post-updated-100',
|
|
286
|
-
} )
|
|
287
|
-
);
|
|
284
|
+
expect( mockCreateNotice ).not.toHaveBeenCalled();
|
|
288
285
|
} );
|
|
286
|
+
} );
|
|
289
287
|
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
288
|
+
describe( 'post save notifications', () => {
|
|
289
|
+
it.each( [
|
|
290
|
+
{
|
|
291
|
+
description: 'a draft is saved',
|
|
293
292
|
postStatus: 'draft',
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
293
|
+
saveEventStatus: undefined,
|
|
294
|
+
prevEvent: null,
|
|
295
|
+
expected: 'Draft saved by Alice.',
|
|
296
|
+
},
|
|
297
|
+
{
|
|
298
|
+
description: 'an already-published post is updated',
|
|
299
|
+
postStatus: 'publish',
|
|
300
|
+
saveEventStatus: 'publish',
|
|
301
|
+
prevEvent: null,
|
|
302
|
+
expected: 'Post updated by Alice.',
|
|
303
|
+
},
|
|
304
|
+
{
|
|
305
|
+
description:
|
|
306
|
+
'a post is first published (no previous save event)',
|
|
307
|
+
postStatus: 'draft',
|
|
308
|
+
saveEventStatus: 'publish',
|
|
309
|
+
prevEvent: null,
|
|
310
|
+
expected: 'Post published by Alice.',
|
|
311
|
+
},
|
|
312
|
+
{
|
|
313
|
+
description:
|
|
314
|
+
'a post is first published (prevEvent carries the prior draft status)',
|
|
315
|
+
postStatus: 'publish',
|
|
316
|
+
saveEventStatus: 'publish',
|
|
317
|
+
prevEvent: {
|
|
318
|
+
savedAt: 0,
|
|
319
|
+
savedByClientId: 1,
|
|
320
|
+
postStatus: 'draft',
|
|
321
|
+
},
|
|
322
|
+
expected: 'Post published by Alice.',
|
|
323
|
+
},
|
|
324
|
+
] )(
|
|
325
|
+
'fires "$expected" when $description',
|
|
326
|
+
( { postStatus, saveEventStatus, prevEvent, expected } ) => {
|
|
327
|
+
renderNotifications( { postStatus } );
|
|
328
|
+
|
|
329
|
+
mockRegistered.save?.(
|
|
330
|
+
{
|
|
331
|
+
savedAt: Date.now(),
|
|
332
|
+
savedByClientId: alice.clientId,
|
|
333
|
+
postStatus: saveEventStatus,
|
|
334
|
+
},
|
|
335
|
+
alice,
|
|
336
|
+
prevEvent
|
|
337
|
+
);
|
|
338
|
+
|
|
339
|
+
expect( mockCreateNotice ).toHaveBeenCalledWith(
|
|
340
|
+
'info',
|
|
341
|
+
expected,
|
|
342
|
+
expect.objectContaining( {
|
|
343
|
+
id: 'collab-post-updated-100',
|
|
344
|
+
type: 'snackbar',
|
|
345
|
+
isDismissible: false,
|
|
346
|
+
} )
|
|
347
|
+
);
|
|
348
|
+
}
|
|
349
|
+
);
|
|
350
|
+
|
|
351
|
+
it( 'does not fire when postStatus is unknown', () => {
|
|
352
|
+
renderNotifications( { postStatus: undefined } );
|
|
297
353
|
|
|
298
|
-
|
|
354
|
+
mockRegistered.save?.(
|
|
299
355
|
{
|
|
300
356
|
savedAt: Date.now(),
|
|
301
357
|
savedByClientId: alice.clientId,
|
|
302
|
-
postStatus:
|
|
358
|
+
postStatus: undefined,
|
|
303
359
|
},
|
|
304
360
|
alice,
|
|
305
361
|
null
|
|
306
362
|
);
|
|
307
363
|
|
|
308
|
-
expect( mockCreateNotice ).
|
|
309
|
-
'info',
|
|
310
|
-
'Post published by Alice.',
|
|
311
|
-
expect.objectContaining( {
|
|
312
|
-
id: 'collab-post-updated-100',
|
|
313
|
-
} )
|
|
314
|
-
);
|
|
364
|
+
expect( mockCreateNotice ).not.toHaveBeenCalled();
|
|
315
365
|
} );
|
|
316
366
|
|
|
317
|
-
it( '
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
...mockEditorState,
|
|
322
|
-
postStatus: 'publish',
|
|
323
|
-
};
|
|
324
|
-
const alice = makeCollaborator();
|
|
325
|
-
renderHook( () => useCollaboratorNotifications( 123, 'post' ) );
|
|
326
|
-
|
|
327
|
-
mockOnPostSaveCallback?.(
|
|
328
|
-
{
|
|
329
|
-
savedAt: Date.now() + 2000,
|
|
330
|
-
savedByClientId: alice.clientId,
|
|
331
|
-
postStatus: 'publish',
|
|
332
|
-
},
|
|
333
|
-
alice,
|
|
334
|
-
{
|
|
335
|
-
savedAt: Date.now() + 1000,
|
|
336
|
-
savedByClientId: alice.clientId,
|
|
337
|
-
postStatus: 'draft',
|
|
338
|
-
}
|
|
339
|
-
);
|
|
367
|
+
it( 'does not fire when post-save notifications are disabled', () => {
|
|
368
|
+
renderNotifications( {
|
|
369
|
+
showCollaborationPostSaveNotifications: false,
|
|
370
|
+
} );
|
|
340
371
|
|
|
341
|
-
expect(
|
|
342
|
-
'info',
|
|
343
|
-
'Post published by Alice.',
|
|
344
|
-
expect.objectContaining( {
|
|
345
|
-
id: 'collab-post-updated-100',
|
|
346
|
-
} )
|
|
347
|
-
);
|
|
348
|
-
} );
|
|
372
|
+
expect( mockRegistered.savePostId ).toBeNull();
|
|
349
373
|
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
postStatus: undefined as any,
|
|
354
|
-
};
|
|
355
|
-
const alice = makeCollaborator();
|
|
356
|
-
renderHook( () => useCollaboratorNotifications( 123, 'post' ) );
|
|
374
|
+
// The other two hooks stay wired to the real post id.
|
|
375
|
+
expect( mockRegistered.joinPostId ).toBe( 123 );
|
|
376
|
+
expect( mockRegistered.leavePostId ).toBe( 123 );
|
|
357
377
|
|
|
358
|
-
|
|
378
|
+
mockRegistered.save?.(
|
|
359
379
|
{
|
|
360
380
|
savedAt: Date.now(),
|
|
361
381
|
savedByClientId: alice.clientId,
|
|
362
|
-
postStatus:
|
|
382
|
+
postStatus: 'publish',
|
|
363
383
|
},
|
|
364
384
|
alice,
|
|
365
385
|
null
|
|
366
386
|
);
|
|
367
|
-
|
|
368
387
|
expect( mockCreateNotice ).not.toHaveBeenCalled();
|
|
369
388
|
} );
|
|
370
389
|
} );
|
|
371
390
|
|
|
372
|
-
describe( 'when
|
|
373
|
-
it( '
|
|
374
|
-
|
|
375
|
-
...mockEditorState,
|
|
376
|
-
showCollaborationNotifications: false,
|
|
377
|
-
};
|
|
378
|
-
renderHook( () => useCollaboratorNotifications( 123, 'post' ) );
|
|
379
|
-
|
|
380
|
-
expect( lastJoinPostId ).toBeNull();
|
|
381
|
-
expect( lastLeavePostId ).toBeNull();
|
|
382
|
-
expect( lastSavePostId ).toBeNull();
|
|
383
|
-
} );
|
|
384
|
-
|
|
385
|
-
it( 'passes null postId to hooks when collaboration is disabled', () => {
|
|
386
|
-
mockEditorState = {
|
|
387
|
-
...mockEditorState,
|
|
388
|
-
isCollaborationEnabled: false,
|
|
389
|
-
};
|
|
390
|
-
renderHook( () => useCollaboratorNotifications( 123, 'post' ) );
|
|
391
|
+
describe( 'when collaboration is disabled entirely', () => {
|
|
392
|
+
it( 'unsubscribes all three hooks', () => {
|
|
393
|
+
renderNotifications( { isCollaborationEnabled: false } );
|
|
391
394
|
|
|
392
|
-
expect(
|
|
393
|
-
expect(
|
|
394
|
-
expect(
|
|
395
|
+
expect( mockRegistered.joinPostId ).toBeNull();
|
|
396
|
+
expect( mockRegistered.leavePostId ).toBeNull();
|
|
397
|
+
expect( mockRegistered.savePostId ).toBeNull();
|
|
395
398
|
} );
|
|
396
399
|
} );
|
|
397
400
|
} );
|