Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test(Table): added unit tests to Table components #1294

Merged
merged 2 commits into from
Feb 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 96 additions & 0 deletions src/components/Table/__tests__/Table.hocs.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import React from 'react';

import {render} from '@testing-library/react';

import {Table, type TableProps} from '../Table';
import {
type WithTableActionsProps,
type WithTableSelectionProps,
type WithTableSettingsProps,
type WithTableSortingProps,
withTableActions,
withTableCopy,
withTableSelection,
withTableSettings,
withTableSorting,
} from '../hoc';

interface Model {
disabled: boolean;
}

function getTextContent(html = '') {
return html.replace(/uniq\d+/g, '');
}

describe('Table HOCs tests', () => {
it('using withTableActions and withTableSelection should not depend of order', () => {
const Table1 = withTableActions(withTableSelection<Model>(Table));
const Table2 = withTableSelection(withTableActions<Model>(Table));

type Props = TableProps<Model> &
WithTableActionsProps<Model> &
WithTableSelectionProps<Model>;
const props: Props = {
data: [{disabled: false}, {disabled: true}],
columns: [{id: 'name'}],
isRowDisabled: ({disabled}) => disabled,
selectedIds: [],
onSelectionChange: () => {},
getRowActions: () => [],
};
const {container: container1} = render(React.createElement<Props>(Table1, props));
const {container: container2} = render(React.createElement<Props>(Table2, props));

expect(getTextContent(container1.outerHTML)).toEqual(getTextContent(container2.outerHTML));
});

it('using withTableActions and withTableSorting should not depend of order', () => {
const Table1 = withTableActions(withTableSorting<Model>(Table));
const Table2 = withTableSorting(withTableActions<Model>(Table));

type Props = TableProps<Model> & WithTableActionsProps<Model> & WithTableSortingProps;
const props: Props = {
data: [{disabled: false}, {disabled: true}],
columns: [{id: 'name'}],
isRowDisabled: ({disabled}) => disabled,
getRowActions: () => [],
};
const {container: container1} = render(React.createElement<Props>(Table1, props));
const {container: container2} = render(React.createElement<Props>(Table2, props));

expect(getTextContent(container1.outerHTML)).toEqual(getTextContent(container2.outerHTML));
});

it('using all HOCs should not depend of order', () => {
const Table1 = withTableSorting(
withTableSettings(
withTableCopy(withTableActions(withTableSelection<Model, {}>(Table))),
),
);
const Table2 = withTableSelection(
withTableActions(withTableCopy(withTableSettings(withTableSorting<Model, {}>(Table)))),
);

type Props = TableProps<Model> &
WithTableActionsProps<Model> &
WithTableSelectionProps<Model> &
WithTableSettingsProps &
WithTableSortingProps;

const props: Props = {
data: [{disabled: false}, {disabled: true}],
columns: [{id: 'name'}],
isRowDisabled: ({disabled}) => disabled,
selectedIds: [],
onSelectionChange: () => {},
getRowActions: () => [],
updateSettings: () => Promise.resolve(),
settings: [],
};
const {container: container1} = render(React.createElement<Props>(Table1, props));
const {container: container2} = render(React.createElement<Props>(Table2, props));

expect(getTextContent(container1.outerHTML)).toEqual(getTextContent(container2.outerHTML));
});
});
148 changes: 146 additions & 2 deletions src/components/Table/__tests__/Table.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ import React from 'react';
import {render, screen, within} from '@testing-library/react';
import userEvent from '@testing-library/user-event';

import {Table, TableProps} from '../Table';
import {Table, TableColumnConfig, TableProps} from '../Table';

import {columns, data} from './utils';
import {DataItem, columns, data} from './utils';

const qaId = 'table-component';

Expand Down Expand Up @@ -185,4 +185,148 @@ describe('Table', () => {
expect(row.className.includes('yc-table__row_disabled')).toBe(expectedFlag);
});
});

describe('getRowId static method', () => {
test('should return index by default', () => {
const props: TableProps<DataItem> = {data, columns: []};

expect(Table.getRowId(props, data[0])).toBe('0');
expect(Table.getRowId(props, data[1])).toBe('1');
expect(Table.getRowId(props, data[2])).toBe('2');
});

test('should use prop as function', () => {
const getRowIdMock = jest.fn((item: DataItem) => '__id__' + item.name);
const props: TableProps<DataItem> = {data, columns: [], getRowId: getRowIdMock};
const id = Table.getRowId(props, data[0]);

expect(getRowIdMock).toBeCalled();
expect(id).toBe('__id__' + data[0].name);
});

test('should call function with correct arguments', () => {
const getRowIdMock = jest.fn();
const props: TableProps<DataItem> = {data, columns: [], getRowId: getRowIdMock};

Table.getRowId(props, data[0]);
Table.getRowId(props, data[1]);
Table.getRowId(props, data[2]);

expect(getRowIdMock.mock.calls.length).toBe(3);
expect(getRowIdMock.mock.calls[0]).toEqual([data[0], 0]);
expect(getRowIdMock.mock.calls[1]).toEqual([data[1], 1]);
expect(getRowIdMock.mock.calls[2]).toEqual([data[2], 2]);
});

test('should use prop as object key', () => {
const props: TableProps<DataItem> = {data, columns: [], getRowId: 'name'};

expect(Table.getRowId(props, data[0])).toBe('Nomlanga Compton');
expect(Table.getRowId(props, data[1])).toBe('Paul Hatfield');
expect(Table.getRowId(props, data[2])).toBe('Phelan Daniel');
});

test('should fallback to index on prop as object key', () => {
const props: TableProps<DataItem> = {data, columns: [], getRowId: 'ts'};

expect(Table.getRowId(props, data[0])).toBe('0');
expect(Table.getRowId(props, data[1])).toBe('1');
expect(Table.getRowId(props, data[2])).toBe('2');
});
});

