Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,4 @@ tests-examples/
build-script.sh
integration-coverage.xml
unit-coverage.xml
.idea/
2 changes: 1 addition & 1 deletion includes/Flag.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class Flag {
*
* @var string $option_name
*/
public static $option_name = 'codeb_feature_flags';
public static string $option_name = 'codeb_feature_flags';


/**
Expand Down
12 changes: 12 additions & 0 deletions jest-setup.js
Original file line number Diff line number Diff line change
@@ -1 +1,13 @@
import '@testing-library/jest-dom';

Object.defineProperty(window, 'matchMedia', {
writable: true,
value: (query) => ({
matches: false,
media: query,
onchange: null,
addEventListener: () => {},
removeEventListener: () => {},
dispatchEvent: () => {},
}),
});
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"lint:js:fix": "wp-scripts lint-js --fix",
"prepare": "husky",
"start": "wp-scripts start",
"test:e2e": "npx playwright test --reporter=list",
"test:e2e": "wp-scripts test-playwright",
"test:js": "wp-scripts test-unit-js",
"test:watch": "wp-scripts test-unit-js --watch",
"version:major": "node ./scripts/version major",
Expand All @@ -25,6 +25,7 @@
"php:multisite": "wp-env run tests-wordpress --env-cwd=wp-content/plugins/feature-flags composer test:multisite"
},
"dependencies": {
"@testing-library/user-event": "^14.5.2",
"@wordpress/api-fetch": "^6.48.0",
"@wordpress/components": "^27.0.0",
"@wordpress/data": "^9.22.0",
Expand Down
4 changes: 2 additions & 2 deletions plugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
include_once __DIR__ . '/vendor/autoload.php';
}

// Enqueure scripts, styles in settings page.
// Enqueue scripts, styles in settings page.
add_action(
'admin_enqueue_scripts',
static function ( string $page ): void {
Expand Down Expand Up @@ -156,7 +156,7 @@ static function ( $links ) {

/**
* Uninstall method for the plugin.
*
*
* @return void
*/
function codeb_feature_flags_uninstall(): void {
Expand Down
8 changes: 4 additions & 4 deletions src/components/Flags.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import Header from './Header';
import { __ } from '@wordpress/i18n';
import { useDispatch } from '@wordpress/data';

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

remoteApi(flags);
await remoteApi(flags);
setIsSaving(false);
};

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

remoteApi(latestFlags);
await remoteApi(latestFlags);
setIsSaving(false);
};

Expand Down Expand Up @@ -120,4 +120,4 @@ const Layout = (): JSX.Element => {
);
};

export default Layout;
export default Flags;
42 changes: 42 additions & 0 deletions src/components/__tests__/FlagRow.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { render, fireEvent } from '@testing-library/react';
import FlagRow from '../FlagRow';

test('FlagRow Function Test', async () => {
const item = {
id: 1,
name: 'Test Flag',
enabled: false,
};
const flags = [{ ...item }];
const setFlags = jest.fn();
const setDisableSave = jest.fn();
const handleSave = jest.fn();
const handleDeleteFlag = jest.fn();

const { getByRole, getByLabelText } = render(
<FlagRow
flags={flags}
setFlags={setFlags}
item={item}
setDisableSave={setDisableSave}
handleSave={handleSave}
handleDeleteFlag={handleDeleteFlag}
/>
);

// Test flipping the toggle
fireEvent.click(getByRole('checkbox'));
expect(setFlags).toHaveBeenCalledTimes(1);
expect(handleSave).toHaveBeenCalledTimes(1);

// Test editing the flag name
const input = getByRole('textbox');
fireEvent.change(input, { target: { value: 'New Flag' } });
expect(setFlags).toHaveBeenCalledTimes(2);

const sdkButton = getByLabelText('Click to see SDK setting');
expect(sdkButton).toBeInTheDocument();

const deleteButton = getByLabelText('Delete Flag');
expect(deleteButton).toBeInTheDocument();
});
78 changes: 78 additions & 0 deletions src/components/__tests__/SubmitControls.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import { render, screen, fireEvent } from '@testing-library/react';

import SubmitControls from '../SubmitControls';

