foreman-tasks 11.0.5 → 11.0.7

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 (75) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/foreman-tasks/locale/de/foreman_tasks.js +5 -2
  3. data/app/assets/javascripts/foreman-tasks/locale/en/foreman_tasks.js +4 -1
  4. data/app/assets/javascripts/foreman-tasks/locale/es/foreman_tasks.js +5 -2
  5. data/app/assets/javascripts/foreman-tasks/locale/fr/foreman_tasks.js +11 -8
  6. data/app/assets/javascripts/foreman-tasks/locale/ja/foreman_tasks.js +12 -9
  7. data/app/assets/javascripts/foreman-tasks/locale/ka/foreman_tasks.js +5 -2
  8. data/app/assets/javascripts/foreman-tasks/locale/ko/foreman_tasks.js +167 -165
  9. data/app/assets/javascripts/foreman-tasks/locale/pt_BR/foreman_tasks.js +5 -2
  10. data/app/assets/javascripts/foreman-tasks/locale/ru/foreman_tasks.js +5 -2
  11. data/app/assets/javascripts/foreman-tasks/locale/zh_CN/foreman_tasks.js +11 -8
  12. data/app/assets/javascripts/foreman-tasks/locale/zh_TW/foreman_tasks.js +5 -2
  13. data/lib/foreman_tasks/dynflow/console_authorizer.rb +1 -3
  14. data/lib/foreman_tasks/version.rb +1 -1
  15. data/locale/Makefile +18 -7
  16. data/locale/de/LC_MESSAGES/foreman_tasks.mo +0 -0
  17. data/locale/de/foreman_tasks.po +5 -2
  18. data/locale/en/LC_MESSAGES/foreman_tasks.mo +0 -0
  19. data/locale/en/foreman_tasks.po +4 -1
  20. data/locale/es/LC_MESSAGES/foreman_tasks.mo +0 -0
  21. data/locale/es/foreman_tasks.po +5 -2
  22. data/locale/foreman_tasks.pot +10 -6
  23. data/locale/fr/LC_MESSAGES/foreman_tasks.mo +0 -0
  24. data/locale/fr/foreman_tasks.po +11 -8
  25. data/locale/ja/LC_MESSAGES/foreman_tasks.mo +0 -0
  26. data/locale/ja/foreman_tasks.po +12 -9
  27. data/locale/ka/LC_MESSAGES/foreman_tasks.mo +0 -0
  28. data/locale/ka/foreman_tasks.po +5 -2
  29. data/locale/ko/LC_MESSAGES/foreman_tasks.mo +0 -0
  30. data/locale/ko/foreman_tasks.po +167 -165
  31. data/locale/pt_BR/LC_MESSAGES/foreman_tasks.mo +0 -0
  32. data/locale/pt_BR/foreman_tasks.po +5 -2
  33. data/locale/ru/LC_MESSAGES/foreman_tasks.mo +0 -0
  34. data/locale/ru/foreman_tasks.po +5 -2
  35. data/locale/zh_CN/LC_MESSAGES/foreman_tasks.mo +0 -0
  36. data/locale/zh_CN/foreman_tasks.po +11 -8
  37. data/locale/zh_TW/LC_MESSAGES/foreman_tasks.mo +0 -0
  38. data/locale/zh_TW/foreman_tasks.po +5 -2
  39. data/webpack/ForemanTasks/Components/TaskDetails/Components/Task.js +37 -9
  40. data/webpack/ForemanTasks/Components/TaskDetails/Components/TaskButtons.js +19 -16
  41. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/TaskButtons.test.js +197 -71
  42. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/__snapshots__/Task.test.js.snap +24 -40
  43. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/__snapshots__/TaskDetails.test.js.snap +2 -16
  44. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/ConfirmModalSelectors.js +0 -16
  45. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/GenericConfirmModal.js +70 -0
  46. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/__test__/ConfirmModalSelectors.test.js +25 -14
  47. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/__test__/__snapshots__/ConfirmModalSelectors.test.js.snap +8 -7
  48. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/__test__/index.test.js +409 -0
  49. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/createBulkTaskModal.js +67 -0
  50. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/createTaskModal.js +51 -0
  51. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/index.js +73 -23
  52. data/webpack/ForemanTasks/Components/TasksTable/TasksTable.js +5 -2
  53. data/webpack/ForemanTasks/Components/TasksTable/TasksTableConstants.js +1 -1
  54. data/webpack/ForemanTasks/Components/TasksTable/TasksTablePage.js +67 -11
  55. data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/TasksTablePage.test.js.snap +86 -6
  56. data/webpack/ForemanTasks/Components/common/ClickConfirmation/ClickConfirmation.test.js +225 -39
  57. data/webpack/ForemanTasks/Components/common/ClickConfirmation/index.js +136 -37
  58. metadata +6 -19
  59. data/webpack/ForemanTasks/Components/TaskActions/UnlockModals.js +0 -60
  60. data/webpack/ForemanTasks/Components/TaskActions/UnlockModals.test.js +0 -14
  61. data/webpack/ForemanTasks/Components/TaskActions/__snapshots__/UnlockModals.test.js.snap +0 -25
  62. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/__snapshots__/TaskButtons.test.js.snap +0 -212
  63. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/ConfirmModal.js +0 -83
  64. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/ConfirmModalActions.js +0 -106
  65. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/ConfirmModalReducer.js +0 -38
  66. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/__test__/ConfirmModal.test.js +0 -36
  67. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/__test__/ConfirmModalActions.test.js +0 -205
  68. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/__test__/ConfirmModalReducer.test.js +0 -27
  69. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/__test__/__snapshots__/ConfirmModal.test.js.snap +0 -41
  70. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/__test__/__snapshots__/ConfirmModalReducer.test.js.snap +0 -19
  71. data/webpack/ForemanTasks/Components/common/ClickConfirmation/ClickConfirmation.scss +0 -9
  72. data/webpack/ForemanTasks/Components/common/ClickConfirmation/__snapshots__/ClickConfirmation.test.js.snap +0 -52
  73. data/webpack/__mocks__/foremanReact/components/ForemanModal/ForemanModalActions.js +0 -2
  74. data/webpack/__mocks__/foremanReact/components/ForemanModal/ForemanModalHooks.js +0 -10
  75. data/webpack/__mocks__/foremanReact/components/ForemanModal/index.js +0 -18
