@wordpress/editor 12.14.1-next.d6164808d3.0 → 12.16.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 +8 -0
- package/build/components/post-featured-image/index.js +6 -4
- package/build/components/post-featured-image/index.js.map +1 -1
- package/build/components/post-publish-panel/index.js +6 -1
- package/build/components/post-publish-panel/index.js.map +1 -1
- package/build/components/post-schedule/index.js +1 -1
- package/build/components/post-schedule/index.js.map +1 -1
- package/build/components/post-schedule/label.js +2 -2
- package/build/components/post-schedule/label.js.map +1 -1
- package/build/components/post-taxonomies/flat-term-selector.js +6 -15
- package/build/components/post-taxonomies/flat-term-selector.js.map +1 -1
- package/build/components/post-trash/index.js +5 -1
- package/build/components/post-trash/index.js.map +1 -1
- package/build/components/post-url/label.js +1 -1
- package/build/components/post-url/label.js.map +1 -1
- package/build/components/provider/use-block-editor-settings.js +13 -5
- package/build/components/provider/use-block-editor-settings.js.map +1 -1
- package/build/store/actions.js +7 -0
- package/build/store/actions.js.map +1 -1
- package/build/store/reducer.js +26 -0
- package/build/store/reducer.js.map +1 -1
- package/build/store/selectors.js +14 -0
- package/build/store/selectors.js.map +1 -1
- package/build-module/components/post-featured-image/index.js +7 -5
- package/build-module/components/post-featured-image/index.js.map +1 -1
- package/build-module/components/post-publish-panel/index.js +7 -2
- package/build-module/components/post-publish-panel/index.js.map +1 -1
- package/build-module/components/post-schedule/index.js +2 -4
- package/build-module/components/post-schedule/index.js.map +1 -1
- package/build-module/components/post-schedule/label.js +3 -4
- package/build-module/components/post-schedule/label.js.map +1 -1
- package/build-module/components/post-taxonomies/flat-term-selector.js +7 -15
- package/build-module/components/post-taxonomies/flat-term-selector.js.map +1 -1
- package/build-module/components/post-trash/index.js +5 -1
- package/build-module/components/post-trash/index.js.map +1 -1
- package/build-module/components/post-url/label.js +1 -1
- package/build-module/components/post-url/label.js.map +1 -1
- package/build-module/components/provider/use-block-editor-settings.js +14 -6
- package/build-module/components/provider/use-block-editor-settings.js.map +1 -1
- package/build-module/store/actions.js +7 -0
- package/build-module/store/actions.js.map +1 -1
- package/build-module/store/reducer.js +24 -0
- package/build-module/store/reducer.js.map +1 -1
- package/build-module/store/selectors.js +11 -0
- package/build-module/store/selectors.js.map +1 -1
- package/package.json +28 -28
- package/src/components/document-outline/test/__snapshots__/index.js.snap +92 -48
- package/src/components/document-outline/test/index.js +27 -44
- package/src/components/page-attributes/test/order.js +57 -64
- package/src/components/post-featured-image/index.js +3 -3
- package/src/components/post-publish-button/test/index.js +88 -71
- package/src/components/post-publish-panel/index.js +7 -6
- package/src/components/post-publish-panel/test/__snapshots__/index.js.snap +670 -130
- package/src/components/post-publish-panel/test/index.js +30 -13
- package/src/components/post-saved-state/test/__snapshots__/index.js.snap +33 -24
- package/src/components/post-saved-state/test/index.js +31 -14
- package/src/components/post-schedule/index.js +2 -2
- package/src/components/post-schedule/label.js +3 -3
- package/src/components/post-schedule/test/label.js +7 -7
- package/src/components/post-slug/test/index.js +12 -25
- package/src/components/post-taxonomies/flat-term-selector.js +7 -18
- package/src/components/post-taxonomies/test/index.js +112 -44
- package/src/components/post-trash/index.js +5 -2
- package/src/components/post-url/label.js +1 -1
- package/src/components/provider/use-block-editor-settings.js +28 -8
- package/src/components/theme-support-check/test/index.js +13 -15
- package/src/store/actions.js +2 -0
- package/src/store/reducer.js +21 -0
- package/src/store/selectors.js +11 -0
- package/src/store/test/actions.js +42 -0
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* External dependencies
|
|
3
3
|
*/
|
|
4
|
-
import {
|
|
4
|
+
import { render } from '@testing-library/react';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* WordPress dependencies
|
|
8
|
+
*/
|
|
9
|
+
import { select } from '@wordpress/data';
|
|
10
|
+
import { store as editorStore } from '@wordpress/editor';
|
|
11
|
+
import { store as coreStore } from '@wordpress/core-data';
|
|
5
12
|
|
|
6
13
|
/**
|
|
7
14
|
* Internal dependencies
|
|
@@ -9,39 +16,49 @@ import { shallow } from 'enzyme';
|
|
|
9
16
|
import { PostPublishPanel } from '../index';
|
|
10
17
|
|
|
11
18
|
describe( 'PostPublishPanel', () => {
|
|
19
|
+
jest.spyOn( select( coreStore ), 'getPostType' ).mockReturnValue( {
|
|
20
|
+
labels: {
|
|
21
|
+
singular_name: 'post',
|
|
22
|
+
},
|
|
23
|
+
} );
|
|
24
|
+
|
|
25
|
+
jest.spyOn( select( editorStore ), 'getCurrentPost' ).mockReturnValue( {
|
|
26
|
+
link: 'https://wordpress.local/sample-page/',
|
|
27
|
+
} );
|
|
28
|
+
|
|
12
29
|
it( 'should render the pre-publish panel if the post is not saving, published or scheduled', () => {
|
|
13
|
-
const
|
|
30
|
+
const { container } = render(
|
|
14
31
|
<PostPublishPanel
|
|
15
32
|
isPublished={ false }
|
|
16
33
|
isScheduled={ false }
|
|
17
34
|
isSaving={ false }
|
|
18
35
|
/>
|
|
19
36
|
);
|
|
20
|
-
expect(
|
|
37
|
+
expect( container ).toMatchSnapshot();
|
|
21
38
|
} );
|
|
22
39
|
|
|
23
40
|
it( 'should render the pre-publish panel if post status is scheduled but date is before now', () => {
|
|
24
|
-
const
|
|
25
|
-
<PostPublishPanel isScheduled
|
|
41
|
+
const { container } = render(
|
|
42
|
+
<PostPublishPanel isScheduled isBeingScheduled={ false } />
|
|
26
43
|
);
|
|
27
44
|
|
|
28
|
-
expect(
|
|
45
|
+
expect( container ).toMatchSnapshot();
|
|
29
46
|
} );
|
|
30
47
|
|
|
31
48
|
it( 'should render the spinner if the post is being saved', () => {
|
|
32
|
-
const
|
|
33
|
-
expect(
|
|
49
|
+
const { container } = render( <PostPublishPanel isSaving /> );
|
|
50
|
+
expect( container ).toMatchSnapshot();
|
|
34
51
|
} );
|
|
35
52
|
|
|
36
53
|
it( 'should render the post-publish panel if the post is published', () => {
|
|
37
|
-
const
|
|
38
|
-
expect(
|
|
54
|
+
const { container } = render( <PostPublishPanel isPublished /> );
|
|
55
|
+
expect( container ).toMatchSnapshot();
|
|
39
56
|
} );
|
|
40
57
|
|
|
41
58
|
it( 'should render the post-publish panel if the post is scheduled', () => {
|
|
42
|
-
const
|
|
43
|
-
<PostPublishPanel isScheduled
|
|
59
|
+
const { container } = render(
|
|
60
|
+
<PostPublishPanel isScheduled isBeingScheduled />
|
|
44
61
|
);
|
|
45
|
-
expect(
|
|
62
|
+
expect( container ).toMatchSnapshot();
|
|
46
63
|
} );
|
|
47
64
|
} );
|
|
@@ -1,34 +1,43 @@
|
|
|
1
1
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
2
|
|
|
3
3
|
exports[`PostSavedState returns a disabled button if the post is not saveable 1`] = `
|
|
4
|
-
<
|
|
5
|
-
aria-disabled=
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
4
|
+
<button
|
|
5
|
+
aria-disabled="true"
|
|
6
|
+
aria-label="Save draft"
|
|
7
|
+
class="components-button has-text has-icon"
|
|
8
|
+
type="button"
|
|
9
|
+
>
|
|
10
|
+
<svg
|
|
11
|
+
aria-hidden="true"
|
|
12
|
+
focusable="false"
|
|
13
|
+
height="24"
|
|
14
|
+
viewBox="0 0 24 24"
|
|
15
|
+
width="24"
|
|
16
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
17
|
+
>
|
|
18
|
+
<path
|
|
19
|
+
d="M17.3 10.1c0-2.5-2.1-4.4-4.8-4.4-2.2 0-4.1 1.4-4.6 3.3h-.2C5.7 9 4 10.7 4 12.8c0 2.1 1.7 3.8 3.7 3.8h9c1.8 0 3.2-1.5 3.2-3.3.1-1.6-1.1-2.9-2.6-3.2zm-.5 5.1h-4v-2.4L14 14l1-1-3-3-3 3 1 1 1.2-1.2v2.4H7.7c-1.2 0-2.2-1.1-2.2-2.3s1-2.4 2.2-2.4H9l.3-1.1c.4-1.3 1.7-2.2 3.2-2.2 1.8 0 3.3 1.3 3.3 2.9v1.3l1.3.2c.8.1 1.4.9 1.4 1.8 0 1-.8 1.8-1.7 1.8z"
|
|
20
|
+
/>
|
|
21
|
+
</svg>
|
|
22
|
+
</button>
|
|
19
23
|
`;
|
|
20
24
|
|
|
21
|
-
exports[`PostSavedState returns a switch to draft link if the post is published 1`] =
|
|
25
|
+
exports[`PostSavedState returns a switch to draft link if the post is published 1`] = `
|
|
26
|
+
<button
|
|
27
|
+
class="components-button editor-post-switch-to-draft is-tertiary"
|
|
28
|
+
type="button"
|
|
29
|
+
>
|
|
30
|
+
Switch to draft
|
|
31
|
+
</button>
|
|
32
|
+
`;
|
|
22
33
|
|
|
23
34
|
exports[`PostSavedState should return Save button if edits to be saved 1`] = `
|
|
24
|
-
<
|
|
25
|
-
aria-disabled=
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
shortcut="Ctrl+S"
|
|
30
|
-
variant="tertiary"
|
|
35
|
+
<button
|
|
36
|
+
aria-disabled="false"
|
|
37
|
+
aria-label="Save draft"
|
|
38
|
+
class="components-button editor-post-save-draft is-tertiary"
|
|
39
|
+
type="button"
|
|
31
40
|
>
|
|
32
41
|
Save draft
|
|
33
|
-
</
|
|
42
|
+
</button>
|
|
34
43
|
`;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* External dependencies
|
|
3
3
|
*/
|
|
4
|
-
import {
|
|
4
|
+
import { render, screen, within } from '@testing-library/react';
|
|
5
|
+
import userEvent from '@testing-library/user-event';
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* WordPress dependencies
|
|
@@ -19,6 +20,7 @@ const mockSavePost = jest.fn();
|
|
|
19
20
|
jest.mock( '@wordpress/data/src/components/use-dispatch', () => {
|
|
20
21
|
return {
|
|
21
22
|
useDispatch: () => ( { savePost: mockSavePost } ),
|
|
23
|
+
useDispatchWithMap: jest.fn(),
|
|
22
24
|
};
|
|
23
25
|
} );
|
|
24
26
|
|
|
@@ -34,6 +36,10 @@ jest.mock( '@wordpress/compose/src/hooks/use-viewport-match', () => {
|
|
|
34
36
|
return mock;
|
|
35
37
|
} );
|
|
36
38
|
|
|
39
|
+
jest.mock( '@wordpress/icons/src/icon', () => () => (
|
|
40
|
+
<div data-testid="test-icon" />
|
|
41
|
+
) );
|
|
42
|
+
|
|
37
43
|
describe( 'PostSavedState', () => {
|
|
38
44
|
it( 'should display saving while save in progress, even if not saveable', () => {
|
|
39
45
|
useSelect.mockImplementation( () => ( {
|
|
@@ -43,9 +49,9 @@ describe( 'PostSavedState', () => {
|
|
|
43
49
|
isSaving: true,
|
|
44
50
|
} ) );
|
|
45
51
|
|
|
46
|
-
|
|
52
|
+
render( <PostSavedState /> );
|
|
47
53
|
|
|
48
|
-
expect(
|
|
54
|
+
expect( screen.getByText( 'Saving' ) ).toBeVisible();
|
|
49
55
|
} );
|
|
50
56
|
|
|
51
57
|
it( 'returns a disabled button if the post is not saveable', () => {
|
|
@@ -56,9 +62,9 @@ describe( 'PostSavedState', () => {
|
|
|
56
62
|
isSaving: false,
|
|
57
63
|
} ) );
|
|
58
64
|
|
|
59
|
-
|
|
65
|
+
render( <PostSavedState /> );
|
|
60
66
|
|
|
61
|
-
expect(
|
|
67
|
+
expect( screen.getByRole( 'button' ) ).toMatchSnapshot();
|
|
62
68
|
} );
|
|
63
69
|
|
|
64
70
|
it( 'returns a switch to draft link if the post is published', () => {
|
|
@@ -66,9 +72,9 @@ describe( 'PostSavedState', () => {
|
|
|
66
72
|
isPublished: true,
|
|
67
73
|
} ) );
|
|
68
74
|
|
|
69
|
-
|
|
75
|
+
render( <PostSavedState /> );
|
|
70
76
|
|
|
71
|
-
expect(
|
|
77
|
+
expect( screen.getByRole( 'button' ) ).toMatchSnapshot();
|
|
72
78
|
} );
|
|
73
79
|
|
|
74
80
|
it( 'should return Saved text if not new and not dirty', () => {
|
|
@@ -79,13 +85,19 @@ describe( 'PostSavedState', () => {
|
|
|
79
85
|
isSaving: false,
|
|
80
86
|
} ) );
|
|
81
87
|
|
|
82
|
-
|
|
88
|
+
render( <PostSavedState /> );
|
|
89
|
+
|
|
90
|
+
const button = screen.getByRole( 'button' );
|
|
83
91
|
|
|
84
|
-
expect(
|
|
85
|
-
expect(
|
|
92
|
+
expect( within( button ).getByTestId( 'test-icon' ) ).toBeVisible();
|
|
93
|
+
expect( within( button ).getByText( 'Saved' ) ).toBeVisible();
|
|
86
94
|
} );
|
|
87
95
|
|
|
88
|
-
it( 'should return Save button if edits to be saved', () => {
|
|
96
|
+
it( 'should return Save button if edits to be saved', async () => {
|
|
97
|
+
const user = userEvent.setup( {
|
|
98
|
+
advanceTimers: jest.advanceTimersByTime,
|
|
99
|
+
} );
|
|
100
|
+
|
|
89
101
|
useSelect.mockImplementation( () => ( {
|
|
90
102
|
isDirty: true,
|
|
91
103
|
isNew: false,
|
|
@@ -96,11 +108,16 @@ describe( 'PostSavedState', () => {
|
|
|
96
108
|
// Simulate the viewport being considered large.
|
|
97
109
|
useViewportMatch.mockImplementation( () => true );
|
|
98
110
|
|
|
99
|
-
|
|
111
|
+
render( <PostSavedState /> );
|
|
112
|
+
|
|
113
|
+
const button = screen.getByRole( 'button' );
|
|
114
|
+
|
|
115
|
+
expect( button ).toMatchSnapshot();
|
|
116
|
+
|
|
117
|
+
await user.click( button );
|
|
100
118
|
|
|
101
|
-
expect( wrapper ).toMatchSnapshot();
|
|
102
|
-
wrapper.simulate( 'click', {} );
|
|
103
119
|
expect( mockSavePost ).toHaveBeenCalled();
|
|
120
|
+
|
|
104
121
|
// Regression: Verify the event object is not passed to prop callback.
|
|
105
122
|
expect( mockSavePost.mock.calls[ 0 ] ).toEqual( [] );
|
|
106
123
|
} );
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* WordPress dependencies
|
|
3
3
|
*/
|
|
4
|
-
import {
|
|
4
|
+
import { getSettings } from '@wordpress/date';
|
|
5
5
|
import { useDispatch, useSelect } from '@wordpress/data';
|
|
6
6
|
import { __experimentalPublishDateTimePicker as PublishDateTimePicker } from '@wordpress/block-editor';
|
|
7
7
|
import { useState, useMemo } from '@wordpress/element';
|
|
@@ -61,7 +61,7 @@ export default function PostSchedule( { onClose } ) {
|
|
|
61
61
|
[ eventsByPostType ]
|
|
62
62
|
);
|
|
63
63
|
|
|
64
|
-
const settings =
|
|
64
|
+
const settings = getSettings();
|
|
65
65
|
|
|
66
66
|
// To know if the current timezone is a 12 hour time with look for "a" in the time format
|
|
67
67
|
// We also make sure this a is not escaped by a "/"
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* WordPress dependencies
|
|
3
3
|
*/
|
|
4
4
|
import { __, _x, sprintf, isRTL } from '@wordpress/i18n';
|
|
5
|
-
import {
|
|
5
|
+
import { getSettings, getDate, dateI18n } from '@wordpress/date';
|
|
6
6
|
import { useSelect } from '@wordpress/data';
|
|
7
7
|
|
|
8
8
|
/**
|
|
@@ -95,7 +95,7 @@ export function getPostScheduleLabel(
|
|
|
95
95
|
}
|
|
96
96
|
|
|
97
97
|
function getTimezoneAbbreviation() {
|
|
98
|
-
const { timezone } =
|
|
98
|
+
const { timezone } = getSettings();
|
|
99
99
|
|
|
100
100
|
if ( timezone.abbr && isNaN( Number( timezone.abbr ) ) ) {
|
|
101
101
|
return timezone.abbr;
|
|
@@ -106,7 +106,7 @@ function getTimezoneAbbreviation() {
|
|
|
106
106
|
}
|
|
107
107
|
|
|
108
108
|
function isTimezoneSameAsSiteTimezone( date ) {
|
|
109
|
-
const { timezone } =
|
|
109
|
+
const { timezone } = getSettings();
|
|
110
110
|
|
|
111
111
|
const siteOffset = Number( timezone.offset );
|
|
112
112
|
const dateOffset = -1 * ( date.getTimezoneOffset() / 60 );
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* WordPress dependencies
|
|
3
3
|
*/
|
|
4
|
-
import {
|
|
4
|
+
import { getSettings, setSettings } from '@wordpress/date';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Internal dependencies
|
|
@@ -15,7 +15,7 @@ describe( 'getFullPostScheduleLabel', () => {
|
|
|
15
15
|
} );
|
|
16
16
|
|
|
17
17
|
it( "should show site's timezone abbr", () => {
|
|
18
|
-
const settings =
|
|
18
|
+
const settings = getSettings();
|
|
19
19
|
|
|
20
20
|
setSettings( {
|
|
21
21
|
...settings,
|
|
@@ -29,7 +29,7 @@ describe( 'getFullPostScheduleLabel', () => {
|
|
|
29
29
|
} );
|
|
30
30
|
|
|
31
31
|
it( "should show site's timezone offset", () => {
|
|
32
|
-
const settings =
|
|
32
|
+
const settings = getSettings();
|
|
33
33
|
|
|
34
34
|
setSettings( {
|
|
35
35
|
...settings,
|
|
@@ -67,7 +67,7 @@ describe( 'getPostScheduleLabel', () => {
|
|
|
67
67
|
} );
|
|
68
68
|
|
|
69
69
|
it( "should show today if date is same day as now and user timezone equals site's timezone", () => {
|
|
70
|
-
const settings =
|
|
70
|
+
const settings = getSettings();
|
|
71
71
|
|
|
72
72
|
setSettings( {
|
|
73
73
|
...settings,
|
|
@@ -86,7 +86,7 @@ describe( 'getPostScheduleLabel', () => {
|
|
|
86
86
|
} );
|
|
87
87
|
|
|
88
88
|
it( "should show tomorrow if date is same day as now + 1 day and user timezone equals site's timezone", () => {
|
|
89
|
-
const settings =
|
|
89
|
+
const settings = getSettings();
|
|
90
90
|
|
|
91
91
|
setSettings( {
|
|
92
92
|
...settings,
|
|
@@ -105,7 +105,7 @@ describe( 'getPostScheduleLabel', () => {
|
|
|
105
105
|
} );
|
|
106
106
|
|
|
107
107
|
it( "should hide year if date is same year as now and user timezone equals site's timezone", () => {
|
|
108
|
-
const settings =
|
|
108
|
+
const settings = getSettings();
|
|
109
109
|
|
|
110
110
|
setSettings( {
|
|
111
111
|
...settings,
|
|
@@ -124,7 +124,7 @@ describe( 'getPostScheduleLabel', () => {
|
|
|
124
124
|
} );
|
|
125
125
|
|
|
126
126
|
it( "should show year if date is not same year as now and user timezone equals site's timezone", () => {
|
|
127
|
-
const settings =
|
|
127
|
+
const settings = getSettings();
|
|
128
128
|
|
|
129
129
|
setSettings( {
|
|
130
130
|
...settings,
|
|
@@ -1,12 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* External dependencies
|
|
3
3
|
*/
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* WordPress dependencies
|
|
8
|
-
*/
|
|
9
|
-
import { TextControl } from '@wordpress/components';
|
|
4
|
+
import { render, screen } from '@testing-library/react';
|
|
5
|
+
import userEvent from '@testing-library/user-event';
|
|
10
6
|
|
|
11
7
|
/**
|
|
12
8
|
* Internal dependencies
|
|
@@ -14,28 +10,19 @@ import { TextControl } from '@wordpress/components';
|
|
|
14
10
|
import { PostSlug } from '../';
|
|
15
11
|
|
|
16
12
|
describe( 'PostSlug', () => {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
wrapper.find( TextControl ).prop( 'onChange' )( 'single' );
|
|
22
|
-
|
|
23
|
-
expect( wrapper.state().editedSlug ).toEqual( 'single' );
|
|
13
|
+
it( 'should update slug with sanitized input', async () => {
|
|
14
|
+
const user = userEvent.setup( {
|
|
15
|
+
advanceTimers: jest.advanceTimersByTime,
|
|
24
16
|
} );
|
|
17
|
+
const onUpdateSlug = jest.fn();
|
|
25
18
|
|
|
26
|
-
|
|
27
|
-
const onUpdateSlug = jest.fn();
|
|
28
|
-
const wrapper = shallow(
|
|
29
|
-
<PostSlug postSlug="index" onUpdateSlug={ onUpdateSlug } />
|
|
30
|
-
);
|
|
19
|
+
render( <PostSlug postSlug="index" onUpdateSlug={ onUpdateSlug } /> );
|
|
31
20
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
} );
|
|
21
|
+
const input = screen.getByRole( 'textbox', { name: 'Slug' } );
|
|
22
|
+
await user.clear( input );
|
|
23
|
+
await user.type( input, 'Foo Bar-Baz 9!' );
|
|
24
|
+
input.blur();
|
|
37
25
|
|
|
38
|
-
|
|
39
|
-
} );
|
|
26
|
+
expect( onUpdateSlug ).toHaveBeenCalledWith( 'foo-bar-baz-9' );
|
|
40
27
|
} );
|
|
41
28
|
} );
|
|
@@ -13,14 +13,13 @@ import { useSelect, useDispatch } from '@wordpress/data';
|
|
|
13
13
|
import { store as coreStore } from '@wordpress/core-data';
|
|
14
14
|
import { useDebounce } from '@wordpress/compose';
|
|
15
15
|
import apiFetch from '@wordpress/api-fetch';
|
|
16
|
-
import { addQueryArgs } from '@wordpress/url';
|
|
17
16
|
import { speak } from '@wordpress/a11y';
|
|
18
17
|
|
|
19
18
|
/**
|
|
20
19
|
* Internal dependencies
|
|
21
20
|
*/
|
|
22
21
|
import { store as editorStore } from '../../store';
|
|
23
|
-
import { unescapeString, unescapeTerm
|
|
22
|
+
import { unescapeString, unescapeTerm } from '../../utils/terms';
|
|
24
23
|
import MostUsedTerms from './most-used-terms';
|
|
25
24
|
|
|
26
25
|
/**
|
|
@@ -64,24 +63,14 @@ function findOrCreateTerm( termName, restBase, namespace ) {
|
|
|
64
63
|
data: { name: escapedTermName },
|
|
65
64
|
} )
|
|
66
65
|
.catch( ( error ) => {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
// If the terms exist, fetch it instead of creating a new one.
|
|
70
|
-
const addRequest = apiFetch( {
|
|
71
|
-
path: addQueryArgs( `/${ namespace }/${ restBase }`, {
|
|
72
|
-
...DEFAULT_QUERY,
|
|
73
|
-
search: escapedTermName,
|
|
74
|
-
} ),
|
|
75
|
-
} ).then( unescapeTerms );
|
|
76
|
-
|
|
77
|
-
return addRequest.then( ( searchResult ) => {
|
|
78
|
-
return find( searchResult, ( result ) =>
|
|
79
|
-
isSameTermName( result.name, termName )
|
|
80
|
-
);
|
|
81
|
-
} );
|
|
66
|
+
if ( error.code !== 'term_exists' ) {
|
|
67
|
+
return Promise.reject( error );
|
|
82
68
|
}
|
|
83
69
|
|
|
84
|
-
return Promise.
|
|
70
|
+
return Promise.resolve( {
|
|
71
|
+
id: error.data.term_id,
|
|
72
|
+
name: termName,
|
|
73
|
+
} );
|
|
85
74
|
} )
|
|
86
75
|
.then( unescapeTerm );
|
|
87
76
|
}
|
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* External dependencies
|
|
3
3
|
*/
|
|
4
|
-
import {
|
|
4
|
+
import { render, screen } from '@testing-library/react';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* WordPress dependencies
|
|
8
|
+
*/
|
|
9
|
+
import { select } from '@wordpress/data';
|
|
10
|
+
import { store as editorStore } from '@wordpress/editor';
|
|
11
|
+
import { store as coreStore } from '@wordpress/core-data';
|
|
5
12
|
|
|
6
13
|
/**
|
|
7
14
|
* Internal dependencies
|
|
@@ -9,49 +16,104 @@ import { shallow } from 'enzyme';
|
|
|
9
16
|
import { PostTaxonomies } from '../';
|
|
10
17
|
|
|
11
18
|
describe( 'PostTaxonomies', () => {
|
|
19
|
+
const genresTaxonomy = {
|
|
20
|
+
name: 'Genres',
|
|
21
|
+
slug: 'genre',
|
|
22
|
+
types: [ 'book' ],
|
|
23
|
+
hierarchical: true,
|
|
24
|
+
rest_base: 'genres',
|
|
25
|
+
visibility: {
|
|
26
|
+
show_ui: true,
|
|
27
|
+
},
|
|
28
|
+
labels: {
|
|
29
|
+
add_new_item: 'Add new genre',
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const categoriesTaxonomy = {
|
|
34
|
+
name: 'Categories',
|
|
35
|
+
slug: 'category',
|
|
36
|
+
types: [ 'post', 'page' ],
|
|
37
|
+
hierarchical: true,
|
|
38
|
+
rest_base: 'categories',
|
|
39
|
+
visibility: {
|
|
40
|
+
show_ui: true,
|
|
41
|
+
},
|
|
42
|
+
labels: {
|
|
43
|
+
add_new_item: 'Add new category',
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
beforeEach( () => {
|
|
48
|
+
jest.spyOn( select( editorStore ), 'getCurrentPost' ).mockReturnValue( {
|
|
49
|
+
_links: {
|
|
50
|
+
'wp:action-create-categories': [
|
|
51
|
+
{
|
|
52
|
+
href: 'http://localhost:8889/index.php?rest_route=/wp/v2/foo/create-categories',
|
|
53
|
+
},
|
|
54
|
+
],
|
|
55
|
+
'wp:action-create-genres': [
|
|
56
|
+
{
|
|
57
|
+
href: 'http://localhost:8889/index.php?rest_route=/wp/v2/create-genres',
|
|
58
|
+
},
|
|
59
|
+
],
|
|
60
|
+
'wp:action-assign-categories': [
|
|
61
|
+
{
|
|
62
|
+
href: 'http://localhost:8889/index.php?rest_route=/wp/v2/foo/assign-categories',
|
|
63
|
+
},
|
|
64
|
+
],
|
|
65
|
+
'wp:action-assign-genres': [
|
|
66
|
+
{
|
|
67
|
+
href: 'http://localhost:8889/index.php?rest_route=/wp/v2/assign-genres',
|
|
68
|
+
},
|
|
69
|
+
],
|
|
70
|
+
},
|
|
71
|
+
} );
|
|
72
|
+
|
|
73
|
+
jest.spyOn( select( coreStore ), 'getTaxonomy' ).mockImplementation(
|
|
74
|
+
( slug ) => {
|
|
75
|
+
switch ( slug ) {
|
|
76
|
+
case 'category': {
|
|
77
|
+
return categoriesTaxonomy;
|
|
78
|
+
}
|
|
79
|
+
case 'genre': {
|
|
80
|
+
return genresTaxonomy;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
);
|
|
85
|
+
} );
|
|
86
|
+
|
|
12
87
|
it( 'should render no children if taxonomy data not available', () => {
|
|
13
88
|
const taxonomies = {};
|
|
14
89
|
|
|
15
|
-
const
|
|
90
|
+
const { container } = render(
|
|
16
91
|
<PostTaxonomies postType="page" taxonomies={ taxonomies } />
|
|
17
92
|
);
|
|
18
93
|
|
|
19
|
-
expect(
|
|
94
|
+
expect( container ).toBeEmptyDOMElement();
|
|
20
95
|
} );
|
|
21
96
|
|
|
22
97
|
it( 'should render taxonomy components for taxonomies assigned to post type', () => {
|
|
23
|
-
const
|
|
24
|
-
name: 'Genres',
|
|
25
|
-
slug: 'genre',
|
|
26
|
-
types: [ 'book' ],
|
|
27
|
-
hierarchical: true,
|
|
28
|
-
rest_base: 'genres',
|
|
29
|
-
visibility: {
|
|
30
|
-
show_ui: true,
|
|
31
|
-
},
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
const categoriesTaxonomy = {
|
|
35
|
-
name: 'Categories',
|
|
36
|
-
slug: 'category',
|
|
37
|
-
types: [ 'post', 'page' ],
|
|
38
|
-
hierarchical: true,
|
|
39
|
-
rest_base: 'categories',
|
|
40
|
-
visibility: {
|
|
41
|
-
show_ui: true,
|
|
42
|
-
},
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
const wrapperOne = shallow(
|
|
98
|
+
const { rerender } = render(
|
|
46
99
|
<PostTaxonomies
|
|
47
100
|
postType="book"
|
|
48
101
|
taxonomies={ [ genresTaxonomy, categoriesTaxonomy ] }
|
|
49
102
|
/>
|
|
50
103
|
);
|
|
51
104
|
|
|
52
|
-
expect(
|
|
105
|
+
expect( screen.getByRole( 'group', { name: 'Genres' } ) ).toBeVisible();
|
|
106
|
+
expect(
|
|
107
|
+
screen.queryByRole( 'group', { name: 'Categories' } )
|
|
108
|
+
).not.toBeInTheDocument();
|
|
109
|
+
expect(
|
|
110
|
+
screen.getByRole( 'button', { name: 'Add new genre' } )
|
|
111
|
+
).toBeVisible();
|
|
112
|
+
expect(
|
|
113
|
+
screen.queryByRole( 'button', { name: 'Add new category' } )
|
|
114
|
+
).not.toBeInTheDocument();
|
|
53
115
|
|
|
54
|
-
|
|
116
|
+
rerender(
|
|
55
117
|
<PostTaxonomies
|
|
56
118
|
postType="book"
|
|
57
119
|
taxonomies={ [
|
|
@@ -64,28 +126,29 @@ describe( 'PostTaxonomies', () => {
|
|
|
64
126
|
/>
|
|
65
127
|
);
|
|
66
128
|
|
|
67
|
-
expect(
|
|
129
|
+
expect( screen.getByRole( 'group', { name: 'Genres' } ) ).toBeVisible();
|
|
130
|
+
expect(
|
|
131
|
+
screen.getByRole( 'group', { name: 'Categories' } )
|
|
132
|
+
).toBeVisible();
|
|
133
|
+
expect(
|
|
134
|
+
screen.getByRole( 'button', { name: 'Add new genre' } )
|
|
135
|
+
).toBeVisible();
|
|
136
|
+
expect(
|
|
137
|
+
screen.getByRole( 'button', { name: 'Add new category' } )
|
|
138
|
+
).toBeVisible();
|
|
68
139
|
} );
|
|
69
140
|
|
|
70
141
|
it( 'should not render taxonomy components that hide their ui', () => {
|
|
71
|
-
const
|
|
72
|
-
name: 'Genres',
|
|
73
|
-
slug: 'genre',
|
|
74
|
-
types: [ 'book' ],
|
|
75
|
-
hierarchical: true,
|
|
76
|
-
rest_base: 'genres',
|
|
77
|
-
visibility: {
|
|
78
|
-
show_ui: true,
|
|
79
|
-
},
|
|
80
|
-
};
|
|
81
|
-
|
|
82
|
-
const wrapperOne = shallow(
|
|
142
|
+
const { rerender } = render(
|
|
83
143
|
<PostTaxonomies postType="book" taxonomies={ [ genresTaxonomy ] } />
|
|
84
144
|
);
|
|
85
145
|
|
|
86
|
-
expect(
|
|
146
|
+
expect( screen.getByRole( 'group', { name: 'Genres' } ) ).toBeVisible();
|
|
147
|
+
expect(
|
|
148
|
+
screen.getByRole( 'button', { name: 'Add new genre' } )
|
|
149
|
+
).toBeVisible();
|
|
87
150
|
|
|
88
|
-
|
|
151
|
+
rerender(
|
|
89
152
|
<PostTaxonomies
|
|
90
153
|
postType="book"
|
|
91
154
|
taxonomies={ [
|
|
@@ -97,6 +160,11 @@ describe( 'PostTaxonomies', () => {
|
|
|
97
160
|
/>
|
|
98
161
|
);
|
|
99
162
|
|
|
100
|
-
expect(
|
|
163
|
+
expect(
|
|
164
|
+
screen.queryByRole( 'group', { name: 'Genres' } )
|
|
165
|
+
).not.toBeInTheDocument();
|
|
166
|
+
expect(
|
|
167
|
+
screen.queryByRole( 'button', { name: 'Add new genre' } )
|
|
168
|
+
).not.toBeInTheDocument();
|
|
101
169
|
} );
|
|
102
170
|
} );
|