Skip to content

Commit 66c70e2

Browse files
authored
Merge pull request #82 from codebtech/chore/add-component-tests
Add tests for react component
2 parents 9123515 + 87b286b commit 66c70e2

21 files changed

+812
-13
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,4 @@ tests-examples/
1717
build-script.sh
1818
integration-coverage.xml
1919
unit-coverage.xml
20+
.idea/

includes/Flag.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ class Flag {
2323
*
2424
* @var string $option_name
2525
*/
26-
public static $option_name = 'codeb_feature_flags';
26+
public static string $option_name = 'codeb_feature_flags';
2727

2828

2929
/**

jest-setup.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,13 @@
11
import '@testing-library/jest-dom';
2+
3+
Object.defineProperty(window, 'matchMedia', {
4+
writable: true,
5+
value: (query) => ({
6+
matches: false,
7+
media: query,
8+
onchange: null,
9+
addEventListener: () => {},
10+
removeEventListener: () => {},
11+
dispatchEvent: () => {},
12+
}),
13+
});

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
"lint:js:fix": "wp-scripts lint-js --fix",
1313
"prepare": "husky",
1414
"start": "wp-scripts start",
15-
"test:e2e": "npx playwright test --reporter=list",
15+
"test:e2e": "wp-scripts test-playwright",
1616
"test:js": "wp-scripts test-unit-js",
1717
"test:watch": "wp-scripts test-unit-js --watch",
1818
"version:major": "node ./scripts/version major",
@@ -25,6 +25,7 @@
2525
"php:multisite": "wp-env run tests-wordpress --env-cwd=wp-content/plugins/feature-flags composer test:multisite"
2626
},
2727
"dependencies": {
28+
"@testing-library/user-event": "^14.5.2",
2829
"@wordpress/api-fetch": "^6.48.0",
2930
"@wordpress/components": "^27.0.0",
3031
"@wordpress/data": "^9.22.0",

plugin.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
include_once __DIR__ . '/vendor/autoload.php';
4040
}
4141

42-
// Enqueure scripts, styles in settings page.
42+
// Enqueue scripts, styles in settings page.
4343
add_action(
4444
'admin_enqueue_scripts',
4545
static function ( string $page ): void {
@@ -156,7 +156,7 @@ static function ( $links ) {
156156

157157
/**
158158
* Uninstall method for the plugin.
159-
*
159+
*
160160
* @return void
161161
*/
162162
function codeb_feature_flags_uninstall(): void {

src/components/Flags.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import Header from './Header';
88
import { __ } from '@wordpress/i18n';
99
import { useDispatch } from '@wordpress/data';
1010

11-
const Layout = (): JSX.Element => {
11+
const Flags = () => {
1212
const [flags, setFlags] = useState<Flag[]>([]);
1313
const [isLoading, setIsLoading] = useState<boolean>(true);
1414
const [isSaving, setIsSaving] = useState<boolean>(false);
@@ -64,7 +64,7 @@ const Layout = (): JSX.Element => {
6464
return prevFlags.filter((f) => f.name !== '');
6565
});
6666

67-
remoteApi(flags);
67+
await remoteApi(flags);
6868
setIsSaving(false);
6969
};
7070

@@ -74,7 +74,7 @@ const Layout = (): JSX.Element => {
7474
const latestFlags = flags.filter((f) => f.id !== flagId);
7575
setFlags(latestFlags);
7676

77-
remoteApi(latestFlags);
77+
await remoteApi(latestFlags);
7878
setIsSaving(false);
7979
};
8080

@@ -120,4 +120,4 @@ const Layout = (): JSX.Element => {
120120
);
121121
};
122122

123-
export default Layout;
123+
export default Flags;
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import { render, fireEvent } from '@testing-library/react';
2+
import FlagRow from '../FlagRow';
3+
4+
test('FlagRow Function Test', async () => {
5+
const item = {
6+
id: 1,
7+
name: 'Test Flag',
8+
enabled: false,
9+
};
10+
const flags = [{ ...item }];
11+
const setFlags = jest.fn();
12+
const setDisableSave = jest.fn();
13+
const handleSave = jest.fn();
14+
const handleDeleteFlag = jest.fn();
15+
16+
const { getByRole, getByLabelText } = render(
17+
<FlagRow
18+
flags={flags}
19+
setFlags={setFlags}
20+
item={item}
21+
setDisableSave={setDisableSave}
22+
handleSave={handleSave}
23+
handleDeleteFlag={handleDeleteFlag}
24+
/>
25+
);
26+
27+
// Test flipping the toggle
28+
fireEvent.click(getByRole('checkbox'));
29+
expect(setFlags).toHaveBeenCalledTimes(1);
30+
expect(handleSave).toHaveBeenCalledTimes(1);
31+
32+
// Test editing the flag name
33+
const input = getByRole('textbox');
34+
fireEvent.change(input, { target: { value: 'New Flag' } });
35+
expect(setFlags).toHaveBeenCalledTimes(2);
36+
37+
const sdkButton = getByLabelText('Click to see SDK setting');
38+
expect(sdkButton).toBeInTheDocument();
39+
40+
const deleteButton = getByLabelText('Delete Flag');
41+
expect(deleteButton).toBeInTheDocument();
42+
});
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
import { render, screen, fireEvent } from '@testing-library/react';
2+
3+
import SubmitControls from '../SubmitControls';
4+
5+
describe('SubmitControls component', () => {
6+
let mockHandleSave, mockSetFlags;
7+
8+
beforeEach(() => {
9+
mockHandleSave = jest.fn();
10+
mockSetFlags = jest.fn();
11+
});
12+
13+
it('renders component with all header fields', () => {
14+
render(
15+
<SubmitControls
16+
flags={[]}
17+
setFlags={mockSetFlags}
18+
lastFlag={0}
19+
disableSave={false}
20+
isSaving={false}
21+
handleSave={mockHandleSave}
22+
/>
23+
);
24+
25+
const addFlagButton = screen.getByText('Add Flag');
26+
const saveButton = screen.queryByText('Save');
27+
const cancelButton = screen.queryByText('Cancel');
28+
29+
// Click on Add Flag button
30+
fireEvent.click(addFlagButton);
31+
32+
// Assert setFlags is called
33+
expect(mockSetFlags).toHaveBeenCalled();
34+
35+
// Assert Save & Cancel buttons do not exist when `lastFlag` is 0
36+
expect(saveButton).toBeNull();
37+
expect(cancelButton).toBeNull();
38+
});
39+
40+
test('save button interaction', () => {
41+
render(
42+
<SubmitControls
43+
flags={[]}
44+
setFlags={mockSetFlags}
45+
lastFlag={1}
46+
disableSave={false}
47+
isSaving={false}
48+
handleSave={mockHandleSave}
49+
/>
50+
);
51+
52+
const saveButton = screen.getByText('Save');
53+
54+
// Click on Save button
55+
fireEvent.click(saveButton);
56+
57+
// Assert handleSave is called
58+
expect(mockHandleSave).toHaveBeenCalled();
59+
});
60+
61+
test('display saving text', () => {
62+
render(
63+
<SubmitControls
64+
flags={[]}
65+
setFlags={mockSetFlags}
66+
lastFlag={1}
67+
disableSave={false}
68+
isSaving={true}
69+
handleSave={mockHandleSave}
70+
/>
71+
);
72+
73+
const savingButton = screen.getByText('Saving');
74+
75+
// Assert Save button is now displaying "Saving"
76+
expect(savingButton).toBeTruthy();
77+
});
78+
});

src/components/snippets/JsSnippet.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { useMemo } from '@wordpress/element';
33
import { __ } from '@wordpress/i18n';
44
import Clipboard from '../common/Clipboard';
55

6-
export default function ({ flag }: { flag: string }): JSX.Element {
6+
const JsSnippet = ({ flag }: { flag: string }) => {
77
const jsSnippet = useMemo(() => {
88
return `import domReady from '@wordpress/dom-ready';
99
domReady(function () {
@@ -22,4 +22,6 @@ domReady(function () {
2222
<Snippet data={jsSnippet} language={'typescript'} />
2323
</div>
2424
);
25-
}
25+
};
26+
27+
export default JsSnippet;

src/components/snippets/PhpSnippet.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { useMemo } from '@wordpress/element';
33
import { __ } from '@wordpress/i18n';
44
import Clipboard from '../common/Clipboard';
55

6-
export default function ({ flag }: { flag: string }): JSX.Element {
6+
const PhpSnippet = ({ flag }: { flag: string }) => {
77
const phpSnippet = useMemo(() => {
88
return `use CodeB\\FeatureFlags\\Flag;
99
if ( class_exists( '\\CodeB\\FeatureFlags\\Flag' ) && Flag::is_enabled( '${flag}' ) ) {
@@ -17,4 +17,6 @@ if ( class_exists( '\\CodeB\\FeatureFlags\\Flag' ) && Flag::is_enabled( '${flag}
1717
<Snippet data={phpSnippet} language={'php'} />
1818
</div>
1919
);
20-
}
20+
};
21+
22+
export default PhpSnippet;

0 commit comments

Comments
 (0)