@@ -6,7 +6,7 @@
6
6
  # Luiz Henrique Vasconcelos <luizvasconceloss@yahoo.com.br>, 2017-2018
7
7
  msgid ""
8
8
  msgstr ""
9
- "Project-Id-Version: foreman_tasks 9.2.2\n"
9
+ "Project-Id-Version: foreman-tasks 11.0.5\n"
10
10
  "Report-Msgid-Bugs-To: \n"
11
11
  "PO-Revision-Date: 2016-02-12 14:04+0000\n"
12
12
  "Last-Translator: Luiz Henrique Vasconcelos <luizvasconceloss@yahoo.com.br>, 20"
@@ -66,7 +66,7 @@ msgid "Action"
66
66
  msgstr "Ação"
67
67
 
68
68
  msgid "Action with sub plans"
69
- msgstr "Ação com subplanos "
69
+ msgstr ""
70
70
 
71
71
  msgid "Active"
72
72
  msgstr "Ativo"
@@ -318,6 +318,9 @@ msgstr "Erro de inicialização: %s"
318
318
  msgid "Input"
319
319
  msgstr "Entrada"
320
320
 
321
+ msgid "Invalid URL"
322
+ msgstr ""
323
+
321
324
  msgid "Iteration limit"
322
325
  msgstr "Limite de iteração"
323
326
 
Binary file
@@ -6,7 +6,7 @@
6
6
  # Yulia <yulia.poyarkova@redhat.com>, 2016
7
7
  msgid ""
8
8
  msgstr ""
9
- "Project-Id-Version: foreman_tasks 9.2.2\n"
9
+ "Project-Id-Version: foreman-tasks 11.0.5\n"
10
10
  "Report-Msgid-Bugs-To: \n"
11
11
  "PO-Revision-Date: 2016-02-12 14:04+0000\n"
12
12
  "Last-Translator: Yulia <yulia.poyarkova@redhat.com>, 2016\n"
