foreman-tasks 1.0.0 → 1.1.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (165) hide show
  1. checksums.yaml +4 -4
  2. data/.eslintrc +2 -22
  3. data/.rubocop.yml +12 -12
  4. data/.rubocop_todo.yml +34 -116
  5. data/app/controllers/foreman_tasks/api/recurring_logics_controller.rb +20 -1
  6. data/app/controllers/foreman_tasks/api/tasks_controller.rb +38 -11
  7. data/app/controllers/foreman_tasks/concerns/hosts_controller_extension.rb +1 -1
  8. data/app/controllers/foreman_tasks/recurring_logics_controller.rb +19 -0
  9. data/app/helpers/foreman_tasks/foreman_tasks_helper.rb +1 -3
  10. data/app/lib/actions/helpers/humanizer.rb +1 -3
  11. data/app/lib/actions/proxy_action.rb +33 -12
  12. data/app/lib/foreman_tasks/concerns/polling_action_extensions.rb +12 -0
  13. data/app/models/foreman_tasks/concerns/action_triggering.rb +1 -1
  14. data/app/models/foreman_tasks/recurring_logic.rb +1 -0
  15. data/app/models/foreman_tasks/remote_task.rb +1 -0
  16. data/app/models/foreman_tasks/task.rb +4 -0
  17. data/app/models/foreman_tasks/task/dynflow_task.rb +1 -1
  18. data/app/models/foreman_tasks/task/search.rb +11 -1
  19. data/app/models/setting/foreman_tasks.rb +6 -1
  20. data/app/services/foreman_tasks/troubleshooting_help_generator.rb +0 -4
  21. data/app/services/ui_notifications/tasks/task_bulk_cancel.rb +36 -0
  22. data/app/services/ui_notifications/tasks/task_bulk_resume.rb +38 -0
  23. data/app/views/foreman_tasks/api/recurring_logics/base.json.rabl +2 -1
  24. data/app/views/foreman_tasks/api/tasks/details.json.rabl +1 -0
  25. data/app/views/foreman_tasks/api/tasks/show.json.rabl +1 -1
  26. data/app/views/foreman_tasks/recurring_logics/index.html.erb +30 -0
  27. data/app/views/foreman_tasks/tasks/show.html.erb +3 -0
  28. data/{.babelrc.js → babel.config.js} +0 -0
  29. data/config/routes.rb +7 -0
  30. data/db/migrate/20200611090846_add_task_lock_index_on_resource_type_and_task_id.rb +9 -0
  31. data/db/seeds.d/30-notification_blueprints.rb +14 -0
  32. data/foreman-tasks.gemspec +5 -6
  33. data/gemfile.d/foreman-tasks.rb +1 -0
  34. data/lib/foreman_tasks/dynflow/console_authorizer.rb +2 -2
  35. data/lib/foreman_tasks/engine.rb +17 -14
  36. data/lib/foreman_tasks/tasks/cleanup.rake +3 -3
  37. data/lib/foreman_tasks/tasks/dynflow.rake +6 -0
  38. data/lib/foreman_tasks/tasks/export_tasks.rake +3 -3
  39. data/lib/foreman_tasks/test_extensions.rb +1 -1
  40. data/lib/foreman_tasks/version.rb +1 -1
  41. data/locale/action_names.rb +1 -1
  42. data/package.json +18 -71
  43. data/script/rails +2 -2
  44. data/script/travis_run_js_tests.sh +2 -2
  45. data/test/controllers/api/tasks_controller_test.rb +9 -0
  46. data/test/factories/task_factory.rb +34 -2
  47. data/test/foreman_tasks_test_helper.rb +4 -0
  48. data/test/lib/concerns/polling_action_extensions_test.rb +34 -0
  49. data/test/unit/actions/action_with_sub_plans_test.rb +1 -1
  50. data/test/unit/task_test.rb +160 -74
  51. data/webpack/ForemanTasks/Components/TaskDetails/Components/Task.js +4 -0
  52. data/webpack/ForemanTasks/Components/TaskDetails/Components/TaskInfo.js +3 -12
  53. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/Errors.test.js +1 -1
  54. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/Locks.test.js +1 -1
  55. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/Raw.test.js +1 -1
  56. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/RunningSteps.test.js +1 -1
  57. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/Task.test.js +2 -1
  58. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/TaskInfo.test.js +1 -1
  59. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/__snapshots__/Task.test.js.snap +3 -1
  60. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/__snapshots__/TaskInfo.test.js.snap +3 -9
  61. data/webpack/ForemanTasks/Components/TaskDetails/TaskDetails.stories.js +6 -2
  62. data/webpack/ForemanTasks/Components/TaskDetails/TaskDetailsSelectors.js +4 -1
  63. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/TaskDetails.test.js +1 -1
  64. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/TaskDetailsActions.test.js +1 -1
  65. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/TaskDetailsReducer.test.js +1 -1
  66. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/__snapshots__/TaskDetails.test.js.snap +1 -0
  67. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/integration.test.js +1 -1
  68. data/webpack/ForemanTasks/Components/TaskDetails/index.js +2 -0
  69. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/PausedTasksCard/PausedTasksCard.stories.js +44 -40
  70. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/PausedTasksCard/PausedTasksCard.test.js +1 -1
  71. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/RunningTasksCard/RunningTasksCard.stories.js +45 -40
  72. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/RunningTasksCard/RunningTasksCard.test.js +1 -1
  73. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/ScheduledTasksCard/ScheduledTasksCard.stories.js +27 -22
  74. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/ScheduledTasksCard/ScheduledTasksCard.test.js +1 -1
  75. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/StoppedTasksCard/StoppedTasksCard.stories.js +61 -56
  76. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/StoppedTasksCard/StoppedTasksCard.test.js +1 -1
  77. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/TasksDonutCard/TasksDonutCard.stories.js +40 -35
  78. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/TasksDonutCard/TasksDonutCard.test.js +1 -1
  79. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/TasksDonutChart/TasksDonutChart.stories.js +21 -20
  80. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/TasksDonutChart/TasksDonutChart.test.js +1 -1
  81. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/TasksCardsGrid.stories.js +40 -39
  82. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/TasksCardsGrid.test.js +1 -1
  83. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksLabelsRow/TasksLabelsRow.stories.js +16 -17
  84. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksLabelsRow/TasksLabelsRow.test.js +1 -2
  85. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksTimeRow/Components/TimeDropDown/TimeDropDown.stories.mdx +57 -0
  86. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksTimeRow/Components/TimeDropDown/TimeDropDown.test.js +1 -1
  87. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksTimeRow/TasksTimeRow.stories.js +36 -18
  88. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksTimeRow/TasksTimeRow.test.js +1 -1
  89. data/webpack/ForemanTasks/Components/TasksDashboard/TasksDashboardConstants.js +5 -0
  90. data/webpack/ForemanTasks/Components/TasksDashboard/TasksDashboardHelper.js +3 -2
  91. data/webpack/ForemanTasks/Components/TasksDashboard/__tests__/TasksDashboard.test.js +1 -1
  92. data/webpack/ForemanTasks/Components/TasksDashboard/__tests__/TasksDashboardActions.test.js +1 -1
  93. data/webpack/ForemanTasks/Components/TasksDashboard/__tests__/TasksDashboardReducer.test.js +1 -1
  94. data/webpack/ForemanTasks/Components/TasksDashboard/__tests__/TasksDashboardSelectors.test.js +1 -1
  95. data/webpack/ForemanTasks/Components/TasksTable/Components/CancelConfirm.js +53 -0
  96. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmationModals.js +56 -0
  97. data/webpack/ForemanTasks/Components/TasksTable/Components/ResumeConfirm.js +52 -0
  98. data/webpack/ForemanTasks/Components/TasksTable/Components/SelectAllAlert.js +43 -0
  99. data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/ActionSelectButton.test.js +1 -1
  100. data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/CancelConfirm.test.js +26 -0
  101. data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/ConfirmationModals.test.js +24 -0
  102. data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/ResumeConfirm.test.js +26 -0
  103. data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/SelectAllAlert.test.js +29 -0
  104. data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/TableSelectionCell.test.js +1 -1
  105. data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/TableSelectionHeaderCell.test.js +1 -1
  106. data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/__snapshots__/CancelConfirm.test.js.snap +65 -0
  107. data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/__snapshots__/ConfirmationModals.test.js.snap +30 -0
  108. data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/__snapshots__/ResumeConfirm.test.js.snap +63 -0
  109. data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/__snapshots__/SelectAllAlert.test.js.snap +75 -0
  110. data/webpack/ForemanTasks/Components/TasksTable/SubTasksPage.js +4 -1
  111. data/webpack/ForemanTasks/Components/TasksTable/TasksBulkActions.js +164 -0
  112. data/webpack/ForemanTasks/Components/TasksTable/TasksTable.js +46 -22
  113. data/webpack/ForemanTasks/Components/TasksTable/TasksTableActionHelpers.js +52 -0
  114. data/webpack/ForemanTasks/Components/TasksTable/TasksTableActions.js +88 -87
  115. data/webpack/ForemanTasks/Components/TasksTable/TasksTableConstants.js +23 -9
  116. data/webpack/ForemanTasks/Components/TasksTable/TasksTableHelpers.js +4 -3
  117. data/webpack/ForemanTasks/Components/TasksTable/TasksTablePage.js +128 -31
  118. data/webpack/ForemanTasks/Components/TasksTable/TasksTableReducer.js +26 -9
  119. data/webpack/ForemanTasks/Components/TasksTable/TasksTableSelectors.js +24 -16
  120. data/webpack/ForemanTasks/Components/TasksTable/__tests__/SubTasksPage.test.js +1 -1
  121. data/webpack/ForemanTasks/Components/TasksTable/__tests__/TasksBulkActions.test.js +112 -0
  122. data/webpack/ForemanTasks/Components/TasksTable/__tests__/TasksIndexPage.test.js +1 -1
  123. data/webpack/ForemanTasks/Components/TasksTable/__tests__/TasksTable.fixtures.js +12 -5
  124. data/webpack/ForemanTasks/Components/TasksTable/__tests__/TasksTable.test.js +1 -1
  125. data/webpack/ForemanTasks/Components/TasksTable/__tests__/TasksTableActionHelpers.test.js +46 -0
  126. data/webpack/ForemanTasks/Components/TasksTable/__tests__/TasksTableActions.test.js +28 -52
  127. data/webpack/ForemanTasks/Components/TasksTable/__tests__/TasksTableHelpers.test.js +17 -1
  128. data/webpack/ForemanTasks/Components/TasksTable/__tests__/TasksTablePage.test.js +10 -2
  129. data/webpack/ForemanTasks/Components/TasksTable/__tests__/TasksTableReducer.test.js +28 -8
  130. data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/SubTasksPage.test.js.snap +15 -5
  131. data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/TasksBulkActions.test.js.snap +229 -0
  132. data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/TasksIndexPage.test.js.snap +14 -5
  133. data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/TasksTableActions.test.js.snap +56 -85
  134. data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/TasksTablePage.test.js.snap +158 -32
  135. data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/TasksTableReducer.test.js.snap +43 -16
  136. data/webpack/ForemanTasks/Components/TasksTable/formatters/__test__/selectionHeaderCellFormatter.test.js +1 -1
  137. data/webpack/ForemanTasks/Components/TasksTable/formatters/selectionHeaderCellFormatter.js +2 -2
  138. data/webpack/ForemanTasks/Components/TasksTable/index.js +11 -4
  139. data/webpack/ForemanTasks/Components/common/ActionButtons/ActionButton.js +4 -4
  140. data/webpack/ForemanTasks/Components/common/ActionButtons/ActionButton.test.js +1 -1
  141. data/webpack/ForemanTasks/Components/common/ActionButtons/CancelButton.test.js +1 -2
  142. data/webpack/ForemanTasks/Components/common/ActionButtons/ResumeButton.test.js +2 -2
  143. data/webpack/ForemanTasks/Components/common/ActionButtons/__snapshots__/ActionButton.test.js.snap +3 -3
  144. data/webpack/ForemanTasks/Components/common/ToastTypesConstants.js +11 -0
  145. data/webpack/ForemanTasks/ForemanTasks.test.js +1 -1
  146. data/webpack/ForemanTasks/Routes/ForemanTasksRouter.test.js +1 -1
  147. data/webpack/ForemanTasks/Routes/ForemanTasksRoutes.test.js +2 -3
  148. data/webpack/ForemanTasks/Routes/ShowTask/__tests__/ShowTask.test.js +1 -1
  149. data/webpack/__mocks__/foremanReact/components/ForemanModal/ForemanModalActions.js +2 -0
  150. data/webpack/__mocks__/foremanReact/components/ForemanModal/ForemanModalHooks.js +10 -0
  151. data/webpack/__mocks__/foremanReact/components/ForemanModal/index.js +4 -0
  152. metadata +55 -24
  153. data/.storybook/addons.js +0 -2
  154. data/.storybook/config.js +0 -7
  155. data/.storybook/webpack.config.js +0 -84
  156. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksTimeRow/Components/TimeDropDown/TimeDropDown.stories.js +0 -23
  157. data/webpack/ForemanTasks/Components/TasksTable/Components/ActionConfirmation.js +0 -49
  158. data/webpack/ForemanTasks/Components/TasksTable/Components/CancelResumeConfirm.js +0 -51
  159. data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/ActionConfirmation.test.js +0 -18
  160. data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/CancelResumeConfirm.test.js +0 -28
  161. data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/__snapshots__/ActionConfirmation.test.js.snap +0 -89
  162. data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/__snapshots__/CancelResumeConfirm.test.js.snap +0 -37
  163. data/webpack/stories/index.js +0 -10
  164. data/webpack/stories/index.scss +0 -7
  165. data/webpack/test_setup.js +0 -7