describe('getHeadCellContent static method', () => {
test('should return id prop value by default', () => {
const column: TableColumnConfig<DataItem> = {id: 'name'};
const {container} = render(Table.getHeadCellContent(column) as React.ReactElement);

expect(container).toHaveTextContent('name');
});

test('should use name prop as function', () => {
const nameMock = jest.fn(() => '__name__');
const column: TableColumnConfig<DataItem> = {id: 'name', name: nameMock};
const {container} = render(Table.getHeadCellContent(column) as React.ReactElement);

expect(nameMock).toBeCalled();
expect(container).toHaveTextContent('__name__');
});

test('should call function with correct arguments', () => {
const nameMock = jest.fn(() => '__name__');
const column: TableColumnConfig<DataItem> = {id: 'name', name: nameMock};
Table.getHeadCellContent(column);

expect(nameMock.mock.calls.length).toBe(1);
expect(nameMock.mock.calls[0]).toEqual([]);
});

test('should use name prop as string', () => {
const column: TableColumnConfig<DataItem> = {id: 'name', name: '__name__'};
const {container} = render(Table.getHeadCellContent(column) as React.ReactElement);

expect(container).toHaveTextContent('__name__');
});
});

describe('getBodyCellContent static method', () => {
test('should return dash by default', () => {
const column: TableColumnConfig<DataItem> = {id: '__unknown__'};
const content = Table.getBodyCellContent(column, data[0], 0);

expect(content).toBe('\u2014');
});

test('should return placeholder on empty value', () => {
const column: TableColumnConfig<any> = {id: 'name', placeholder: '-'};
const items = [{id: 'asdf'}, {name: null}, {name: undefined}, {name: ''}];

expect(Table.getBodyCellContent(column, items[0], 0)).toBe('-');
expect(Table.getBodyCellContent(column, items[0], 1)).toBe('-');
expect(Table.getBodyCellContent(column, items[0], 2)).toBe('-');
expect(Table.getBodyCellContent(column, items[0], 3)).toBe('-');
});

test('should use template prop as function', () => {
const templateMock = jest.fn(() => '__content__');
const column: TableColumnConfig<DataItem> = {id: 'name', template: templateMock};
const content = Table.getBodyCellContent(column, data[0], 0);

expect(templateMock).toBeCalled();
expect(content).toBe('__content__');
});

test('should call function with correct arguments', () => {
const templateMock = jest.fn();
const column: TableColumnConfig<DataItem> = {id: 'name', template: templateMock};
Table.getBodyCellContent(column, data[0], 0);
Table.getBodyCellContent(column, data[1], 1);
Table.getBodyCellContent(column, data[2], 2);

expect(templateMock.mock.calls.length).toBe(3);
expect(templateMock.mock.calls[0]).toEqual([data[0], 0]);
expect(templateMock.mock.calls[1]).toEqual([data[1], 1]);
expect(templateMock.mock.calls[2]).toEqual([data[2], 2]);
});

test('should use template prop as object key', () => {
const column1: TableColumnConfig<DataItem> = {id: 'name', template: 'count'};
const column2: TableColumnConfig<DataItem> = {id: 'name', template: 'city'};

expect(Table.getBodyCellContent(column1, data[0], 0)).toBe(82);
expect(Table.getBodyCellContent(column1, data[1], 1)).toBe(51);
expect(Table.getBodyCellContent(column1, data[2], 2)).toBe(10);
expect(Table.getBodyCellContent(column2, data[0], 0)).toBe('Erli');
expect(Table.getBodyCellContent(column2, data[1], 1)).toBe('Campitello di Fassa');
expect(Table.getBodyCellContent(column2, data[2], 2)).toBe('Meugliano');
});

test('should use id prop as object key', () => {
const column: TableColumnConfig<DataItem> = {id: 'name'};

expect(Table.getBodyCellContent(column, data[0], 0)).toBe('Nomlanga Compton');
expect(Table.getBodyCellContent(column, data[1], 1)).toBe('Paul Hatfield');
expect(Table.getBodyCellContent(column, data[2], 2)).toBe('Phelan Daniel');
});
});
});
Loading
Loading