@@ -66,7 +66,7 @@ msgid "Action"
66
66
  msgstr "Действие"
67
67
 
68
68
  msgid "Action with sub plans"
69
- msgstr "Действия с подпланами"
69
+ msgstr ""
70
70
 
71
71
  msgid "Active"
72
72
  msgstr "Активно"
@@ -318,6 +318,9 @@ msgstr "Ошибка инициализации: %s"
318
318
  msgid "Input"
319
319
  msgstr "Вход"
320
320
 
321
+ msgid "Invalid URL"
322
+ msgstr ""
323
+
321
324
  msgid "Iteration limit"
322
325
  msgstr "Максимальное число итераций"
323
326
 
@@ -5,7 +5,7 @@
5
5
  # Translators:
6
6
  msgid ""
7
7
  msgstr ""
8
- "Project-Id-Version: foreman_tasks 9.2.2\n"
8
+ "Project-Id-Version: foreman-tasks 11.0.5\n"
9
9
  "Report-Msgid-Bugs-To: \n"
10
10
  "PO-Revision-Date: 2016-02-12 14:04+0000\n"
11
11
  "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
@@ -63,7 +63,7 @@ msgid "Action"
63
63
  msgstr "操作"
64
64
 
65
65
  msgid "Action with sub plans"
66
- msgstr "有子计划的操作"
66
+ msgstr ""
67
67
 
68
68
  msgid "Active"
69
69
  msgstr "活跃"
@@ -148,7 +148,7 @@ msgid "Cannot update a cancelled Recurring Logic."
148
148
  msgstr "无法更新一个已取消的周期性逻辑。"
149
149
 
150
150
  msgid "Changing request id %{request_id} to saved id %{saved_id}"
151
- msgstr "将请求 id %%{request_id} 改为保存的 id %%{saved_id}"
151
+ msgstr "将请求 id %{request_id} 改为保存的 id %%{saved_id}"
152
152
 
153
153
  msgid "Check for long running tasks"
154
154
  msgstr "检查长时间运行的任务"
@@ -241,7 +241,7 @@ msgid "Errors:"
241
241
  msgstr "错误:"
242
242
 
243
243
  msgid "Event delivered by request %{request_id}"
244
- msgstr "由请求 %%{request_id} 发送的事件"
244
+ msgstr "由请求 %{request_id} 发送的事件"
245
245
 
246
246
  msgid "Exception"
247
247
  msgstr "例外"
@@ -315,6 +315,9 @@ msgstr "初始化错误:%s"
315
315
  msgid "Input"
316
316
  msgstr "输入"
317
317
 
318
+ msgid "Invalid URL"
319
+ msgstr ""
320
+
318
321
  msgid "Iteration limit"
319
322
  msgstr "重述限制"
320
323
 
@@ -548,7 +551,7 @@ msgid "Schedule future execution"
548
551
  msgstr "调度未来的执行"
549
552
 
550
553
  msgid "Scheduled"
551
- msgstr "调度的"
554
+ msgstr "调度"
552
555
 
553
556
  msgid "Search query"
554
557
  msgstr "搜索查询"
@@ -804,7 +807,7 @@ msgid "is hour (range: 0-23)"
804
807
  msgstr "小时(范围:0-23)"
805
808
 
806
809
  msgid "is in the past"
807
- msgstr ""
810
+ msgstr "在过去"
808
811
 
809
812
  #. TRANSLATORS: this translation is referring to an option which is a time interval
810
813
  msgid "is minute (range: 0-59)"
@@ -824,10 +827,10 @@ msgid "mode"
824
827
  msgstr "模式"
825
828
 
826
829
  msgid "mode has to be one of %{allowed_modes}"
827
- msgstr "模式必须是 %%{allowed_modes} 之一"
830
+ msgstr "模式必须是 %{allowed_modes} 之一"
828
831
 
829
832
  msgid "must be set"
830
- msgstr ""
833
+ msgstr "必须设置"
831
834
 
832
835
  msgid "older"
833
836
  msgstr "较老"
@@ -5,7 +5,7 @@
5
5
  # Translators:
6
6
  msgid ""
7
7
  msgstr ""
