foreman_openscap 8.0.2 → 9.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (159) 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/db/migrate/20240617105409_remove_oval_permissions.rb +24 -0
  8. data/lib/foreman_openscap/engine.rb +2 -56
  9. data/lib/foreman_openscap/version.rb +1 -1
  10. data/test/factories/compliance_host_factory.rb +0 -12
  11. data/test/test_plugin_helper.rb +0 -2
  12. data/webpack/global_index.js +0 -4
  13. metadata +8 -168
  14. data/app/controllers/api/v2/compliance/oval_contents_controller.rb +0 -72
  15. data/app/controllers/api/v2/compliance/oval_policies_controller.rb +0 -111
  16. data/app/controllers/api/v2/compliance/oval_reports_controller.rb +0 -47
  17. data/app/controllers/concerns/foreman/controller/parameters/oval_content.rb +0 -22
  18. data/app/controllers/concerns/foreman/controller/parameters/oval_policy.rb +0 -22
  19. data/app/graphql/mutations/oval_contents/delete.rb +0 -9
  20. data/app/graphql/mutations/oval_policies/create.rb +0 -33
  21. data/app/graphql/mutations/oval_policies/delete.rb +0 -9
  22. data/app/graphql/mutations/oval_policies/update.rb +0 -15
  23. data/app/graphql/types/cve.rb +0 -17
  24. data/app/graphql/types/oval_check.rb +0 -11
  25. data/app/graphql/types/oval_content.rb +0 -19
  26. data/app/graphql/types/oval_policy.rb +0 -24
  27. data/app/models/concerns/foreman_openscap/oval_facet_host_extensions.rb +0 -38
  28. data/app/models/concerns/foreman_openscap/oval_facet_hostgroup_extensions.rb +0 -31
  29. data/app/models/foreman_openscap/cve.rb +0 -23
  30. data/app/models/foreman_openscap/host/oval_facet.rb +0 -14
  31. data/app/models/foreman_openscap/host_cve.rb +0 -7
  32. data/app/models/foreman_openscap/hostgroup/oval_facet.rb +0 -14
  33. data/app/models/foreman_openscap/hostgroup_oval_facet_oval_policy.rb +0 -6
  34. data/app/models/foreman_openscap/oval_content.rb +0 -28
  35. data/app/models/foreman_openscap/oval_facet_oval_policy.rb +0 -6
  36. data/app/models/foreman_openscap/oval_policy.rb +0 -54
  37. data/app/models/foreman_openscap/oval_status.rb +0 -45
  38. data/app/services/foreman_openscap/oval/check_collection.rb +0 -45
  39. data/app/services/foreman_openscap/oval/configure.rb +0 -83
  40. data/app/services/foreman_openscap/oval/cves.rb +0 -41
  41. data/app/services/foreman_openscap/oval/setup.rb +0 -93
  42. data/app/services/foreman_openscap/oval/setup_check.rb +0 -58
  43. data/app/services/foreman_openscap/oval/sync_oval_contents.rb +0 -42
  44. data/app/views/api/v2/compliance/oval_contents/base.json.rabl +0 -6
  45. data/app/views/api/v2/compliance/oval_contents/create.json.rabl +0 -3
  46. data/app/views/api/v2/compliance/oval_contents/destroy.json.rabl +0 -3
  47. data/app/views/api/v2/compliance/oval_contents/index.json.rabl +0 -3
  48. data/app/views/api/v2/compliance/oval_contents/show.json.rabl +0 -3
  49. data/app/views/api/v2/compliance/oval_contents/sync.json.rabl +0 -3
  50. data/app/views/api/v2/compliance/oval_contents/sync_result.json.rabl +0 -11
  51. data/app/views/api/v2/compliance/oval_contents/update.json.rabl +0 -3
  52. data/app/views/api/v2/compliance/oval_policies/create.json.rabl +0 -3
  53. data/app/views/api/v2/compliance/oval_policies/index.json.rabl +0 -3
  54. data/app/views/api/v2/compliance/oval_policies/main.json.rabl +0 -15
  55. data/app/views/api/v2/compliance/oval_policies/show.json.rabl +0 -3
  56. data/app/views/job_templates/run_oval_scans.erb +0 -24
  57. data/locale/cs_CZ/foreman_openscap.edit.po +0 -1863
  58. data/locale/cs_CZ/foreman_openscap.po.time_stamp +0 -0
  59. data/locale/de/foreman_openscap.edit.po +0 -1873
  60. data/locale/de/foreman_openscap.po.time_stamp +0 -0
  61. data/locale/en/foreman_openscap.edit.po +0 -1863
  62. data/locale/en/foreman_openscap.po.time_stamp +0 -0
  63. data/locale/en_GB/foreman_openscap.edit.po +0 -1863
  64. data/locale/en_GB/foreman_openscap.po.time_stamp +0 -0
  65. data/locale/es/foreman_openscap.edit.po +0 -1868
  66. data/locale/es/foreman_openscap.po.time_stamp +0 -0
  67. data/locale/fr/foreman_openscap.edit.po +0 -1874
  68. data/locale/fr/foreman_openscap.po.time_stamp +0 -0
  69. data/locale/gl/foreman_openscap.edit.po +0 -1863
  70. data/locale/gl/foreman_openscap.po.time_stamp +0 -0
  71. data/locale/it/foreman_openscap.edit.po +0 -1865
  72. data/locale/it/foreman_openscap.po.time_stamp +0 -0
  73. data/locale/ja/foreman_openscap.edit.po +0 -1869
  74. data/locale/ja/foreman_openscap.po.time_stamp +0 -0
  75. data/locale/ka/foreman_openscap.edit.po +0 -1863
  76. data/locale/ka/foreman_openscap.po.time_stamp +0 -0
  77. data/locale/ko/foreman_openscap.edit.po +0 -1863
  78. data/locale/ko/foreman_openscap.po.time_stamp +0 -0
  79. data/locale/pt_BR/foreman_openscap.edit.po +0 -1873
  80. data/locale/pt_BR/foreman_openscap.po.time_stamp +0 -0
  81. data/locale/ru/foreman_openscap.edit.po +0 -1867
  82. data/locale/ru/foreman_openscap.po.time_stamp +0 -0
  83. data/locale/sv_SE/foreman_openscap.edit.po +0 -1863
  84. data/locale/sv_SE/foreman_openscap.po.time_stamp +0 -0
  85. data/locale/zh_CN/foreman_openscap.edit.po +0 -1868
  86. data/locale/zh_CN/foreman_openscap.po.time_stamp +0 -0
  87. data/locale/zh_TW/foreman_openscap.edit.po +0 -1864
  88. data/locale/zh_TW/foreman_openscap.po.time_stamp +0 -0
  89. data/test/factories/oval_content_factory.rb +0 -7
  90. data/test/factories/oval_policy_factory.rb +0 -9
  91. data/test/fixtures/cve_fixtures.rb +0 -104
  92. data/test/functional/api/v2/compliance/oval_contents_controller_test.rb +0 -39
  93. data/test/functional/api/v2/compliance/oval_policies_controller_test.rb +0 -141
  94. data/test/functional/api/v2/compliance/oval_reports_controller_test.rb +0 -32
  95. data/test/graphql/mutations/oval_policies/delete_mutation_test.rb +0 -63
  96. data/test/graphql/queries/oval_content_query_test.rb +0 -29
  97. data/test/graphql/queries/oval_contents_query_test.rb +0 -35
  98. data/test/graphql/queries/oval_policies_query_test.rb +0 -35
  99. data/test/unit/oval_host_test.rb +0 -45
  100. data/test/unit/oval_policy_test.rb +0 -133
  101. data/test/unit/oval_status_test.rb +0 -47
  102. data/test/unit/services/oval/cves_test.rb +0 -81
  103. data/test/unit/services/oval/setup_check_test.rb +0 -37
  104. data/test/unit/services/oval/setup_test.rb +0 -87
  105. data/webpack/graphql/mutations/createOvalPolicy.gql +0 -22
  106. data/webpack/graphql/mutations/deleteOvalContent.gql +0 -9
  107. data/webpack/graphql/mutations/deleteOvalPolicy.gql +0 -9
  108. data/webpack/graphql/mutations/updateOvalPolicy.gql +0 -14
  109. data/webpack/graphql/queries/currentUserAttributes.gql +0 -11
  110. data/webpack/graphql/queries/cves.gql +0 -23
  111. data/webpack/graphql/queries/hostgroups.gql +0 -14
  112. data/webpack/graphql/queries/ovalContent.gql +0 -8
  113. data/webpack/graphql/queries/ovalContents.gql +0 -19
  114. data/webpack/graphql/queries/ovalPolicies.gql +0 -20
  115. data/webpack/graphql/queries/ovalPolicy.gql +0 -29
  116. data/webpack/helpers/pathsHelper.js +0 -29
  117. data/webpack/routes/OvalContents/OvalContentsIndex/OvalContentsIndex.js +0 -71
  118. data/webpack/routes/OvalContents/OvalContentsIndex/OvalContentsTable.js +0 -83
  119. data/webpack/routes/OvalContents/OvalContentsIndex/__tests__/OvalContentsDestroy.fixtures.js +0 -105
  120. data/webpack/routes/OvalContents/OvalContentsIndex/__tests__/OvalContentsDestroy.test.js +0 -124
  121. data/webpack/routes/OvalContents/OvalContentsIndex/__tests__/OvalContentsIndex.fixtures.js +0 -127
  122. data/webpack/routes/OvalContents/OvalContentsIndex/__tests__/OvalContentsIndex.test.js +0 -89
  123. data/webpack/routes/OvalContents/OvalContentsIndex/index.js +0 -13
  124. data/webpack/routes/OvalContents/OvalContentsNew/OvalContentsNew.js +0 -138
  125. data/webpack/routes/OvalContents/OvalContentsNew/OvalContentsNew.scss +0 -3
  126. data/webpack/routes/OvalContents/OvalContentsNew/OvalContentsNewHelper.js +0 -73
  127. data/webpack/routes/OvalContents/OvalContentsNew/__tests__/OvalContentsNew.test.js +0 -104
  128. data/webpack/routes/OvalContents/OvalContentsNew/index.js +0 -13
  129. data/webpack/routes/OvalContents/OvalContentsShow/OvalContentsShow.js +0 -62
  130. data/webpack/routes/OvalContents/OvalContentsShow/OvalContentsShow.test.js +0 -45
  131. data/webpack/routes/OvalContents/OvalContentsShow/OvalContentsShowHelper.js +0 -0
  132. data/webpack/routes/OvalContents/OvalContentsShow/index.js +0 -35
  133. data/webpack/routes/OvalPolicies/OvalPoliciesIndex/OvalPoliciesIndex.js +0 -62
  134. data/webpack/routes/OvalPolicies/OvalPoliciesIndex/OvalPoliciesTable.js +0 -74
  135. data/webpack/routes/OvalPolicies/OvalPoliciesIndex/__tests__/OvalPoliciesDestroy.fixtures.js +0 -101
  136. data/webpack/routes/OvalPolicies/OvalPoliciesIndex/__tests__/OvalPoliciesDestroy.test.js +0 -117
  137. data/webpack/routes/OvalPolicies/OvalPoliciesIndex/__tests__/OvalPoliciesIndex.fixtures.js +0 -111
  138. data/webpack/routes/OvalPolicies/OvalPoliciesIndex/__tests__/OvalPoliciesIndex.test.js +0 -81
  139. data/webpack/routes/OvalPolicies/OvalPoliciesIndex/index.js +0 -13
  140. data/webpack/routes/OvalPolicies/OvalPoliciesNew/HostgroupSelect.js +0 -135
  141. data/webpack/routes/OvalPolicies/OvalPoliciesNew/NewOvalPolicyForm.js +0 -119
  142. data/webpack/routes/OvalPolicies/OvalPoliciesNew/NewOvalPolicyFormHelpers.js +0 -107
  143. data/webpack/routes/OvalPolicies/OvalPoliciesNew/OvalPoliciesNew.js +0 -32
  144. data/webpack/routes/OvalPolicies/OvalPoliciesNew/__tests__/OvalPoliciesNew.fixtures.js +0 -147
  145. data/webpack/routes/OvalPolicies/OvalPoliciesNew/__tests__/OvalPoliciesNew.test.js +0 -172
  146. data/webpack/routes/OvalPolicies/OvalPoliciesNew/index.js +0 -11
  147. data/webpack/routes/OvalPolicies/OvalPoliciesShow/CvesTab.js +0 -49
  148. data/webpack/routes/OvalPolicies/OvalPoliciesShow/CvesTable.js +0 -63
  149. data/webpack/routes/OvalPolicies/OvalPoliciesShow/DetailsTab.js +0 -87
  150. data/webpack/routes/OvalPolicies/OvalPoliciesShow/HostgroupsTab.js +0 -49
  151. data/webpack/routes/OvalPolicies/OvalPoliciesShow/HostgroupsTable.js +0 -38
  152. data/webpack/routes/OvalPolicies/OvalPoliciesShow/OvalPoliciesShow.js +0 -82
  153. data/webpack/routes/OvalPolicies/OvalPoliciesShow/OvalPoliciesShowHelper.js +0 -117
  154. data/webpack/routes/OvalPolicies/OvalPoliciesShow/__tests__/OvalPoliciesEdit.fixtures.js +0 -48
  155. data/webpack/routes/OvalPolicies/OvalPoliciesShow/__tests__/OvalPoliciesEdit.test.js +0 -202
  156. data/webpack/routes/OvalPolicies/OvalPoliciesShow/__tests__/OvalPoliciesShow.fixtures.js +0 -124
  157. data/webpack/routes/OvalPolicies/OvalPoliciesShow/__tests__/OvalPoliciesShow.test.js +0 -172
  158. data/webpack/routes/OvalPolicies/OvalPoliciesShow/index.js +0 -39
  159. data/webpack/routes/routes.js +0 -49
