mirror of
https://github.com/Unleash/unleash.git
synced 2025-05-03 01:18:43 +02: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",
|
"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": "NODE_OPTIONS=\"${NODE_OPTIONS} --no-experimental-fetch\" vitest run",
|
||||||
"test:snapshot": "NODE_OPTIONS=\"${NODE_OPTIONS} --no-experimental-fetch\" yarn test -u",
|
"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": "biome lint src --apply",
|
||||||
"lint:check": "biome check src",
|
"lint:check": "biome check src",
|
||||||
"fmt": "biome format src --write",
|
"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 { AnnouncerProvider } from 'component/common/Announcer/AnnouncerProvider/AnnouncerProvider';
|
||||||
import { AccessProviderMock } from 'component/providers/AccessProvider/AccessProviderMock';
|
import { AccessProviderMock } from 'component/providers/AccessProvider/AccessProviderMock';
|
||||||
import { UIProviderContainer } from '../component/providers/UIProvider/UIProviderContainer';
|
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 = (
|
export const render = (
|
||||||
ui: JSX.Element,
|
ui: JSX.Element,
|
||||||
@ -27,11 +29,15 @@ export const render = (
|
|||||||
value={{ provider: () => new Map(), dedupingInterval: 0 }}
|
value={{ provider: () => new Map(), dedupingInterval: 0 }}
|
||||||
>
|
>
|
||||||
<AccessProviderMock permissions={permissions}>
|
<AccessProviderMock permissions={permissions}>
|
||||||
<ThemeProvider>
|
<BrowserRouter>
|
||||||
<AnnouncerProvider>
|
<QueryParamProvider adapter={ReactRouter6Adapter}>
|
||||||
<BrowserRouter>{children}</BrowserRouter>
|
<ThemeProvider>
|
||||||
</AnnouncerProvider>
|
<AnnouncerProvider>
|
||||||
</ThemeProvider>
|
{children}
|
||||||
|
</AnnouncerProvider>
|
||||||
|
</ThemeProvider>
|
||||||
|
</QueryParamProvider>
|
||||||
|
</BrowserRouter>
|
||||||
</AccessProviderMock>
|
</AccessProviderMock>
|
||||||
</SWRConfig>
|
</SWRConfig>
|
||||||
</UIProviderContainer>
|
</UIProviderContainer>
|
||||||
|
Loading…
Reference in New Issue
Block a user