foreman_ansible 9.0.1 → 10.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/helpers/foreman_ansible/ansible_hostgroups_helper.rb +1 -1
- data/lib/foreman_ansible/register.rb +1 -1
- data/lib/foreman_ansible/version.rb +1 -1
- data/package.json +0 -1
- data/test/integration/hostgroup_js_test.rb +30 -0
- data/webpack/components/AnsibleHostDetail/AnsibleHostDetail.js +1 -0
- data/webpack/components/AnsibleHostDetail/components/AnsibleVariableOverrides/AnsibleVariableOverridesTable.js +10 -4
- data/webpack/components/AnsibleHostDetail/components/AnsibleVariableOverrides/EditableAction.js +3 -0
- data/webpack/components/AnsibleHostDetail/components/AnsibleVariableOverrides/EditableValueHelper.js +5 -1
- data/webpack/components/AnsibleHostDetail/components/JobsTab/NewRecurringJobModal.js +3 -0
- data/webpack/components/AnsibleHostDetail/components/JobsTab/PreviousJobsTable.js +10 -4
- data/webpack/components/AnsibleHostDetail/components/JobsTab/RecurringJobsTable.js +3 -3
- data/webpack/components/AnsibleHostDetail/components/JobsTab/index.js +5 -1
- data/webpack/components/AnsibleHostDetail/components/RolesTab/AllRolesModal/AllRolesTable.js +10 -4
- data/webpack/components/AnsibleHostDetail/components/RolesTab/AllRolesModal/index.js +1 -0
- data/webpack/components/AnsibleHostDetail/components/RolesTab/EditRolesModal/EditRolesForm.js +2 -1
- data/webpack/components/AnsibleHostDetail/components/RolesTab/EditRolesModal/index.js +7 -1
- data/webpack/components/AnsibleHostDetail/components/RolesTab/RolesTable.js +14 -5
- data/webpack/components/AnsibleHostDetail/components/RolesTab/__test__/EditRoles.test.js +2 -1
- data/webpack/components/AnsibleHostDetail/components/RolesTab/__test__/RolesTab.test.js +3 -1
- data/webpack/components/AnsibleHostDetail/components/RolesTab/index.js +27 -2
- data/webpack/components/AnsibleHostDetail/components/SecondaryTabRoutes.js +1 -1
- data/webpack/testHelper.js +12 -3
- metadata +20 -56
- data/lib/foreman_ansible/register.rb.orig +0 -257
- data/locale/ca/foreman_ansible.edit.po +0 -1162
- data/locale/ca/foreman_ansible.po.time_stamp +0 -0
- data/locale/cs_CZ/foreman_ansible.edit.po +0 -1207
- data/locale/cs_CZ/foreman_ansible.po.time_stamp +0 -0
- data/locale/de/foreman_ansible.edit.po +0 -1148
- data/locale/de/foreman_ansible.po.time_stamp +0 -0
- data/locale/en/foreman_ansible.edit.po +0 -1146
- data/locale/en/foreman_ansible.po.time_stamp +0 -0
- data/locale/en_GB/foreman_ansible.edit.po +0 -1155
- data/locale/en_GB/foreman_ansible.po.time_stamp +0 -0
- data/locale/es/foreman_ansible.edit.po +0 -1148
- data/locale/es/foreman_ansible.po.time_stamp +0 -0
- data/locale/fr/foreman_ansible.edit.po +0 -1148
- data/locale/fr/foreman_ansible.po.time_stamp +0 -0
- data/locale/gl/foreman_ansible.edit.po +0 -1156
- data/locale/gl/foreman_ansible.po.time_stamp +0 -0
- data/locale/it/foreman_ansible.edit.po +0 -1148
- data/locale/it/foreman_ansible.po.time_stamp +0 -0
- data/locale/ja/foreman_ansible.edit.po +0 -1148
- data/locale/ja/foreman_ansible.po.time_stamp +0 -0
- data/locale/ko/foreman_ansible.edit.po +0 -1148
- data/locale/ko/foreman_ansible.po.time_stamp +0 -0
- data/locale/nl_NL/foreman_ansible.edit.po +0 -1168
- data/locale/nl_NL/foreman_ansible.po.time_stamp +0 -0
- data/locale/pl/foreman_ansible.edit.po +0 -1180
- data/locale/pl/foreman_ansible.po.time_stamp +0 -0
- data/locale/pt_BR/foreman_ansible.edit.po +0 -1148
- data/locale/pt_BR/foreman_ansible.po.time_stamp +0 -0
- data/locale/ru/foreman_ansible.edit.po +0 -1149
- data/locale/ru/foreman_ansible.po.time_stamp +0 -0
- data/locale/sv_SE/foreman_ansible.edit.po +0 -1180
- data/locale/sv_SE/foreman_ansible.po.time_stamp +0 -0
- data/locale/zh_CN/foreman_ansible.edit.po +0 -1148
- data/locale/zh_CN/foreman_ansible.po.time_stamp +0 -0
- data/locale/zh_TW/foreman_ansible.edit.po +0 -1148
- data/locale/zh_TW/foreman_ansible.po.time_stamp +0 -0
- data/webpack/components/AnsibleHostDetail/components/JobsTab/PreviousJobsTable.js.orig +0 -151
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3141b6325f66438c16c630fc728eb9bb7f381ade6987491cbc62fa98d911e83b
|
4
|
+
data.tar.gz: 68f84c9a0251af1aa1a284c5ae509008d24c9d68802097b50aa700f407d5cabb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d62e5e435516a8cef1dc345663d735a767b0b2150ac2c0938fd278e1466d7d1c15428cad48b9313d86902ac10acc00bb34fdadc2337456ed5bf52acb1aaad94e
|
7
|
+
data.tar.gz: 881639c08f95a3cf8771bbf20d74d3410b2caef5e25c4f000e414faf7d4292f365ed4a22ec8edebc3c357d89efd10f8b3ae41bfbb7eeca4e9ea894867c020b0f
|
@@ -4,7 +4,7 @@ module ForemanAnsible
|
|
4
4
|
module AnsibleHostgroupsHelper
|
5
5
|
def ansible_hostgroups_actions(hostgroup)
|
6
6
|
play_roles = if hostgroup.all_ansible_roles.empty?
|
7
|
-
{ action: (link_to _('Run all Ansible roles'), 'javascript:void(0);', disabled: true, title: 'No
|
7
|
+
{ action: { content: (link_to _('Run all Ansible roles'), 'javascript:void(0);', disabled: true, title: 'No roles assigned', class: 'disabled'), options: { class: 'disabled' } }, priority: 31 }
|
8
8
|
else
|
9
9
|
{ action: display_link_if_authorized(_('Run all Ansible roles'), hash_for_play_roles_hostgroup_path(id: hostgroup), 'data-no-turbolink': true, title: _('Run all Ansible roles on hosts belonging to this host group')), priority: 31 }
|
10
10
|
end
|
data/package.json
CHANGED
@@ -0,0 +1,30 @@
|
|
1
|
+
require_relative '../test_plugin_helper'
|
2
|
+
require 'integration_test_helper'
|
3
|
+
|
4
|
+
class HostgroupJsTest < IntegrationTestWithJavascript
|
5
|
+
let(:hostgroup) { FactoryBot.create(:hostgroup, :name => 'HostgroupWithoutRoles') }
|
6
|
+
let(:hostgroup_with_roles) { FactoryBot.create(:hostgroup, :with_ansible_roles, :name => 'HostgroupWithRoles') }
|
7
|
+
|
8
|
+
setup do
|
9
|
+
FactoryBot.create(:host, :hostgroup_id => hostgroup.id)
|
10
|
+
FactoryBot.create(:host, :hostgroup_id => hostgroup_with_roles.id)
|
11
|
+
end
|
12
|
+
|
13
|
+
test 'hostgroup without roles should have disabled link' do
|
14
|
+
visit hostgroups_path(search: hostgroup.name)
|
15
|
+
|
16
|
+
first_row = page.find('table > tbody > tr:nth-child(1)')
|
17
|
+
first_row.find('td:nth-child(4) > div > a').click
|
18
|
+
|
19
|
+
assert_includes first(:link, 'Run all Ansible roles')[:class], 'disabled'
|
20
|
+
end
|
21
|
+
|
22
|
+
test 'hostgroup with roles should have clickable link' do
|
23
|
+
visit hostgroups_path(search: hostgroup_with_roles.name)
|
24
|
+
|
25
|
+
first_row = page.find('table > tbody > tr:nth-child(1)')
|
26
|
+
first_row.find('td:nth-child(4) > div > a').click
|
27
|
+
|
28
|
+
assert_not first(:link, 'Run all Ansible roles')[:class].include?('disabled')
|
29
|
+
end
|
30
|
+
end
|
@@ -148,12 +148,17 @@ const AnsibleVariableOverridesTable = ({
|
|
148
148
|
<React.Fragment>
|
149
149
|
<Flex direction={{ default: 'column' }}>
|
150
150
|
<FlexItem align={{ default: 'alignRight' }}>
|
151
|
-
<Pagination
|
151
|
+
<Pagination
|
152
|
+
ouiaId="pagination-top"
|
153
|
+
updateParamsByUrl
|
154
|
+
itemCount={totalCount}
|
155
|
+
variant="top"
|
156
|
+
/>
|
152
157
|
</FlexItem>
|
153
158
|
<FlexItem>
|
154
|
-
<TableComposable variant="compact">
|
159
|
+
<TableComposable ouiaId="table-composable-compact" variant="compact">
|
155
160
|
<Thead>
|
156
|
-
<Tr>
|
161
|
+
<Tr ouiaId="row-header">
|
157
162
|
{columns.map(col => (
|
158
163
|
<Th key={col}>{col}</Th>
|
159
164
|
))}
|
@@ -162,7 +167,7 @@ const AnsibleVariableOverridesTable = ({
|
|
162
167
|
</Thead>
|
163
168
|
<Tbody>
|
164
169
|
{variables.map((variable, idx) => (
|
165
|
-
<Tr key={idx}>
|
170
|
+
<Tr key={idx} ouiaId={`row-${idx}`}>
|
166
171
|
<Td>
|
167
172
|
<a href={variable.path}>{variable.key}</a>
|
168
173
|
</Td>
|
@@ -202,6 +207,7 @@ const AnsibleVariableOverridesTable = ({
|
|
202
207
|
</FlexItem>
|
203
208
|
<FlexItem align={{ default: 'alignRight' }}>
|
204
209
|
<Pagination
|
210
|
+
ouiaId="pagination-bottom"
|
205
211
|
updateParamsByUrl
|
206
212
|
itemCount={totalCount}
|
207
213
|
variant="bottom"
|
data/webpack/components/AnsibleHostDetail/components/AnsibleVariableOverrides/EditableAction.js
CHANGED
@@ -111,6 +111,7 @@ const EditableAction = ({
|
|
111
111
|
onClick={onClose}
|
112
112
|
isDisabled={state.working}
|
113
113
|
aria-label="Cancel editing override button"
|
114
|
+
ouiaId="cancel-editing-override-button"
|
114
115
|
>
|
115
116
|
<TimesIcon />
|
116
117
|
</Button>
|
@@ -119,6 +120,7 @@ const EditableAction = ({
|
|
119
120
|
onClick={onSubmit}
|
120
121
|
isDisabled={state.working || hasError(state)}
|
121
122
|
aria-label="Submit editing override button"
|
123
|
+
ouiaId="submit-editing-override-button"
|
122
124
|
>
|
123
125
|
<CheckIcon />
|
124
126
|
</Button>
|
@@ -136,6 +138,7 @@ const EditableAction = ({
|
|
136
138
|
onClick={onOpen}
|
137
139
|
variant="plain"
|
138
140
|
aria-label="Edit override button"
|
141
|
+
ouiaId="edit-override-button"
|
139
142
|
>
|
140
143
|
<PencilAltIcon />
|
141
144
|
</Button>
|
data/webpack/components/AnsibleHostDetail/components/AnsibleVariableOverrides/EditableValueHelper.js
CHANGED
@@ -23,7 +23,11 @@ const withFormGroup = Component => componentProps => {
|
|
23
23
|
export const SelectField = componentProps => {
|
24
24
|
const { selectItems, ...rest } = componentProps;
|
25
25
|
return (
|
26
|
-
<FormSelect
|
26
|
+
<FormSelect
|
27
|
+
className="without_select2"
|
28
|
+
ouiaId="without-form-select"
|
29
|
+
{...rest}
|
30
|
+
>
|
27
31
|
{selectItems.map(item => (
|
28
32
|
<FormSelectOption key={item.id} value={item.value} label={item.name} />
|
29
33
|
))}
|
@@ -57,6 +57,7 @@ const NewRecurringJobModal = props => {
|
|
57
57
|
const actions = [
|
58
58
|
<Button
|
59
59
|
aria-label="submit creating job"
|
60
|
+
ouiaId="submit-creating-job"
|
60
61
|
key="confirm"
|
61
62
|
variant="primary"
|
62
63
|
onClick={formProps.handleSubmit}
|
@@ -66,6 +67,7 @@ const NewRecurringJobModal = props => {
|
|
66
67
|
</Button>,
|
67
68
|
<Button
|
68
69
|
aria-label="cancel creating job"
|
70
|
+
ouiaId="cancel-creating-job"
|
69
71
|
key="cancel"
|
70
72
|
variant="link"
|
71
73
|
onClick={onClose}
|
@@ -83,6 +85,7 @@ const NewRecurringJobModal = props => {
|
|
83
85
|
<Modal
|
84
86
|
variant={ModalVariant.large}
|
85
87
|
title="Create New Recurring Ansible Run"
|
88
|
+
ouiaId="modal-recurring-ansible-run"
|
86
89
|
isOpen={props.isOpen}
|
87
90
|
className="foreman-modal modal-high"
|
88
91
|
showClose={false}
|
@@ -32,12 +32,17 @@ const PreviousJobsTable = ({ history, totalCount, jobs, pagination }) => {
|
|
32
32
|
<h3>{__('Previously executed jobs')}</h3>
|
33
33
|
<Flex direction={{ default: 'column' }} className="pf-u-pt-md">
|
34
34
|
<FlexItem align={{ default: 'alignRight' }}>
|
35
|
-
<Pagination
|
35
|
+
<Pagination
|
36
|
+
ouiaId="pagination-top"
|
37
|
+
updateParamsByUrl
|
38
|
+
itemCount={totalCount}
|
39
|
+
variant="top"
|
40
|
+
/>
|
36
41
|
</FlexItem>
|
37
42
|
<FlexItem>
|
38
|
-
<TableComposable variant="compact">
|
43
|
+
<TableComposable ouiaId="table-composable-compact" variant="compact">
|
39
44
|
<Thead>
|
40
|
-
<Tr>
|
45
|
+
<Tr ouiaId="row-header">
|
41
46
|
{columns.map(col => (
|
42
47
|
<Th key={col}>{col}</Th>
|
43
48
|
))}
|
@@ -45,7 +50,7 @@ const PreviousJobsTable = ({ history, totalCount, jobs, pagination }) => {
|
|
45
50
|
</Thead>
|
46
51
|
<Tbody>
|
47
52
|
{jobs.map(job => (
|
48
|
-
<Tr key={job.id}>
|
53
|
+
<Tr key={job.id} ouiaId={`row-${job.id}`}>
|
49
54
|
<Td>
|
50
55
|
<a
|
51
56
|
onClick={() =>
|
@@ -72,6 +77,7 @@ const PreviousJobsTable = ({ history, totalCount, jobs, pagination }) => {
|
|
72
77
|
</FlexItem>
|
73
78
|
<FlexItem align={{ default: 'alignRight' }}>
|
74
79
|
<Pagination
|
80
|
+
ouiaId="pagination-bottom"
|
75
81
|
updateParamsByUrl
|
76
82
|
itemCount={totalCount}
|
77
83
|
variant="bottom"
|
@@ -60,9 +60,9 @@ const RecurringJobsTable = ({
|
|
60
60
|
return (
|
61
61
|
<React.Fragment>
|
62
62
|
<h3>{__('Scheduled recurring jobs')}</h3>
|
63
|
-
<TableComposable variant="compact">
|
63
|
+
<TableComposable ouiaId="table-composable-compact" variant="compact">
|
64
64
|
<Thead>
|
65
|
-
<Tr>
|
65
|
+
<Tr ouiaId="row-header">
|
66
66
|
{columns.map(col => (
|
67
67
|
<Th key={col}>{col}</Th>
|
68
68
|
))}
|
@@ -71,7 +71,7 @@ const RecurringJobsTable = ({
|
|
71
71
|
</Thead>
|
72
72
|
<Tbody>
|
73
73
|
{jobs.map(job => (
|
74
|
-
<Tr key={job.id}>
|
74
|
+
<Tr key={job.id} ouiaId={`row-${job.id}`}>
|
75
75
|
<Td>
|
76
76
|
<a
|
77
77
|
onClick={() =>
|
@@ -33,7 +33,11 @@ const JobsTab = ({ resourceName, resourceId, hostGroupId, history }) => {
|
|
33
33
|
];
|
34
34
|
|
35
35
|
const scheduleBtn = (
|
36
|
-
<Button
|
36
|
+
<Button
|
37
|
+
aria-label="schedule recurring job"
|
38
|
+
ouiaId="schedule-recurring-job"
|
39
|
+
onClick={toggleModal}
|
40
|
+
>
|
37
41
|
{__('Schedule recurring job')}
|
38
42
|
</Button>
|
39
43
|
);
|
data/webpack/components/AnsibleHostDetail/components/RolesTab/AllRolesModal/AllRolesTable.js
CHANGED
@@ -21,11 +21,16 @@ const AllRolesTable = ({ allAnsibleRoles, totalCount }) => {
|
|
21
21
|
<React.Fragment>
|
22
22
|
<Flex direction={{ default: 'column' }} className="pf-u-pt-md">
|
23
23
|
<FlexItem align={{ default: 'alignRight' }}>
|
24
|
-
<Pagination
|
24
|
+
<Pagination
|
25
|
+
ouiaId="pagination-top"
|
26
|
+
updateParamsByUrl
|
27
|
+
itemCount={totalCount}
|
28
|
+
variant="top"
|
29
|
+
/>
|
25
30
|
</FlexItem>
|
26
|
-
<TableComposable variant="compact">
|
31
|
+
<TableComposable ouiaId="table-composable-compact" variant="compact">
|
27
32
|
<Thead>
|
28
|
-
<Tr>
|
33
|
+
<Tr ouiaId="row-header">
|
29
34
|
<Th />
|
30
35
|
{columns.map(col => (
|
31
36
|
<Th key={`${col}-all`}>{col}</Th>
|
@@ -34,7 +39,7 @@ const AllRolesTable = ({ allAnsibleRoles, totalCount }) => {
|
|
34
39
|
</Thead>
|
35
40
|
<Tbody>
|
36
41
|
{allAnsibleRoles.map(role => (
|
37
|
-
<Tr key={`${role.id}-all`} id={role.id}>
|
42
|
+
<Tr key={`${role.id}-all`} id={role.id} ouiaId={`row-${role.id}`}>
|
38
43
|
<Td />
|
39
44
|
<Td>{role.name}</Td>
|
40
45
|
<Td>
|
@@ -58,6 +63,7 @@ const AllRolesTable = ({ allAnsibleRoles, totalCount }) => {
|
|
58
63
|
</TableComposable>
|
59
64
|
<FlexItem align={{ default: 'alignRight' }}>
|
60
65
|
<Pagination
|
66
|
+
ouiaId="pagination-bottom"
|
61
67
|
updateParamsByUrl
|
62
68
|
itemCount={totalCount}
|
63
69
|
variant="bottom"
|
data/webpack/components/AnsibleHostDetail/components/RolesTab/EditRolesModal/EditRolesForm.js
CHANGED
@@ -54,6 +54,7 @@ const EditRolesForm = props => {
|
|
54
54
|
onClick={() => callMutation({ variables })}
|
55
55
|
isDisabled={loading || didNotModifyOptions()}
|
56
56
|
aria-label="submit ansible roles"
|
57
|
+
ouiaId="submit-ansible-roles-button"
|
57
58
|
>
|
58
59
|
{__('Confirm')}
|
59
60
|
</Button>,
|
@@ -65,7 +66,7 @@ const EditRolesForm = props => {
|
|
65
66
|
}
|
66
67
|
|
67
68
|
return (
|
68
|
-
<Modal {...baseModalProps} actions={formActions}>
|
69
|
+
<Modal ouiaId="modal-edit-roles" {...baseModalProps} actions={formActions}>
|
69
70
|
<DualList
|
70
71
|
availableOptions={availableOptions}
|
71
72
|
chosenOptions={chosenOptions}
|
@@ -20,6 +20,7 @@ const EditRolesModal = ({
|
|
20
20
|
canEditHost,
|
21
21
|
}) => {
|
22
22
|
const baseModalProps = {
|
23
|
+
ouiaId: 'edit-ansible-roles-modal',
|
23
24
|
width: '50%',
|
24
25
|
isOpen,
|
25
26
|
className: 'foreman-modal',
|
@@ -32,7 +33,12 @@ const EditRolesModal = ({
|
|
32
33
|
};
|
33
34
|
|
34
35
|
const actions = [
|
35
|
-
<Button
|
36
|
+
<Button
|
37
|
+
ouiaId="close-button"
|
38
|
+
variant="link"
|
39
|
+
onClick={event => closeModal()}
|
40
|
+
key="close"
|
41
|
+
>
|
36
42
|
{__('Close')}
|
37
43
|
</Button>,
|
38
44
|
];
|
@@ -32,7 +32,10 @@ const RolesTable = ({
|
|
32
32
|
const editBtn = canEditHost ? (
|
33
33
|
<FlexItem>
|
34
34
|
<Link to="/Ansible/roles/edit">
|
35
|
-
<Button
|
35
|
+
<Button
|
36
|
+
aria-label="edit ansible roles"
|
37
|
+
ouiaId="edit-ansible-roles-button"
|
38
|
+
>
|
36
39
|
{__('Edit Ansible roles')}
|
37
40
|
</Button>
|
38
41
|
</Link>
|
@@ -53,14 +56,19 @@ const RolesTable = ({
|
|
53
56
|
<Flex>
|
54
57
|
<FlexItem>{editBtn}</FlexItem>
|
55
58
|
<FlexItem align={{ default: 'alignRight' }}>
|
56
|
-
<Pagination
|
59
|
+
<Pagination
|
60
|
+
ouiaId="pagination-top"
|
61
|
+
updateParamsByUrl
|
62
|
+
itemCount={totalCount}
|
63
|
+
variant="top"
|
64
|
+
/>
|
57
65
|
</FlexItem>
|
58
66
|
</Flex>
|
59
67
|
<Flex direction={{ default: 'column' }}>
|
60
68
|
<FlexItem>
|
61
|
-
<TableComposable variant="compact">
|
69
|
+
<TableComposable variant="compact" ouiaId="table-composable-compact">
|
62
70
|
<Thead>
|
63
|
-
<Tr>
|
71
|
+
<Tr ouiaId="row-header">
|
64
72
|
{columns.map(col => (
|
65
73
|
<Th key={col}>{col}</Th>
|
66
74
|
))}
|
@@ -68,7 +76,7 @@ const RolesTable = ({
|
|
68
76
|
</Thead>
|
69
77
|
<Tbody>
|
70
78
|
{ansibleRoles.map(role => (
|
71
|
-
<Tr key={role.id}>
|
79
|
+
<Tr key={role.id} ouiaId={`row-${role.id}`}>
|
72
80
|
<Td>
|
73
81
|
<a href={role.path}>{role.name}</a>
|
74
82
|
</Td>
|
@@ -88,6 +96,7 @@ const RolesTable = ({
|
|
88
96
|
</FlexItem>
|
89
97
|
<FlexItem align={{ default: 'alignRight' }}>
|
90
98
|
<Pagination
|
99
|
+
ouiaId="pagination-bottom"
|
91
100
|
updateParamsByUrl
|
92
101
|
itemCount={totalCount}
|
93
102
|
variant="bottom"
|
@@ -21,7 +21,8 @@ import {
|
|
21
21
|
assignRolesErrorMock,
|
22
22
|
} from './RolesTab.fixtures';
|
23
23
|
|
24
|
-
|
24
|
+
jest.mock('axios');
|
25
|
+
const TestComponent = withRedux(withReactRouter(withMockedProvider(RolesTab)));
|
25
26
|
|
26
27
|
describe('assigning Ansible roles', () => {
|
27
28
|
it('should assign Ansible roles', async () => {
|
@@ -6,6 +6,7 @@ import {
|
|
6
6
|
tick,
|
7
7
|
withMockedProvider,
|
8
8
|
withReactRouter,
|
9
|
+
withRedux,
|
9
10
|
} from '../../../../../testHelper';
|
10
11
|
|
11
12
|
import {
|
@@ -18,7 +19,8 @@ import {
|
|
18
19
|
|
19
20
|
import RolesTab from '../';
|
20
21
|
|
21
|
-
|
22
|
+
jest.mock('axios');
|
23
|
+
const TestComponent = withRedux(withReactRouter(withMockedProvider(RolesTab)));
|
22
24
|
|
23
25
|
describe('RolesTab', () => {
|
24
26
|
it('should load Ansible Roles as admin', async () => {
|
@@ -2,7 +2,10 @@ import React, { useState } from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
3
3
|
import { useQuery } from '@apollo/client';
|
4
4
|
import { Button } from '@patternfly/react-core';
|
5
|
+
import { Link, Route } from 'react-router-dom';
|
5
6
|
import { translate as __ } from 'foremanReact/common/I18n';
|
7
|
+
import { foremanUrl } from 'foremanReact/common/helpers';
|
8
|
+
import { useAPI } from 'foremanReact/common/hooks/API/APIHooks';
|
6
9
|
|
7
10
|
import ansibleRolesQuery from '../../../../graphql/queries/hostAnsibleRoles.gql';
|
8
11
|
import { encodeId } from '../../../../globalIdHelper';
|
@@ -12,6 +15,7 @@ import {
|
|
12
15
|
useCurrentPagination,
|
13
16
|
} from '../../../../helpers/pageParamsHelper';
|
14
17
|
import EditRolesModal from './EditRolesModal';
|
18
|
+
import AllRolesModal from './AllRolesModal';
|
15
19
|
|
16
20
|
const RolesTab = ({ hostId, history, canEditHost }) => {
|
17
21
|
const hostGlobalId = encodeId('Host', hostId);
|
@@ -32,10 +36,30 @@ const RolesTab = ({ hostId, history, canEditHost }) => {
|
|
32
36
|
<Button
|
33
37
|
onClick={() => setAssignModal(true)}
|
34
38
|
aria-label="edit ansible roles"
|
39
|
+
ouiaId="edit-ansible-roles-button"
|
35
40
|
>
|
36
|
-
{__('Assign
|
41
|
+
{__('Assign roles directly to the host')}
|
37
42
|
</Button>
|
38
43
|
) : null;
|
44
|
+
|
45
|
+
const url = hostId && foremanUrl(`/api/v2/hosts/${hostId}/ansible_roles`);
|
46
|
+
const { response: allAnsibleRoles } = useAPI('get', url, {
|
47
|
+
key: 'ANSIBLE_ROLES',
|
48
|
+
});
|
49
|
+
const emptyStateDescription = allAnsibleRoles.length > 0 && (
|
50
|
+
<>
|
51
|
+
<Route path="/Ansible/roles/all">
|
52
|
+
<AllRolesModal
|
53
|
+
onClose={() => history.push('/Ansible/roles')}
|
54
|
+
isOpen
|
55
|
+
hostGlobalId={hostGlobalId}
|
56
|
+
history={history}
|
57
|
+
/>
|
58
|
+
</Route>
|
59
|
+
<Link to="/Ansible/roles/all">{__('View inherited roles')}</Link>
|
60
|
+
</>
|
61
|
+
);
|
62
|
+
|
39
63
|
return (
|
40
64
|
<>
|
41
65
|
<RolesTable
|
@@ -46,8 +70,9 @@ const RolesTab = ({ hostId, history, canEditHost }) => {
|
|
46
70
|
history={history}
|
47
71
|
hostGlobalId={hostGlobalId}
|
48
72
|
emptyStateProps={{
|
49
|
-
header: __('No
|
73
|
+
header: __('No roles assigned directly to the host'),
|
50
74
|
action: editBtn,
|
75
|
+
description: emptyStateDescription,
|
51
76
|
}}
|
52
77
|
pagination={pagination}
|
53
78
|
canEditHost={canEditHost}
|
@@ -12,7 +12,7 @@ import { ANSIBLE_KEY } from '../constants';
|
|
12
12
|
import { route } from '../helpers';
|
13
13
|
|
14
14
|
const SecondaryTabRoutes = ({ response, router, history }) => (
|
15
|
-
<Switch>
|
15
|
+
<Switch ouiaId="switch">
|
16
16
|
<Route exact path={`/${ANSIBLE_KEY}`}>
|
17
17
|
<Redirect to={route('roles')} />
|
18
18
|
</Route>
|
data/webpack/testHelper.js
CHANGED
@@ -1,15 +1,24 @@
|
|
1
1
|
import React from 'react';
|
2
2
|
import { Provider } from 'react-redux';
|
3
|
+
import thunk from 'redux-thunk';
|
4
|
+
import { applyMiddleware, createStore, compose, combineReducers } from 'redux';
|
3
5
|
import { MockedProvider } from '@apollo/react-testing';
|
4
6
|
import { Router, MemoryRouter } from 'react-router-dom';
|
5
7
|
import { createMemoryHistory } from 'history';
|
6
8
|
|
7
|
-
import
|
8
|
-
import ConfirmModal
|
9
|
+
import { reducers as apiReducer, APIMiddleware } from 'foremanReact/redux/API';
|
10
|
+
import ConfirmModal, {
|
11
|
+
reducers as confirmModalReducers,
|
12
|
+
} from 'foremanReact/components/ConfirmModal';
|
9
13
|
import { getForemanContext } from 'foremanReact/Root/Context/ForemanContext';
|
10
14
|
|
15
|
+
const reducers = combineReducers({ ...apiReducer, ...confirmModalReducers });
|
16
|
+
|
17
|
+
export const generateStore = () =>
|
18
|
+
createStore(reducers, compose(applyMiddleware(thunk, APIMiddleware)));
|
19
|
+
|
11
20
|
export const withRedux = Component => props => (
|
12
|
-
<Provider store={
|
21
|
+
<Provider store={generateStore()}>
|
13
22
|
<Component {...props} />
|
14
23
|
<ConfirmModal />
|
15
24
|
</Provider>
|