Skip to content

Commit

Permalink
Merge pull request #2713 from sarahd93/refactor_host_listpage_master
Browse files Browse the repository at this point in the history
Refactor host listpage
  • Loading branch information
bjoernricks committed Feb 9, 2021
2 parents 71aa65a + 2a0d7d6 commit f4ba8eb
Show file tree
Hide file tree
Showing 7 changed files with 732 additions and 166 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
### Added

### Changed
- Implement host listpage queries and mutations [#2713](https://github.com/greenbone/gsa/pull/2713)
- Implement host detailspage queries and mutations [#2702](https://github.com/greenbone/gsa/pull/2702)
- Implement audit component mutations [#2699](https://github.com/greenbone/gsa/pull/2699)
- Implement policy component mutations [#2684](https://github.com/greenbone/gsa/pull/2684)
Expand Down
1 change: 1 addition & 0 deletions gsa/src/gmp/utils/entitytype.js
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ export const apiType = type => {
export const hyperionEntityTypes = [
'task',
'alert',
'host',
'policy',
'permission',
'scanconfig',
Expand Down
87 changes: 86 additions & 1 deletion gsa/src/web/graphql/__mocks__/hosts.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,14 @@
*/

import {deepFreeze, createGenericQueryMock} from 'web/utils/testing';
import {DELETE_HOSTS_BY_IDS, EXPORT_HOSTS_BY_IDS, GET_HOST} from '../hosts';
import {
DELETE_HOSTS_BY_IDS,
DELETE_HOSTS_BY_FILTER,
EXPORT_HOSTS_BY_IDS,
EXPORT_HOSTS_BY_FILTER,
GET_HOST,
GET_HOSTS,
} from '../hosts';

export const host = deepFreeze({
id: '12345',
Expand Down Expand Up @@ -136,6 +143,47 @@ export const hostWithoutPermission = deepFreeze({
severity: 10.0,
});

const mockHosts = {
edges: [
{
node: host,
},
],
counts: {
total: 1,
filtered: 1,
offset: 0,
limit: 10,
length: 1,
},
pageInfo: {
hasNextPage: false,
hasPreviousPage: false,
startCursor: 'c2NoZWR1bGU6MA==',
endCursor: 'c2NoZWR1bGU6MA==',
lastPageCursor: 'c2NoZWR1bGU6MA==',
},
};

export const createGetHostsQueryMock = (variables = {}) => {
const queryResult = {
data: {
hosts: mockHosts,
},
};

const resultFunc = jest.fn().mockReturnValue(queryResult);

const queryMock = {
request: {
query: GET_HOSTS,
variables,
},
newData: resultFunc,
};
return [queryMock, resultFunc];
};

export const createGetHostQueryMock = (id = '12345', result = host) =>
createGenericQueryMock(GET_HOST, {host: result}, {id});

Expand All @@ -150,6 +198,20 @@ export const createExportHostsByIdsQueryMock = (hostIds = ['234']) =>
ids: hostIds,
});

const exportHostsByFilterResult = {
exportHostsByFilter: {
exportedEntities: '<get_assets_response status="200" status_text="OK" />',
},
};

export const createExportHostsByFilterQueryMock = (filterString = 'foo') => {
return createGenericQueryMock(
EXPORT_HOSTS_BY_FILTER,
exportHostsByFilterResult,
{filterString},
);
};

const bulkDeleteByIdsResult = {
deleteHostsByIds: {
ok: true,
Expand All @@ -160,3 +222,26 @@ export const createDeleteHostsByIdsQueryMock = (hostIds = ['234']) =>
createGenericQueryMock(DELETE_HOSTS_BY_IDS, bulkDeleteByIdsResult, {
ids: hostIds,
});

const bulkDeleteByFilterResult = {
deleteHostsByFilter: {
ok: true,
},
};

export const createDeleteHostsByFilterQueryMock = (filterString = 'foo') =>
createGenericQueryMock(DELETE_HOSTS_BY_FILTER, bulkDeleteByFilterResult, {
filterString,
});

const deleteHostResult = {
deleteHostByIds: {
ok: true,
status: 200,
},
};

export const createDeleteHostQueryMock = (hostId = 'foo') =>
createGenericQueryMock(DELETE_HOSTS_BY_IDS, deleteHostResult, {
ids: [hostId],
});
165 changes: 163 additions & 2 deletions gsa/src/web/graphql/__tests__/hosts.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,28 @@
/* eslint-disable react/prop-types */
import React from 'react';

import {isDefined} from 'gmp/utils/identity';

import {fireEvent, rendererWith, screen, wait} from 'web/utils/testing';

import {
createGetHostQueryMock,
createGetHostsQueryMock,
createDeleteHostsByIdsQueryMock,
createDeleteHostsByFilterQueryMock,
createDeleteHostQueryMock,
createExportHostsByIdsQueryMock,
createExportHostsByFilterQueryMock,
} from '../__mocks__/hosts';
import {useDeleteHost, useExportHostsByIds, useGetHost} from '../hosts';
import {
useDeleteHost,
useDeleteHostsByIds,
useDeleteHostsByFilter,
useExportHostsByIds,
useExportHostsByFilter,
useGetHost,
useLazyGetHosts,
} from '../hosts';

const GetHostComponent = ({id}) => {
const {loading, host, error} = useGetHost(id);
Expand Down Expand Up @@ -69,6 +83,78 @@ describe('useGetHost tests', () => {
});
});

const GetLazyHostsComponent = () => {
const [getHosts, {counts, loading, hosts}] = useLazyGetHosts();

if (loading) {
return <span data-testid="loading">Loading</span>;
}
return (
<div>
<button data-testid="load" onClick={() => getHosts()} />
{isDefined(counts) ? (
<div data-testid="counts">
<span data-testid="total">{counts.all}</span>
<span data-testid="filtered">{counts.filtered}</span>
<span data-testid="first">{counts.first}</span>
<span data-testid="limit">{counts.rows}</span>
<span data-testid="length">{counts.length}</span>
</div>
) : (
<div data-testid="no-counts" />
)}
{isDefined(hosts) ? (
hosts.map(host => {
return (
<div key={host.id} data-testid="host">
{host.id}
</div>
);
})
) : (
<div data-testid="no-hosts" />
)}
</div>
);
};

describe('useLazyGetHosts tests', () => {
test('should query hosts after user interaction', async () => {
const [mock, resultFunc] = createGetHostsQueryMock();
const {render} = rendererWith({queryMocks: [mock]});
render(<GetLazyHostsComponent />);

let hostElements = screen.queryAllByTestId('host');
expect(hostElements).toHaveLength(0);

expect(screen.queryByTestId('no-hosts')).toBeInTheDocument();
expect(screen.queryByTestId('no-counts')).toBeInTheDocument();

const button = screen.getByTestId('load');
fireEvent.click(button);

const loading = await screen.findByTestId('loading');
expect(loading).toHaveTextContent('Loading');

await wait();

expect(resultFunc).toHaveBeenCalled();

hostElements = screen.getAllByTestId('host');
expect(hostElements).toHaveLength(1);

expect(hostElements[0]).toHaveTextContent('12345');

expect(screen.queryByTestId('no-hosts')).not.toBeInTheDocument();

expect(screen.getByTestId('total')).toHaveTextContent(1);
expect(screen.getByTestId('filtered')).toHaveTextContent(1);
expect(screen.getByTestId('first')).toHaveTextContent(1);
expect(screen.getByTestId('limit')).toHaveTextContent(10);
expect(screen.getByTestId('length')).toHaveTextContent(1);
});
});

const ExportHostsByIdsComponent = () => {
const exportHostsByIds = useExportHostsByIds();
return (
Expand All @@ -94,14 +180,89 @@ describe('useExportHostsByIds tests', () => {
});
});

const ExportHostsByFilterComponent = () => {
const exportHostsByFilter = useExportHostsByFilter();
return (
<button
data-testid="filter-export"
onClick={() => exportHostsByFilter('foo')}
/>
);
};

describe('useExportHostsByFilter tests', () => {
test('should export a list of hosts by filter string after user interaction', async () => {
const [mock, resultFunc] = createExportHostsByFilterQueryMock();
const {render} = rendererWith({queryMocks: [mock]});

render(<ExportHostsByFilterComponent />);
const button = screen.getByTestId('filter-export');
fireEvent.click(button);

await wait();

expect(resultFunc).toHaveBeenCalled();
});
});

const DeleteHostsByIdsComponent = () => {
const [deleteHostsByIds] = useDeleteHostsByIds();
return (
<button
data-testid="bulk-delete"
onClick={() => deleteHostsByIds(['foo', 'bar'])}
/>
);
};

describe('useDeleteHostsByIds tests', () => {
test('should delete a list of hosts after user interaction', async () => {
const [mock, resultFunc] = createDeleteHostsByIdsQueryMock(['foo', 'bar']);
const {render} = rendererWith({queryMocks: [mock]});

render(<DeleteHostsByIdsComponent />);
const button = screen.getByTestId('bulk-delete');
fireEvent.click(button);

await wait();

expect(resultFunc).toHaveBeenCalled();
});
});

const DeleteHostsByFilterComponent = () => {
const [deleteHostsByFilter] = useDeleteHostsByFilter();
return (
<button
data-testid="filter-delete"
onClick={() => deleteHostsByFilter('foo')}
/>
);
};

describe('useDeleteHostsByFilter tests', () => {
test('should delete a list of hosts by filter string after user interaction', async () => {
const [mock, resultFunc] = createDeleteHostsByFilterQueryMock('foo');
const {render} = rendererWith({queryMocks: [mock]});

render(<DeleteHostsByFilterComponent />);
const button = screen.getByTestId('filter-delete');
fireEvent.click(button);

await wait();

expect(resultFunc).toHaveBeenCalled();
});
});

const DeleteHostComponent = () => {
const [deleteHost] = useDeleteHost();
return <button data-testid="delete" onClick={() => deleteHost('234')} />;
};

describe('useDeleteHostsByIds tests', () => {
test('should delete a list of hosts after user interaction', async () => {
const [mock, resultFunc] = createDeleteHostsByIdsQueryMock(['234']);
const [mock, resultFunc] = createDeleteHostQueryMock('234');
const {render} = rendererWith({queryMocks: [mock]});

render(<DeleteHostComponent />);
Expand Down
Loading

0 comments on commit f4ba8eb

Please sign in to comment.