8
- "Project-Id-Version: foreman_tasks 9.2.2\n"
8
+ "Project-Id-Version: foreman-tasks 11.0.5\n"
9
9
  "Report-Msgid-Bugs-To: \n"
10
10
  "PO-Revision-Date: 2016-02-12 14:04+0000\n"
11
11
  "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
@@ -63,7 +63,7 @@ msgid "Action"
63
63
  msgstr "動作"
64
64
 
65
65
  msgid "Action with sub plans"
66
- msgstr "有子計畫的動作"
66
+ msgstr ""
67
67
 
68
68
  msgid "Active"
69
69
  msgstr "啟用中"
@@ -315,6 +315,9 @@ msgstr "初始化錯誤:%s"
315
315
  msgid "Input"
316
316
  msgstr "輸入"
317
317
 
318
+ msgid "Invalid URL"
319
+ msgstr ""
320
+
318
321
  msgid "Iteration limit"
319
322
  msgstr "重述限制"
320
323
 
@@ -1,7 +1,11 @@
1
- import React from 'react';
1
+ import React, { useState } from 'react';
2
2
  import { Grid, Row } from 'patternfly-react';
3
+ import PropTypes from 'prop-types';
3
4
  import TaskInfo from './TaskInfo';
4
- import { ForceUnlockModal, UnlockModal } from '../../TaskActions/UnlockModals';
5
+ import {
6
+ ForceUnlockConfirmationModal,
7
+ UnlockConfirmationModal,
8
+ } from '../../common/ClickConfirmation';
5
9
  import { TaskButtons } from './TaskButtons';
6
10
 
7
11
  const Task = props => {
@@ -25,13 +29,29 @@ const Task = props => {
25
29
  }
26
30
  unlockTaskRequest(id, action);
27
31
  };
