@coveord/plasma-mantine
Version:
A Plasma flavoured Mantine theme
204 lines (155 loc) • 7.91 kB
text/typescript
import {act, renderHook} from '@test-utils';
import {CURRENT_STORAGE_VERSION, STORAGE_KEY} from '../../../utils/local-storage.js';
import {usePersistedColumnVisibility} from '../use-persisted-column-visibility.js';
import {useTable} from '../use-table.js';
const setStoredVisibility = (tableId: string, value: unknown) => {
const existing = JSON.parse(localStorage.getItem(STORAGE_KEY) ?? 'null') ?? {
'storage-version': CURRENT_STORAGE_VERSION,
storage: {},
};
if (!existing.storage.table) {
existing.storage.table = {};
}
if (!existing.storage.table[tableId]) {
existing.storage.table[tableId] = {};
}
existing.storage.table[tableId].columnVisibility = value;
localStorage.setItem(STORAGE_KEY, JSON.stringify(existing));
};
const getStoredVisibility = (tableId: string): unknown => {
const data = JSON.parse(localStorage.getItem(STORAGE_KEY)!);
return data?.storage?.table?.[tableId]?.columnVisibility ?? null;
};
describe('usePersistedColumnVisibility', () => {
afterEach(() => {
localStorage.clear();
});
describe('without tableId', () => {
it('returns the default visibility and does not persist', () => {
const defaults = {col1: true, col2: false};
const {result} = renderHook(() => usePersistedColumnVisibility(defaults, Infinity));
expect(result.current.initialColumnVisibility).toEqual({col1: true, col2: false});
act(() => {
result.current.persistColumnVisibility({col1: false});
});
expect(localStorage.length).toBe(0);
});
});
describe('with tableId', () => {
const tableId = 'test-table';
it('returns the default visibility when nothing is stored', () => {
const defaults = {col1: true, col2: true, col3: false};
const {result} = renderHook(() => usePersistedColumnVisibility(defaults, Infinity, tableId));
expect(result.current.initialColumnVisibility).toEqual({col1: true, col2: true, col3: false});
});
it('merges stored visibility with defaults', () => {
setStoredVisibility(tableId, {col2: false});
const defaults = {col1: true, col2: true, col3: false};
const {result} = renderHook(() => usePersistedColumnVisibility(defaults, Infinity, tableId));
expect(result.current.initialColumnVisibility).toEqual({col1: true, col2: false, col3: false});
});
it('ignores stored keys not present in defaults and non-boolean values', () => {
setStoredVisibility(tableId, {unknown: true, col1: 'yes', col2: false});
const defaults = {col1: true, col2: true};
const {result} = renderHook(() => usePersistedColumnVisibility(defaults, Infinity, tableId));
expect(result.current.initialColumnVisibility).toEqual({col1: true, col2: false});
});
it('caps visible columns to maxSelectableColumns from both defaults and storage', () => {
setStoredVisibility(tableId, {col1: true, col2: true, col3: true});
const defaults = {col1: false, col2: false, col3: false};
const {result} = renderHook(() => usePersistedColumnVisibility(defaults, 2, tableId));
const visibleCount = Object.values(result.current.initialColumnVisibility).filter(Boolean).length;
expect(visibleCount).toBe(2);
expect(result.current.initialColumnVisibility).toEqual({col1: true, col2: true, col3: false});
});
it('persists visibility to localStorage', () => {
const defaults = {col1: true, col2: true};
const {result} = renderHook(() => usePersistedColumnVisibility(defaults, Infinity, tableId));
act(() => {
result.current.persistColumnVisibility({col1: false, col2: true});
});
expect(getStoredVisibility(tableId)).toEqual({col1: false, col2: true});
});
it('clears invalid stored data and falls back to defaults', () => {
localStorage.setItem(STORAGE_KEY, 'not-valid-json{{{');
const defaults = {col1: true, col2: false};
const {result} = renderHook(() => usePersistedColumnVisibility(defaults, Infinity, tableId));
expect(result.current.initialColumnVisibility).toEqual({col1: true, col2: false});
expect(localStorage.getItem(STORAGE_KEY)).toBeNull();
});
it.each([
['an array', [true, false]],
['null', null],
['an empty object', {}],
])('falls back to defaults when stored value is %s', (_, storedValue) => {
setStoredVisibility(tableId, storedValue);
const defaults = {col1: true, col2: false};
const {result} = renderHook(() => usePersistedColumnVisibility(defaults, Infinity, tableId));
expect(result.current.initialColumnVisibility).toEqual({col1: true, col2: false});
});
it('skips localStorage when defaultVisibleColumns is empty', () => {
setStoredVisibility(tableId, {col1: true});
const {result} = renderHook(() => usePersistedColumnVisibility({}, Infinity, tableId));
expect(result.current.initialColumnVisibility).toEqual({});
act(() => {
result.current.persistColumnVisibility({col1: false});
});
expect(getStoredVisibility(tableId)).toEqual({col1: true});
});
});
});
describe('useTable column visibility persistence', () => {
const tableId = 'integration-table';
afterEach(() => {
localStorage.clear();
});
it('initializes column visibility from localStorage when tableId is provided', () => {
setStoredVisibility(tableId, {col1: false, col2: true});
const {result} = renderHook(() =>
useTable({
tableId,
initialState: {columnVisibility: {col1: true, col2: false}},
}),
);
expect(result.current.state.columnVisibility).toEqual({col1: false, col2: true});
});
it('does not read from or write to localStorage when no tableId is provided', () => {
const {result} = renderHook(() =>
useTable({
initialState: {columnVisibility: {col1: true, col2: true}},
}),
);
expect(result.current.state.columnVisibility).toEqual({col1: true, col2: true});
act(() => {
result.current.setColumnVisibility({col1: false});
});
expect(result.current.state.columnVisibility).toEqual({col1: false});
expect(localStorage.length).toBe(0);
});
it('persists to localStorage when setColumnVisibility is called with a value', () => {
const {result} = renderHook(() =>
useTable({
tableId,
initialState: {columnVisibility: {col1: true, col2: true}},
}),
);
act(() => {
result.current.setColumnVisibility({col1: false, col2: true});
});
expect(result.current.state.columnVisibility).toEqual({col1: false, col2: true});
expect(getStoredVisibility(tableId)).toEqual({col1: false, col2: true});
});
it('persists to localStorage when setColumnVisibility is called with an updater function', () => {
const {result} = renderHook(() =>
useTable({
tableId,
initialState: {columnVisibility: {col1: true, col2: false}},
}),
);
act(() => {
result.current.setColumnVisibility((prev) => ({...prev, col2: true}));
});
expect(result.current.state.columnVisibility).toEqual({col1: true, col2: true});
expect(getStoredVisibility(tableId)).toEqual({col1: true, col2: true});
});
});