Skip to content

Commit 1e33a3a

Browse files
authored
Tests: Add Jest unit tests for Block V3 React components (#331)
1 parent fba4d95 commit 1e33a3a

9 files changed

+3188
-0
lines changed

tests/js/blocks-v3/block-edit.test.js

Lines changed: 410 additions & 0 deletions
Large diffs are not rendered by default.

tests/js/blocks-v3/block-form.test.js

Lines changed: 508 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
/**
2+
* Unit tests for BlockPlaceholder component
3+
* Tests the placeholder UI shown when a block has no preview HTML
4+
*/
5+
6+
import React from 'react';
7+
import { render, screen, fireEvent } from '@testing-library/react';
8+
import '@testing-library/jest-dom';
9+
10+
import { BlockPlaceholder } from '../../../assets/src/js/pro/blocks-v3/components/block-placeholder';
11+
12+
// Mock the acf global object
13+
global.acf = {
14+
__: jest.fn( ( key ) => {
15+
const translations = {
16+
'Edit Block': 'Edit Block',
17+
};
18+
return translations[ key ] || key;
19+
} ),
20+
};
21+
22+
describe( 'BlockPlaceholder Component', () => {
23+
beforeEach( () => {
24+
jest.clearAllMocks();
25+
} );
26+
27+
test( 'renders with block label', () => {
28+
const mockSetModalOpen = jest.fn();
29+
30+
render(
31+
<BlockPlaceholder
32+
blockLabel="Test Block"
33+
setBlockFormModalOpen={ mockSetModalOpen }
34+
/>
35+
);
36+
37+
expect( screen.getByTestId( 'placeholder' ) ).toBeInTheDocument();
38+
expect( screen.getByTestId( 'placeholder-label' ) ).toHaveTextContent(
39+
'Test Block'
40+
);
41+
} );
42+
43+
test( 'renders with instructions when provided', () => {
44+
const mockSetModalOpen = jest.fn();
45+
46+
render(
47+
<BlockPlaceholder
48+
blockLabel="Test Block"
49+
setBlockFormModalOpen={ mockSetModalOpen }
50+
instructions="Please fill in the block fields"
51+
/>
52+
);
53+
54+
expect(
55+
screen.getByTestId( 'placeholder-instructions' )
56+
).toHaveTextContent( 'Please fill in the block fields' );
57+
} );
58+
59+
test( 'does not render instructions when not provided', () => {
60+
const mockSetModalOpen = jest.fn();
61+
62+
render(
63+
<BlockPlaceholder
64+
blockLabel="Test Block"
65+
setBlockFormModalOpen={ mockSetModalOpen }
66+
/>
67+
);
68+
69+
expect(
70+
screen.queryByTestId( 'placeholder-instructions' )
71+
).not.toBeInTheDocument();
72+
} );
73+
74+
test( 'renders Edit Block button', () => {
75+
const mockSetModalOpen = jest.fn();
76+
77+
render(
78+
<BlockPlaceholder
79+
blockLabel="Test Block"
80+
setBlockFormModalOpen={ mockSetModalOpen }
81+
/>
82+
);
83+
84+
const button = screen.getByRole( 'button' );
85+
expect( button ).toHaveTextContent( 'Edit Block' );
86+
} );
87+
88+
test( 'calls setBlockFormModalOpen with true when Edit Block button is clicked', () => {
89+
const mockSetModalOpen = jest.fn();
90+
91+
render(
92+
<BlockPlaceholder
93+
blockLabel="Test Block"
94+
setBlockFormModalOpen={ mockSetModalOpen }
95+
/>
96+
);
97+
98+
const button = screen.getByRole( 'button' );
99+
fireEvent.click( button );
100+
101+
expect( mockSetModalOpen ).toHaveBeenCalledTimes( 1 );
102+
expect( mockSetModalOpen ).toHaveBeenCalledWith( true );
103+
} );
104+
105+
test( 'renders icon in placeholder', () => {
106+
const mockSetModalOpen = jest.fn();
107+
108+
render(
109+
<BlockPlaceholder
110+
blockLabel="Test Block"
111+
setBlockFormModalOpen={ mockSetModalOpen }
112+
/>
113+
);
114+
115+
expect( screen.getByTestId( 'icon' ) ).toBeInTheDocument();
116+
} );
117+
118+
test( 'renders button with primary variant', () => {
119+
const mockSetModalOpen = jest.fn();
120+
121+
render(
122+
<BlockPlaceholder
123+
blockLabel="Test Block"
124+
setBlockFormModalOpen={ mockSetModalOpen }
125+
/>
126+
);
127+
128+
const button = screen.getByRole( 'button' );
129+
expect( button ).toHaveAttribute( 'data-variant', 'primary' );
130+
} );
131+
132+
test( 'uses acf.__ for translations', () => {
133+
const mockSetModalOpen = jest.fn();
134+
135+
render(
136+
<BlockPlaceholder
137+
blockLabel="Test Block"
138+
setBlockFormModalOpen={ mockSetModalOpen }
139+
/>
140+
);
141+
142+
expect( global.acf.__ ).toHaveBeenCalledWith( 'Edit Block' );
143+
} );
144+
145+
test( 'renders with different block labels', () => {
146+
const mockSetModalOpen = jest.fn();
147+
const testCases = [
148+
'Testimonial Block',
149+
'Image Gallery',
150+
'Contact Form',
151+
'Hero Section',
152+
];
153+
154+
testCases.forEach( ( label ) => {
155+
const { unmount } = render(
156+
<BlockPlaceholder
157+
blockLabel={ label }
158+
setBlockFormModalOpen={ mockSetModalOpen }
159+
/>
160+
);
161+
162+
expect(
163+
screen.getByTestId( 'placeholder-label' )
164+
).toHaveTextContent( label );
165+
unmount();
166+
} );
167+
} );
168+
} );
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
/**
2+
* Unit tests for BlockPreview component
3+
* Tests the simple wrapper component that renders block preview HTML with block props
4+
*/
5+
6+
/* global HTMLDivElement */
7+
8+
import React from 'react';
9+
import { render, screen } from '@testing-library/react';
10+
import '@testing-library/jest-dom';
11+
12+
import { BlockPreview } from '../../../assets/src/js/pro/blocks-v3/components/block-preview';
13+
14+
describe( 'BlockPreview Component', () => {
15+
test( 'renders children inside a div with block props', () => {
16+
const blockProps = {
17+
className: 'acf-block-preview',
18+
'data-testid': 'block-preview',
19+
};
20+
21+
render(
22+
<BlockPreview blockProps={ blockProps }>
23+
<p>Preview content</p>
24+
</BlockPreview>
25+
);
26+
27+
const previewElement = screen.getByTestId( 'block-preview' );
28+
expect( previewElement ).toBeInTheDocument();
29+
expect( previewElement ).toHaveClass( 'acf-block-preview' );
30+
expect( previewElement ).toContainHTML( '<p>Preview content</p>' );
31+
} );
32+
33+
test( 'renders multiple children correctly', () => {
34+
const blockProps = {
35+
'data-testid': 'block-preview',
36+
};
37+
38+
render(
39+
<BlockPreview blockProps={ blockProps }>
40+
<h1>Title</h1>
41+
<p>Paragraph 1</p>
42+
<p>Paragraph 2</p>
43+
</BlockPreview>
44+
);
45+
46+
const previewElement = screen.getByTestId( 'block-preview' );
47+
expect( previewElement.querySelectorAll( 'p' ) ).toHaveLength( 2 );
48+
expect( screen.getByText( 'Title' ) ).toBeInTheDocument();
49+
} );
50+
51+
test( 'renders empty when no children provided', () => {
52+
const blockProps = {
53+
'data-testid': 'block-preview',
54+
};
55+
56+
render( <BlockPreview blockProps={ blockProps } /> );
57+
58+
const previewElement = screen.getByTestId( 'block-preview' );
59+
expect( previewElement ).toBeEmptyDOMElement();
60+
} );
61+
62+
test( 'passes through all block props to the wrapper div', () => {
63+
const blockProps = {
64+
className: 'custom-class',
65+
id: 'block-123',
66+
'data-block': 'acf/test-block',
67+
'data-testid': 'block-preview',
68+
style: { backgroundColor: 'red' },
69+
};
70+
71+
render(
72+
<BlockPreview blockProps={ blockProps }>
73+
<span>Content</span>
74+
</BlockPreview>
75+
);
76+
77+
const previewElement = screen.getByTestId( 'block-preview' );
78+
expect( previewElement ).toHaveClass( 'custom-class' );
79+
expect( previewElement ).toHaveAttribute( 'id', 'block-123' );
80+
expect( previewElement ).toHaveAttribute(
81+
'data-block',
82+
'acf/test-block'
83+
);
84+
expect( previewElement ).toHaveStyle( { backgroundColor: 'red' } );
85+
} );
86+
87+
test( 'renders text content correctly', () => {
88+
const blockProps = {
89+
'data-testid': 'block-preview',
90+
};
91+
92+
render(
93+
<BlockPreview blockProps={ blockProps }>
94+
Plain text content
95+
</BlockPreview>
96+
);
97+
98+
expect( screen.getByText( 'Plain text content' ) ).toBeInTheDocument();
99+
} );
100+
101+
test( 'renders nested components correctly', () => {
102+
const blockProps = {
103+
'data-testid': 'block-preview',
104+
};
105+
106+
const NestedComponent = () => (
107+
<div data-testid="nested">Nested content</div>
108+
);
109+
110+
render(
111+
<BlockPreview blockProps={ blockProps }>
112+
<NestedComponent />
113+
</BlockPreview>
114+
);
115+
116+
expect( screen.getByTestId( 'nested' ) ).toBeInTheDocument();
117+
expect( screen.getByText( 'Nested content' ) ).toBeInTheDocument();
118+
} );
119+
120+
test( 'handles ref in block props', () => {
121+
const ref = React.createRef();
122+
const blockProps = {
123+
ref,
124+
'data-testid': 'block-preview',
125+
};
126+
127+
render(
128+
<BlockPreview blockProps={ blockProps }>
129+
<span>Content</span>
130+
</BlockPreview>
131+
);
132+
133+
expect( ref.current ).toBeInstanceOf( HTMLDivElement );
134+
} );
135+
} );

0 commit comments

Comments
 (0)