foreman_openscap 8.0.2 → 9.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (158) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +0 -1
  3. data/app/services/foreman_openscap/client_config/ansible.rb +1 -10
  4. data/config/initializers/inflections.rb +0 -2
  5. data/config/routes.rb +0 -15
  6. data/db/migrate/20240313111822_drop_oval.rb +17 -0
  7. data/lib/foreman_openscap/engine.rb +2 -56
  8. data/lib/foreman_openscap/version.rb +1 -1
  9. data/test/factories/compliance_host_factory.rb +0 -12
  10. data/test/test_plugin_helper.rb +0 -2
  11. data/webpack/global_index.js +0 -4
  12. metadata +7 -168
  13. data/app/controllers/api/v2/compliance/oval_contents_controller.rb +0 -72
  14. data/app/controllers/api/v2/compliance/oval_policies_controller.rb +0 -111
  15. data/app/controllers/api/v2/compliance/oval_reports_controller.rb +0 -47
  16. data/app/controllers/concerns/foreman/controller/parameters/oval_content.rb +0 -22
  17. data/app/controllers/concerns/foreman/controller/parameters/oval_policy.rb +0 -22
  18. data/app/graphql/mutations/oval_contents/delete.rb +0 -9
  19. data/app/graphql/mutations/oval_policies/create.rb +0 -33
  20. data/app/graphql/mutations/oval_policies/delete.rb +0 -9
  21. data/app/graphql/mutations/oval_policies/update.rb +0 -15
  22. data/app/graphql/types/cve.rb +0 -17
  23. data/app/graphql/types/oval_check.rb +0 -11
  24. data/app/graphql/types/oval_content.rb +0 -19
  25. data/app/graphql/types/oval_policy.rb +0 -24
  26. data/app/models/concerns/foreman_openscap/oval_facet_host_extensions.rb +0 -38
  27. data/app/models/concerns/foreman_openscap/oval_facet_hostgroup_extensions.rb +0 -31
  28. data/app/models/foreman_openscap/cve.rb +0 -23
  29. data/app/models/foreman_openscap/host/oval_facet.rb +0 -14
  30. data/app/models/foreman_openscap/host_cve.rb +0 -7
  31. data/app/models/foreman_openscap/hostgroup/oval_facet.rb +0 -14
  32. data/app/models/foreman_openscap/hostgroup_oval_facet_oval_policy.rb +0 -6
  33. data/app/models/foreman_openscap/oval_content.rb +0 -28
  34. data/app/models/foreman_openscap/oval_facet_oval_policy.rb +0 -6
  35. data/app/models/foreman_openscap/oval_policy.rb +0 -54
  36. data/app/models/foreman_openscap/oval_status.rb +0 -45
  37. data/app/services/foreman_openscap/oval/check_collection.rb +0 -45
  38. data/app/services/foreman_openscap/oval/configure.rb +0 -83
  39. data/app/services/foreman_openscap/oval/cves.rb +0 -41
  40. data/app/services/foreman_openscap/oval/setup.rb +0 -93
  41. data/app/services/foreman_openscap/oval/setup_check.rb +0 -58
  42. data/app/services/foreman_openscap/oval/sync_oval_contents.rb +0 -42
  43. data/app/views/api/v2/compliance/oval_contents/base.json.rabl +0 -6
  44. data/app/views/api/v2/compliance/oval_contents/create.json.rabl +0 -3
  45. data/app/views/api/v2/compliance/oval_contents/destroy.json.rabl +0 -3
  46. data/app/views/api/v2/compliance/oval_contents/index.json.rabl +0 -3
  47. data/app/views/api/v2/compliance/oval_contents/show.json.rabl +0 -3
  48. data/app/views/api/v2/compliance/oval_contents/sync.json.rabl +0 -3
  49. data/app/views/api/v2/compliance/oval_contents/sync_result.json.rabl +0 -11
  50. data/app/views/api/v2/compliance/oval_contents/update.json.rabl +0 -3
  51. data/app/views/api/v2/compliance/oval_policies/create.json.rabl +0 -3
  52. data/app/views/api/v2/compliance/oval_policies/index.json.rabl +0 -3
  53. data/app/views/api/v2/compliance/oval_policies/main.json.rabl +0 -15
  54. data/app/views/api/v2/compliance/oval_policies/show.json.rabl +0 -3
  55. data/app/views/job_templates/run_oval_scans.erb +0 -24
  56. data/locale/cs_CZ/foreman_openscap.edit.po +0 -1863
  57. data/locale/cs_CZ/foreman_openscap.po.time_stamp +0 -0
  58. data/locale/de/foreman_openscap.edit.po +0 -1873
  59. data/locale/de/foreman_openscap.po.time_stamp +0 -0
  60. data/locale/en/foreman_openscap.edit.po +0 -1863
  61. data/locale/en/foreman_openscap.po.time_stamp +0 -0
  62. data/locale/en_GB/foreman_openscap.edit.po +0 -1863
  63. data/locale/en_GB/foreman_openscap.po.time_stamp +0 -0
  64. data/locale/es/foreman_openscap.edit.po +0 -1868
  65. data/locale/es/foreman_openscap.po.time_stamp +0 -0
  66. data/locale/fr/foreman_openscap.edit.po +0 -1874
  67. data/locale/fr/foreman_openscap.po.time_stamp +0 -0
  68. data/locale/gl/foreman_openscap.edit.po +0 -1863
  69. data/locale/gl/foreman_openscap.po.time_stamp +0 -0
  70. data/locale/it/foreman_openscap.edit.po +0 -1865
  71. data/locale/it/foreman_openscap.po.time_stamp +0 -0
  72. data/locale/ja/foreman_openscap.edit.po +0 -1869
  73. data/locale/ja/foreman_openscap.po.time_stamp +0 -0
  74. data/locale/ka/foreman_openscap.edit.po +0 -1863
  75. data/locale/ka/foreman_openscap.po.time_stamp +0 -0
  76. data/locale/ko/foreman_openscap.edit.po +0 -1863
  77. data/locale/ko/foreman_openscap.po.time_stamp +0 -0
  78. data/locale/pt_BR/foreman_openscap.edit.po +0 -1873
  79. data/locale/pt_BR/foreman_openscap.po.time_stamp +0 -0
  80. data/locale/ru/foreman_openscap.edit.po +0 -1867
  81. data/locale/ru/foreman_openscap.po.time_stamp +0 -0
  82. data/locale/sv_SE/foreman_openscap.edit.po +0 -1863
  83. data/locale/sv_SE/foreman_openscap.po.time_stamp +0 -0
  84. data/locale/zh_CN/foreman_openscap.edit.po +0 -1868
  85. data/locale/zh_CN/foreman_openscap.po.time_stamp +0 -0
  86. data/locale/zh_TW/foreman_openscap.edit.po +0 -1864
  87. data/locale/zh_TW/foreman_openscap.po.time_stamp +0 -0
  88. data/test/factories/oval_content_factory.rb +0 -7
  89. data/test/factories/oval_policy_factory.rb +0 -9
  90. data/test/fixtures/cve_fixtures.rb +0 -104
  91. data/test/functional/api/v2/compliance/oval_contents_controller_test.rb +0 -39
  92. data/test/functional/api/v2/compliance/oval_policies_controller_test.rb +0 -141
  93. data/test/functional/api/v2/compliance/oval_reports_controller_test.rb +0 -32
  94. data/test/graphql/mutations/oval_policies/delete_mutation_test.rb +0 -63
  95. data/test/graphql/queries/oval_content_query_test.rb +0 -29
  96. data/test/graphql/queries/oval_contents_query_test.rb +0 -35
  97. data/test/graphql/queries/oval_policies_query_test.rb +0 -35
  98. data/test/unit/oval_host_test.rb +0 -45
  99. data/test/unit/oval_policy_test.rb +0 -133
  100. data/test/unit/oval_status_test.rb +0 -47
  101. data/test/unit/services/oval/cves_test.rb +0 -81
  102. data/test/unit/services/oval/setup_check_test.rb +0 -37
  103. data/test/unit/services/oval/setup_test.rb +0 -87
  104. data/webpack/graphql/mutations/createOvalPolicy.gql +0 -22
  105. data/webpack/graphql/mutations/deleteOvalContent.gql +0 -9
  106. data/webpack/graphql/mutations/deleteOvalPolicy.gql +0 -9
  107. data/webpack/graphql/mutations/updateOvalPolicy.gql +0 -14
  108. data/webpack/graphql/queries/currentUserAttributes.gql +0 -11
  109. data/webpack/graphql/queries/cves.gql +0 -23
  110. data/webpack/graphql/queries/hostgroups.gql +0 -14
  111. data/webpack/graphql/queries/ovalContent.gql +0 -8
  112. data/webpack/graphql/queries/ovalContents.gql +0 -19
  113. data/webpack/graphql/queries/ovalPolicies.gql +0 -20
  114. data/webpack/graphql/queries/ovalPolicy.gql +0 -29
  115. data/webpack/helpers/pathsHelper.js +0 -29
  116. data/webpack/routes/OvalContents/OvalContentsIndex/OvalContentsIndex.js +0 -71
  117. data/webpack/routes/OvalContents/OvalContentsIndex/OvalContentsTable.js +0 -83
  118. data/webpack/routes/OvalContents/OvalContentsIndex/__tests__/OvalContentsDestroy.fixtures.js +0 -105
  119. data/webpack/routes/OvalContents/OvalContentsIndex/__tests__/OvalContentsDestroy.test.js +0 -124
  120. data/webpack/routes/OvalContents/OvalContentsIndex/__tests__/OvalContentsIndex.fixtures.js +0 -127
  121. data/webpack/routes/OvalContents/OvalContentsIndex/__tests__/OvalContentsIndex.test.js +0 -89
  122. data/webpack/routes/OvalContents/OvalContentsIndex/index.js +0 -13
  123. data/webpack/routes/OvalContents/OvalContentsNew/OvalContentsNew.js +0 -138
  124. data/webpack/routes/OvalContents/OvalContentsNew/OvalContentsNew.scss +0 -3
  125. data/webpack/routes/OvalContents/OvalContentsNew/OvalContentsNewHelper.js +0 -73
  126. data/webpack/routes/OvalContents/OvalContentsNew/__tests__/OvalContentsNew.test.js +0 -104
  127. data/webpack/routes/OvalContents/OvalContentsNew/index.js +0 -13
  128. data/webpack/routes/OvalContents/OvalContentsShow/OvalContentsShow.js +0 -62
  129. data/webpack/routes/OvalContents/OvalContentsShow/OvalContentsShow.test.js +0 -45
  130. data/webpack/routes/OvalContents/OvalContentsShow/OvalContentsShowHelper.js +0 -0
  131. data/webpack/routes/OvalContents/OvalContentsShow/index.js +0 -35
  132. data/webpack/routes/OvalPolicies/OvalPoliciesIndex/OvalPoliciesIndex.js +0 -62
  133. data/webpack/routes/OvalPolicies/OvalPoliciesIndex/OvalPoliciesTable.js +0 -74
  134. data/webpack/routes/OvalPolicies/OvalPoliciesIndex/__tests__/OvalPoliciesDestroy.fixtures.js +0 -101
  135. data/webpack/routes/OvalPolicies/OvalPoliciesIndex/__tests__/OvalPoliciesDestroy.test.js +0 -117
  136. data/webpack/routes/OvalPolicies/OvalPoliciesIndex/__tests__/OvalPoliciesIndex.fixtures.js +0 -111
  137. data/webpack/routes/OvalPolicies/OvalPoliciesIndex/__tests__/OvalPoliciesIndex.test.js +0 -81
  138. data/webpack/routes/OvalPolicies/OvalPoliciesIndex/index.js +0 -13
  139. data/webpack/routes/OvalPolicies/OvalPoliciesNew/HostgroupSelect.js +0 -135
  140. data/webpack/routes/OvalPolicies/OvalPoliciesNew/NewOvalPolicyForm.js +0 -119
  141. data/webpack/routes/OvalPolicies/OvalPoliciesNew/NewOvalPolicyFormHelpers.js +0 -107
  142. data/webpack/routes/OvalPolicies/OvalPoliciesNew/OvalPoliciesNew.js +0 -32
  143. data/webpack/routes/OvalPolicies/OvalPoliciesNew/__tests__/OvalPoliciesNew.fixtures.js +0 -147
  144. data/webpack/routes/OvalPolicies/OvalPoliciesNew/__tests__/OvalPoliciesNew.test.js +0 -172
  145. data/webpack/routes/OvalPolicies/OvalPoliciesNew/index.js +0 -11
  146. data/webpack/routes/OvalPolicies/OvalPoliciesShow/CvesTab.js +0 -49
  147. data/webpack/routes/OvalPolicies/OvalPoliciesShow/CvesTable.js +0 -63
  148. data/webpack/routes/OvalPolicies/OvalPoliciesShow/DetailsTab.js +0 -87
  149. data/webpack/routes/OvalPolicies/OvalPoliciesShow/HostgroupsTab.js +0 -49
  150. data/webpack/routes/OvalPolicies/OvalPoliciesShow/HostgroupsTable.js +0 -38
  151. data/webpack/routes/OvalPolicies/OvalPoliciesShow/OvalPoliciesShow.js +0 -82
  152. data/webpack/routes/OvalPolicies/OvalPoliciesShow/OvalPoliciesShowHelper.js +0 -117
  153. data/webpack/routes/OvalPolicies/OvalPoliciesShow/__tests__/OvalPoliciesEdit.fixtures.js +0 -48
  154. data/webpack/routes/OvalPolicies/OvalPoliciesShow/__tests__/OvalPoliciesEdit.test.js +0 -202
  155. data/webpack/routes/OvalPolicies/OvalPoliciesShow/__tests__/OvalPoliciesShow.fixtures.js +0 -124
  156. data/webpack/routes/OvalPolicies/OvalPoliciesShow/__tests__/OvalPoliciesShow.test.js +0 -172
  157. data/webpack/routes/OvalPolicies/OvalPoliciesShow/index.js +0 -39
  158. data/webpack/routes/routes.js +0 -49
