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

Implement policy component mutations #2684

Merged
merged 10 commits into from
Feb 1, 2021
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
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 policy component mutations [#2684](https://github.com/greenbone/gsa/pull/2684)
- Refactor host component into function [#2693](https://github.com/greenbone/gsa/pull/2693)
- Refactor Audit Component into Function [#2695](https://github.com/greenbone/gsa/pull/2695)
- Implement policy listpage queries and mutations [#2679](https://github.com/greenbone/gsa/pull/2679)
Expand Down
29 changes: 28 additions & 1 deletion gsa/src/web/graphql/__mocks__/policies.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,13 @@
import {deepFreeze, createGenericQueryMock} from 'web/utils/testing';
import {
CLONE_POLICY,
DELETE_POLICIES_BY_FILTER,
CREATE_POLICY,
DELETE_POLICIES_BY_IDS,
DELETE_POLICIES_BY_FILTER,
EXPORT_POLICIES_BY_FILTER,
EXPORT_POLICIES_BY_IDS,
GET_POLICY,
IMPORT_POLICY,
GET_POLICIES,
} from '../policies';

Expand Down Expand Up @@ -335,6 +337,13 @@ export const createDeletePoliciesByIdsQueryMock = (policyIds = ['234']) =>
ids: policyIds,
});

const createPolicyResult = {
createPolicy: {
id: '345',
status: 200,
},
};

const bulkDeleteByFilterResult = {
deletePoliciesByFilter: {
ok: true,
Expand All @@ -358,3 +367,21 @@ export const createExportPoliciesByFilterQueryMock = (filterString = 'foo') =>
exportPoliciesByFilterResult,
{filterString},
);

export const createCreatePolicyQueryMock = () =>
createGenericQueryMock(CREATE_POLICY, createPolicyResult, {
input: {policyId: 'foo', name: 'bar', comment: 'lorem'},
});

export const importPolicyInput = {
policy: '<get_configs_response />',
};

export const importPolicyResult = {
importPolicy: {
id: '456',
},
};

export const createImportPolicyQueryMock = () =>
createGenericQueryMock(IMPORT_POLICY, importPolicyResult, importPolicyInput);
151 changes: 148 additions & 3 deletions gsa/src/web/graphql/__tests__/policies.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,28 +16,33 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* eslint-disable react/prop-types */
import React from 'react';
import React, {useState} from 'react';

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

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

import {
createClonePolicyQueryMock,
createDeletePoliciesByFilterQueryMock,
createCreatePolicyQueryMock,
createDeletePoliciesByIdsQueryMock,
createDeletePoliciesByFilterQueryMock,
createExportPoliciesByFilterQueryMock,
createExportPoliciesByIdsQueryMock,
createGetPoliciesQueryMock,
createGetPolicyQueryMock,
createImportPolicyQueryMock,
} from '../__mocks__/policies';
import {
useClonePolicy,
useDeletePoliciesByFilter,
useCreatePolicy,
useDeletePolicy,
useDeletePoliciesByFilter,
useExportPoliciesByFilter,
useExportPoliciesByIds,
useGetPolicy,
useLazyGetPolicy,
useImportPolicy,
useLazyGetPolicies,
} from '../policies';

Expand Down Expand Up @@ -277,3 +282,143 @@ describe('useLazyGetPolicies tests', () => {
expect(screen.getByTestId('length')).toHaveTextContent(1);
});
});

const GetLazyPolicyComponent = () => {
const [getPolicy] = useLazyGetPolicy();
const [policy, setPolicy] = useState();

const handleLoadPolicy = policyId => {
return getPolicy(policyId).then(response => setPolicy(response));
};

return (
<div>
<button data-testid="load" onClick={() => handleLoadPolicy('234')} />
{isDefined(policy) ? (
<div key={policy.id} data-testid="policy">
{policy.id}
</div>
) : (
<div data-testid="no-policy" />
)}
</div>
);
};

describe('useLazyGetPolicy tests', () => {
test('should query policy after user interaction', async () => {
const [mock, resultFunc] = createGetPolicyQueryMock();
const {render} = rendererWith({queryMocks: [mock]});
render(<GetLazyPolicyComponent />);

await wait();

let policyElement = screen.queryAllByTestId('policy');
expect(policyElement).toHaveLength(0);

expect(screen.queryByTestId('no-policy')).toBeInTheDocument();

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

await wait();

expect(resultFunc).toHaveBeenCalled();

policyElement = screen.getByTestId('policy');

expect(policyElement).toHaveTextContent('234');
});
});

const CreatePolicyComponent = () => {
const [notification, setNotification] = useState('');

const [createPolicy] = useCreatePolicy();

const handleCreateResult = id => {
setNotification(`Policy created with id ${id}.`);
};

return (
<div>
<button
title={'Create Policy'}
onClick={() =>
createPolicy({policyId: 'foo', name: 'bar', comment: 'lorem'}).then(
handleCreateResult,
)
}
/>
<h3 data-testid="notification">{notification}</h3>
</div>
);
};

describe('Policy mutation tests', () => {
test('should create a policy', async () => {
const [
createPolicyMock,
createPolicyResult,
] = createCreatePolicyQueryMock();
const {render} = rendererWith({queryMocks: [createPolicyMock]});

const {element} = render(<CreatePolicyComponent />);

const buttons = element.querySelectorAll('button');

fireEvent.click(buttons[0]);

await wait();

expect(createPolicyResult).toHaveBeenCalled();
expect(screen.getByTestId('notification')).toHaveTextContent(
'Policy created with id 345.',
);
});
});

const ImportPolicyComponent = () => {
const [notification, setNotification] = useState('');

const [importPolicy] = useImportPolicy();

const handleCreateResult = id => {
setNotification(`Policy imported with id ${id}.`);
};

return (
<div>
<button
title={'Import Policy'}
onClick={() =>
importPolicy('<get_configs_response />').then(handleCreateResult)
}
/>
<h3 data-testid="notification">{notification}</h3>
</div>
);
};

describe('Import Policy tests', () => {
test('should import a policy', async () => {
const [
importPolicyQueryMock,
importPolicyQueryResult,
] = createImportPolicyQueryMock();
const {render} = rendererWith({queryMocks: [importPolicyQueryMock]});

const {element} = render(<ImportPolicyComponent />);

const buttons = element.querySelectorAll('button');

fireEvent.click(buttons[0]);

await wait();

expect(importPolicyQueryResult).toHaveBeenCalled();
expect(screen.getByTestId('notification')).toHaveTextContent(
'Policy imported with id 456.',
);
});
});
95 changes: 86 additions & 9 deletions gsa/src/web/graphql/policies.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,13 @@
*/
import {useCallback} from 'react';

import {gql, useQuery, useMutation, useLazyQuery} from '@apollo/client';
import {
gql,
useQuery,
useMutation,
useLazyQuery,
useApolloClient,
} from '@apollo/client';

import CollectionCounts from 'gmp/collection/collectioncounts';
import Policy from 'gmp/models/policy';
Expand Down Expand Up @@ -133,14 +139,6 @@ export const EXPORT_POLICIES_BY_IDS = gql`
}
`;

export const CLONE_POLICY = gql`
mutation clonePolicy($id: UUID!) {
clonePolicy(id: $id) {
id
}
}
`;

export const DELETE_POLICIES_BY_FILTER = gql`
mutation deletePoliciesByFilter($filterString: String!) {
deletePoliciesByFilter(filterString: $filterString) {
Expand All @@ -157,6 +155,30 @@ export const EXPORT_POLICIES_BY_FILTER = gql`
}
`;

export const CLONE_POLICY = gql`
mutation clonePolicy($id: UUID!) {
clonePolicy(id: $id) {
id
}
}
`;

export const CREATE_POLICY = gql`
mutation createPolicy($input: CreatePolicyInput!) {
createPolicy(input: $input) {
id
}
}
`;

export const IMPORT_POLICY = gql`
mutation importPolicy($policy: String) {
importPolicy(policy: $policy) {
id
}
}
`;

export const useGetPolicy = (id, options) => {
const {data, ...other} = useQuery(GET_POLICY, {
...options,
Expand Down Expand Up @@ -297,3 +319,58 @@ export const useDeletePoliciesByFilter = options => {
);
return [deletePoliciesByFilter, data];
};

export const useCreatePolicy = options => {
const [queryCreatePolicy, {data, ...other}] = useMutation(
CREATE_POLICY,
options,
);
const createPolicy = useCallback(
// eslint-disable-next-line no-shadow
(inputObject, options) =>
queryCreatePolicy({...options, variables: {input: inputObject}}).then(
result => result?.data?.createPolicy?.id,
),
[queryCreatePolicy],
);
const policyId = data?.createPolicy?.id;
return [createPolicy, {...other, id: policyId}];
};

export const useLazyGetPolicy = () => {
const client = useApolloClient();
let policy;
const getPolicy = policyId =>
client
.query({
query: GET_POLICY,
variables: {id: policyId},
fetchPolicy: 'no-cache', // do not cache, since this is used when a change is saved
})
.then(response => {
if (isDefined(response?.data?.policy)) {
policy = Policy.fromObject(response?.data?.policy);
}

return policy;
});

return [getPolicy, policy];
};

export const useImportPolicy = options => {
const [queryImportPolicy, {data, ...other}] = useMutation(
IMPORT_POLICY,
options,
);
const importPolicy = useCallback(
// eslint-disable-next-line no-shadow
(policy, options) =>
queryImportPolicy({...options, variables: {policy}}).then(
result => result.data.importPolicy.id,
),
[queryImportPolicy],
);
const policyId = data?.importPolicy?.id;
return [importPolicy, {...other, id: policyId}];
};
Loading