describe('SubmitControls component', () => {
let mockHandleSave, mockSetFlags;

beforeEach(() => {
mockHandleSave = jest.fn();
mockSetFlags = jest.fn();
});

it('renders component with all header fields', () => {
render(
<SubmitControls
flags={[]}
setFlags={mockSetFlags}
lastFlag={0}
disableSave={false}
isSaving={false}
handleSave={mockHandleSave}
/>
);

const addFlagButton = screen.getByText('Add Flag');
const saveButton = screen.queryByText('Save');
const cancelButton = screen.queryByText('Cancel');

// Click on Add Flag button
fireEvent.click(addFlagButton);

// Assert setFlags is called
expect(mockSetFlags).toHaveBeenCalled();

// Assert Save & Cancel buttons do not exist when `lastFlag` is 0
expect(saveButton).toBeNull();
expect(cancelButton).toBeNull();
});

test('save button interaction', () => {
render(
<SubmitControls
flags={[]}
setFlags={mockSetFlags}
lastFlag={1}
disableSave={false}
isSaving={false}
handleSave={mockHandleSave}
/>
);

const saveButton = screen.getByText('Save');

// Click on Save button
fireEvent.click(saveButton);

// Assert handleSave is called
expect(mockHandleSave).toHaveBeenCalled();
});

test('display saving text', () => {
render(
<SubmitControls
flags={[]}
setFlags={mockSetFlags}
lastFlag={1}
disableSave={false}
isSaving={true}
handleSave={mockHandleSave}
/>
);

const savingButton = screen.getByText('Saving');

// Assert Save button is now displaying "Saving"
expect(savingButton).toBeTruthy();
});
});
6 changes: 4 additions & 2 deletions src/components/snippets/JsSnippet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { useMemo } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import Clipboard from '../common/Clipboard';

export default function ({ flag }: { flag: string }): JSX.Element {
const JsSnippet = ({ flag }: { flag: string }) => {
const jsSnippet = useMemo(() => {
return `import domReady from '@wordpress/dom-ready';
domReady(function () {
Expand All @@ -22,4 +22,6 @@ domReady(function () {
<Snippet data={jsSnippet} language={'typescript'} />
</div>
);
}
};

export default JsSnippet;
6 changes: 4 additions & 2 deletions src/components/snippets/PhpSnippet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { useMemo } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import Clipboard from '../common/Clipboard';

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

export default PhpSnippet;
2 changes: 1 addition & 1 deletion src/components/snippets/Snippet.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import SyntaxHighlighter from 'react-syntax-highlighter';
import { a11yDark } from 'react-syntax-highlighter/dist/esm/styles/hljs';
import { a11yDark } from 'react-syntax-highlighter/dist/cjs/styles/hljs';

const Snippet = ({
data,
Expand Down
32 changes: 32 additions & 0 deletions src/components/snippets/__tests__/JsSnippet.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import JsSnippet from '../JsSnippet';
import { render, screen } from '@testing-library/react';
import '@testing-library/jest-dom';

describe('JsSnippet component', () => {
test('should render JsSnippet correctly with passed flag prop', async () => {
render(<JsSnippet flag="testFlag" />);
const result = screen.getByText(/JavaScript Snippet/i);
expect(result).toBeInTheDocument();
});

test('should render the correct JavaScript snippet with the passed flag', async () => {
render(<JsSnippet flag="testFlag" />);
const snip = screen.getByText(/.codebFeatureFlags.isEnabled/i);
expect(snip).toBeInTheDocument();
});

test('should update the JavaScript snippet when the flag prop changes', async () => {
const { rerender, asFragment } = render(<JsSnippet flag="testFlag1" />);
let snip = screen.getByText(/testFlag1'/i);
expect(snip).toBeInTheDocument();
expect(asFragment()).toMatchSnapshot();

rerender(<JsSnippet flag="testFlag2" />);
snip = screen.queryByText(/'testFlag1'/i);
expect(snip).toBeNull();

snip = screen.getByText(/'testFlag2'/i);
expect(snip).toBeInTheDocument();
expect(asFragment()).toMatchSnapshot();
});
});
14 changes: 14 additions & 0 deletions src/components/snippets/__tests__/PhpSnippet.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import PhpSnippet from '../PhpSnippet';
import { render } from '@testing-library/react';

describe('PhpSnippet component', () => {
it('it should render the correct PHP snippet', () => {
const { getByText } = render(<PhpSnippet flag={'testFlag'} />);
expect(getByText(/testFlag/i)).toBeInTheDocument();
});

it('matches snapshot', () => {
const { asFragment } = render(<PhpSnippet flag={'testFlag'} />);
expect(asFragment()).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions src/components/snippets/__tests__/TsSupport.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { render } from '@testing-library/react';
import TsSupport from '../TsSupport';

describe('Typescript snippet component', () => {
test('renders without any error', async () => {
const { asFragment } = render(<TsSupport />);
expect(asFragment()).toMatchSnapshot();
});
});
Loading