1
0
mirror of https://github.com/Unleash/unleash.git synced 2024-12-28 00:06:53 +01:00
unleash.unleash/frontend/src/hooks/usePersistentTableState.test.tsx

276 lines
8.3 KiB
TypeScript
Raw Normal View History

2023-12-04 15:47:53 +01:00
import { render } from 'utils/testRenderer';
import { screen, waitFor } from '@testing-library/react';
import { usePersistentTableState } from './usePersistentTableState';
import { Route, Routes } from 'react-router-dom';
import { createLocalStorage } from '../utils/createLocalStorage';
2024-01-19 09:27:47 +01:00
import { ArrayParam, NumberParam, StringParam } from 'use-query-params';
2023-12-05 17:31:23 +01:00
import { FilterItemParam } from '../utils/serializeQueryParams';
2023-12-04 15:47:53 +01:00
type TestComponentProps = {
keyName: string;
queryParamsDefinition: Record<string, any>;
nonPersistentParams?: string[];
2023-12-04 15:47:53 +01:00
};
function TestComponent({
keyName,
queryParamsDefinition,
nonPersistentParams,
}: TestComponentProps) {
2023-12-04 15:47:53 +01:00
const [tableState, setTableState] = usePersistentTableState(
keyName,
queryParamsDefinition,
nonPersistentParams,
2023-12-04 15:47:53 +01:00
);
return (
<Routes>
<Route
path={'/my-url'}
element={
<div>
<span data-testid='state-value'>
{tableState.query}
</span>
2023-12-19 15:35:39 +01:00
<span data-testid='state-keys'>
{Object.keys(tableState).join(',')}
</span>
2023-12-04 15:47:53 +01:00
<button
type='button'
onClick={() => setTableState({ query: 'after' })}
>
Update State
</button>
<button
type='button'
onClick={() => setTableState({ offset: 20 })}
>
Update Offset
</button>
</div>
}
/>
</Routes>
);
}
describe('usePersistentTableState', () => {
it('initializes correctly from URL', async () => {
createLocalStorage('testKey', {});
render(
<TestComponent
keyName='testKey'
queryParamsDefinition={{ query: StringParam }}
/>,
{ route: '/my-url?query=initialUrl' },
);
expect(screen.getByTestId('state-value').textContent).toBe(
'initialUrl',
);
expect(window.location.href).toContain('my-url?query=initialUrl');
});
it('initializes correctly from localStorage', async () => {
createLocalStorage('testKey', {}).setValue({ query: 'initialStorage' });
render(
<TestComponent
keyName='testKey'
queryParamsDefinition={{ query: StringParam }}
/>,
{ route: '/my-url' },
);
expect(screen.getByTestId('state-value').textContent).toBe(
'initialStorage',
);
expect(window.location.href).toContain('my-url?query=initialStorage');
});
2023-12-05 17:31:23 +01:00
it('initializes correctly from localStorage with complex decoder', async () => {
createLocalStorage('testKey', {}).setValue({
query: 'initialStorage',
filterItem: {
operator: 'IS',
values: ['default'],
},
2024-01-19 09:27:47 +01:00
columns: ['a', 'b'],
2023-12-05 17:31:23 +01:00
});
render(
<TestComponent
keyName='testKey'
queryParamsDefinition={{
query: StringParam,
filterItem: FilterItemParam,
2024-01-19 09:27:47 +01:00
columns: ArrayParam,
2023-12-05 17:31:23 +01:00
}}
/>,
{ route: '/my-url' },
);
expect(screen.getByTestId('state-value').textContent).toBe(
'initialStorage',
);
expect(window.location.href).toContain(
2024-01-19 09:27:47 +01:00
'my-url?query=initialStorage&filterItem=IS%3Adefault&columns=a&columns=b',
2023-12-05 17:31:23 +01:00
);
});
2023-12-04 15:47:53 +01:00
it('initializes correctly from localStorage and URL', async () => {
createLocalStorage('testKey', {}).setValue({ query: 'initialStorage' });
render(
<TestComponent
keyName='testKey'
queryParamsDefinition={{ query: StringParam }}
/>,
{ route: '/my-url?query=initialUrl' },
);
expect(screen.getByTestId('state-value').textContent).toBe(
'initialUrl',
);
expect(window.location.href).toContain('my-url?query=initialUrl');
});
it('partially updates the state on button click', async () => {
createLocalStorage('testKey', {}).setValue({
query: 'before',
other: 'other',
});
render(
<TestComponent
keyName='testKey'
queryParamsDefinition={{
query: StringParam,
other: StringParam,
}}
/>,
{ route: '/my-url' },
);
expect(screen.getByTestId('state-value').textContent).toBe('before');
(await screen.findByText('Update State')).click();
2023-12-04 15:47:53 +01:00
expect((await screen.findByTestId('state-value')).textContent).toBe(
'after',
);
2023-12-04 15:47:53 +01:00
expect(window.location.href).toContain(
'my-url?query=after&other=other',
);
await waitFor(() => {
const { value } = createLocalStorage('testKey', {});
expect(value).toStrictEqual({
query: 'after',
other: 'other',
});
2023-12-04 15:47:53 +01:00
});
});
it('omits offset in local storage', async () => {
createLocalStorage('testKey', {}).setValue({ query: 'before' });
render(
<TestComponent
keyName='testKey'
queryParamsDefinition={{
query: StringParam,
offset: NumberParam,
}}
/>,
{ route: '/my-url' },
);
screen.getByText('Update Offset').click();
screen.getByText('Update State').click();
expect(window.location.href).toContain('my-url?query=after&offset=0');
2023-12-04 15:47:53 +01:00
await waitFor(() => {
const { value } = createLocalStorage('testKey', {});
expect(value).toStrictEqual({ query: 'after' });
});
});
it('resets offset to 0 on state update', async () => {
createLocalStorage('testKey', {}).setValue({ query: 'before' });
render(
<TestComponent
keyName='testKey'
queryParamsDefinition={{
query: StringParam,
offset: NumberParam,
}}
/>,
{ route: '/my-url?query=before&offset=10' },
);
expect(window.location.href).toContain('my-url?query=before&offset=10');
screen.getByText('Update State').click();
await waitFor(() => {
expect(window.location.href).toContain(
'my-url?query=after&offset=0',
);
expect(window.location.href).not.toContain('offset=10');
});
});
it('does not reset offset to 0 without offset decoder', async () => {
createLocalStorage('testKey', {}).setValue({ query: 'before' });
render(
<TestComponent
keyName='testKey'
queryParamsDefinition={{
query: StringParam,
}}
/>,
{ route: '/my-url?query=before&offset=10' },
);
expect(window.location.href).toContain('my-url?query=before&offset=10');
screen.getByText('Update State').click();
await waitFor(() => {
expect(window.location.href).toContain(
'my-url?query=after&offset=10',
);
});
});
2023-12-19 15:35:39 +01:00
it('maintains key order', async () => {
createLocalStorage('testKey', {});
render(
<TestComponent
keyName='testKey'
queryParamsDefinition={{
query: StringParam,
another: StringParam,
ignore: StringParam,
}}
/>,
{ route: '/my-url?another=another&query=initialUrl' },
);
expect(screen.getByTestId('state-keys').textContent).toBe(
'another,query,ignore',
);
await waitFor(() => {
const { value } = createLocalStorage('testKey', {});
expect(Object.keys(value)).toStrictEqual(['another', 'query']);
});
});
2023-12-04 15:47:53 +01:00
});