mirror of
https://github.com/Unleash/unleash.git
synced 2025-03-09 00:18:26 +01:00
test: persistent table state (#5529)
This commit is contained in:
parent
d1984b2447
commit
5c889df9be
@ -17,7 +17,7 @@
|
||||
"start:demo": "UNLEASH_BASE_PATH=/demo/ UNLEASH_API=https://app.unleash-hosted.com/ yarn run start",
|
||||
"test": "NODE_OPTIONS=\"${NODE_OPTIONS} --no-experimental-fetch\" vitest run",
|
||||
"test:snapshot": "NODE_OPTIONS=\"${NODE_OPTIONS} --no-experimental-fetch\" yarn test -u",
|
||||
"test:watch": "NODE_OPTIONS=\"${NODE_OPTIONS} --no-experimental-fetch\" vitest watch",
|
||||
"test:watch": "NODE_OPTIONS=\"${NODE_OPTIONS} --no-experimental-fetch\" vitest watch usePersistentTable",
|
||||
"lint": "biome lint src --apply",
|
||||
"lint:check": "biome check src",
|
||||
"fmt": "biome format src --write",
|
||||
|
156
frontend/src/hooks/usePersistentTableState.test.tsx
Normal file
156
frontend/src/hooks/usePersistentTableState.test.tsx
Normal file
@ -0,0 +1,156 @@
|
||||
import { render } from 'utils/testRenderer';
|
||||
import React from 'react';
|
||||
import { screen, waitFor } from '@testing-library/react';
|
||||
import { usePersistentTableState } from './usePersistentTableState';
|
||||
import { Route, Routes } from 'react-router-dom';
|
||||
import { createLocalStorage } from '../utils/createLocalStorage';
|
||||
import { NumberParam, StringParam } from 'use-query-params';
|
||||
|
||||
type TestComponentProps = {
|
||||
keyName: string;
|
||||
queryParamsDefinition: Record<string, any>;
|
||||
};
|
||||
|
||||
function TestComponent({ keyName, queryParamsDefinition }: TestComponentProps) {
|
||||
const [tableState, setTableState] = usePersistentTableState(
|
||||
keyName,
|
||||
queryParamsDefinition,
|
||||
);
|
||||
|
||||
return (
|
||||
<Routes>
|
||||
<Route
|
||||
path={'/my-url'}
|
||||
element={
|
||||
<div>
|
||||
<span data-testid='state-value'>
|
||||
{tableState.query}
|
||||
</span>
|
||||
<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');
|
||||
});
|
||||
|
||||
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');
|
||||
|
||||
screen.getByText('Update State').click();
|
||||
|
||||
expect(screen.getByTestId('state-value').textContent).toBe('after');
|
||||
expect(window.location.href).toContain(
|
||||
'my-url?query=after&other=other',
|
||||
);
|
||||
|
||||
await waitFor(() => {
|
||||
const { value } = createLocalStorage('testKey', {});
|
||||
expect(value).toStrictEqual({ query: 'after', other: 'other' });
|
||||
});
|
||||
});
|
||||
|
||||
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=20');
|
||||
|
||||
await waitFor(() => {
|
||||
const { value } = createLocalStorage('testKey', {});
|
||||
expect(value).toStrictEqual({ query: 'after' });
|
||||
});
|
||||
});
|
||||
});
|
@ -7,6 +7,8 @@ import { IPermission } from 'interfaces/user';
|
||||
import { AnnouncerProvider } from 'component/common/Announcer/AnnouncerProvider/AnnouncerProvider';
|
||||
import { AccessProviderMock } from 'component/providers/AccessProvider/AccessProviderMock';
|
||||
import { UIProviderContainer } from '../component/providers/UIProvider/UIProviderContainer';
|
||||
import { ReactRouter6Adapter } from 'use-query-params/adapters/react-router-6';
|
||||
import { QueryParamProvider } from 'use-query-params';
|
||||
|
||||
export const render = (
|
||||
ui: JSX.Element,
|
||||
@ -27,11 +29,15 @@ export const render = (
|
||||
value={{ provider: () => new Map(), dedupingInterval: 0 }}
|
||||
>
|
||||
<AccessProviderMock permissions={permissions}>
|
||||
<ThemeProvider>
|
||||
<AnnouncerProvider>
|
||||
<BrowserRouter>{children}</BrowserRouter>
|
||||
</AnnouncerProvider>
|
||||
</ThemeProvider>
|
||||
<BrowserRouter>
|
||||
<QueryParamProvider adapter={ReactRouter6Adapter}>
|
||||
<ThemeProvider>
|
||||
<AnnouncerProvider>
|
||||
{children}
|
||||
</AnnouncerProvider>
|
||||
</ThemeProvider>
|
||||
</QueryParamProvider>
|
||||
</BrowserRouter>
|
||||
</AccessProviderMock>
|
||||
</SWRConfig>
|
||||
</UIProviderContainer>
|
||||
|
Loading…
Reference in New Issue
Block a user