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,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
- }