Skip to content

Commit

Permalink
[Watcher] Retain search and pagination values when watch list refresh…
Browse files Browse the repository at this point in the history
…es (#82651)
  • Loading branch information
alisonelizabeth authored Nov 5, 2020
1 parent 7c66880 commit 340f85c
Show file tree
Hide file tree
Showing 3 changed files with 131 additions and 50 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {
nextTick,
} from '../../../../../test_utils';
import { WatchList } from '../../../public/application/sections/watch_list/components/watch_list';
import { ROUTES } from '../../../common/constants';
import { ROUTES, REFRESH_INTERVALS } from '../../../common/constants';
import { withAppContext } from './app_context.mock';

const testBedConfig: TestBedConfig = {
Expand All @@ -31,6 +31,8 @@ export interface WatchListTestBed extends TestBed<WatchListTestSubjects> {
selectWatchAt: (index: number) => void;
clickWatchAt: (index: number) => void;
clickWatchActionAt: (index: number, action: 'delete' | 'edit') => void;
searchWatches: (term: string) => void;
advanceTimeToTableRefresh: () => Promise<void>;
};
}

Expand Down Expand Up @@ -73,12 +75,35 @@ export const setup = async (): Promise<WatchListTestBed> => {
});
};

const searchWatches = (term: string) => {
const { find, component } = testBed;
const searchInput = find('watchesTableContainer').find('.euiFieldSearch');

// Enter input into the search box
// @ts-ignore
searchInput.instance().value = term;
searchInput.simulate('keyup', { key: 'Enter', keyCode: 13, which: 13 });

component.update();
};

const advanceTimeToTableRefresh = async () => {
const { component } = testBed;
await act(async () => {
// Advance timers to simulate another request
jest.advanceTimersByTime(REFRESH_INTERVALS.WATCH_LIST);
});
component.update();
};

return {
...testBed,
actions: {
selectWatchAt,
clickWatchAt,
clickWatchActionAt,
searchWatches,
advanceTimeToTableRefresh,
},
};
};
Expand All @@ -95,4 +120,5 @@ export type TestSubjects =
| 'createWatchButton'
| 'emptyPrompt'
| 'emptyPrompt.createWatchButton'
| 'editWatchButton';
| 'editWatchButton'
| 'watchesTableContainer';
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,7 @@

import { act } from 'react-dom/test-utils';
import * as fixtures from '../../test/fixtures';
import {
setupEnvironment,
pageHelpers,
nextTick,
getRandomString,
findTestSubject,
} from './helpers';
import { setupEnvironment, pageHelpers, getRandomString, findTestSubject } from './helpers';
import { WatchListTestBed } from './helpers/watch_list.helpers';
import { ROUTES } from '../../common/constants';

