@furystack/shades-common-components
Version:
Common UI components for FuryStack Shades
127 lines • 6.5 kB
JavaScript
import { createInjector } from '@furystack/inject';
import { createComponent, flushUpdates, initializeShadeRoot } from '@furystack/shades';
import { usingAsync } from '@furystack/utils';
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
import { CollectionService } from '../../services/collection-service.js';
import { SelectionCell } from './selection-cell.js';
describe('SelectionCell', () => {
beforeEach(() => {
document.body.innerHTML = '<div id="root"></div>';
});
afterEach(() => {
document.body.innerHTML = '';
});
const renderSelectionCell = async (entry, service) => {
const injector = createInjector();
const root = document.getElementById('root');
initializeShadeRoot({
injector,
rootElement: root,
jsxElement: createComponent(SelectionCell, { entry: entry, service: service }),
});
await flushUpdates();
return {
injector,
cell: root.querySelector('shades-data-grid-selection-cell'),
getCheckbox: () => root.querySelector('shades-data-grid-selection-cell')?.querySelector('input[type="checkbox"]'),
[Symbol.asyncDispose]: () => injector[Symbol.asyncDispose](),
};
};
describe('rendering', () => {
it('should render a checkbox input', async () => {
await usingAsync(new CollectionService(), async (service) => {
const entry = { id: 1, name: 'Test' };
await usingAsync(await renderSelectionCell(entry, service), async ({ cell, getCheckbox }) => {
expect(cell).toBeTruthy();
expect(getCheckbox()).toBeTruthy();
expect(getCheckbox()?.type).toBe('checkbox');
});
});
});
});
describe('checkbox state sync', () => {
it('should be unchecked when entry is not selected', async () => {
await usingAsync(new CollectionService(), async (service) => {
const entry = { id: 1, name: 'Test' };
await usingAsync(await renderSelectionCell(entry, service), async ({ getCheckbox }) => {
expect(getCheckbox()?.checked).toBe(false);
});
});
});
it('should be checked when entry is in selection', async () => {
await usingAsync(new CollectionService(), async (service) => {
const entry = { id: 1, name: 'Test' };
service.selection.setValue([entry]);
await usingAsync(await renderSelectionCell(entry, service), async ({ getCheckbox }) => {
expect(getCheckbox()?.checked).toBe(true);
});
});
});
it('should update checkbox when selection changes externally', async () => {
await usingAsync(new CollectionService(), async (service) => {
const entry = { id: 1, name: 'Test' };
await usingAsync(await renderSelectionCell(entry, service), async ({ getCheckbox }) => {
expect(getCheckbox()?.checked).toBe(false);
service.selection.setValue([entry]);
await flushUpdates();
expect(getCheckbox()?.checked).toBe(true);
service.selection.setValue([]);
await flushUpdates();
expect(getCheckbox()?.checked).toBe(false);
});
});
});
it('should remain unchecked when different entries are selected', async () => {
await usingAsync(new CollectionService(), async (service) => {
const entry = { id: 1, name: 'Test' };
const otherEntry = { id: 2, name: 'Other' };
service.selection.setValue([otherEntry]);
await usingAsync(await renderSelectionCell(entry, service), async ({ getCheckbox }) => {
expect(getCheckbox()?.checked).toBe(false);
});
});
});
});
describe('selection toggle', () => {
it('should add entry to selection when checkbox is clicked and entry is not selected', async () => {
await usingAsync(new CollectionService(), async (service) => {
const entry = { id: 1, name: 'Test' };
await usingAsync(await renderSelectionCell(entry, service), async ({ getCheckbox }) => {
expect(service.selection.getValue()).toEqual([]);
const checkbox = getCheckbox();
checkbox?.dispatchEvent(new Event('change', { bubbles: true }));
await flushUpdates();
expect(service.selection.getValue()).toContain(entry);
});
});
});
it('should remove entry from selection when checkbox is clicked and entry is selected', async () => {
await usingAsync(new CollectionService(), async (service) => {
const entry = { id: 1, name: 'Test' };
service.selection.setValue([entry]);
await usingAsync(await renderSelectionCell(entry, service), async ({ getCheckbox }) => {
expect(service.selection.getValue()).toContain(entry);
const checkbox = getCheckbox();
checkbox?.dispatchEvent(new Event('change', { bubbles: true }));
await flushUpdates();
expect(service.selection.getValue()).not.toContain(entry);
});
});
});
it('should preserve other selected entries when toggling', async () => {
await usingAsync(new CollectionService(), async (service) => {
const entry = { id: 1, name: 'Test' };
const otherEntry = { id: 2, name: 'Other' };
service.selection.setValue([otherEntry]);
await usingAsync(await renderSelectionCell(entry, service), async ({ getCheckbox }) => {
const checkbox = getCheckbox();
checkbox?.dispatchEvent(new Event('change', { bubbles: true }));
await flushUpdates();
expect(service.selection.getValue()).toContain(entry);
expect(service.selection.getValue()).toContain(otherEntry);
});
});
});
});
});
//# sourceMappingURL=selection-cell.spec.js.map