Skip to content

Commit fd8dad7

Browse files
authored
Merge pull request #2684 from saberlynx/policy-component
Implement policy component mutations
2 parents 0955977 + 9392565 commit fd8dad7

File tree

5 files changed

+297
-27
lines changed

5 files changed

+297
-27
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
99
### Added
1010

1111
### Changed
12+
- Implement policy component mutations [#2684](https://github.com/greenbone/gsa/pull/2684)
1213
- Refactor host component into function [#2693](https://github.com/greenbone/gsa/pull/2693)
1314
- Refactor Audit Component into Function [#2695](https://github.com/greenbone/gsa/pull/2695)
1415
- Implement policy listpage queries and mutations [#2679](https://github.com/greenbone/gsa/pull/2679)

gsa/src/web/graphql/__mocks__/policies.js

+28-1
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,13 @@
1919
import {deepFreeze, createGenericQueryMock} from 'web/utils/testing';
2020
import {
2121
CLONE_POLICY,
22-
DELETE_POLICIES_BY_FILTER,
22+
CREATE_POLICY,
2323
DELETE_POLICIES_BY_IDS,
24+
DELETE_POLICIES_BY_FILTER,
2425
EXPORT_POLICIES_BY_FILTER,
2526
EXPORT_POLICIES_BY_IDS,
2627
GET_POLICY,
28+
IMPORT_POLICY,
2729
GET_POLICIES,
2830
} from '../policies';
2931

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

340+
const createPolicyResult = {
341+
createPolicy: {
342+
id: '345',
343+
status: 200,
344+
},
345+
};
346+
338347
const bulkDeleteByFilterResult = {
339348
deletePoliciesByFilter: {
340349
ok: true,
@@ -358,3 +367,21 @@ export const createExportPoliciesByFilterQueryMock = (filterString = 'foo') =>
358367
exportPoliciesByFilterResult,
359368
{filterString},
360369
);
370+
371+
export const createCreatePolicyQueryMock = () =>
372+
createGenericQueryMock(CREATE_POLICY, createPolicyResult, {
373+
input: {policyId: 'foo', name: 'bar', comment: 'lorem'},
374+
});
375+
376+
export const importPolicyInput = {
377+
policy: '<get_configs_response />',
378+
};
379+
380+
export const importPolicyResult = {
381+
importPolicy: {
382+
id: '456',
383+
},
384+
};
385+
386+
export const createImportPolicyQueryMock = () =>
387+
createGenericQueryMock(IMPORT_POLICY, importPolicyResult, importPolicyInput);

gsa/src/web/graphql/__tests__/policies.js

+148-3
Original file line numberDiff line numberDiff line change
@@ -16,28 +16,33 @@
1616
* along with this program. If not, see <http://www.gnu.org/licenses/>.
1717
*/
1818
/* eslint-disable react/prop-types */
19-
import React from 'react';
19+
import React, {useState} from 'react';
2020

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

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

2525
import {
2626
createClonePolicyQueryMock,
27-
createDeletePoliciesByFilterQueryMock,
27+
createCreatePolicyQueryMock,
2828
createDeletePoliciesByIdsQueryMock,
29+
createDeletePoliciesByFilterQueryMock,
2930
createExportPoliciesByFilterQueryMock,
3031
createExportPoliciesByIdsQueryMock,
3132
createGetPoliciesQueryMock,
3233
createGetPolicyQueryMock,
34+
createImportPolicyQueryMock,
3335
} from '../__mocks__/policies';
3436
import {
3537
useClonePolicy,
36-
useDeletePoliciesByFilter,
38+
useCreatePolicy,
3739
useDeletePolicy,
40+
useDeletePoliciesByFilter,
3841
useExportPoliciesByFilter,
3942
useExportPoliciesByIds,
4043
useGetPolicy,
44+
useLazyGetPolicy,
45+
useImportPolicy,
4146
useLazyGetPolicies,
4247
} from '../policies';
4348

@@ -277,3 +282,143 @@ describe('useLazyGetPolicies tests', () => {
277282
expect(screen.getByTestId('length')).toHaveTextContent(1);
278283
});
279284
});
285+
286+
const GetLazyPolicyComponent = () => {
287+
const [getPolicy] = useLazyGetPolicy();
288+
const [policy, setPolicy] = useState();
289+
290+
const handleLoadPolicy = policyId => {
291+
return getPolicy(policyId).then(response => setPolicy(response));
292+
};
293+
294+
return (
295+
<div>
296+
<button data-testid="load" onClick={() => handleLoadPolicy('234')} />
297+
{isDefined(policy) ? (
298+
<div key={policy.id} data-testid="policy">
299+
{policy.id}
300+
</div>
301+
) : (
302+
<div data-testid="no-policy" />
303+
)}
304+
</div>
305+
);
306+
};
307+
308+
describe('useLazyGetPolicy tests', () => {
309+
test('should query policy after user interaction', async () => {
310+
const [mock, resultFunc] = createGetPolicyQueryMock();
311+
const {render} = rendererWith({queryMocks: [mock]});
312+
render(<GetLazyPolicyComponent />);
313+
314+
await wait();
315+
316+
let policyElement = screen.queryAllByTestId('policy');
317+
expect(policyElement).toHaveLength(0);
318+
319+
expect(screen.queryByTestId('no-policy')).toBeInTheDocument();
320+
321+
const button = screen.getByTestId('load');
322+
fireEvent.click(button);
323+
324+
await wait();
325+
326+
expect(resultFunc).toHaveBeenCalled();
327+
328+
policyElement = screen.getByTestId('policy');
329+
330+
expect(policyElement).toHaveTextContent('234');
331+
});
332+
});
333+
334+
const CreatePolicyComponent = () => {
335+
const [notification, setNotification] = useState('');
336+
337+
const [createPolicy] = useCreatePolicy();
338+
339+
const handleCreateResult = id => {
340+
setNotification(`Policy created with id ${id}.`);
341+
};
342+
343+
return (
344+
<div>
345+
<button
346+
title={'Create Policy'}
347+
onClick={() =>
348+
createPolicy({policyId: 'foo', name: 'bar', comment: 'lorem'}).then(
349+
handleCreateResult,
350+
)
351+
}
352+
/>
353+
<h3 data-testid="notification">{notification}</h3>
354+
</div>
355+
);
356+
};
357+
358+
describe('Policy mutation tests', () => {
359+
test('should create a policy', async () => {
360+
const [
361+
createPolicyMock,
362+
createPolicyResult,
363+
] = createCreatePolicyQueryMock();
364+
const {render} = rendererWith({queryMocks: [createPolicyMock]});
365+
366+
const {element} = render(<CreatePolicyComponent />);
367+
368+
const buttons = element.querySelectorAll('button');
369+
370+
fireEvent.click(buttons[0]);
371+
372+
await wait();
373+
374+
expect(createPolicyResult).toHaveBeenCalled();
375+
expect(screen.getByTestId('notification')).toHaveTextContent(
376+
'Policy created with id 345.',
377+
);
378+
});
379+
});
380+
381+
const ImportPolicyComponent = () => {
382+
const [notification, setNotification] = useState('');
383+
384+
const [importPolicy] = useImportPolicy();
385+
386+
const handleCreateResult = id => {
387+
setNotification(`Policy imported with id ${id}.`);
388+
};
389+
390+
return (
391+
<div>
392+
<button
393+
title={'Import Policy'}
394+
onClick={() =>
395+
importPolicy('<get_configs_response />').then(handleCreateResult)
396+
}
397+
/>
398+
<h3 data-testid="notification">{notification}</h3>
399+
</div>
400+
);
401+
};
402+
403+
describe('Import Policy tests', () => {
404+
test('should import a policy', async () => {
405+
const [
406+
importPolicyQueryMock,
407+
importPolicyQueryResult,
408+
] = createImportPolicyQueryMock();
409+
const {render} = rendererWith({queryMocks: [importPolicyQueryMock]});
410+
411+
const {element} = render(<ImportPolicyComponent />);
412+
413+
const buttons = element.querySelectorAll('button');
414+
415+
fireEvent.click(buttons[0]);
416+
417+
await wait();
418+
419+
expect(importPolicyQueryResult).toHaveBeenCalled();
420+
expect(screen.getByTestId('notification')).toHaveTextContent(
421+
'Policy imported with id 456.',
422+
);
423+
});
424+
});

gsa/src/web/graphql/policies.js

+86-9
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,13 @@
1818
*/
1919
import {useCallback} from 'react';
2020

21-
import {gql, useQuery, useMutation, useLazyQuery} from '@apollo/client';
21+
import {
22+
gql,
23+
useQuery,
24+
useMutation,
25+
useLazyQuery,
26+
useApolloClient,
27+
} from '@apollo/client';
2228

2329
import CollectionCounts from 'gmp/collection/collectioncounts';
2430
import Policy from 'gmp/models/policy';
@@ -133,14 +139,6 @@ export const EXPORT_POLICIES_BY_IDS = gql`
133139
}
134140
`;
135141

136-
export const CLONE_POLICY = gql`
137-
mutation clonePolicy($id: UUID!) {
138-
clonePolicy(id: $id) {
139-
id
140-
}
141-
}
142-
`;
143-
144142
export const DELETE_POLICIES_BY_FILTER = gql`
145143
mutation deletePoliciesByFilter($filterString: String!) {
146144
deletePoliciesByFilter(filterString: $filterString) {
@@ -157,6 +155,30 @@ export const EXPORT_POLICIES_BY_FILTER = gql`
157155
}
158156
`;
159157

158+
export const CLONE_POLICY = gql`
159+
mutation clonePolicy($id: UUID!) {
160+
clonePolicy(id: $id) {
161+
id
162+
}
163+
}
164+
`;
165+
166+
export const CREATE_POLICY = gql`
167+
mutation createPolicy($input: CreatePolicyInput!) {
168+
createPolicy(input: $input) {
169+
id
170+
}
171+
}
172+
`;
173+
174+
export const IMPORT_POLICY = gql`
175+
mutation importPolicy($policy: String) {
176+
importPolicy(policy: $policy) {
177+
id
178+
}
179+
}
180+
`;
181+
160182
export const useGetPolicy = (id, options) => {
161183
const {data, ...other} = useQuery(GET_POLICY, {
162184
...options,
@@ -297,3 +319,58 @@ export const useDeletePoliciesByFilter = options => {
297319
);
298320
return [deletePoliciesByFilter, data];
299321
};
322+
323+
export const useCreatePolicy = options => {
324+
const [queryCreatePolicy, {data, ...other}] = useMutation(
325+
CREATE_POLICY,
326+
options,
327+
);
328+
const createPolicy = useCallback(
329+
// eslint-disable-next-line no-shadow
330+
(inputObject, options) =>
331+
queryCreatePolicy({...options, variables: {input: inputObject}}).then(
332+
result => result?.data?.createPolicy?.id,
333+
),
334+
[queryCreatePolicy],
335+
);
336+
const policyId = data?.createPolicy?.id;
337+
return [createPolicy, {...other, id: policyId}];
338+
};
339+
340+
export const useLazyGetPolicy = () => {
341+
const client = useApolloClient();
342+
let policy;
343+
const getPolicy = policyId =>
344+
client
345+
.query({
346+
query: GET_POLICY,
347+
variables: {id: policyId},
348+
fetchPolicy: 'no-cache', // do not cache, since this is used when a change is saved
349+
})
350+
.then(response => {
351+
if (isDefined(response?.data?.policy)) {
352+
policy = Policy.fromObject(response?.data?.policy);
353+
}
354+
355+
return policy;
356+
});
357+
358+
return [getPolicy, policy];
359+
};
360+
361+
export const useImportPolicy = options => {
362+
const [queryImportPolicy, {data, ...other}] = useMutation(
363+
IMPORT_POLICY,
364+
options,
365+
);
366+
const importPolicy = useCallback(
367+
// eslint-disable-next-line no-shadow
368+
(policy, options) =>
369+
queryImportPolicy({...options, variables: {policy}}).then(
370+
result => result.data.importPolicy.id,
371+
),
372+
[queryImportPolicy],
373+
);
374+
const policyId = data?.importPolicy?.id;
375+
return [importPolicy, {...other, id: policyId}];
376+
};

0 commit comments

Comments
 (0)