32
+ const [unlockModalOpen, setUnlockModalOpen] = useState(false);
33
+ const [forceUnlockModalOpen, setForceUnlockModalOpen] = useState(false);
34
+
28
35
  return (
29
36
  <React.Fragment>
30
- <UnlockModal onClick={unlock} />
31
- <ForceUnlockModal onClick={forceUnlock} />
37
+ <UnlockConfirmationModal
38
+ onClick={unlock}
39
+ isOpen={unlockModalOpen}
40
+ setModalClosed={() => setUnlockModalOpen(false)}
41
+ />
42
+ <ForceUnlockConfirmationModal
43
+ onClick={forceUnlock}
44
+ isOpen={forceUnlockModalOpen}
45
+ setModalClosed={() => setForceUnlockModalOpen(false)}
46
+ />
32
47
  <Grid>
33
48
  <Row>
34
- <TaskButtons taskReloadStart={taskReloadStart} {...props} />
49
+ <TaskButtons
50
+ taskReloadStart={taskReloadStart}
51
+ setUnlockModalOpen={setUnlockModalOpen}
52
+ setForceUnlockModalOpen={setForceUnlockModalOpen}
53
+ {...props}
54
+ />
35
55
  </Row>
36
56
  <TaskInfo {...props} />
37
57
  </Grid>
@@ -40,13 +60,21 @@ const Task = props => {
40
60
  };
41
61
 
42
62
  Task.propTypes = {
43
- ...TaskInfo.PropTypes,
44
- ...TaskButtons.PropTypes,
63
+ taskReload: PropTypes.bool,
64
+ id: PropTypes.string,
65
+ forceCancelTaskRequest: PropTypes.func,
66
+ unlockTaskRequest: PropTypes.func,
67
+ action: PropTypes.string,
68
+ taskReloadStart: PropTypes.func,
45
69
  };
46
70
 
47
71
  Task.defaultProps = {
48
- ...TaskInfo.defaultProps,
49
- ...TaskButtons.defaultProps,
72
+ taskReload: false,
73
+ id: '',
74
+ forceCancelTaskRequest: () => null,
75
+ unlockTaskRequest: () => null,
76
+ action: '',
77
+ taskReloadStart: () => null,
50
78
  };
51
79
 
52
80
  export default Task;
@@ -1,12 +1,7 @@
1
1
  import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import { Col, Button } from 'patternfly-react';
4
- import { useForemanModal } from 'foremanReact/components/ForemanModal/ForemanModalHooks';
5
4
  import { translate as __ } from 'foremanReact/common/I18n';
6
- import {
7
- UNLOCK_MODAL,
8
- FORCE_UNLOCK_MODAL,
9
- } from '../../TaskActions/TaskActionsConstants';
10
5
 
11
6
  export const TaskButtons = ({
12
7
  canEdit,
@@ -24,13 +19,9 @@ export const TaskButtons = ({
24
19
  parentTask,
25
20
  cancelTaskRequest,
26
21
  resumeTaskRequest,
22
+ setUnlockModalOpen,
23
+ setForceUnlockModalOpen,
27
24
  }) => {
28
- const unlockModalActions = useForemanModal({
29
- id: UNLOCK_MODAL,
30
- });
31
- const forceUnlockModalActions = useForemanModal({
32
- id: FORCE_UNLOCK_MODAL,
33
- });
34
25
  const editActionsTitle = canEdit
35
26
  ? undefined
36
27
  : __('You do not have permission');
@@ -114,7 +105,9 @@ export const TaskButtons = ({
114
105
  className="unlock-button"
115
106
  bsSize="small"
116
107
  disabled={!canEdit || state !== 'paused'}
117
- onClick={unlockModalActions.setModalOpen}
108
+ onClick={() => {
109
+ setUnlockModalOpen(true);
110
+ }}
118
111
  title={editActionsTitle}
119
112
  data-original-title={editActionsTitle}
120
113
  >
@@ -124,7 +117,7 @@ export const TaskButtons = ({
124
117
  className="force-unlock-button"
125
118
  bsSize="small"
126
119
  disabled={!canEdit || state === 'stopped'}
127
- onClick={forceUnlockModalActions.setModalOpen}
120
+ onClick={() => setForceUnlockModalOpen(true)}
128
121
  title={editActionsTitle}
129
122
  data-original-title={editActionsTitle}
130
123
  >
@@ -134,7 +127,7 @@ export const TaskButtons = ({
134
127
  );
135
128
  };
136
129
 
137
- TaskButtons.propTypes = {
130
+ export const TaskButtonspropTypes = {
138
131
  canEdit: PropTypes.bool,
139
132
  dynflowEnableConsole: PropTypes.bool,
140
133
  taskReloadStart: PropTypes.func.isRequired,
@@ -151,8 +144,7 @@ TaskButtons.propTypes = {
151
144
  cancelTaskRequest: PropTypes.func,
152
145
  resumeTaskRequest: PropTypes.func,
153
146
  };
154
-
155
- TaskButtons.defaultProps = {
147
+ export const TaskButtonsdefaultProps = {
156
148
  canEdit: false,
157
149
  dynflowEnableConsole: false,
158
150
  taskReload: false,
@@ -166,3 +158,14 @@ TaskButtons.defaultProps = {
166
158
  cancelTaskRequest: () => null,
167
159
  resumeTaskRequest: () => null,
168
160
  };
161
+
162
+ TaskButtons.propTypes = {
163
+ ...TaskButtonspropTypes,
164
+ setUnlockModalOpen: PropTypes.func,
165
+ setForceUnlockModalOpen: PropTypes.func,
166
+ };
167
+ TaskButtons.defaultProps = {
168
+ setUnlockModalOpen: () => null,
169
+ setForceUnlockModalOpen: () => null,
170
+ ...TaskButtonsdefaultProps,
171
+ };
@@ -1,45 +1,160 @@
1
1
  import React from 'react';
2
- import {
3
- testComponentSnapshotsWithFixtures,
4
- mount,
5
- shallow,
6
- } from '@theforeman/test';
7
- import { useForemanModal } from 'foremanReact/components/ForemanModal/ForemanModalHooks';
2
+ import { render, screen, fireEvent } from '@testing-library/react';
3
+ import '@testing-library/jest-dom';
8
4
  import { STATUS } from 'foremanReact/constants';
9
5
  import { TaskButtons } from '../TaskButtons';
10
- import {
11
- UNLOCK_MODAL,
12
- FORCE_UNLOCK_MODAL,
13
- } from '../../../TaskActions/TaskActionsConstants';
14
-
15
- const fixtures = {
16
- 'render with minimal Props': {
17
- id: 'test',
18
- taskReloadStart: jest.fn(),
19
- taskProgressToggle: jest.fn(),
20
- },
21
- 'render with some Props': {
22
- id: 'test',
23
- state: 'paused',
24
- hasSubTasks: true,
25
- dynflowEnableConsole: true,
26
- parentTask: 'parent-id',
27
- taskReload: true,
28
- canEdit: true,
29
- status: STATUS.RESOLVED,
30
- taskReloadStart: jest.fn(),
31
- taskProgressToggle: jest.fn(),
32
- },
6
+
7
+ const setUnlockModalOpen = jest.fn();
8
+ const setForceUnlockModalOpen = jest.fn();
9
+
10
+ const defaultProps = {
11
+ id: 'test',
12
+ taskReloadStart: jest.fn(),
13
+ taskProgressToggle: jest.fn(),
14
+ cancelTaskRequest: jest.fn(),
15
+ resumeTaskRequest: jest.fn(),
16
+ setUnlockModalOpen,
17
+ setForceUnlockModalOpen,
33
18
  };
34
19
 
35
- describe('Task', () => {
36
- describe('rendering', () =>
37
- testComponentSnapshotsWithFixtures(TaskButtons, fixtures));
38
- describe('click test', () => {
39
- const setModalOpen = jest.fn();
40
- useForemanModal.mockImplementation(id => ({
41
- setModalOpen: () => setModalOpen(id),
42
- }));
20
+ describe('TaskButtons', () => {
21
+ beforeEach(() => {
22
+ jest.clearAllMocks();
23
+ });
24
+
25
+ describe('rendering', () => {
26
+ it('renders reload button with correct text when taskReload is false', () => {
27
+ render(<TaskButtons {...defaultProps} taskReload={false} />);
28
+ expect(
29
+ screen.getByRole('button', { name: /start auto-reloading/i })
30
+ ).toBeInTheDocument();
31
+ expect(
32
+ screen.queryByRole('button', { name: /stop auto-reloading/i })
33
+ ).not.toBeInTheDocument();
34
+ });
35
+
36
+ it('renders reload button with correct text when taskReload is true', () => {
37
+ render(<TaskButtons {...defaultProps} taskReload />);
38
+ expect(
39
+ screen.getByRole('button', { name: /stop auto-reloading/i })
40
+ ).toBeInTheDocument();
41
+ expect(
42
+ screen.queryByRole('button', { name: /start auto-reloading/i })
43
+ ).not.toBeInTheDocument();
44
+ });
45
+
46
+ it('renders dynflow console link with correct href when externalId is provided', () => {
47
+ render(<TaskButtons {...defaultProps} externalId="external-123" />);
48
+ const dynflowLink = screen.getByRole('link', {
49
+ name: /dynflow console/i,
50
+ });
51
+ expect(dynflowLink).toHaveAttribute(
52
+ 'href',
53
+ '/foreman_tasks/dynflow/external-123'
54
+ );
55
+ expect(dynflowLink).toHaveAttribute('target', '_blank');
56
+ expect(dynflowLink).toHaveAttribute('rel', 'noopener noreferrer');
57
+ });
58
+
59
+ it('disables dynflow console link when dynflowEnableConsole is false', () => {
60
+ render(<TaskButtons {...defaultProps} dynflowEnableConsole={false} />);
61
+ const dynflowLink = screen.getByRole('link', {
62
+ name: /dynflow console/i,
63
+ });
64
+ expect(dynflowLink).toHaveClass('disabled');
65
+ });
66
+
67
+ it('enables dynflow console link when dynflowEnableConsole is true', () => {
68
+ render(
69
+ <TaskButtons
70
+ {...defaultProps}
71
+ dynflowEnableConsole
72
+ externalId="external-123"
73
+ />
74
+ );
75
+ const dynflowLink = screen.getByRole('link', {
76
+ name: /dynflow console/i,
77
+ });
78
+ expect(dynflowLink).not.toHaveClass('disabled');
79
+ });
80
+
81
+ it('disables resume and cancel buttons when canEdit is false', () => {
82
+ render(<TaskButtons {...defaultProps} canEdit={false} />);
83
+ expect(screen.getByRole('button', { name: /resume/i })).toBeDisabled();
84
+ expect(screen.getByRole('button', { name: /cancel/i })).toBeDisabled();
85
+ });
86
+
87
+ it('disables resume button when resumable is false', () => {
88
+ render(<TaskButtons {...defaultProps} canEdit resumable={false} />);
89
+ expect(screen.getByRole('button', { name: /resume/i })).toBeDisabled();
90
+ });
91
+
92
+ it('disables cancel button when cancellable is false', () => {
93
+ render(<TaskButtons {...defaultProps} canEdit cancellable={false} />);
94
+ expect(screen.getByRole('button', { name: /cancel/i })).toBeDisabled();
95
+ });
96
+
97
+ it('disables unlock button when state is not paused', () => {
98
+ render(<TaskButtons {...defaultProps} canEdit state="running" />);
99
+ expect(screen.getByRole('button', { name: /^unlock$/i })).toBeDisabled();
100
+ });
101
+
102
+ it('enables unlock button when state is paused and canEdit is true', () => {
103
+ render(<TaskButtons {...defaultProps} canEdit state="paused" />);
104
+ expect(
105
+ screen.getByRole('button', { name: /^unlock$/i })
106
+ ).not.toBeDisabled();
107
+ });
108
+
109
+ it('disables force unlock button when state is stopped', () => {
110
+ render(<TaskButtons {...defaultProps} canEdit state="stopped" />);
111
+ expect(
112
+ screen.getByRole('button', { name: /force unlock/i })
113
+ ).toBeDisabled();
114
+ });
115
+
116
+ it('enables force unlock button when state is not stopped and canEdit is true', () => {
117
+ render(<TaskButtons {...defaultProps} canEdit state="running" />);
118
+ expect(
119
+ screen.getByRole('button', { name: /force unlock/i })
120
+ ).not.toBeDisabled();
121
+ });
122
+
123
+ it('renders parent task button when parentTask is provided', () => {
124
+ render(<TaskButtons {...defaultProps} parentTask="parent-123" />);
125
+ const parentButton = screen.getByRole('link', { name: /parent task/i });
126
+ expect(parentButton).toBeInTheDocument();
127
+ expect(parentButton).toHaveAttribute(
128
+ 'href',
129
+ '/foreman_tasks/tasks/parent-123'
130
+ );
131
+ });
132
+
133
+ it('does not render parent task button when parentTask is not provided', () => {
134
+ render(<TaskButtons {...defaultProps} />);
135
+ expect(
136
+ screen.queryByRole('link', { name: /parent task/i })
137
+ ).not.toBeInTheDocument();
138
+ });
139
+
140
+ it('renders sub tasks button when hasSubTasks is true', () => {
141
+ render(<TaskButtons {...defaultProps} hasSubTasks id="task-123" />);
142
+ const subTasksButton = screen.getByRole('link', { name: /sub tasks/i });
143
+ expect(subTasksButton).toBeInTheDocument();
144
+ expect(subTasksButton).toHaveAttribute(
145
+ 'href',
146
+ '/foreman_tasks/tasks/task-123/sub_tasks'
147
+ );
148
+ });
149
+
150
+ it('does not render sub tasks button when hasSubTasks is false', () => {
151
+ render(<TaskButtons {...defaultProps} hasSubTasks={false} />);
152
+ expect(
153
+ screen.queryByRole('link', { name: /sub tasks/i })
154
+ ).not.toBeInTheDocument();
155
+ });
156
+ });
157
+ describe('user interactions', () => {
43
158
  const cancelTaskRequest = jest.fn();
44
159
  const resumeTaskRequest = jest.fn();
45
160
  const taskProgressToggle = jest.fn();
@@ -47,6 +162,7 @@ describe('Task', () => {
47
162
  const id = 'some-id';
48
163
  const action = 'some-action';
49
164
  const props = {
165
+ ...defaultProps,
50
166
  taskReload: false,
51
167
  id,
52
168
  action,
@@ -55,41 +171,51 @@ describe('Task', () => {
55
171
  taskProgressToggle,
56
172
  taskReloadStart,
57
173
  status: STATUS.RESOLVED,
174
+ canEdit: true,
175
+ resumable: true,
176
+ cancellable: true,
177
+ state: 'paused',
58
178
  };
59
- afterEach(() => {
60
- jest.clearAllMocks();
61
- });
62
- it('reload', () => {
63
- const component = mount(<TaskButtons {...props} />);
64
- const reloadButton = component.find('.reload-button').at(0);
65
- reloadButton.simulate('click');
66
- expect(taskProgressToggle).toBeCalled();
67
- });
68
- it('resume', () => {
69
- const component = shallow(<TaskButtons {...props} />);
70
- const resumeButton = component.find('.resume-button').at(0);
71
- resumeButton.props().onClick();
72
- expect(taskReloadStart).toBeCalled();
73
- expect(resumeTaskRequest).toBeCalledWith(id, action);
74
- });
75
- it('cancel', () => {
76
- const component = shallow(<TaskButtons {...props} />);
77
- const cancelButton = component.find('.cancel-button').at(0);
78
- cancelButton.props().onClick();
79
- expect(taskReloadStart).toBeCalled();
80
- expect(cancelTaskRequest).toBeCalledWith(id, action);
81
- });
82
- it('unlock', () => {
83
- const component = shallow(<TaskButtons {...props} />);
84
- const unlockButton = component.find('.unlock-button').at(0);
85
- unlockButton.props().onClick();
86
- expect(setModalOpen).toBeCalledWith({ id: UNLOCK_MODAL });
87
- });
88
- it('focrce unlock', () => {
89
- const component = shallow(<TaskButtons {...props} />);
90
- const forceUnlockButton = component.find('.force-unlock-button').at(0);
91
- forceUnlockButton.props().onClick();
92
- expect(setModalOpen).toBeCalledWith({ id: FORCE_UNLOCK_MODAL });
179
+
180
+ it('calls taskProgressToggle when reload button is clicked', () => {
181
+ render(<TaskButtons {...props} />);
182
+ const reloadButton = screen.getByRole('button', {
183
+ name: /start auto-reloading/i,
184
+ });
185
+ fireEvent.click(reloadButton);
186
+ expect(taskProgressToggle).toHaveBeenCalled();
187
+ });
188
+
189
+ it('calls taskReloadStart and resumeTaskRequest when resume button is clicked', () => {
190
+ render(<TaskButtons {...props} />);
191
+ const resumeButton = screen.getByRole('button', { name: /resume/i });
192
+ fireEvent.click(resumeButton);
193
+ expect(taskReloadStart).toHaveBeenCalledWith(id);
194
+ expect(resumeTaskRequest).toHaveBeenCalledWith(id, action);
195
+ });
196
+
197
+ it('calls taskReloadStart and cancelTaskRequest when cancel button is clicked', () => {
198
+ render(<TaskButtons {...props} />);
199
+ const cancelButton = screen.getByRole('button', { name: /cancel/i });
200
+ fireEvent.click(cancelButton);
201
+ expect(taskReloadStart).toHaveBeenCalledWith(id);
202
+ expect(cancelTaskRequest).toHaveBeenCalledWith(id, action);
203
+ });
204
+
205
+ it('calls setUnlockModalOpen when unlock button is clicked', () => {
206
+ render(<TaskButtons {...props} />);
207
+ const unlockButton = screen.getByRole('button', { name: /^unlock$/i });
208
+ fireEvent.click(unlockButton);
209
+ expect(setUnlockModalOpen).toHaveBeenCalledWith(true);
210
+ });
211
+
212
+ it('calls setForceUnlockModalOpen when force unlock button is clicked', () => {
213
+ render(<TaskButtons {...props} />);
214
+ const forceUnlockButton = screen.getByRole('button', {
215
+ name: /force unlock/i,
216
+ });
217
+ fireEvent.click(forceUnlockButton);
218
+ expect(setForceUnlockModalOpen).toHaveBeenCalledWith(true);
93
219
  });
94
220
  });
95
221
  });