import { render, screen, fireEvent, cleanup } from '@testing-library/react';
import { expect } from 'chai';
import React from 'react';
import sinon from 'sinon';
import { SelectTable } from './select-table';
import { cloneDeep } from 'lodash';
type TestItem = {
id: string;
selected: boolean;
col1: string;
col2: string;
};
describe('SelectTable', function () {
let items: TestItem[];
let columns: [key: keyof TestItem, label: string | JSX.Element][];
let onChange: sinon.SinonStub;
beforeEach(function () {
items = [
{ id: 'id1', selected: true, col1: '1x1', col2: '1x2' },
{ id: 'id2', selected: true, col1: '2x1', col2: '2x2' },
];
columns = [
['col1', 'Column1'],
[
'col2',
Column2
,
],
];
onChange = sinon.stub();
});
afterEach(function () {
cleanup();
});
describe('render', function () {
it('allows listing multiple selectable items in a table', function () {
render(
);
expect(screen.getByTestId('column2-span')).to.be.visible;
expect(screen.getByTestId('item-id1-col1')).to.have.text('1x1');
expect(screen.getByTestId('item-id1-col2')).to.have.text('1x2');
});
it('renders checkboxes as expected when all items are selected', function () {
render(
);
expect(
screen.getByTestId('select-table-all-checkbox').closest('input')
?.checked
).to.equal(true);
expect(
screen
.getByTestId('select-table-all-checkbox')
.closest('input')
?.getAttribute('aria-checked')
).to.equal('true');
expect(
screen.getByTestId('select-id1').closest('input')?.checked
).to.equal(true);
expect(
screen.getByTestId('select-id2').closest('input')?.checked
).to.equal(true);
});
it('renders checkboxes as expected when no items are selected', function () {
items[0].selected = false;
items[1].selected = false;
render(
);
expect(
screen.getByTestId('select-table-all-checkbox').closest('input')
?.checked
).to.equal(false);
expect(
screen
.getByTestId('select-table-all-checkbox')
.closest('input')
?.getAttribute('aria-checked')
).to.equal('false');
expect(
screen.getByTestId('select-id1').closest('input')?.checked
).to.equal(false);
expect(
screen.getByTestId('select-id2').closest('input')?.checked
).to.equal(false);
});
it('renders checkboxes as expected when some items are selected', function () {
items[0].selected = false;
render(
);
expect(
screen.getByTestId('select-table-all-checkbox').closest('input')
?.checked
).to.equal(false);
expect(
screen
.getByTestId('select-table-all-checkbox')
.closest('input')
?.getAttribute('aria-checked')
).to.equal('mixed');
expect(
screen.getByTestId('select-id1').closest('input')?.checked
).to.equal(false);
expect(
screen.getByTestId('select-id2').closest('input')?.checked
).to.equal(true);
});
});
describe('updates', function () {
it('calls onChange when a single item is selected', function () {
const originalItems = cloneDeep(items);
items[0].selected = false;
render(
);
fireEvent.click(screen.getByTestId('select-id1'));
expect(onChange).to.have.been.calledWith(originalItems);
});
it('calls onChange when a single item is deselected', function () {
const expectedItems = cloneDeep(items);
items[0].selected = false;
render(
);
fireEvent.click(screen.getByTestId('select-id1'));
expect(onChange).to.have.been.calledWith(expectedItems);
});
it('calls onChange when all items are selected', function () {
const originalItems = cloneDeep(items);
items[0].selected = false;
items[1].selected = false;
render(
);
fireEvent.click(screen.getByTestId('select-table-all-checkbox'));
expect(onChange).to.have.been.calledWith(originalItems);
});
it('calls onChange when all items are deselected', function () {
const expectedItems = cloneDeep(items);
items[0].selected = false;
items[1].selected = false;
render(
);
fireEvent.click(screen.getByTestId('select-table-all-checkbox'));
expect(onChange).to.have.been.calledWith(expectedItems);
});
});
});