@@ -1,83 +0,0 @@
1
- import React from 'react';
2
- import PropTypes from 'prop-types';
3
- import { translate as __ } from 'foremanReact/common/I18n';
4
- import { Button } from '@patternfly/react-core';
5
-
6
- import withLoading from '../../../components/withLoading';
7
- import withDeleteModal from '../../../components/withDeleteModal';
8
- import IndexTable from '../../../components/IndexTable';
9
- import {
10
- ovalContentsNewPath,
11
- ovalContentsPath,
12
- modelPath,
13
- } from '../../../helpers/pathsHelper';
14
-
15
- import { linkCell } from '../../../helpers/tableHelper';
16
-
17
- const OvalContentsTable = props => {
18
- const columns = [
19
- { title: __('Name') },
20
- { title: __('URL') },
21
- { title: __('Original File Name') },
22
- ];
23
-
24
- const rows = props.ovalContents.map(ovalContent => ({
25
- cells: [
26
- {
27
- title: linkCell(
28
- modelPath(ovalContentsPath, ovalContent),
29
- ovalContent.name
30
- ),
31
- },
32
- { title: ovalContent.url || '' },
33
- { title: ovalContent.originalFilename || '' },
34
- ],
35
- ovalContent,
36
- }));
37
-
38
- const actionResolver = (rowData, rest) => {
39
- const actions = [];
40
- if (rowData.ovalContent.meta.canDestroy) {
41
- actions.push({
42
- title: __('Delete OVAL Content'),
43
- onClick: (event, rowId, rData, extra) => {
44
- props.toggleModal(rData.ovalContent);
45
- },
46
- });
47
- }
48
- return actions;
49
- };
50
-
51
- const createBtn = (
52
- <Button
53
- onClick={() => props.history.push(ovalContentsNewPath)}
54
- variant="primary"
55
- aria-label="create_oval_content"
56
- >
57
- {__('Create OVAL Content')}
58
- </Button>
59
- );
60
-
61
- return (
62
- <IndexTable
63
- columns={columns}
64
- rows={rows}
65
- actionResolver={actionResolver}
66
- pagination={props.pagination}
67
- totalCount={props.totalCount}
68
- history={props.history}
69
- ariaTableLabel={__('OVAL Contents table')}
70
- toolbarBtns={createBtn}
71
- />
72
- );
73
- };
74
-
75
- OvalContentsTable.propTypes = {
76
- ovalContents: PropTypes.array.isRequired,
77
- pagination: PropTypes.object.isRequired,
78
- totalCount: PropTypes.number.isRequired,
79
- history: PropTypes.object.isRequired,
80
- toggleModal: PropTypes.func.isRequired,
81
- };
82
-
83
- export default withLoading(withDeleteModal(OvalContentsTable));
@@ -1,105 +0,0 @@
1
- import { admin } from '../../../../testHelper';
2
-
3
- import ovalContentsQuery from '../../../../graphql/queries/ovalContents.gql';
4
- import deleteOvalContent from '../../../../graphql/mutations/deleteOvalContent.gql';
5
-
6
- export const firstCall = {
7
- data: {
8
- ovalContents: {
9
- totalCount: 5,
10
- nodes: [
11
- {
12
- id: 'MDE6Rm9yZW1hbk9wZW5zY2FwOjpPdmFsQ29udGVudC0z',
13
- name: 'ansible OVAL content',
14
- url:
15
- 'http://oval-content-source/security/data/oval/ansible-2-including-unpatched.oval.xml.bz2',
16
- originalFilename: '',
17
- meta: { canDestroy: true },
18
- },
19
- {
20
- id: 'MDE6Rm9yZW1hbk9wZW5zY2FwOjpPdmFsQ29udGVudC00',
21
- name: 'dotnet OVAL content',
22
- url:
23
- 'http://oval-content-source/security/data/oval/dotnet-2.2.oval.xml.bz2',
24
- originalFilename: '',
25
- meta: { canDestroy: true },
26
- },
27
- ],
28
- },
29
- currentUser: admin,
30
- },
31
- };
32
-
33
- export const secondCall = {
34
- data: {
35
- ovalContents: {
36
- totalCount: 4,
37
- nodes: [
38
- {
39
- id: 'MDE6Rm9yZW1hbk9wZW5zY2FwOjpPdmFsQ29udGVudC00',
40
- name: 'dotnet OVAL content',
41
- url:
42
- 'http://oval-content-source/security/data/oval/dotnet-2.2.oval.xml.bz2',
43
- originalFilename: '',
44
- meta: { canDestroy: true },
45
- },
46
- {
47
- id: 'MDE6Rm9yZW1hbk9wZW5zY2FwOjpPdmFsQ29udGVudC03',
48
- name: 'jboss OVAL content',
49
- url: '',
50
- originalFilename: 'jboss.oval.xml.bz2',
51
- meta: { canDestroy: true },
52
- },
53
- ],
54
- },
55
- currentUser: admin,
56
- },
57
- };
58
-
59
- export const deleteMockFactory = (first, second, errors = null) => {
60
- let called = false;
61
-
62
- const deleteMocks = [
63
- {
64
- request: {
65
- query: deleteOvalContent,
66
- variables: {
67
- id: 'MDE6Rm9yZW1hbk9wZW5zY2FwOjpPdmFsQ29udGVudC0z',
68
- },
69
- },
70
- result: {
71
- data: {
72
- deleteOvalContent: {
73
- id: 'MDE6Rm9yZW1hbk9wZW5zY2FwOjpPdmFsQ29udGVudC0z',
74
- errors,
75
- },
76
- },
77
- },
78
- },
79
- {
80
- request: {
81
- query: ovalContentsQuery,
82
- variables: {
83
- first: 2,
84
- last: 2,
85
- },
86
- },
87
- newData: () => {
88
- if (called && !errors) {
89
- return second;
90
- } else if (called && errors) {
91
- return first;
92
- }
93
- called = true;
94
- return first;
95
- },
96
- },
97
- ];
98
- return deleteMocks;
99
- };
100
-
101
- export const pageParamsHistoryMock = {
102
- location: {
103
- search: '?page=1&perPage=2',
104
- },
105
- };
@@ -1,124 +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 OvalContentsIndex from '../OvalContentsIndex';
7
- import {
8
- withRouter,
9
- withRedux,
10
- withMockedProvider,
11
- tick,
12
- historyMock,
13
- } from '../../../../testHelper';
14
- import { mocks, noDeleteMocks } from './OvalContentsIndex.fixtures';
15
- import {
16
- firstCall,
17
- secondCall,
18
- deleteMockFactory,
19
- pageParamsHistoryMock,
20
- } from './OvalContentsDestroy.fixtures';
21
-
22
- const TestComponent = withRouter(
23
- withRedux(withMockedProvider(OvalContentsIndex))
24
- );
25
-
26
- describe('OvalContentsIndex', () => {
27
- it('should open and close delete modal', async () => {
28
- render(
29
- <TestComponent
30
- history={historyMock}
31
- location={{}}
32
- mocks={mocks}
33
- showToast={jest.fn()}
34
- />
35
- );
36
- await waitFor(tick);
37
- expect(screen.getByText('ansible OVAL content')).toBeInTheDocument();
38
- userEvent.click(screen.getAllByRole('button', { name: 'Actions' })[0]);
39
- userEvent.click(screen.getByText('Delete OVAL Content'));
40
- await waitFor(tick);
41
- expect(
42
- screen.getByText('Are you sure you want to delete ansible OVAL content?')
43
- ).toBeInTheDocument();
44
- userEvent.click(screen.getByText('Cancel'));
45
- await waitFor(tick);
46
- expect(
47
- screen.queryByText(
48
- 'Are you sure you want to delete ansible OVAL content?'
49
- )
50
- ).not.toBeInTheDocument();
51
- expect(screen.getByText('ansible OVAL content')).toBeInTheDocument();
52
- });
53
- it('should delete OVAL content', async () => {
54
- const mocked = deleteMockFactory(firstCall, secondCall);
55
- const showToast = jest.fn();
56
- render(
57
- <TestComponent
58
- history={pageParamsHistoryMock}
59
- location={{}}
60
- mocks={mocked}
61
- showToast={showToast}
62
- />
63
- );
64
- await waitFor(tick);
65
- expect(screen.getByText('ansible OVAL content')).toBeInTheDocument();
66
- expect(screen.queryByText('jboss OVAL content')).not.toBeInTheDocument();
67
- userEvent.click(screen.getAllByRole('button', { name: 'Actions' })[0]);
68
- userEvent.click(screen.getByText('Delete OVAL Content'));
69
- await waitFor(tick);
70
- userEvent.click(screen.getByText('Confirm'));
71
- await waitFor(tick);
72
- expect(showToast).toHaveBeenCalledWith({
73
- type: 'success',
74
- message: 'OVAL Content successfully deleted.',
75
- });
76
- await waitFor(tick);
77
- expect(screen.queryByText('ansible OVAL content')).not.toBeInTheDocument();
78
- expect(screen.getByText('jboss OVAL content')).toBeInTheDocument();
79
- });
80
- it('should show error when deleting OVAL content fails', async () => {
81
- const showToast = jest.fn();
82
- render(
83
- <TestComponent
84
- history={pageParamsHistoryMock}
85
- location={{}}
86
- mocks={deleteMockFactory(firstCall, secondCall, [
87
- { message: 'is used by first policy', path: ['base'] },
88
- { message: 'is used by second policy', path: ['base'] },
89
- ])}
90
- showToast={showToast}
91
- />
92
- );
93
- await waitFor(tick);
94
- expect(screen.getByText('ansible OVAL content')).toBeInTheDocument();
95
- expect(screen.queryByText('jboss OVAL content')).not.toBeInTheDocument();
96
- userEvent.click(screen.getAllByRole('button', { name: 'Actions' })[0]);
97
- userEvent.click(screen.getByText('Delete OVAL Content'));
98
- await waitFor(tick);
99
- userEvent.click(screen.getByText('Confirm'));
100
- await waitFor(tick);
101
- expect(showToast).toHaveBeenCalledWith({
102
- type: 'error',
103
- message:
104
- 'There was a following error when deleting OVAL Content: is used by first policy, is used by second policy',
105
- });
106
- expect(screen.getByText('ansible OVAL content')).toBeInTheDocument();
107
- expect(screen.queryByText('jboss OVAL content')).not.toBeInTheDocument();
108
- });
109
- it('should not show delete button when user does not have delete permissions', async () => {
110
- render(
111
- <TestComponent
112
- history={historyMock}
113
- location={{}}
114
- mocks={noDeleteMocks}
115
- showToast={jest.fn()}
116
- />
117
- );
118
- await waitFor(tick);
119
- expect(screen.getByText('ansible OVAL content')).toBeInTheDocument();
120
- expect(
121
- screen.queryByRole('button', { name: 'Actions' })
122
- ).not.toBeInTheDocument();
123
- });
124
- });
@@ -1,127 +0,0 @@
1
- import ovalContentsQuery from '../../../../graphql/queries/ovalContents.gql';
2
- import { ovalContentsPath } from '../../../../helpers/pathsHelper';
3
- import {
4
- mockFactory,
5
- admin,
6
- intruder,
7
- userFactory,
8
- } from '../../../../testHelper';
9
-
10
- const ovalContentMockFactory = mockFactory('ovalContents', ovalContentsQuery);
11
-
12
- const viewer = userFactory('viewer', [
13
- {
14
- __typename: 'Permission',
15
- id: 'MDE6UGVybWlzc2lvbi0yOTY=',
16
- name: 'view_oval_contents',
17
- },
18
- ]);
19
-
20
- const firstContent = (meta = { canDestroy: true }) => ({
21
- id: 'MDE6Rm9yZW1hbk9wZW5zY2FwOjpPdmFsQ29udGVudC0z',
22
- name: 'ansible OVAL content',
23
- url:
24
- 'http://oval-content-source/security/data/oval/ansible-2-including-unpatched.oval.xml.bz2',
25
- originalFilename: '',
26
- meta,
27
- });
28
-
29
- const secondContent = (meta = { canDestroy: true }) => ({
30
- id: 'MDE6Rm9yZW1hbk9wZW5zY2FwOjpPdmFsQ29udGVudC00',
31
- name: 'dotnet OVAL content',
32
- url: 'http://oval-content-source/security/data/oval/dotnet-2.2.oval.xml.bz2',
33
- originalFilename: '',
34
- meta,
35
- });
36
-
37
- const thirdContent = (meta = { canDestroy: true }) => ({
38
- id: 'MDE6Rm9yZW1hbk9wZW5zY2FwOjpPdmFsQ29udGVudC03',
39
- name: 'jboss OVAL content',
40
- url: '',
41
- originalFilename: 'jboss.oval.xml.bz2',
42
- meta,
43
- });
44
-
45
- const fourthContent = (meta = { canDestroy: true }) => ({
46
- id: 'MDE6Rm9yZW1hbk9wZW5zY2FwOjpPdmFsQ29udGVudC0zMw==',
47
- name: 'openshift OVAL content',
48
- url: '',
49
- originalFilename: 'openshift.oval.xml.bz2',
50
- meta,
51
- });
52
-
53
- const ovalContentNodes = [
54
- firstContent(),
55
- secondContent(),
56
- thirdContent(),
57
- fourthContent(),
58
- ];
59
-
60
- export const ovalContents = {
61
- totalCount: ovalContentNodes.length,
62
- nodes: ovalContentNodes,
63
- };
64
-
65
- export const mocks = ovalContentMockFactory(
66
- { first: 20, last: 20 },
67
- {
68
- totalCount: 4,
69
- nodes: [firstContent(), secondContent(), thirdContent(), fourthContent()],
70
- },
71
- { currentUser: admin }
72
- );
73
-
74
- export const unpagedMocks = ovalContentMockFactory({}, ovalContents, {
75
- currentUser: admin,
76
- });
77
-
78
- export const paginatedMocks = ovalContentMockFactory(
79
- { first: 10, last: 5 },
80
- { totalCount: 7, nodes: [secondContent(), fourthContent()] },
81
- { currentUser: admin }
82
- );
83
-
84
- export const emptyMocks = ovalContentMockFactory(
85
- { first: 20, last: 20 },
86
- { totalCount: 0, nodes: [] },
87
- { currentUser: admin }
88
- );
89
- export const errorMocks = ovalContentMockFactory(
90
- { first: 20, last: 20 },
91
- { totalCount: 0, nodes: [] },
92
- { errors: [{ message: 'Something very bad happened.' }], currentUser: admin }
93
- );
94
-
95
- export const viewerMocks = ovalContentMockFactory(
96
- { first: 20, last: 20 },
97
- ovalContents,
98
- { currentUser: viewer }
99
- );
100
-
101
- export const unauthorizedMocks = ovalContentMockFactory(
102
- { first: 20, last: 20 },
103
- ovalContents,
104
- { currentUser: intruder }
105
- );
106
-
107
- export const noDeleteMocks = ovalContentMockFactory(
108
- { first: 20, last: 20 },
109
- {
110
- totalCount: 2,
111
- nodes: [
112
- firstContent({ canDestroy: false }),
113
- secondContent({ canDestroy: false }),
114
- ],
115
- },
116
- { currentUser: admin }
117
- );
118
-
119
- export const pushMock = jest.fn();
120
-
121
- export const pagePaginationHistoryMock = {
122
- location: {
123
- search: '?page=2&perPage=5',
124
- pathname: ovalContentsPath,
125
- },
126
- push: pushMock,
127
- };
@@ -1,89 +0,0 @@
1
- import React from 'react';
2
- import { render, screen, waitFor } from '@testing-library/react';
3
- import '@testing-library/jest-dom';
4
-
5
- import OvalContentsIndex from '../';
6
-
7
- import {
8
- withRouter,
9
- withRedux,
10
- withMockedProvider,
11
- tick,
12
- historyMock,
13
- } from '../../../../testHelper';
14
-
15
- import {
16
- mocks,
17
- emptyMocks,
18
- errorMocks,
19
- viewerMocks,
20
- unauthorizedMocks,
21
- } from './OvalContentsIndex.fixtures';
22
-
23
- const TestComponent = withRedux(
24
- withRouter(withMockedProvider(OvalContentsIndex))
25
- );
26
-
27
- describe('OvalContentsIndex', () => {
28
- it('should load page', async () => {
29
- render(<TestComponent history={historyMock} mocks={mocks} location={{}} />);
30
- expect(screen.getByText('Loading')).toBeInTheDocument();
31
- await waitFor(tick);
32
- expect(screen.queryByText('Loading')).not.toBeInTheDocument();
33
- expect(screen.getByText('ansible OVAL content')).toBeInTheDocument();
34
- expect(
35
- screen.getByText(
36
- 'http://oval-content-source/security/data/oval/ansible-2-including-unpatched.oval.xml.bz2'
37
- )
38
- ).toBeInTheDocument();
39
- expect(screen.getByText('openshift OVAL content')).toBeInTheDocument();
40
- expect(screen.getByText('openshift.oval.xml.bz2')).toBeInTheDocument();
41
- });
42
- it('should show empty state', async () => {
43
- render(
44
- <TestComponent history={historyMock} mocks={emptyMocks} location={{}} />
45
- );
46
- expect(screen.getByText('Loading')).toBeInTheDocument();
47
- await waitFor(tick);
48
- expect(screen.queryByText('Loading')).not.toBeInTheDocument();
49
- expect(screen.getByText('No OVAL Contents found.')).toBeInTheDocument();
50
- });
51
- it('should show errors', async () => {
52
- render(
53
- <TestComponent history={historyMock} mocks={errorMocks} location={{}} />
54
- );
55
- expect(screen.getByText('Loading')).toBeInTheDocument();
56
- await waitFor(tick);
57
- expect(screen.queryByText('Loading')).not.toBeInTheDocument();
58
- expect(
59
- screen.getByText('Something very bad happened.')
60
- ).toBeInTheDocument();
61
- expect(screen.getByText('Error!')).toBeInTheDocument();
62
- });
63
- it('should load page for user with permissions', async () => {
64
- render(
65
- <TestComponent history={historyMock} mocks={viewerMocks} location={{}} />
66
- );
67
- await waitFor(tick);
68
- expect(screen.queryByText('Loading')).not.toBeInTheDocument();
69
- expect(screen.getByText('ansible OVAL content')).toBeInTheDocument();
70
- });
71
- it('should not load page for user without permissions', async () => {
72
- render(
73
- <TestComponent
74
- history={historyMock}
75
- mocks={unauthorizedMocks}
76
- location={{}}
77
- />
78
- );
79
- await waitFor(tick);
80
- expect(screen.queryByText('Loading')).not.toBeInTheDocument();
81
- expect(screen.queryByText('ansible OVAL content')).not.toBeInTheDocument();
82
- expect(
83
- screen.getByText(
84
- 'You are not authorized to view the page. Request the following permissions from administrator: view_oval_contents.'
85
- )
86
- ).toBeInTheDocument();
87
- expect(screen.getByText('Permission denied')).toBeInTheDocument();
88
- });
89
- });
@@ -1,13 +0,0 @@
1
- import React from 'react';
2
- import { useDispatch } from 'react-redux';
3
- import { showToast } from '../../../helpers/toastHelper';
4
-
5
- import OvalContentsIndex from './OvalContentsIndex';
6
-
7
- const WrappedOvalContentsIndex = props => {
8
- const dispatch = useDispatch();
9
-
10
- return <OvalContentsIndex {...props} showToast={showToast(dispatch)} />;
11
- };
12
-
13
- export default WrappedOvalContentsIndex;
@@ -1,138 +0,0 @@
1
- import React, { useState } from 'react';
2
- import PropTypes from 'prop-types';
3
- import { translate as __ } from 'foremanReact/common/I18n';
4
- import { Formik, Field as FormikField } from 'formik';
5
-
6
- import {
7
- Form as PfForm,
8
- ActionGroup,
9
- Button,
10
- FileUpload,
11
- FormGroup,
12
- Radio,
13
- Spinner,
14
- } from '@patternfly/react-core';
15
- import {
16
- onSubmit,
17
- createValidationSchema,
18
- validateFile,
19
- submitDisabled,
20
- } from './OvalContentsNewHelper';
21
- import LinkButton from '../../../components/LinkButton';
22
- import IndexLayout from '../../../components/IndexLayout';
23
- import { TextField } from '../../../helpers/formFieldsHelper';
24
- import { ovalContentsPath } from '../../../helpers/pathsHelper';
25
-
26
- import './OvalContentsNew.scss';
27
-
28
- const OvalContentsNew = props => {
29
- const [file, setFile] = useState(null);
30
- const [fileTouched, setFileTouched] = useState(false);
31
- const [fileFromUrl, setFileFromUrl] = useState(true);
32
-
33
- const handleFileChange = (value, filename, event) => {
34
- setFile(value);
35
- setFileTouched(true);
36
- };
37
-
38
- return (
39
- <IndexLayout pageTitle={__('New OVAL Content')} contentWidthSpan={6}>
40
- <Formik
41
- onSubmit={(values, actions) =>
42
- onSubmit(
43
- values,
44
- actions,
45
- props.showToast,
46
- props.history,
47
- fileFromUrl,
48
- file
49
- )
50
- }
51
- initialValues={{ name: '', url: '' }}
52
- validationSchema={createValidationSchema(fileFromUrl)}
53
- >
54
- {formProps => (
55
- <PfForm>
56
- <FormikField
57
- label={__('Name')}
58
- name="name"
59
- component={TextField}
60
- isRequired
61
- />
62
- <FormGroup label={__('OVAL Content Source')}>
63
- <Radio
64
- id="scap-file-source-url"
65
- isChecked={fileFromUrl}
66
- isDisabled={formProps.isSubmitting}
67
- name="fileSource"
68
- onChange={() => {
69
- setFileFromUrl(true);
70
- // Force validations to run by setting the same value.
71
- // Workaround for https://github.com/formium/formik/issues/1755
72
- formProps.setFieldValue(formProps.values.url);
73
- }}
74
- label={__('OVAL Content from URL')}
75
- />
76
- <Radio
77
- id="scap-file-source-file"
78
- isChecked={!fileFromUrl}
79
- isDisabled={formProps.isSubmitting}
80
- name="fileSource"
81
- onChange={() => {
82
- setFileFromUrl(false);
83
- const filtered = Object.entries(formProps.errors).filter(
84
- ([key, value]) => key !== 'url'
85
- );
86
- formProps.setErrors(Object.fromEntries(filtered));
87
- }}
88
- label={__('OVAL Content from file')}
89
- />
90
- </FormGroup>
91
- {!fileFromUrl ? (
92
- <FormGroup label={__('File')} isRequired>
93
- <FileUpload
94
- value={file}
95
- filename={file ? file.name : ''}
96
- onChange={handleFileChange}
97
- isDisabled={formProps.isSubmitting}
98
- validated={validateFile(file, fileTouched)}
99
- />
100
- </FormGroup>
101
- ) : (
102
- <FormikField
103
- label={__('URL')}
104
- name="url"
105
- component={TextField}
106
- placeholder="https://www.redhat.com/security/data/oval/v2/RHEL8/rhel-8.oval.xml.bz2"
107
- isRequired
108
- />
109
- )}
110
- <ActionGroup>
111
- <Button
112
- variant="primary"
113
- onClick={formProps.handleSubmit}
114
- isDisabled={submitDisabled(formProps, file, fileFromUrl)}
115
- >
116
- {__('Submit')}
117
- </Button>
118
- <LinkButton
119
- btnVariant="link"
120
- isDisabled={formProps.isSubmitting}
121
- btnText={__('Cancel')}
122
- path={ovalContentsPath}
123
- />
124
- {formProps.isSubmitting ? <Spinner size="lg" /> : null}
125
- </ActionGroup>
126
- </PfForm>
127
- )}
128
- </Formik>
129
- </IndexLayout>
130
- );
131
- };
132
-
133
- OvalContentsNew.propTypes = {
134
- showToast: PropTypes.func.isRequired,
135
- history: PropTypes.object.isRequired,
136
- };
137
-
138
- export default OvalContentsNew;
@@ -1,3 +0,0 @@
1
- #scap-file-source-url, #scap-file-source-file {
2
- margin: 0;
3
- }