Skip to content
Open
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

import React from 'react';
import { render, screen, fireEvent } from '@testing-library/react';
import { TableCell, TableCellProps } from './table_cell';

describe('TableCell', () => {
const defaultProps: TableCellProps = {
columnId: 'testField',
sanitizedCellValue: '<span>test value</span>',
onFilter: jest.fn(),
fieldMapping: { name: 'testField', type: 'text' },
filterable: true,
};

beforeEach(() => {
jest.clearAllMocks();
});

it('renders the sanitized cell value', () => {
render(
<table>
<tbody>
<tr>
<TableCell {...defaultProps} />
</tr>
</tbody>
</table>
);
expect(screen.getByTestId('osdDocTableCellDataField')).toBeInTheDocument();
expect(screen.getByTestId('osdDocTableCellDataField').innerHTML).toBe(
'<span>test value</span>'
);
});

it('renders filter buttons', () => {
render(
<table>
<tbody>
<tr>
<TableCell {...defaultProps} />
</tr>
</tbody>
</table>
);
expect(screen.getByTestId('filterForValue')).toBeInTheDocument();
expect(screen.getByTestId('filterOutValue')).toBeInTheDocument();
});

it('calls onFilter with "+" when filter-for button is clicked', () => {
render(
<table>
<tbody>
<tr>
<TableCell {...defaultProps} />
</tr>
</tbody>
</table>
);
fireEvent.click(screen.getByTestId('filterForValue'));
expect(defaultProps.onFilter).toHaveBeenCalledWith('testField', defaultProps.fieldMapping, '+');
});

it('calls onFilter with "-" when filter-out button is clicked', () => {
render(
<table>
<tbody>
<tr>
<TableCell {...defaultProps} />
</tr>
</tbody>
</table>
);
fireEvent.click(screen.getByTestId('filterOutValue'));
expect(defaultProps.onFilter).toHaveBeenCalledWith('testField', defaultProps.fieldMapping, '-');
});

it('applies eui-textNoWrap class for time fields', () => {
const { container } = render(
<table>
<tbody>
<tr>
<TableCell {...defaultProps} isTimeField={true} />
</tr>
</tbody>
</table>
);
const td = container.querySelector('td');
expect(td).toHaveClass('eui-textNoWrap');
});

it('applies eui-textBreakAll class for non-time fields', () => {
const { container } = render(
<table>
<tbody>
<tr>
<TableCell {...defaultProps} isTimeField={false} />
</tr>
</tbody>
</table>
);
const td = container.querySelector('td');
expect(td).toHaveClass('eui-textBreakAll');
});

it('wraps non-time field content in a truncate-by-height div', () => {
const { container } = render(
<table>
<tbody>
<tr>
<TableCell {...defaultProps} isTimeField={false} />
</tr>
</tbody>
</table>
);
expect(container.querySelector('.truncate-by-height')).toBeInTheDocument();
});

it('does not wrap time field content in truncate-by-height div', () => {
const { container } = render(
<table>
<tbody>
<tr>
<TableCell {...defaultProps} isTimeField={true} />
</tr>
</tbody>
</table>
);
expect(container.querySelector('.truncate-by-height')).not.toBeInTheDocument();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,225 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

import React from 'react';
import { render, screen, fireEvent } from '@testing-library/react';
import { TableHeaderColumn } from './table_header_column';
import { SortOrder } from '../../../saved_searches/types';

describe('TableHeaderColumn', () => {
const defaultProps = {
colLeftIdx: 0,
colRightIdx: 2,
displayName: 'Test Field' as React.ReactNode,
isRemoveable: true,
isSortable: true,
name: 'testField',
onChangeSortOrder: jest.fn(),
onMoveColumn: jest.fn(),
onRemoveColumn: jest.fn(),
sortOrder: [] as SortOrder[],
};

beforeEach(() => {
jest.clearAllMocks();
});

it('renders the column display name', () => {
render(
<table>
<thead>
<tr>
<TableHeaderColumn {...defaultProps} />
</tr>
</thead>
</table>
);
expect(screen.getByText('Test Field')).toBeInTheDocument();
});

it('renders with the correct data-test-subj', () => {
render(
<table>
<thead>
<tr>
<TableHeaderColumn {...defaultProps} />
</tr>
</thead>
</table>
);
expect(screen.getByTestId('docTableHeader-testField')).toBeInTheDocument();
});

it('renders sort button when column is sortable', () => {
render(
<table>
<thead>
<tr>
<TableHeaderColumn {...defaultProps} />
</tr>
</thead>
</table>
);
expect(screen.getByTestId('docTableHeaderFieldSort_testField')).toBeInTheDocument();
});

it('does not render sort button when column is not sortable', () => {
render(
<table>
<thead>
<tr>
<TableHeaderColumn {...defaultProps} isSortable={false} />
</tr>
</thead>
</table>
);
expect(screen.queryByTestId('docTableHeaderFieldSort_testField')).not.toBeInTheDocument();
});

it('renders remove button when column is removeable', () => {
render(
<table>
<thead>
<tr>
<TableHeaderColumn {...defaultProps} />
</tr>
</thead>
</table>
);
expect(screen.getByTestId('docTableRemoveHeader-testField')).toBeInTheDocument();
});

it('calls onRemoveColumn when remove button is clicked', () => {
render(
<table>
<thead>
<tr>
<TableHeaderColumn {...defaultProps} />
</tr>
</thead>
</table>
);
fireEvent.click(screen.getByTestId('docTableRemoveHeader-testField'));
expect(defaultProps.onRemoveColumn).toHaveBeenCalledWith('testField');
});

it('renders move-left button when colLeftIdx >= 0', () => {
render(
<table>
<thead>
<tr>
<TableHeaderColumn {...defaultProps} />
</tr>
</thead>
</table>
);
expect(screen.getByTestId('docTableMoveLeftHeader-testField')).toBeInTheDocument();
});

it('does not render move-left button when colLeftIdx < 0', () => {
render(
<table>
<thead>
<tr>
<TableHeaderColumn {...defaultProps} colLeftIdx={-1} />
</tr>
</thead>
</table>
);
expect(screen.queryByTestId('docTableMoveLeftHeader-testField')).not.toBeInTheDocument();
});

it('calls onMoveColumn with left index when move-left is clicked', () => {
render(
<table>
<thead>
<tr>
<TableHeaderColumn {...defaultProps} colLeftIdx={1} />
</tr>
</thead>
</table>
);
fireEvent.click(screen.getByTestId('docTableMoveLeftHeader-testField'));
expect(defaultProps.onMoveColumn).toHaveBeenCalledWith('testField', 1);
});

it('calls onMoveColumn with right index when move-right is clicked', () => {
render(
<table>
<thead>
<tr>
<TableHeaderColumn {...defaultProps} colRightIdx={3} />
</tr>
</thead>
</table>
);
fireEvent.click(screen.getByTestId('docTableMoveRightHeader-testField'));
expect(defaultProps.onMoveColumn).toHaveBeenCalledWith('testField', 3);
});

describe('sort order cycling', () => {
it('sets ascending sort when column is unsorted', () => {
render(
<table>
<thead>
<tr>
<TableHeaderColumn {...defaultProps} sortOrder={[]} />
</tr>
</thead>
</table>
);
fireEvent.click(screen.getByTestId('docTableHeaderFieldSort_testField'));
expect(defaultProps.onChangeSortOrder).toHaveBeenCalledWith([['testField', 'asc']]);
});

it('sets descending sort when column is ascending', () => {
render(
<table>
<thead>
<tr>
<TableHeaderColumn {...defaultProps} sortOrder={[['testField', 'asc']]} />
</tr>
</thead>
</table>
);
fireEvent.click(screen.getByTestId('docTableHeaderFieldSort_testField'));
expect(defaultProps.onChangeSortOrder).toHaveBeenCalledWith([['testField', 'desc']]);
});

it('cycles back to ascending when column is descending and is the only sort', () => {
render(
<table>
<thead>
<tr>
<TableHeaderColumn {...defaultProps} sortOrder={[['testField', 'desc']]} />
</tr>
</thead>
</table>
);
fireEvent.click(screen.getByTestId('docTableHeaderFieldSort_testField'));
expect(defaultProps.onChangeSortOrder).toHaveBeenCalledWith([['testField', 'asc']]);
});

it('removes sort when column is descending and other sorts exist', () => {
render(
<table>
<thead>
<tr>
<TableHeaderColumn
{...defaultProps}
sortOrder={[
['otherField', 'asc'],
['testField', 'desc'],
]}
/>
</tr>
</thead>
</table>
);
fireEvent.click(screen.getByTestId('docTableHeaderFieldSort_testField'));
expect(defaultProps.onChangeSortOrder).toHaveBeenCalledWith([['otherField', 'asc']]);
});
});
});
Loading