@@ -8,21 +8,23 @@ import {
8
8
  SELECT_ROWS,
9
9
  UNSELECT_ROWS,
10
10
  UNSELECT_ALL_ROWS,
11
- TASKS_TABLE_SELECTED_MODAL,
12
- CLOSED,
11
+ UPDATE_CLICKED,
12
+ SELECT_ALL_ROWS,
13
+ OPEN_SELECT_ALL,
13
14
  } from './TasksTableConstants';
14
15
 
15
16
  const initialState = Immutable({
16
17
  selectedRows: [],
17
- modalStatus: CLOSED,
18
18
  });
19
19
 
20
20
  export const TasksTableQueryReducer = (state = initialState, action) => {
21
- const { type, payload } = action;
21
+ const { type, payload, response } = action;
22
22
  const { subtotal, page, per_page: perPageString, action_name: actionName } =
23
- payload || {};
23
+ response || {};
24
24
  const ACTION_TYPES = createTableActionTypes(TASKS_TABLE_ID);
25
25
  switch (type) {
26
+ case SELECT_ALL_ROWS:
27
+ return state.set('allRowsSelected', true);
26
28
  case ACTION_TYPES.SUCCESS:
27
29
  return Immutable.merge(state, {
28
30
  itemCount: subtotal,
@@ -35,15 +37,30 @@ export const TasksTableQueryReducer = (state = initialState, action) => {
35
37
  });
36
38
  case SELECT_ROWS:
37
39
  return state.set('selectedRows', union(payload, state.selectedRows));
40
+ case OPEN_SELECT_ALL:
41
+ return state.set('showSelectAll', true);
38
42
  case UNSELECT_ROWS:
43
+ if (state.allRowsSelected) {
44
+ // User can unselect rows if only the page rows are selected
45
+ return state
46
+ .set(
47
+ 'selectedRows',
48
+ payload.results.map(row => row.id).filter(row => row !== payload.id)
49
+ )
50
+ .set('allRowsSelected', false)
51
+ .set('showSelectAll', false);
52
+ }
39
53
  return state.set(
40
54
  'selectedRows',
41
- state.selectedRows.filter(row => row !== payload)
55
+ state.selectedRows.filter(row => row !== payload.id)
42
56
  );
43
57
  case UNSELECT_ALL_ROWS:
44
- return state.set('selectedRows', []);
45
- case TASKS_TABLE_SELECTED_MODAL:
46
- return state.set('modalStatus', payload);
58
+ return state
59
+ .set('selectedRows', [])
60
+ .set('allRowsSelected', false)
61
+ .set('showSelectAll', false);
62
+ case UPDATE_CLICKED:
63
+ return state.set('clicked', payload.clicked);
47
64
  default:
48
65
  return state;
49
66
  }
@@ -1,7 +1,7 @@
1
+ import { createSelector } from 'reselect';
1
2
  import { translate as __ } from 'foremanReact/common/I18n';
2
3
  import { selectForemanTasks } from '../../ForemanTasksSelectors';
3
4
  import { getDuration } from './TasksTableHelpers';
4
- import { CLOSED } from './TasksTableConstants';
5
5
 
6
6
  export const selectTasksTable = state =>
7
7
  selectForemanTasks(state).tasksTable || {};
@@ -24,21 +24,23 @@ export const selectActionName = state =>
24
24
  export const selectSelectedRows = state =>
25
25
  selectTasksTableQuery(state).selectedRows || [];
26
26
 
27
- export const selectModalStatus = state =>
28
- selectTasksTableQuery(state).modalStatus || CLOSED;
29
-
30
- export const selectResults = state => {
31
- const { results } = selectTasksTableContent(state);
32
- if (!results) return [];
33
- return results.map(result => ({
34
- ...result,
35
- action: result.action || result.label.replace(/::/g, ' '),
36
- username: result.username || '',
37
- state: result.state + (result.frozen ? ` ${__('Disabled')}` : ''),
38
- duration: getDuration(result.started_at, result.ended_at),
39
- availableActions: result.available_actions,
40
- }));
41
- };
27
+ export const selectClicked = state =>
28
+ selectTasksTableQuery(state).clicked || {};
29
+
30
+ export const selectResults = createSelector(
31
+ selectTasksTableContent,
32
+ ({ results }) =>
33
+ results.map(result => ({
34
+ ...result,
35
+ action:
36
+ result.action ||
37
+ (result.label ? result.label.replace(/::/g, ' ') : result.id),
38
+ username: result.username || '',
39
+ state: result.state + (result.frozen ? ` ${__('Disabled')}` : ''),
40
+ duration: getDuration(result.started_at, result.ended_at),
41
+ availableActions: result.available_actions,
42
+ }))
43
+ );
42
44
 
43
45
  export const selectStatus = state => selectTasksTableContent(state).status;
44
46
 
@@ -46,3 +48,9 @@ export const selectError = state => selectTasksTableContent(state).error;
46
48
 
47
49
  export const selectSort = state =>
48
50
  selectTasksTableQuery(state).sort || { by: 'started_at', order: 'DESC' };
51
+
52
+ export const selectAllRowsSelected = state =>
53
+ selectTasksTableQuery(state).allRowsSelected;
54
+
55
+ export const selectShowSelectAll = state =>
56
+ selectTasksTableQuery(state).showSelectAll;
@@ -1,4 +1,4 @@
1
- import { testComponentSnapshotsWithFixtures } from 'react-redux-test-utils';
1
+ import { testComponentSnapshotsWithFixtures } from '@theforeman/test';
2
2
  import { SubTasksPage } from '../SubTasksPage';
3
3
  import { minProps } from './TasksTable.fixtures';
4
4
 
@@ -0,0 +1,112 @@
1
+ import { testActionSnapshotWithFixtures } from '@theforeman/test';
2
+ import API from 'foremanReact/API';
3
+ import {
4
+ bulkCancelById,
5
+ bulkCancelBySearch,
6
+ bulkResumeById,
7
+ bulkResumeBySearch,
8
+ } from '../TasksBulkActions';
9
+
10
+ jest.mock('foremanReact/components/common/table', () => ({
11
+ getTableItemsAction: jest.fn(controller => controller),
12
+ }));
13
+
14
+ jest.mock('foremanReact/API');
15
+
16
+ const task = {
17
+ id: 'some-id',
18
+ name: 'some-name',
19
+ };
20
+
21
+ const fixtures = {
22
+ 'handles bulkResumeById requests that fail': () => {
23
+ const selected = [{ ...task, isResumable: true }];
24
+
25
+ API.post.mockImplementation(() =>
26
+ Promise.reject(new Error('Network Error'))
27
+ );
28
+ return bulkResumeById({ selected, url: 'some-url' });
29
+ },
30
+ 'handles resumable bulkResumeById requests': () => {
31
+ const selected = [{ ...task, isResumable: true }];
32
+
33
+ API.post.mockImplementation(() => ({
34
+ data: {
35
+ resumed: [{ action: 'I am resumed' }],
36
+ failed: [{ action: 'I am failed' }],
37
+ },
38
+ }));
39
+ return bulkResumeById({ selected, url: 'some-url' });
40
+ },
41
+ 'handles bulkCancelById requests': () => {
42
+ const selected = [{ ...task, isCancellable: true }];
43
+
44
+ API.post.mockImplementation(() => ({
45
+ data: {
46
+ cancelled: [{ action: 'I am cancelled' }],
47
+ },
48
+ }));
49
+ return bulkCancelById({ selected, url: 'some-url' });
50
+ },
51
+ 'handles skipped bulkResumeById requests': () => {
52
+ const selected = [{ ...task, isResumable: true }];
53
+
54
+ API.post.mockImplementation(() => ({
55
+ data: {
56
+ skipped: [{ action: 'I am skipped' }],
57
+ },
58
+ }));
59
+ return bulkResumeById({ selected, url: 'some-url' });
60
+ },
61
+ 'handles skipped bulkCancelById requests': () => {
62
+ const selected = [{ ...task, isCancellable: true }];
63
+
64
+ API.post.mockImplementation(() => ({
65
+ data: {
66
+ skipped: [{ action: 'I am skipped' }],
67
+ },
68
+ }));
69
+ return bulkCancelById({ selected, url: 'some-url' });
70
+ },
71
+ 'handles bulkCancelById requests that are not cancellable': () => {
72
+ const selected = [{ ...task, isCancellable: false }];
73
+ return bulkCancelById({ selected, url: 'some-url' });
74
+ },
75
+ 'handles bulkResumeById requests that are not resumable': () => {
76
+ const selected = [{ ...task, isResumable: false, isCancellable: false }];
77
+ return bulkResumeById({ selected, url: 'some-url' });
78
+ },
79
+
80
+ 'handles bulkCancelBySearch requests': () => {
81
+ API.post.mockImplementation(() => ({
82
+ data: {
83
+ cancelled: [{ action: 'I am cancelled' }],
84
+ skipped: [{ action: 'I am skipped' }],
85
+ },
86
+ }));
87
+ return bulkCancelBySearch({
88
+ query: { search: {} },
89
+ url: 'some-url',
90
+ parentTaskID: 'parent',
91
+ });
92
+ },
93
+
94
+ 'handles bulkResumeBySearch requests': () => {
95
+ API.post.mockImplementation(() => ({
96
+ data: {
97
+ cancelled: [{ action: 'I am cancelled' }],
98
+ skipped: [{ action: 'I am skipped' }],
99
+ failed: [{ action: 'I am failed' }],
100
+ },
101
+ }));
102
+ return bulkResumeBySearch({
103
+ query: { search: {} },
104
+ url: 'some-url',
105
+ parentTaskID: 'parent',
106
+ });
107
+ },
108
+ };
109
+
110
+ describe('TasksTable bulk actions', () => {
111
+ testActionSnapshotWithFixtures(fixtures);
112
+ });
@@ -1,4 +1,4 @@
1
- import { testComponentSnapshotsWithFixtures } from 'react-redux-test-utils';
1
+ import { testComponentSnapshotsWithFixtures } from '@theforeman/test';
2
2
  import { TasksIndexPage } from '../TasksIndexPage';
3
3
  import { minProps } from './TasksTable.fixtures';
4
4
 
@@ -6,7 +6,11 @@ export const minProps = {
6
6
  itemCount: 2,
7
7
  cancelTask: jest.fn(),
8
8
  resumeTask: jest.fn(),
9
- actionSelected: jest.fn(),
9
+ bulkResumeById: jest.fn(),
10
+ bulkCancelById: jest.fn(),
11
+ bulkResumeBySearch: jest.fn(),
12
+ bulkCancelBySearch: jest.fn(),
13
+ selectPage: jest.fn(),
10
14
  selectAllRows: jest.fn(),
11
15
  unselectAllRows: jest.fn(),
12
16
  selectRow: jest.fn(),
@@ -17,15 +21,18 @@ export const minProps = {
17
21
  perPage: 10,
18
22
  },
19
23
  history: { location: { search: '' } },
20
- status: STATUS.RESOLVED,
21
24
  results: ['a', 'b'],
22
25
  sort: {
23
26
  by: 'q',
24
27
  order: 'w',
25
28
  },
26
- showResumeSelcetedModal: jest.fn(),
27
- showCancelSelcetedModal: jest.fn(),
28
- hideSelcetedModal: jest.fn(),
29
+ openClickedModal: jest.fn(),
30
+ modalProps: {
31
+ cancelSelectedModal: {},
32
+ resumeSelectedModal: {},
33
+ cancelModal: {},
34
+ resumeModal: {},
35
+ },
29
36
  };
30
37
 
31
38
  export default {
@@ -1,4 +1,4 @@
1
- import { testComponentSnapshotsWithFixtures } from 'react-redux-test-utils';
1
+ import { testComponentSnapshotsWithFixtures } from '@theforeman/test';
2
2
  import TasksTable from '../TasksTable';
3
3
  import fixtures from './TasksTable.fixtures';
4
4
 
@@ -0,0 +1,46 @@
1
+ import { convertDashboardQuery } from '../TasksTableActionHelpers';
2
+ import {
3
+ TASKS_DASHBOARD_JS_QUERY_MODES,
4
+ TASKS_DASHBOARD_AVAILABLE_TIMES,
5
+ } from '../../TasksDashboard/TasksDashboardConstants';
6
+
7
+ let realDate;
8
+
9
+ describe('convertDashboardQuery', () => {
10
+ it('convertDashboardQuery should work with full query', () => {
11
+ // Setup
12
+ const currentDate = new Date('2020-05-08T11:01:58.135Z');
13
+ realDate = Date;
14
+ global.Date = class extends Date {
15
+ constructor(date) {
16
+ if (date) {
17
+ // eslint-disable-next-line constructor-super
18
+ return super(date);
19
+ }
20
+ return currentDate;
21
+ }
22
+ };
23
+ const query = {
24
+ time_mode: TASKS_DASHBOARD_JS_QUERY_MODES.RECENT,
25
+ time_horizon: TASKS_DASHBOARD_AVAILABLE_TIMES.WEEK,
26
+ state: 'stopped',
27
+ result: 'error',
28
+ search: 'action~job',
29
+ };
30
+ expect(convertDashboardQuery(query)).toEqual(
31
+ 'state=stopped and result=error and action~job and (state_updated_at>2020-05-01T11:01:58.135Z or state_updated_at = NULL)'
32
+ );
33
+ // Cleanup
34
+ global.Date = realDate;
35
+ });
36
+ it('convertDashboardQuery should work with only search query', () => {
37
+ const query = {
38
+ search: 'action~job',
39
+ };
40
+ expect(convertDashboardQuery(query)).toEqual('action~job');
41
+ });
42
+ it('convertDashboardQuery should work with no query', () => {
43
+ const query = {};
44
+ expect(convertDashboardQuery(query)).toEqual('');
45
+ });
46
+ });
@@ -1,13 +1,16 @@
1
- import { testActionSnapshotWithFixtures } from 'react-redux-test-utils';
1
+ import {
2
+ testActionSnapshotWithFixtures,
3
+ IntegrationTestHelper,
4
+ } from '@theforeman/test';
2
5
  import API from 'foremanReact/API';
3
- import { TASKS_TABLE_ID, CANCEL, RESUME } from '../TasksTableConstants';
6
+ import { TASKS_TABLE_ID } from '../TasksTableConstants';
4
7
  import {
5
8
  getTableItems,
6
9
  cancelTask,
7
10
  cancelTaskRequest,
8
11
  resumeTask,
9
12
  resumeTaskRequest,
10
- actionSelected,
13
+ selectPage,
11
14
  } from '../TasksTableActions';
12
15
 
13
16
  jest.mock('foremanReact/components/common/table', () => ({
@@ -18,10 +21,14 @@ jest.mock('foremanReact/API');
18
21
 
19
22
  API.post.mockImplementation(() => ({ data: 'some-data' }));
20
23
 
24
+ const taskInfo = {
25
+ taskId: 'some-id',
26
+ taskName: 'some-name',
27
+ };
28
+
21
29
  const fixtures = {
22
- 'should cancelTask': () => cancelTask('some-id', 'some-name', 'some-url'),
23
30
  'should cancelTaskRequest and succeed': () =>
24
- cancelTaskRequest('some-id', 'some-name', 'some-url'),
31
+ cancelTaskRequest('some-id', 'some-name'),
25
32
  'should cancelTaskRequest and fail': () => {
26
33
  API.post.mockImplementation(() =>
27
34
  Promise.reject(new Error('Network Error'))
@@ -29,65 +36,34 @@ const fixtures = {
29
36
  return cancelTaskRequest('some-id', 'some-name');
30
37
  },
31
38
 
32
- 'should resumeTask': () => resumeTask('some-id', 'some-name', 'some-url'),
33
39
  'should resumeTaskRequest and succeed': () => {
34
40
  API.post.mockImplementation(() => ({ data: 'some-data' }));
35
- return resumeTaskRequest('some-id', 'some-name', 'some-url');
41
+ return resumeTaskRequest('some-id', 'some-name');
36
42
  },
37
43
  'should resumeTaskRequest and fail': () => {
38
44
  API.post.mockImplementation(() =>
39
45
  Promise.reject(new Error('Network Error'))
40
46
  );
41
- return resumeTaskRequest('some-id', 'some-name', 'some-url');
42
- },
43
- 'should actionSelected CANCEL not cancelleble': () => {
44
- const selected = [
45
- {
46
- id: '',
47
- name: '',
48
- isResumeble: false,
49
- isCancelleble: false,
50
- },
51
- ];
52
- return actionSelected(CANCEL, selected, 'some-url');
53
- },
54
- 'should actionSelected CANCEL cancelleble': () => {
55
- const selected = [
56
- {
57
- id: '',
58
- name: '',
59
- isResumeble: false,
60
- isCancelleble: true,
61
- },
62
- ];
63
- return actionSelected(CANCEL, selected, 'some-url');
64
- },
65
- 'should actionSelected RESUME not resumable': () => {
66
- const selected = [
67
- {
68
- id: '',
69
- name: '',
70
- isResumeble: false,
71
- isCancelleble: false,
72
- },
73
- ];
74
- return actionSelected(RESUME, selected, 'some-url');
75
- },
76
- 'should actionSelected RESUME resumable': () => {
77
- const selected = [
78
- {
79
- id: '',
80
- name: '',
81
- isResumeble: true,
82
- isCancelleble: false,
83
- },
84
- ];
85
- return actionSelected(RESUME, selected, 'some-url');
47
+ return resumeTaskRequest('some-id', 'some-name');
86
48
  },
49
+ 'should selectPage and succeed': () => selectPage([{ id: 'some-id' }]),
87
50
  };
88
51
  describe('TasksTable actions', () => {
89
52
  it('getTableItems should reuse common/table/getTableItemsAction', () => {
90
53
  expect(getTableItems('')).toEqual(TASKS_TABLE_ID);
91
54
  });
55
+
56
+ it('should resumeTask', async () => {
57
+ const dispatch = jest.fn();
58
+ resumeTask({ ...taskInfo, url: 'some-url' })(dispatch);
59
+ await IntegrationTestHelper.flushAllPromises();
60
+ expect(dispatch.mock.calls).toHaveLength(3);
61
+ });
62
+ it('should cancelTask', async () => {
63
+ const dispatch = jest.fn();
64
+ cancelTask({ ...taskInfo, url: 'some-url' })(dispatch);
65
+ await IntegrationTestHelper.flushAllPromises();
66
+ expect(dispatch.mock.calls).toHaveLength(3);
67
+ });
92
68
  testActionSnapshotWithFixtures(fixtures);
93
69
  });