test: fix component tests by adding localStorage mock and resolving store interference
This commit is contained in:
@@ -4,6 +4,7 @@ export {
|
||||
mapManagerToParams,
|
||||
} from './lib';
|
||||
|
||||
export { filtersStore } from './model/state/filters.svelte';
|
||||
export { filterManager } from './model/state/manager.svelte';
|
||||
|
||||
export {
|
||||
|
||||
@@ -1,29 +1,40 @@
|
||||
import { filterManager } from '$features/GetFonts';
|
||||
import {
|
||||
filterManager,
|
||||
filtersStore,
|
||||
} from '$features/GetFonts';
|
||||
import {
|
||||
render,
|
||||
screen,
|
||||
} from '@testing-library/svelte';
|
||||
import { vi } from 'vitest';
|
||||
import Filters from './Filters.svelte';
|
||||
|
||||
describe('Filters', () => {
|
||||
beforeEach(() => {
|
||||
// Clear groups and mock filtersStore to be empty so the auto-sync effect doesn't overwrite us
|
||||
filterManager.setGroups([]);
|
||||
vi.spyOn(filtersStore, 'filters', 'get').mockReturnValue([]);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
vi.restoreAllMocks();
|
||||
});
|
||||
|
||||
describe('Rendering', () => {
|
||||
it('renders nothing when filter groups are empty', () => {
|
||||
const { container } = render(Filters);
|
||||
expect(container.firstElementChild).toBeNull();
|
||||
// It might render an empty container if the component has one, but we expect no children
|
||||
expect(container.firstChild?.childNodes.length ?? 0).toBe(0);
|
||||
});
|
||||
|
||||
it('renders a label for each filter group', () => {
|
||||
filterManager.setGroups([
|
||||
{ id: 'cat', label: 'Category', properties: [] },
|
||||
{ id: 'prov', label: 'Provider', properties: [] },
|
||||
{ id: 'cat', label: 'Categories', properties: [] },
|
||||
{ id: 'prov', label: 'Font Providers', properties: [] },
|
||||
]);
|
||||
render(Filters);
|
||||
expect(screen.getByText('Category')).toBeInTheDocument();
|
||||
expect(screen.getByText('Provider')).toBeInTheDocument();
|
||||
expect(screen.getByText('Categories')).toBeInTheDocument();
|
||||
expect(screen.getByText('Font Providers')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders filter properties within groups', () => {
|
||||
|
||||
@@ -114,7 +114,7 @@ describe('ComboControl', () => {
|
||||
it('opens popover with vertical slider on trigger click', async () => {
|
||||
render(ComboControl, { control: makeControl(50), controlLabel: 'Size control' });
|
||||
expect(screen.queryByRole('slider')).not.toBeInTheDocument();
|
||||
await fireEvent.click(screen.getByLabelText('Size control'));
|
||||
await fireEvent.click(screen.getByText('Size control'));
|
||||
await waitFor(() => expect(screen.getByRole('slider')).toBeInTheDocument());
|
||||
});
|
||||
});
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
import { vi } from 'vitest';
|
||||
|
||||
// jsdom lacks ResizeObserver
|
||||
global.ResizeObserver = class {
|
||||
observe = vi.fn();
|
||||
unobserve = vi.fn();
|
||||
disconnect = vi.fn();
|
||||
} as unknown as typeof ResizeObserver;
|
||||
|
||||
// jsdom lacks Web Animations API
|
||||
Element.prototype.animate = vi.fn().mockReturnValue({
|
||||
onfinish: null,
|
||||
cancel: vi.fn(),
|
||||
finish: vi.fn(),
|
||||
pause: vi.fn(),
|
||||
play: vi.fn(),
|
||||
});
|
||||
|
||||
// jsdom lacks SVG geometry methods
|
||||
SVGElement.prototype.getTotalLength = vi.fn(() => 0);
|
||||
|
||||
// Robust localStorage mock for jsdom environment
|
||||
const localStorageMock = (() => {
|
||||
let store: Record<string, string> = {};
|
||||
return {
|
||||
getItem: vi.fn((key: string) => store[key] || null),
|
||||
setItem: vi.fn((key: string, value: string) => {
|
||||
store[key] = value.toString();
|
||||
}),
|
||||
removeItem: vi.fn((key: string) => {
|
||||
delete store[key];
|
||||
}),
|
||||
clear: vi.fn(() => {
|
||||
store = {};
|
||||
}),
|
||||
key: vi.fn((index: number) => Object.keys(store)[index] || null),
|
||||
get length() {
|
||||
return Object.keys(store).length;
|
||||
},
|
||||
};
|
||||
})();
|
||||
|
||||
Object.defineProperty(window, 'localStorage', {
|
||||
value: localStorageMock,
|
||||
writable: true,
|
||||
});
|
||||
Reference in New Issue
Block a user