2023-06-20 11:34:27 +02:00
|
|
|
import { screen } from '@testing-library/react';
|
|
|
|
import { render } from 'utils/testRenderer';
|
|
|
|
import AdvancedPlayground from './AdvancedPlayground';
|
|
|
|
import { createLocalStorage } from 'utils/createLocalStorage';
|
2023-06-21 08:17:53 +02:00
|
|
|
import { testServerRoute, testServerSetup } from 'utils/testServer';
|
|
|
|
import userEvent from '@testing-library/user-event';
|
2023-06-20 11:34:27 +02:00
|
|
|
|
2023-06-21 08:17:53 +02:00
|
|
|
const testDisplayComponent = (
|
2023-10-06 09:19:49 +02:00
|
|
|
<AdvancedPlayground
|
|
|
|
FormComponent={(props) => (
|
|
|
|
<div>
|
|
|
|
<div data-id='projects'>{JSON.stringify(props.projects)}</div>
|
|
|
|
<div data-id='environments'>
|
|
|
|
{JSON.stringify(props.environments)}
|
2023-06-20 11:34:27 +02:00
|
|
|
</div>
|
2023-10-06 09:19:49 +02:00
|
|
|
<div data-id='context'>{JSON.stringify(props.context)}</div>
|
|
|
|
</div>
|
|
|
|
)}
|
|
|
|
/>
|
2023-06-20 11:34:27 +02:00
|
|
|
);
|
|
|
|
|
2023-06-21 08:17:53 +02:00
|
|
|
const testEvaluateComponent = (
|
2023-10-06 09:19:49 +02:00
|
|
|
<AdvancedPlayground
|
|
|
|
FormComponent={(props) => (
|
|
|
|
<form onSubmit={props.onSubmit}>
|
|
|
|
<button type='submit'>Submit</button>
|
|
|
|
</form>
|
|
|
|
)}
|
|
|
|
/>
|
2023-06-21 08:17:53 +02:00
|
|
|
);
|
|
|
|
|
2023-06-20 11:34:27 +02:00
|
|
|
afterEach(() => {
|
|
|
|
const { setValue } = createLocalStorage('AdvancedPlayground:v1', {});
|
|
|
|
setValue({});
|
|
|
|
});
|
|
|
|
|
|
|
|
test('should fetch initial form data from local storage', async () => {
|
|
|
|
const { setValue } = createLocalStorage('AdvancedPlayground:v1', {});
|
|
|
|
setValue({
|
|
|
|
projects: ['projectA', 'projectB'],
|
|
|
|
environments: ['development', 'production'],
|
|
|
|
context: { userId: '1' },
|
|
|
|
});
|
|
|
|
|
2023-06-21 08:17:53 +02:00
|
|
|
render(testDisplayComponent);
|
2023-06-20 11:34:27 +02:00
|
|
|
|
|
|
|
expect(screen.getByText('Unleash playground')).toBeInTheDocument();
|
|
|
|
expect(screen.getByText('["projectA","projectB"]')).toBeInTheDocument();
|
|
|
|
expect(
|
2023-10-02 14:25:46 +02:00
|
|
|
screen.getByText('["development","production"]'),
|
2023-06-20 11:34:27 +02:00
|
|
|
).toBeInTheDocument();
|
|
|
|
expect(screen.getByText('{"userId":"1"}')).toBeInTheDocument();
|
|
|
|
});
|
|
|
|
|
|
|
|
test('should fetch initial form data from url', async () => {
|
|
|
|
const { setValue } = createLocalStorage('AdvancedPlayground:v1', {});
|
|
|
|
setValue({
|
|
|
|
projects: ['projectA', 'projectB'],
|
|
|
|
environments: ['development', 'production'],
|
|
|
|
context: { userId: '1' },
|
|
|
|
});
|
|
|
|
|
2023-06-21 08:17:53 +02:00
|
|
|
render(testDisplayComponent, {
|
2023-06-20 11:34:27 +02:00
|
|
|
route: '/playground?context=customContext&environments=customEnv&projects=urlProject&sort=name',
|
|
|
|
});
|
|
|
|
|
|
|
|
expect(screen.getByText('Unleash playground')).toBeInTheDocument();
|
|
|
|
expect(screen.getByText('["urlProject"]')).toBeInTheDocument();
|
|
|
|
expect(screen.getByText('["customEnv"]')).toBeInTheDocument();
|
|
|
|
expect(screen.getByText('"customContext"')).toBeInTheDocument();
|
|
|
|
});
|
2023-06-21 08:17:53 +02:00
|
|
|
|
|
|
|
const server = testServerSetup();
|
|
|
|
|
|
|
|
test('should display error on submit', async () => {
|
|
|
|
testServerRoute(
|
|
|
|
server,
|
|
|
|
'/api/admin/playground/advanced',
|
|
|
|
{
|
|
|
|
name: 'BadDataError',
|
|
|
|
details: [{ message: 'some error about too many items' }],
|
|
|
|
},
|
|
|
|
'post',
|
2023-10-02 14:25:46 +02:00
|
|
|
400,
|
2023-06-21 08:17:53 +02:00
|
|
|
);
|
|
|
|
|
|
|
|
render(testEvaluateComponent);
|
|
|
|
|
|
|
|
const user = userEvent.setup();
|
|
|
|
const submitButton = screen.getByText('Submit');
|
2024-04-12 12:35:33 +02:00
|
|
|
await user.click(submitButton);
|
2023-06-21 08:17:53 +02:00
|
|
|
|
|
|
|
await screen.findByText('some error about too many items');
|
|
|
|
});
|
2024-04-12 12:35:33 +02:00
|
|
|
|
|
|
|
describe('context warnings on successful evaluation', () => {
|
|
|
|
const warningSummaryText =
|
|
|
|
'Some context properties were not taken into account during evaluation';
|
|
|
|
|
|
|
|
test('should show context warnings if they exist in the response', async () => {
|
|
|
|
const response = {
|
|
|
|
features: [],
|
|
|
|
input: {
|
|
|
|
environments: [],
|
|
|
|
projects: [],
|
|
|
|
context: {},
|
|
|
|
},
|
|
|
|
warnings: {
|
|
|
|
invalidContextProperties: [
|
|
|
|
'empty array',
|
|
|
|
'true',
|
|
|
|
'false',
|
|
|
|
'number',
|
|
|
|
'null',
|
|
|
|
'accountId',
|
|
|
|
'object',
|
|
|
|
],
|
|
|
|
},
|
|
|
|
};
|
|
|
|
testServerRoute(
|
|
|
|
server,
|
|
|
|
'/api/admin/playground/advanced',
|
|
|
|
response,
|
|
|
|
'post',
|
|
|
|
200,
|
|
|
|
);
|
|
|
|
|
|
|
|
render(testEvaluateComponent);
|
|
|
|
|
|
|
|
const user = userEvent.setup();
|
|
|
|
const submitButton = screen.getByText('Submit');
|
|
|
|
await user.click(submitButton);
|
|
|
|
|
|
|
|
await screen.findByText(warningSummaryText, { exact: false });
|
|
|
|
for (const prop of response.warnings.invalidContextProperties) {
|
|
|
|
await screen.findByText(prop);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
test('sorts context warnings alphabetically', async () => {
|
|
|
|
const response = {
|
|
|
|
features: [],
|
|
|
|
input: {
|
|
|
|
environments: [],
|
|
|
|
projects: [],
|
|
|
|
context: {},
|
|
|
|
},
|
|
|
|
warnings: {
|
|
|
|
invalidContextProperties: ['b', 'a', 'z'],
|
|
|
|
},
|
|
|
|
};
|
|
|
|
testServerRoute(
|
|
|
|
server,
|
|
|
|
'/api/admin/playground/advanced',
|
|
|
|
response,
|
|
|
|
'post',
|
|
|
|
200,
|
|
|
|
);
|
|
|
|
|
|
|
|
render(testEvaluateComponent);
|
|
|
|
|
|
|
|
const user = userEvent.setup();
|
|
|
|
const submitButton = screen.getByText('Submit');
|
|
|
|
await user.click(submitButton);
|
|
|
|
|
|
|
|
const warnings = screen.getAllByTestId('context-warning-list-element');
|
|
|
|
|
|
|
|
expect(warnings[0]).toHaveTextContent('a');
|
|
|
|
expect(warnings[1]).toHaveTextContent('b');
|
|
|
|
expect(warnings[2]).toHaveTextContent('z');
|
|
|
|
});
|
|
|
|
|
|
|
|
test('does not render context warnings if the list of properties is empty', async () => {
|
|
|
|
const response = {
|
|
|
|
features: [],
|
|
|
|
input: {
|
|
|
|
environments: [],
|
|
|
|
projects: [],
|
|
|
|
context: {},
|
|
|
|
},
|
|
|
|
warnings: {
|
|
|
|
invalidContextProperties: [],
|
|
|
|
},
|
|
|
|
};
|
|
|
|
testServerRoute(
|
|
|
|
server,
|
|
|
|
'/api/admin/playground/advanced',
|
|
|
|
response,
|
|
|
|
'post',
|
|
|
|
200,
|
|
|
|
);
|
|
|
|
|
|
|
|
render(testEvaluateComponent);
|
|
|
|
|
|
|
|
const user = userEvent.setup();
|
|
|
|
const submitButton = screen.getByText('Submit');
|
|
|
|
await user.click(submitButton);
|
|
|
|
|
|
|
|
const warningSummary = screen.queryByText(warningSummaryText, {
|
|
|
|
exact: false,
|
|
|
|
});
|
|
|
|
|
|
|
|
expect(warningSummary).toBeNull();
|
|
|
|
});
|
|
|
|
|
|
|
|
test("should not show context warnings if they don't exist in the response", async () => {
|
|
|
|
testServerRoute(
|
|
|
|
server,
|
|
|
|
'/api/admin/playground/advanced',
|
|
|
|
{
|
|
|
|
features: [],
|
|
|
|
input: {
|
|
|
|
environments: [],
|
|
|
|
projects: [],
|
|
|
|
context: {},
|
|
|
|
},
|
|
|
|
warnings: {},
|
|
|
|
},
|
|
|
|
'post',
|
|
|
|
200,
|
|
|
|
);
|
|
|
|
|
|
|
|
render(testEvaluateComponent);
|
|
|
|
|
|
|
|
const user = userEvent.setup();
|
|
|
|
const submitButton = screen.getByText('Submit');
|
|
|
|
await user.click(submitButton);
|
|
|
|
|
|
|
|
const warningSummary = screen.queryByText(warningSummaryText, {
|
|
|
|
exact: false,
|
|
|
|
});
|
|
|
|
|
|
|
|
expect(warningSummary).toBeNull();
|
|
|
|
});
|
|
|
|
});
|