@@ -1,73 +0,0 @@
1
- import * as Yup from 'yup';
2
-
3
- import api from 'foremanReact/redux/API/API';
4
- import { prepareErrors } from 'foremanReact/redux/actions/common/forms';
5
- import { sprintf, translate as __ } from 'foremanReact/common/I18n';
6
- import {
7
- ovalContentsPath,
8
- ovalContentsApiPath,
9
- } from '../../../helpers/pathsHelper';
10
-
11
- export const submitForm = (params, actions) => {
12
- const headers = {
13
- 'Content-Type': 'multipart/form-data',
14
- };
15
- return api.post(ovalContentsApiPath, params, headers);
16
- };
17
-
18
- export const onSubmit = async (
19
- values,
20
- actions,
21
- showToast,
22
- history,
23
- fileFromUrl,
24
- file
25
- ) => {
26
- const formData = new FormData();
27
- if (fileFromUrl) {
28
- formData.append('oval_content[url]', values.url);
29
- } else {
30
- formData.append('oval_content[scap_file]', file);
31
- }
32
- formData.append('oval_content[name]', values.name);
33
- try {
34
- await submitForm(formData, actions);
35
- history.push(ovalContentsPath, { refreshOvalContents: true });
36
- showToast({
37
- type: 'success',
38
- message: sprintf(__('OVAL Content %s successfully created'), values.name),
39
- });
40
- } catch (error) {
41
- onError(error, actions, showToast);
42
- }
43
- };
44
-
45
- const onError = (error, actions, showToast) => {
46
- actions.setSubmitting(false);
47
- if (error.response?.status === 422) {
48
- actions.setErrors(prepareErrors(error?.response?.data?.error?.errors, {}));
49
- } else {
50
- showToast({
51
- type: 'error',
52
- message: __(
53
- 'Unknown error when submitting data, please try again later.'
54
- ),
55
- });
56
- }
57
- };
58
-
59
- export const validateFile = (file, touched) => {
60
- if (!touched) {
61
- return 'default';
62
- }
63
- return file ? 'success' : 'error';
64
- };
65
-
66
- export const submitDisabled = (formProps, file, fileFromUrl) =>
67
- formProps.isSubmitting || !formProps.isValid || (!fileFromUrl && !file);
68
-
69
- export const createValidationSchema = contentFromUrl =>
70
- Yup.object().shape({
71
- name: Yup.string().required("can't be blank"),
72
- ...(contentFromUrl && { url: Yup.string().required("can't be blank") }),
73
- });
@@ -1,104 +0,0 @@
1
- import React from 'react';
2
-
3
- import { render, screen, waitFor } from '@testing-library/react';
4
- import userEvent from '@testing-library/user-event';
5
- import '@testing-library/jest-dom';
6
- import api from 'foremanReact/redux/API/API';
7
-
8
- import OvalContentsNew from '../OvalContentsNew';
9
- import { withRouter, withRedux, tick } from '../../../../testHelper';
10
- import { ovalContentsPath } from '../../../../helpers/pathsHelper';
11
-
12
- jest.mock('foremanReact/redux/API/API', () => ({ post: jest.fn() }));
13
-
14
- const TestComponent = withRouter(withRedux(OvalContentsNew));
15
-
16
- describe('OvalContentsNew', () => {
17
- it('should create with content from URL', async () => {
18
- const pushMock = jest.fn();
19
- const toastMock = jest.fn();
20
-
21
- api.post.mockImplementation(() => Promise.resolve());
22
-
23
- render(
24
- <TestComponent history={{ push: pushMock }} showToast={toastMock} />
25
- );
26
- expect(screen.getByText('Name')).toBeInTheDocument();
27
- expect(screen.getByText('OVAL Content Source')).toBeInTheDocument();
28
- expect(screen.getByText('URL')).toBeInTheDocument();
29
- expect(screen.queryByText('File')).not.toBeInTheDocument();
30
- expect(screen.getByText('Submit')).toBeDisabled();
31
- userEvent.type(screen.getByLabelText('name'), 'test content');
32
- await waitFor(tick);
33
- expect(screen.getByText('Submit')).toBeDisabled();
34
- userEvent.type(
35
- screen.getByLabelText(/url/),
36
- 'http://oval-content-source.org/security/data/oval/v2/CentOS7/ansible-2.9.oval.xml.bz2'
37
- );
38
- await waitFor(tick);
39
- expect(screen.getByText('Submit')).not.toBeDisabled();
40
- userEvent.click(screen.getByText('Submit'));
41
- await waitFor(tick);
42
- expect(pushMock).toHaveBeenCalledWith(ovalContentsPath, {
43
- refreshOvalContents: true,
44
- });
45
- expect(toastMock).toHaveBeenCalledWith({
46
- type: 'success',
47
- message: 'OVAL Content test content successfully created',
48
- });
49
- });
50
- it('should show resource errors', async () => {
51
- const pushMock = jest.fn();
52
- const toastMock = jest.fn();
53
- api.post.mockImplementation(() => {
54
- // eslint-disable-next-line no-throw-literal
55
- throw {
56
- response: {
57
- status: 422,
58
- data: { error: { errors: { name: ['has already been taken'] } } },
59
- },
60
- };
61
- });
62
-
63
- render(
64
- <TestComponent history={{ push: pushMock }} showToast={toastMock} />
65
- );
66
- userEvent.type(screen.getByLabelText('name'), 'test content');
67
- userEvent.type(
68
- screen.getByLabelText(/url/),
69
- 'http://oval-content-source.org/security/data/oval/v2/CentOS7/ansible-2.9.oval.xml.bz2'
70
- );
71
- await waitFor(tick);
72
- userEvent.click(screen.getByText('Submit'));
73
- await waitFor(tick);
74
- expect(pushMock).not.toHaveBeenCalled();
75
- expect(screen.getByText('has already been taken')).toBeInTheDocument();
76
- });
77
- it('should show error toast on unexpected error', async () => {
78
- const pushMock = jest.fn();
79
- const toastMock = jest.fn();
80
-
81
- api.post.mockImplementation(() => {
82
- // eslint-disable-next-line no-throw-literal
83
- throw { response: { status: 500 } };
84
- });
85
-
86
- render(
87
- <TestComponent history={{ push: pushMock }} showToast={toastMock} />
88
- );
89
- userEvent.type(screen.getByLabelText('name'), 'test content');
90
- userEvent.type(
91
- screen.getByLabelText(/url/),
92
- 'http://oval-content-source.org/security/data/oval/v2/CentOS7/ansible-2.9.oval.xml.bz2'
93
- );
94
- await waitFor(tick);
95
- userEvent.click(screen.getByText('Submit'));
96
- await waitFor(tick);
97
- expect(pushMock).not.toHaveBeenCalled();
98
- expect(screen.getByText('Submit')).not.toBeDisabled();
99
- expect(toastMock).toHaveBeenCalledWith({
100
- type: 'error',
101
- message: 'Unknown error when submitting data, please try again later.',
102
- });
103
- });
104
- });
@@ -1,13 +0,0 @@
1
- import React from 'react';
2
- import { useDispatch } from 'react-redux';
3
- import { showToast } from '../../../helpers/toastHelper';
4
-
5
- import OvalContentsNew from './OvalContentsNew';
6
-
7
- const WrappedOvalContentsNew = props => {
8
- const dispatch = useDispatch();
9
-
10
- return <OvalContentsNew {...props} showToast={showToast(dispatch)} />;
11
- };
12
-
13
- export default WrappedOvalContentsNew;
@@ -1,62 +0,0 @@
1
- import React from 'react';
2
- import PropTypes from 'prop-types';
3
- import { Helmet } from 'react-helmet';
4
- import { translate as __ } from 'foremanReact/common/I18n';
5
-
6
- import {
7
- Grid,
8
- GridItem,
9
- TextContent,
10
- Text,
11
- TextVariants,
12
- } from '@patternfly/react-core';
13
-
14
- import withLoading from '../../../components/withLoading';
15
-
16
- const OvalContentsShow = ({ ovalContent }) => {
17
- let contentSource;
18
- if (ovalContent.url) {
19
- contentSource = (
20
- <React.Fragment>
21
- <Text component={TextVariants.h3}>{__('URL')}</Text>
22
- <Text component={TextVariants.p}>{ovalContent.url || ''}</Text>
23
- </React.Fragment>
24
- );
25
- } else {
26
- contentSource = (
27
- <React.Fragment>
28
- <Text component={TextVariants.h3}>{__('File')}</Text>
29
- <Text component={TextVariants.p}>
30
- {ovalContent.originalFilename || ''}
31
- </Text>
32
- </React.Fragment>
33
- );
34
- }
35
-
36
- return (
37
- <React.Fragment>
38
- <Helmet>
39
- <title>{`${ovalContent.name} | ${__('OVAL Content')}`}</title>
40
- </Helmet>
41
- <Grid className="scap-page-grid">
42
- <GridItem span={10}>
43
- <Text component={TextVariants.h1}>{ovalContent.name}</Text>
44
- </GridItem>
45
- <GridItem span={2} />
46
- <GridItem span={12}>
47
- <TextContent className="pf-u-pt-md">
48
- <Text component={TextVariants.h3}>{__('Name')}</Text>
49
- <Text component={TextVariants.p}>{ovalContent.name}</Text>
50
- {contentSource}
51
- </TextContent>
52
- </GridItem>
53
- </Grid>
54
- </React.Fragment>
55
- );
56
- };
57
-
58
- OvalContentsShow.propTypes = {
59
- ovalContent: PropTypes.object.isRequired,
60
- };
61
-
62
- export default withLoading(OvalContentsShow);
@@ -1,45 +0,0 @@
1
- import React from 'react';
2
- import '@testing-library/jest-dom';
3
- import { render, screen, waitFor } from '@testing-library/react';
4
-
5
- import { withMockedProvider, tick } from '../../../testHelper';
6
- import ovalContentQuery from '../../../graphql/queries/ovalContent.gql';
7
- import OvalContentsShow from './';
8
-
9
- const TestComponent = withMockedProvider(OvalContentsShow);
10
-
11
- const matchMock = { params: { id: 4 } };
12
- const name = 'dotnet OVAL content';
13
- const url =
14
- 'http://oval-content-source/security/data/oval/dotnet-2.2.oval.xml.bz2';
15
- const id = 'MDE6Rm9yZW1hbk9wZW5zY2FwOjpPdmFsQ29udGVudC00';
16
-
17
- const mocks = [
18
- {
19
- request: {
20
- query: ovalContentQuery,
21
- variables: { id },
22
- },
23
- result: {
24
- data: {
25
- ovalContent: {
26
- id,
27
- name,
28
- url,
29
- originalFilename: '',
30
- },
31
- },
32
- },
33
- },
34
- ];
35
-
36
- describe('OVAL Contents show page', () => {
37
- it('should show OVAL Content', async () => {
38
- render(<TestComponent match={matchMock} mocks={mocks} />);
39
- expect(screen.getByText('Loading')).toBeInTheDocument();
40
- await waitFor(tick);
41
- expect(screen.queryByText('Loading')).not.toBeInTheDocument();
42
- expect(screen.getAllByText(name).length === 2).toBeTruthy();
43
- expect(screen.getByText(url)).toBeInTheDocument();
44
- });
45
- });
@@ -1,35 +0,0 @@
1
- import React from 'react';
2
- import PropTypes from 'prop-types';
3
- import { useQuery } from '@apollo/client';
4
-
5
- import { translate as __ } from 'foremanReact/common/I18n';
6
-
7
- import OvalContentsShow from './OvalContentsShow';
8
- import { encodeId } from '../../../helpers/globalIdHelper';
9
-
10
- import ovalContent from '../../../graphql/queries/ovalContent.gql';
11
-
12
- const WrappedOvalContentsShow = props => {
13
- const id = encodeId('ForemanOpenscap::OvalContent', props.match.params.id);
14
-
15
- const useFetchFn = componentProps =>
16
- useQuery(ovalContent, { variables: { id } });
17
-
18
- const renameData = data => ({ ovalContent: data.ovalContent });
19
-
20
- return (
21
- <OvalContentsShow
22
- {...props}
23
- fetchFn={useFetchFn}
24
- renameData={renameData}
25
- resultPath="ovalContent"
26
- emptyStateTitle={__('No OVAL Content found')}
27
- />
28
- );
29
- };
30
-
31
- WrappedOvalContentsShow.propTypes = {
32
- match: PropTypes.object.isRequired,
33
- };
34
-
35
- export default WrappedOvalContentsShow;
@@ -1,62 +0,0 @@
1
- import React from 'react';
2
- import PropTypes from 'prop-types';
3
- import { useQuery } from '@apollo/client';
4
- import { translate as __ } from 'foremanReact/common/I18n';
5
-
6
- import OvalPoliciesTable from './OvalPoliciesTable';
7
- import { submitDelete, prepareMutation } from '../../../helpers/mutationHelper';
8
-
9
- import IndexLayout from '../../../components/IndexLayout';
10
-
11
- import {
12
- useParamsToVars,
13
- useCurrentPagination,
14
- } from '../../../helpers/pageParamsHelper';
15
- import policiesQuery from '../../../graphql/queries/ovalPolicies.gql';
16
- import deleteOvalPolicyMutation from '../../../graphql/mutations/deleteOvalPolicy.gql';
17
-
18
- const OvalPoliciesIndex = props => {
19
- const useFetchFn = componentProps =>
20
- useQuery(policiesQuery, {
21
- variables: useParamsToVars(componentProps.history),
22
- });
23
-
24
- const renameData = data => ({
25
- policies: data.ovalPolicies.nodes,
26
- totalCount: data.ovalPolicies.totalCount,
27
- });
28
-
29
- const pagination = useCurrentPagination(props.history);
30
-
31
- return (
32
- <IndexLayout pageTitle={__('OVAL Policies')}>
33
- <OvalPoliciesTable
34
- {...props}
35
- fetchFn={useFetchFn}
36
- renameData={renameData}
37
- resultPath="ovalPolicies.nodes"
38
- pagination={pagination}
39
- emptyStateTitle={__('No OVAL Policies found')}
40
- permissions={['view_oval_policies']}
41
- confirmDeleteTitle={__('Delete OVAL Policy')}
42
- submitDelete={submitDelete}
43
- prepareMutation={prepareMutation(
44
- props.history,
45
- props.showToast,
46
- policiesQuery,
47
- 'deleteOvalPolicy',
48
- __('OVAL policy was successfully deleted.'),
49
- deleteOvalPolicyMutation,
50
- __('OVAL policy')
51
- )}
52
- />
53
- </IndexLayout>
54
- );
55
- };
56
-
57
- OvalPoliciesIndex.propTypes = {
58
- history: PropTypes.object.isRequired,
59
- showToast: PropTypes.func.isRequired,
60
- };
61
-
62
- export default OvalPoliciesIndex;
@@ -1,74 +0,0 @@
1
- import React from 'react';
2
- import PropTypes from 'prop-types';
3
- import { Button } from '@patternfly/react-core';
4
-
5
- import { translate as __ } from 'foremanReact/common/I18n';
6
-
7
- import IndexTable from '../../../components/IndexTable';
8
- import withLoading from '../../../components/withLoading';
9
- import withDeleteModal from '../../../components/withDeleteModal';
10
-
11
- import { linkCell } from '../../../helpers/tableHelper';
12
- import {
13
- ovalPoliciesPath,
14
- modelPath,
15
- ovalPoliciesNewPath,
16
- } from '../../../helpers/pathsHelper';
17
-
18
- const OvalPoliciesTable = props => {
19
- const columns = [{ title: __('Name') }, { title: __('OVAL Content') }];
20
-
21
- const rows = props.policies.map(policy => ({
22
- cells: [
23
- { title: linkCell(modelPath(ovalPoliciesPath, policy), policy.name) },
24
- { title: policy.ovalContent.name },
25
- ],
26
- policy,
27
- }));
28
-
29
- const actionResolver = (rowData, rest) => {
30
- const actions = [];
31
- if (rowData.policy.meta.canDestroy) {
32
- actions.push({
33
- title: __('Delete OVAL Policy'),
34
- onClick: (event, rowId, rData, extra) => {
35
- props.toggleModal(rData.policy);
36
- },
37
- });
38
- }
39
- return actions;
40
- };
41
-
42
- const createBtn = (
43
- <Button
44
- onClick={() => props.history.push(ovalPoliciesNewPath)}
45
- variant="primary"
46
- aria-label="create_oval_policy"
47
- >
48
- {__('Create OVAL Policy')}
49
- </Button>
50
- );
51
-
52
- return (
53
- <IndexTable
54
- columns={columns}
55
- rows={rows}
56
- actionResolver={actionResolver}
57
- pagination={props.pagination}
58
- totalCount={props.totalCount}
59
- history={props.history}
60
- ariaTableLabel={__('OVAL Policies Table')}
61
- toolbarBtns={createBtn}
62
- />
63
- );
64
- };
65
-
66
- OvalPoliciesTable.propTypes = {
67
- policies: PropTypes.array.isRequired,
68
- pagination: PropTypes.object.isRequired,
69
- totalCount: PropTypes.number.isRequired,
70
- history: PropTypes.object.isRequired,
71
- toggleModal: PropTypes.func.isRequired,
72
- };
73
-
74
- export default withLoading(withDeleteModal(OvalPoliciesTable));
@@ -1,101 +0,0 @@
1
- import policiesQuery from '../../../../graphql/queries/ovalPolicies.gql';
2
- import deleteOvalPolicy from '../../../../graphql/mutations/deleteOvalPolicy.gql';
3
-
4
- import { admin } from '../../../../testHelper';
5
-
6
- export const firstCall = {
7
- data: {
8
- ovalPolicies: {
9
- totalCount: 5,
10
- nodes: [
11
- {
12
- __typename: 'ForemanOpenscap::OvalPolicy',
13
- id: 'MDE6Rm9yZW1hbk9wZW5zY2FwOjpPdmFsUG9saWN5LTQz',
14
- name: 'first policy',
15
- meta: { canDestroy: true },
16
- ovalContent: { name: 'foo' },
17
- },
18
- {
19
- __typename: 'ForemanOpenscap::OvalPolicy',
20
- id: 'MDE6Rm9yZW1hbk9wZW5zY2FwOjpPdmFsUG9saWN5LTQ0',
21
- name: 'second policy',
22
- meta: { canDestroy: true },
23
- ovalContent: { name: 'foo' },
24
- },
25
- ],
26
- },
27
- currentUser: admin,
28
- },
29
- };
30
-
31
- export const secondCall = {
32
- data: {
33
- ovalPolicies: {
34
- totalCount: 4,
35
- nodes: [
36
- {
37
- id: 'MDE6Rm9yZW1hbk9wZW5zY2FwOjpPdmFsUG9saWN5LTQ0',
38
- name: 'second policy',
39
- meta: { canDestroy: true },
40
- ovalContent: { name: 'foo' },
41
- },
42
- {
43
- id: 'MDE6Rm9yZW1hbk9wZW5zY2FwOjpPdmFsUG9saWN5LTQ1',
44
- name: 'third policy',
45
- meta: { canDestroy: true },
46
- ovalContent: { name: 'foo' },
47
- },
48
- ],
49
- },
50
- currentUser: admin,
51
- },
52
- };
53
-
54
- export const deleteMockFactory = (first, second, errors = null) => {
55
- let called = false;
56
-
57
- const deleteMocks = [
58
- {
59
- request: {
60
- query: deleteOvalPolicy,
61
- variables: {
62
- id: 'MDE6Rm9yZW1hbk9wZW5zY2FwOjpPdmFsUG9saWN5LTQz',
63
- },
64
- },
65
- result: {
66
- data: {
67
- deleteOvalPolicy: {
68
- __typename: 'ForemanOpenscap::OvalPolicy',
69
- id: 'MDE6Rm9yZW1hbk9wZW5zY2FwOjpPdmFsUG9saWN5LTQz',
70
- errors,
71
- },
72
- },
73
- },
74
- },
75
- {
76
- request: {
77
- query: policiesQuery,
78
- variables: {
79
- first: 2,
80
- last: 2,
81
- },
82
- },
83
- newData: () => {
84
- if (called && !errors) {
85
- return second;
86
- } else if (called && errors) {
87
- return first;
88
- }
89
- called = true;
90
- return first;
91
- },
92
- },
93
- ];
94
- return deleteMocks;
95
- };
96
-
97
- export const pageParamsHistoryMock = {
98
- location: {
99
- search: '?page=1&perPage=2',
100
- },
101
- };
@@ -1,117 +0,0 @@
1
- import React from 'react';
2
- import { render, screen, waitFor } from '@testing-library/react';
3
- import '@testing-library/jest-dom';
4
- import userEvent from '@testing-library/user-event';
5
-
6
- import OvalPoliciesIndex from '../OvalPoliciesIndex';
7
- import {
8
- withRouter,
9
- withRedux,
10
- withMockedProvider,
11
- tick,
12
- historyMock,
13
- } from '../../../../testHelper';
14
- import { mocks, noDeleteMocks } from './OvalPoliciesIndex.fixtures';
15
- import {
16
- firstCall,
17
- secondCall,
18
- deleteMockFactory,
19
- pageParamsHistoryMock,
20
- } from './OvalPoliciesDestroy.fixtures';
21
-
22
- const TestComponent = withRouter(
23
- withRedux(withMockedProvider(OvalPoliciesIndex))
24
- );
25
-
26
- describe('OvalPoliciesIndex', () => {
27
- it('should open and close delete modal', async () => {
28
- render(
29
- <TestComponent
30
- history={historyMock}
31
- mocks={mocks}
32
- showToast={jest.fn()}
33
- />
34
- );
35
- await waitFor(tick);
36
- expect(screen.getByText('first policy')).toBeInTheDocument();
37
- userEvent.click(screen.getAllByRole('button', { name: 'Actions' })[0]);
38
- userEvent.click(screen.getByText('Delete OVAL Policy'));
39
- await waitFor(tick);
40
- expect(
41
- screen.getByText('Are you sure you want to delete first policy?')
42
- ).toBeInTheDocument();
43
- userEvent.click(screen.getByText('Cancel'));
44
- await waitFor(tick);
45
- expect(
46
- screen.queryByText('Are you sure you want to delete first policy?')
47
- ).not.toBeInTheDocument();
48
- expect(screen.getByText('first policy')).toBeInTheDocument();
49
- });
50
- it('should delete OVAL policy', async () => {
51
- const showToast = jest.fn();
52
- render(
53
- <TestComponent
54
- history={pageParamsHistoryMock}
55
- mocks={deleteMockFactory(firstCall, secondCall)}
56
- showToast={showToast}
57
- />
58
- );
59
- await waitFor(tick);
60
- expect(screen.getByText('first policy')).toBeInTheDocument();
61
- expect(screen.queryByText('third policy')).not.toBeInTheDocument();
62
- userEvent.click(screen.getAllByRole('button', { name: 'Actions' })[0]);
63
- userEvent.click(screen.getByText('Delete OVAL Policy'));
64
- await waitFor(tick);
65
- userEvent.click(screen.getByText('Confirm'));
66
- await waitFor(tick);
67
- expect(showToast).toHaveBeenCalledWith({
68
- type: 'success',
69
- message: 'OVAL policy was successfully deleted.',
70
- });
71
- await waitFor(tick);
72
- expect(screen.queryByText('first policy')).not.toBeInTheDocument();
73
- expect(screen.getByText('third policy')).toBeInTheDocument();
74
- });
75
- it('should show error when deleting OVAL policy fails', async () => {
76
- const showToast = jest.fn();
77
- render(
78
- <TestComponent
79
- history={pageParamsHistoryMock}
80
- mocks={deleteMockFactory(firstCall, secondCall, [
81
- { message: 'cannot do it', path: 'base' },
82
- { message: 'will not do it', path: 'base' },
83
- ])}
84
- showToast={showToast}
85
- />
86
- );
87
- await waitFor(tick);
88
- expect(screen.getByText('first policy')).toBeInTheDocument();
89
- expect(screen.queryByText('third policy')).not.toBeInTheDocument();
90
- userEvent.click(screen.getAllByRole('button', { name: 'Actions' })[0]);
91
- userEvent.click(screen.getByText('Delete OVAL Policy'));
92
- await waitFor(tick);
93
- userEvent.click(screen.getByText('Confirm'));
94
- await waitFor(tick);
95
- expect(showToast).toHaveBeenCalledWith({
96
- type: 'error',
97
- message:
98
- 'There was a following error when deleting OVAL policy: cannot do it, will not do it',
99
- });
100
- expect(screen.getByText('first policy')).toBeInTheDocument();
101
- expect(screen.queryByText('third policy')).not.toBeInTheDocument();
102
- });
103
- it('should not show delete button when user does not have delete permissions', async () => {
104
- render(
105
- <TestComponent
106
- history={historyMock}
107
- mocks={noDeleteMocks}
108
- showToast={jest.fn()}
109
- />
110
- );
111
- await waitFor(tick);
112
- expect(screen.getByText('first policy')).toBeInTheDocument();
113
- expect(
114
- screen.queryByRole('button', { name: 'Actions' })
115
- ).not.toBeInTheDocument();
116
- });
117
- });