Skip to content

Commit c383e86

Browse files
committed
Unit test coverage
1 parent 77463ee commit c383e86

2 files changed

Lines changed: 249 additions & 0 deletions

File tree

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/**
2+
* Internal dependencies
3+
*/
4+
import { resolveCurrentViewport } from '../resolve-current-viewport';
5+
6+
describe( 'resolveCurrentViewport', () => {
7+
it( 'returns mobile for Mobile device preview', () => {
8+
expect( resolveCurrentViewport( 'mobile', true, true ) ).toBe(
9+
'mobile'
10+
);
11+
} );
12+
13+
it( 'returns tablet for Tablet device preview', () => {
14+
expect( resolveCurrentViewport( 'tablet', true, true ) ).toBe(
15+
'tablet'
16+
);
17+
} );
18+
19+
it( 'falls back to mobile in Desktop preview on narrow width', () => {
20+
expect( resolveCurrentViewport( 'desktop', false, false ) ).toBe(
21+
'mobile'
22+
);
23+
} );
24+
25+
it( 'falls back to tablet in Desktop preview on medium width', () => {
26+
expect( resolveCurrentViewport( 'desktop', true, false ) ).toBe(
27+
'tablet'
28+
);
29+
} );
30+
31+
it( 'returns desktop in Desktop preview on wide width', () => {
32+
expect( resolveCurrentViewport( 'desktop', true, true ) ).toBe(
33+
'desktop'
34+
);
35+
} );
36+
} );
Lines changed: 213 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,213 @@
1+
/**
2+
* External dependencies
3+
*/
4+
import { render, screen } from '@testing-library/react';
5+
import userEvent from '@testing-library/user-event';
6+
7+
/**
8+
* WordPress dependencies
9+
*/
10+
import { useViewportMatch } from '@wordpress/compose';
11+
import { useSelect, useDispatch, useRegistry } from '@wordpress/data';
12+
import { store as blockEditorStore } from '@wordpress/block-editor';
13+
14+
/**
15+
* Internal dependencies
16+
*/
17+
import PreviewDropdown from '..';
18+
import { store as editorStore } from '../../../store';
19+
20+
jest.mock( '../../../store', () => ( {
21+
store: { name: 'editor' },
22+
} ) );
23+
24+
jest.mock( '@wordpress/compose', () => ( {
25+
useViewportMatch: jest.fn(),
26+
} ) );
27+
28+
jest.mock( '@wordpress/data', () => ( {
29+
useSelect: jest.fn(),
30+
useDispatch: jest.fn(),
31+
useRegistry: jest.fn(),
32+
} ) );
33+
34+
jest.mock( '@wordpress/core-data', () => ( {
35+
store: { name: 'core' },
36+
} ) );
37+
38+
jest.mock( '@wordpress/preferences', () => ( {
39+
store: { name: 'preferences' },
40+
} ) );
41+
42+
jest.mock( '@wordpress/i18n', () => ( {
43+
__: ( value ) => value,
44+
} ) );
45+
46+
jest.mock( '@wordpress/block-editor', () => ( {
47+
store: { name: 'block-editor' },
48+
privateApis: {
49+
resolveCurrentViewport: (
50+
deviceType,
51+
isLargerThanMobile,
52+
isLargerThanTablet
53+
) => {
54+
const normalized = deviceType?.toLowerCase();
55+
if ( normalized === 'mobile' || normalized === 'tablet' ) {
56+
return normalized;
57+
}
58+
if ( ! isLargerThanMobile ) {
59+
return 'mobile';
60+
}
61+
if ( ! isLargerThanTablet ) {
62+
return 'tablet';
63+
}
64+
return 'desktop';
65+
},
66+
},
67+
} ) );
68+
69+
jest.mock( '@wordpress/components', () => ( {
70+
DropdownMenu: ( { children } ) => (
71+
<div>{ children( { onClose: jest.fn() } ) }</div>
72+
),
73+
MenuGroup: ( { children } ) => <div>{ children }</div>,
74+
MenuItem: ( { children } ) => <div>{ children }</div>,
75+
MenuItemsChoice: ( { onSelect } ) => (
76+
<button onClick={ () => onSelect( 'Mobile' ) }>switch-to-mobile</button>
77+
),
78+
VisuallyHidden: ( { children } ) => <span>{ children }</span>,
79+
Icon: () => null,
80+
} ) );
81+
82+
jest.mock( '@wordpress/interface', () => ( {
83+
ActionItem: {
84+
Slot: () => null,
85+
},
86+
} ) );
87+
88+
jest.mock( '../../post-preview-button', () => () => null );
89+
90+
jest.mock( '../../../lock-unlock', () => ( {
91+
unlock: ( value ) => value,
92+
} ) );
93+
94+
describe( 'PreviewDropdown', () => {
95+
const editorDispatch = {
96+
setDeviceType: jest.fn(),
97+
setRenderingMode: jest.fn(),
98+
setDefaultRenderingMode: jest.fn(),
99+
};
100+
const blockEditorDispatch = {
101+
clearSelectedBlock: jest.fn(),
102+
resetZoomLevel: jest.fn(),
103+
};
104+
const registry = {
105+
select: jest.fn(),
106+
};
107+
108+
beforeEach( () => {
109+
jest.clearAllMocks();
110+
111+
useViewportMatch.mockImplementation( ( breakpoint, operator ) => {
112+
if ( breakpoint === 'mobile' && operator === '>=' ) {
113+
return true;
114+
}
115+
if ( breakpoint === 'medium' && operator === '>=' ) {
116+
return true;
117+
}
118+
if ( breakpoint === 'medium' && operator === '<' ) {
119+
return false;
120+
}
121+
return true;
122+
} );
123+
124+
useSelect.mockImplementation( ( mapSelect ) =>
125+
mapSelect( ( store ) => {
126+
if ( store === editorStore ) {
127+
return {
128+
getDeviceType: () => 'Desktop',
129+
getCurrentPostType: () => 'post',
130+
getCurrentTemplateId: () => null,
131+
getRenderingMode: () => 'template-locked',
132+
isListViewOpened: () => false,
133+
};
134+
}
135+
return {
136+
getEntityRecord: () => ( { home: 'https://example.com' } ),
137+
getPostType: () => ( { viewable: true } ),
138+
get: () => false,
139+
};
140+
} )
141+
);
142+
143+
useDispatch.mockImplementation( ( store ) => {
144+
if ( store === editorStore ) {
145+
return editorDispatch;
146+
}
147+
if ( store === blockEditorStore ) {
148+
return blockEditorDispatch;
149+
}
150+
return {};
151+
} );
152+
153+
registry.select.mockImplementation( ( store ) => {
154+
if ( store === editorStore ) {
155+
return {
156+
isListViewOpened: () => false,
157+
};
158+
}
159+
if ( store === blockEditorStore ) {
160+
return {
161+
getSelectedBlockClientId: () => 'client-1',
162+
isBlockHiddenAtViewport: () => true,
163+
isBlockParentHiddenAtViewport: () => false,
164+
};
165+
}
166+
return {};
167+
} );
168+
useRegistry.mockReturnValue( registry );
169+
} );
170+
171+
it( 'deselects when list view is closed and selected block is hidden', async () => {
172+
const user = userEvent.setup();
173+
render( <PreviewDropdown /> );
174+
175+
await user.click(
176+
screen.getByRole( 'button', { name: 'switch-to-mobile' } )
177+
);
178+
179+
expect( blockEditorDispatch.clearSelectedBlock ).toHaveBeenCalledTimes(
180+
1
181+
);
182+
expect( editorDispatch.setDeviceType ).toHaveBeenCalledWith( 'Mobile' );
183+
expect( blockEditorDispatch.resetZoomLevel ).toHaveBeenCalledTimes( 1 );
184+
} );
185+
186+
it( 'does not deselect when list view is open', async () => {
187+
const user = userEvent.setup();
188+
registry.select.mockImplementation( ( store ) => {
189+
if ( store === editorStore ) {
190+
return {
191+
isListViewOpened: () => true,
192+
};
193+
}
194+
if ( store === blockEditorStore ) {
195+
return {
196+
getSelectedBlockClientId: () => 'client-1',
197+
isBlockHiddenAtViewport: () => true,
198+
isBlockParentHiddenAtViewport: () => false,
199+
};
200+
}
201+
return {};
202+
} );
203+
204+
render( <PreviewDropdown /> );
205+
await user.click(
206+
screen.getByRole( 'button', { name: 'switch-to-mobile' } )
207+
);
208+
209+
expect( blockEditorDispatch.clearSelectedBlock ).not.toHaveBeenCalled();
210+
expect( editorDispatch.setDeviceType ).toHaveBeenCalledWith( 'Mobile' );
211+
expect( blockEditorDispatch.resetZoomLevel ).toHaveBeenCalledTimes( 1 );
212+
} );
213+
} );

0 commit comments

Comments
 (0)