Expand All @@ -24,28 +18,29 @@ describe('<WatchList />', () => {
const { server, httpRequestsMockHelpers } = setupEnvironment();
let testBed: WatchListTestBed;

beforeAll(() => {
jest.useFakeTimers();
});

afterAll(() => {
jest.useRealTimers();
server.restore();
});

describe('on component mount', () => {
beforeEach(async () => {
testBed = await setup();
});

describe('watches', () => {
describe('when there are no watches', () => {
beforeEach(() => {
beforeEach(async () => {
httpRequestsMockHelpers.setLoadWatchesResponse({ watches: [] });
});

test('should display an empty prompt', async () => {
const { component, exists } = await setup();

await act(async () => {
await nextTick();
component.update();
testBed = await setup();
});
testBed.component.update();
});

test('should display an empty prompt', async () => {
const { exists } = testBed;

expect(exists('emptyPrompt')).toBe(true);
expect(exists('emptyPrompt.createWatchButton')).toBe(true);
Expand Down Expand Up @@ -76,12 +71,47 @@ describe('<WatchList />', () => {
beforeEach(async () => {
httpRequestsMockHelpers.setLoadWatchesResponse({ watches });

testBed = await setup();

await act(async () => {
await nextTick();
testBed.component.update();
testBed = await setup();
});

testBed.component.update();
});

test('should retain the search query', async () => {
const { table, actions } = testBed;

actions.searchWatches(watch1.name);

const { tableCellsValues } = table.getMetaData('watchesTable');

// Expect "watch1" is only visible in the table
expect(tableCellsValues.length).toEqual(1);
const row = tableCellsValues[0];
const { name, id, watchStatus } = watch1;

const expectedRow = [
'', // checkbox
id,
name,
watchStatus.state,
'', // comment
'', // lastMetCondition
'', // lastChecked
'', // actions
];

expect(row).toEqual(expectedRow);

await actions.advanceTimeToTableRefresh();

const { tableCellsValues: updatedTableCellsValues } = table.getMetaData('watchesTable');

// Verify "watch1" is still the only watch visible in the table
expect(updatedTableCellsValues.length).toEqual(1);
const updatedRow = updatedTableCellsValues[0];

expect(updatedRow).toEqual(expectedRow);
});

test('should set the correct app title', () => {
Expand Down Expand Up @@ -185,7 +215,7 @@ describe('<WatchList />', () => {
});

test('should send the correct HTTP request to delete watch', async () => {
const { component, actions, table } = testBed;
const { actions, table } = testBed;
const { rows } = table.getMetaData('watchesTable');

const watchId = rows[0].columns[2].value;
Expand All @@ -208,8 +238,6 @@ describe('<WatchList />', () => {

await act(async () => {
confirmButton!.click();
await nextTick();
component.update();
});

const latestRequest = server.requests[server.requests.length - 1];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import React, { useState, useMemo, useEffect, Fragment } from 'react';

import {
CriteriaWithPagination,
EuiButton,
EuiButtonEmpty,
EuiFlexGroup,
Expand Down Expand Up @@ -57,6 +58,11 @@ export const WatchList = () => {
// Filter out deleted watches on the client, because the API will return 200 even though some watches
// may not really be deleted until after they're done firing and this could take some time.
const [deletedWatches, setDeletedWatches] = useState<string[]>([]);
const [pagination, setPagination] = useState({
pageIndex: 0,
pageSize: PAGINATION.initialPageSize,
});
const [query, setQuery] = useState('');

useEffect(() => {
setBreadcrumbs([listBreadcrumb]);
Expand Down Expand Up @@ -379,7 +385,14 @@ export const WatchList = () => {
: '',
};

const handleOnChange = (search: { queryText: string }) => {
setQuery(search.queryText);
return true;
};

const searchConfig = {
query,
onChange: handleOnChange,
box: {
incremental: true,
},
Expand Down Expand Up @@ -409,29 +422,43 @@ export const WatchList = () => {
};

content = (
<EuiInMemoryTable
items={availableWatches}
itemId="id"
columns={columns}
search={searchConfig}
pagination={PAGINATION}
sorting={true}
selection={selectionConfig}
isSelectable={true}
message={
<FormattedMessage
id="xpack.watcher.sections.watchList.watchTable.noWatchesMessage"
defaultMessage="No watches to show"
/>
}
rowProps={() => ({
'data-test-subj': 'row',
})}
cellProps={() => ({
'data-test-subj': 'cell',
})}
data-test-subj="watchesTable"
/>
<div data-test-subj="watchesTableContainer">
<EuiInMemoryTable
onTableChange={({ page: { index, size } }: CriteriaWithPagination<never>) =>
setPagination({ pageIndex: index, pageSize: size })
}
items={availableWatches}
itemId="id"
columns={columns}
search={searchConfig}
pagination={{
...PAGINATION,
pageIndex: pagination.pageIndex,
pageSize: pagination.pageSize,
}}
sorting={{
sort: {
field: 'name',
direction: 'asc',
},
}}
selection={selectionConfig}
isSelectable={true}
message={
<FormattedMessage
id="xpack.watcher.sections.watchList.watchTable.noWatchesMessage"
defaultMessage="No watches to show"
/>
}
rowProps={() => ({
'data-test-subj': 'row',
})}
cellProps={() => ({
'data-test-subj': 'cell',
})}
data-test-subj="watchesTable"
/>
</div>
);
}

Expand Down

0 comments on commit 340f85c

Please sign in to comment.