Skip to content

Commit

Permalink
[Fleet] fixing dropping select all (#135124)
Browse files Browse the repository at this point in the history
* fixing dropping select all

* added unit test for agent list selection

Co-authored-by: Kibana Machine <[email protected]>
(cherry picked from commit eb4529e)
  • Loading branch information
juliaElastic committed Jun 27, 2022
1 parent a07a372 commit 5c60cc2
Show file tree
Hide file tree
Showing 2 changed files with 173 additions and 4 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import React from 'react';

import type { RenderResult } from '@testing-library/react';
import { act, fireEvent, waitFor } from '@testing-library/react';

import { createFleetTestRendererMock } from '../../../../../mock';

import { sendGetAgents } from '../../../hooks';

import { AgentListPage } from '.';

jest.mock('../../../hooks', () => ({
...jest.requireActual('../../../hooks'),
sendGetAgents: jest.fn(),
useGetAgentPolicies: jest.fn().mockReturnValue({
data: { items: [{ id: 'policy1' }] },
isLoading: false,
resendRequest: jest.fn(),
}),
FleetStatusProvider: (props: any) => {
return props.children;
},
useFleetStatus: jest.fn().mockReturnValue({}),
sendGetAgentStatus: jest.fn().mockResolvedValue({
data: {
results: {
online: 6,
error: 0,
offline: 0,
updating: 0,
},
totalInactive: 0,
},
}),
useAuthz: jest.fn().mockReturnValue({ fleet: { all: true } }),
useStartServices: jest.fn().mockReturnValue({
notifications: {
toasts: {
addError: jest.fn(),
},
},
cloud: {},
data: { dataViews: { getFieldsForWildcard: jest.fn() } },
}),
useBreadcrumbs: jest.fn(),
useLink: jest.fn().mockReturnValue({ getHref: jest.fn() }),
useUrlParams: jest.fn().mockReturnValue({ urlParams: { kuery: '' } }),
useKibanaVersion: jest.fn().mockReturnValue('8.3.0'),
usePagination: jest.fn().mockReturnValue({
pagination: {
currentPage: 1,
pageSize: 5,
},
pageSizeOptions: [5, 20, 50],
setPagination: jest.fn(),
}),
useFleetServerUnhealthy: jest.fn().mockReturnValue({
isUnhealthy: false,
isLoading: false,
}),
}));

jest.mock('./components/search_and_filter_bar', () => {
return {
SearchAndFilterBar: () => <>SearchAndFilterBar</>,
};
});

const mockedSendGetAgents = sendGetAgents as jest.Mock;

function renderAgentList() {
const renderer = createFleetTestRendererMock();

const utils = renderer.render(<AgentListPage />);

return { utils };
}

describe('agent_list_page', () => {
const mapAgents = (ids: string[]) =>
ids.map((agent) => ({
id: agent,
active: true,
policy_id: 'policy1',
local_metadata: { host: { hostname: agent } },
}));

let utils: RenderResult;

beforeEach(async () => {
mockedSendGetAgents
.mockResolvedValueOnce({
data: {
items: mapAgents(['agent1', 'agent2', 'agent3', 'agent4', 'agent5']),
total: 6,
totalInactive: 0,
},
})
.mockResolvedValueOnce({
data: {
items: mapAgents(['agent1', 'agent2', 'agent3', 'agent4', 'agent6']),
total: 6,
totalInactive: 0,
},
});
jest.useFakeTimers();

({ utils } = renderAgentList());

await waitFor(() => {
expect(utils.getByText('Showing 6 agents')).toBeInTheDocument();
});

act(() => {
const selectAll = utils.container.querySelector('[data-test-subj="checkboxSelectAll"]');
fireEvent.click(selectAll!);
});

await waitFor(() => {
utils.getByText('5 agents selected');
});

act(() => {
fireEvent.click(utils.getByText('Select everything on all pages'));
});
utils.getByText('All agents selected');
});

afterEach(() => {
jest.useRealTimers();
});

it('should not set selection mode when agent selection changed automatically', async () => {
act(() => {
jest.runOnlyPendingTimers();
});

await waitFor(() => {
expect(utils.getByText('agent6')).toBeInTheDocument();
});

utils.getByText('All agents selected');
});

it('should set selection mode when agent selection changed manually', async () => {
act(() => {
fireEvent.click(utils.getAllByRole('checkbox')[3]);
});

utils.getByText('4 agents selected');
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*/

import React, { useState, useMemo, useCallback, useRef, useEffect } from 'react';
import { differenceBy } from 'lodash';
import {
EuiBasicTable,
EuiFlexGroup,
Expand Down Expand Up @@ -319,6 +320,18 @@ export const AgentListPage: React.FunctionComponent<{}> = () => {
return !isHosted;
};

const onSelectionChange = (newAgents: Agent[]) => {
setSelectedAgents(newAgents);
if (selectionMode === 'query' && newAgents.length < selectedAgents.length) {
// differentiating between selection changed by agents dropping from current page or user action
const areSelectedAgentsStillVisible =
selectedAgents.length > 0 && differenceBy(selectedAgents, agents, 'id').length === 0;
if (areSelectedAgentsStillVisible) {
setSelectionMode('manual');
}
}
};

const agentToUnenrollHasFleetServer = useMemo(() => {
if (!agentToUnenroll || !agentToUnenroll.policy_id) {
return false;
Expand Down Expand Up @@ -631,10 +644,7 @@ export const AgentListPage: React.FunctionComponent<{}> = () => {
}}
isSelectable={true}
selection={{
onSelectionChange: (newAgents: Agent[]) => {
setSelectedAgents(newAgents);
setSelectionMode('manual');
},
onSelectionChange,
selectable: isAgentSelectable,
selectableMessage: (selectable, agent) => {
if (selectable) return '';
Expand Down

0 comments on commit 5c60cc2

Please sign in to comment.