foreman_rh_cloud 14.1.2 → 14.1.3

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 (111) hide show
  1. checksums.yaml +4 -4
  2. data/lib/foreman_inventory_upload/generators/fact_helpers.rb +26 -4
  3. data/lib/foreman_inventory_upload.rb +8 -1
  4. data/lib/foreman_rh_cloud/version.rb +1 -1
  5. data/lib/foreman_rh_cloud.rb +36 -9
  6. data/lib/insights_cloud/async/insights_generate_notifications.rb +10 -1
  7. data/lib/inventory_sync/async/inventory_self_host_sync.rb +12 -2
  8. data/package.json +1 -1
  9. data/test/jobs/insights_generate_notifications_test.rb +26 -0
  10. data/test/jobs/inventory_self_host_sync_test.rb +9 -0
  11. data/test/unit/foreman_rh_cloud_self_host_test.rb +50 -2
  12. data/test/unit/metadata_generator_test.rb +24 -1
  13. data/webpack/ForemanInventoryUpload/Components/AccountList/Components/EmptyResults/__tests__/EmptyResults.test.js +10 -9
  14. data/webpack/ForemanInventoryUpload/Components/AccountList/Components/EmptyState/__tests__/EmptyState.test.js +13 -9
  15. data/webpack/ForemanInventoryUpload/Components/AccountList/Components/ErrorState/__tests__/ErrorState.test.js +20 -9
  16. data/webpack/ForemanInventoryUpload/Components/AccountList/Components/ListItem/__tests__/ListItem.test.js +31 -8
  17. data/webpack/ForemanInventoryUpload/Components/AccountList/Components/ListItemStatus/__tests__/ListItemStatus.test.js +26 -10
  18. data/webpack/ForemanInventoryUpload/Components/AccountList/__tests__/AccountList.test.js +33 -9
  19. data/webpack/ForemanInventoryUpload/Components/AccountList/__tests__/AccountListReducer.test.js +55 -35
  20. data/webpack/ForemanInventoryUpload/Components/FileDownload/__tests__/FileDownload.test.js +13 -9
  21. data/webpack/ForemanInventoryUpload/Components/InventoryFilter/__tests__/InventoryFilter.test.js +12 -15
  22. data/webpack/ForemanInventoryUpload/Components/InventoryFilter/__tests__/integration.test.js +32 -12
  23. data/webpack/ForemanInventoryUpload/Components/PageHeader/__tests__/PageTitle.test.js +14 -7
  24. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/CloudConnectorButton/__tests__/CloudConnectorButton.test.js +47 -18
  25. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SettingsWarning/SettingsWarning.test.js +58 -15
  26. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SyncButton/__tests__/SyncButton.test.js +23 -9
  27. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SyncButton/__tests__/SyncButtonSelectors.test.js +19 -17
  28. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SyncButton/__tests__/integrations.test.js +25 -37
  29. data/webpack/ForemanInventoryUpload/Components/ScheduledRun/__tests__/ScheduledRun.test.js +28 -8
  30. data/webpack/ForemanInventoryUpload/Components/StatusChart/__tests__/StatusChart.test.js +25 -8
  31. data/webpack/ForemanInventoryUpload/Components/TabContainer/__tests__/TabContainer.test.js +11 -9
  32. data/webpack/ForemanInventoryUpload/Components/TabFooter/__tests__/TabFooter.test.js +11 -9
  33. data/webpack/ForemanInventoryUpload/SubscriptionsPageExtension/InventoryAutoUpload/__tests__/InventoryAutoUpload.test.js +33 -12
  34. data/webpack/ForemanInventoryUpload/__tests__/ForemanInventoryHelpers.test.js +21 -8
  35. data/webpack/InsightsCloudSync/Components/InsightsSettings/__tests__/InsightsSettingsActions.test.js +61 -47
  36. data/webpack/InsightsCloudSync/Components/InsightsTable/__tests__/InsightsTable.test.js +48 -4
  37. data/webpack/InsightsCloudSync/Components/InsightsTable/__tests__/InsightsTableActions.test.js +126 -35
  38. data/webpack/InsightsCloudSync/Components/InsightsTable/__tests__/InsightsTableSelectors.test.js +90 -24
  39. data/webpack/InsightsCloudSync/InsightsCloudSync.test.js +79 -21
  40. data/webpack/InsightsCloudSync/__tests__/InsightsCloudSyncActions.test.js +31 -6
  41. data/webpack/InsightsHostDetailsTab/__tests__/InsightsTab.test.js +42 -9
  42. data/webpack/__tests__/ForemanRhCloudHelpers.test.js +91 -53
  43. data/webpack/common/Switcher/__tests__/HelpLabel.test.js +25 -10
  44. data/webpack/common/Switcher/__tests__/SwitcherPF4.test.js +41 -10
  45. metadata +3 -67
  46. data/webpack/ForemanInventoryUpload/Components/AccountList/Components/EmptyResults/__tests__/__snapshots__/EmptyResults.test.js.snap +0 -18
  47. data/webpack/ForemanInventoryUpload/Components/AccountList/Components/EmptyState/__tests__/__snapshots__/EmptyState.test.js.snap +0 -25
  48. data/webpack/ForemanInventoryUpload/Components/AccountList/Components/ErrorState/__tests__/__snapshots__/ErrorState.test.js.snap +0 -20
  49. data/webpack/ForemanInventoryUpload/Components/AccountList/Components/ListItem/__tests__/__snapshots__/ListItem.test.js.snap +0 -47
  50. data/webpack/ForemanInventoryUpload/Components/AccountList/Components/ListItemStatus/__tests__/__snapshots__/ListItemStatus.test.js.snap +0 -59
  51. data/webpack/ForemanInventoryUpload/Components/AccountList/__tests__/AccountListActions.test.js +0 -34
  52. data/webpack/ForemanInventoryUpload/Components/AccountList/__tests__/AccountListIntegration.test.js +0 -14
  53. data/webpack/ForemanInventoryUpload/Components/AccountList/__tests__/AccountListSelectors.test.js +0 -25
  54. data/webpack/ForemanInventoryUpload/Components/AccountList/__tests__/__snapshots__/AccountList.test.js.snap +0 -49
  55. data/webpack/ForemanInventoryUpload/Components/AccountList/__tests__/__snapshots__/AccountListActions.test.js.snap +0 -86
  56. data/webpack/ForemanInventoryUpload/Components/AccountList/__tests__/__snapshots__/AccountListReducer.test.js.snap +0 -75
  57. data/webpack/ForemanInventoryUpload/Components/AccountList/__tests__/__snapshots__/AccountListSelectors.test.js.snap +0 -46
  58. data/webpack/ForemanInventoryUpload/Components/FileDownload/__tests__/__snapshots__/FileDownload.test.js.snap +0 -26
  59. data/webpack/ForemanInventoryUpload/Components/InventoryFilter/__tests__/InventoryFilterActions.test.js +0 -14
  60. data/webpack/ForemanInventoryUpload/Components/InventoryFilter/__tests__/InventoryFilterReducer.test.js +0 -28
  61. data/webpack/ForemanInventoryUpload/Components/InventoryFilter/__tests__/InventoryFilterSelectors.test.js +0 -21
  62. data/webpack/ForemanInventoryUpload/Components/InventoryFilter/__tests__/__snapshots__/InventoryFilter.test.js.snap +0 -21
  63. data/webpack/ForemanInventoryUpload/Components/InventoryFilter/__tests__/__snapshots__/InventoryFilterActions.test.js.snap +0 -17
  64. data/webpack/ForemanInventoryUpload/Components/InventoryFilter/__tests__/__snapshots__/InventoryFilterReducer.test.js.snap +0 -19
  65. data/webpack/ForemanInventoryUpload/Components/InventoryFilter/__tests__/__snapshots__/InventoryFilterSelectors.test.js.snap +0 -9
  66. data/webpack/ForemanInventoryUpload/Components/InventoryFilter/__tests__/__snapshots__/integration.test.js.snap +0 -43
  67. data/webpack/ForemanInventoryUpload/Components/InventorySettings/AdvancedSetting/__tests__/AdvancedSettingActions.test.js +0 -9
  68. data/webpack/ForemanInventoryUpload/Components/InventorySettings/AdvancedSetting/__tests__/__snapshots__/AdvancedSettingActions.test.js.snap +0 -18
  69. data/webpack/ForemanInventoryUpload/Components/InventorySettings/__tests__/InventorySettingsActions.test.js +0 -14
  70. data/webpack/ForemanInventoryUpload/Components/InventorySettings/__tests__/__snapshots__/InventorySettingsActions.test.js.snap +0 -26
  71. data/webpack/ForemanInventoryUpload/Components/PageHeader/__tests__/__snapshots__/PageTitle.test.js.snap +0 -68
  72. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/CloudConnectorButton/__tests__/CloudConnectorActions.test.js +0 -9
  73. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/CloudConnectorButton/__tests__/__snapshots__/CloudConnectorActions.test.js.snap +0 -11
  74. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/CloudConnectorButton/__tests__/__snapshots__/CloudConnectorButton.test.js.snap +0 -59
  75. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SettingsWarning/__snapshots__/SettingsWarning.test.js.snap +0 -32
  76. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SyncButton/__tests__/__snapshots__/SyncButton.test.js.snap +0 -15
  77. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SyncButton/__tests__/__snapshots__/SyncButtonSelectors.test.js.snap +0 -3
  78. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SyncButton/__tests__/__snapshots__/integrations.test.js.snap +0 -58
  79. data/webpack/ForemanInventoryUpload/Components/ScheduledRun/__tests__/__snapshots__/ScheduledRun.test.js.snap +0 -23
  80. data/webpack/ForemanInventoryUpload/Components/StatusChart/__tests__/__snapshots__/StatusChart.test.js.snap +0 -74
  81. data/webpack/ForemanInventoryUpload/Components/TabContainer/__tests__/__snapshots__/TabContainer.test.js.snap +0 -18
  82. data/webpack/ForemanInventoryUpload/Components/TabFooter/__tests__/__snapshots__/TabFooter.test.js.snap +0 -12
  83. data/webpack/ForemanInventoryUpload/SubscriptionsPageExtension/InventoryAutoUpload/__tests__/__snapshots__/InventoryAutoUpload.test.js.snap +0 -96
  84. data/webpack/ForemanInventoryUpload/__tests__/ForemanInventoryUpload.test.js +0 -10
  85. data/webpack/ForemanInventoryUpload/__tests__/__snapshots__/ForemanInventoryHelpers.test.js.snap +0 -5
  86. data/webpack/ForemanInventoryUpload/__tests__/__snapshots__/ForemanInventoryUpload.test.js.snap +0 -14
  87. data/webpack/InsightsCloudSync/Components/InsightsSettings/__tests__/InsightsSettingsReducer.test.js +0 -33
  88. data/webpack/InsightsCloudSync/Components/InsightsSettings/__tests__/InsightsSettingsSelectors.test.js +0 -21
  89. data/webpack/InsightsCloudSync/Components/InsightsSettings/__tests__/__snapshots__/InsightsSettingsActions.test.js.snap +0 -65
  90. data/webpack/InsightsCloudSync/Components/InsightsSettings/__tests__/__snapshots__/InsightsSettingsReducer.test.js.snap +0 -19
  91. data/webpack/InsightsCloudSync/Components/InsightsSettings/__tests__/__snapshots__/InsightsSettingsSelectors.test.js.snap +0 -9
  92. data/webpack/InsightsCloudSync/Components/InsightsTable/__tests__/__snapshots__/InsightsTableActions.test.js.snap +0 -131
  93. data/webpack/InsightsCloudSync/Components/InsightsTable/__tests__/__snapshots__/InsightsTableSelectors.test.js.snap +0 -87
  94. data/webpack/InsightsCloudSync/__snapshots__/InsightsCloudSync.test.js.snap +0 -10
  95. data/webpack/InsightsCloudSync/__tests__/InsightsCloudSyncHelpers.test.js +0 -9
  96. data/webpack/InsightsCloudSync/__tests__/__snapshots__/InsightsCloudSyncActions.test.js.snap +0 -15
  97. data/webpack/InsightsCloudSync/__tests__/__snapshots__/InsightsCloudSyncHelpers.test.js.snap +0 -3
  98. data/webpack/InsightsHostDetailsTab/__tests__/InsightsTabActions.test.js +0 -19
  99. data/webpack/InsightsHostDetailsTab/__tests__/InsightsTabReducer.test.js +0 -26
  100. data/webpack/InsightsHostDetailsTab/__tests__/InsightsTabSelectors.test.js +0 -13
  101. data/webpack/InsightsHostDetailsTab/__tests__/__snapshots__/InsightsTab.test.js.snap +0 -34
  102. data/webpack/InsightsHostDetailsTab/__tests__/__snapshots__/InsightsTabActions.test.js.snap +0 -56
  103. data/webpack/InsightsHostDetailsTab/__tests__/__snapshots__/InsightsTabReducer.test.js.snap +0 -32
  104. data/webpack/InsightsHostDetailsTab/__tests__/__snapshots__/InsightsTabSelectors.test.js.snap +0 -18
  105. data/webpack/__tests__/ForemanRhCloudSelectors.test.js +0 -22
  106. data/webpack/__tests__/ForemanRhCloudTestHelpers.test.js +0 -20
  107. data/webpack/__tests__/__snapshots__/ForemanRhCloudHelpers.test.js.snap +0 -19
  108. data/webpack/__tests__/__snapshots__/ForemanRhCloudSelectors.test.js.snap +0 -25
  109. data/webpack/__tests__/__snapshots__/ForemanRhCloudTestHelpers.test.js.snap +0 -39
  110. data/webpack/common/Switcher/__tests__/__snapshots__/HelpLabel.test.js.snap +0 -16
  111. data/webpack/common/Switcher/__tests__/__snapshots__/SwitcherPF4.test.js.snap +0 -24
@@ -1,13 +1,15 @@
1
- import { testComponentSnapshotsWithFixtures } from '@theforeman/test';
2
-
1
+ import React from 'react';
2
+ import { render, screen } from '@testing-library/react';
3
3
  import TabFooter from '../TabFooter';
4
4
 
5
- const fixtures = {
6
- 'render without Props': {},
7
- /** fixtures, props for the component */
8
- };
9
-
10
5
  describe('TabFooter', () => {
11
- describe('rendering', () =>
12
- testComponentSnapshotsWithFixtures(TabFooter, fixtures));
6
+ it('renders children', () => {
7
+ render(<TabFooter><span>Footer content</span></TabFooter>);
8
+ expect(screen.getByText('Footer content')).toBeTruthy();
9
+ });
10
+
11
+ it('renders with the tab-footer class', () => {
12
+ const { container } = render(<TabFooter />);
13
+ expect(container.querySelector('.tab-footer')).toBeTruthy();
14
+ });
13
15
  });
@@ -1,17 +1,38 @@
1
- import { testComponentSnapshotsWithFixtures } from '@theforeman/test';
2
- import { noop } from 'foremanReact/common/helpers';
3
-
1
+ import React from 'react';
2
+ import { render, screen } from '@testing-library/react';
4
3
  import InventoryAutoUpload from '../InventoryAutoUpload';
5
4
 
6
- const fixtures = {
7
- 'render with props': {
8
- autoUploadEnabled: true,
9
- setSetting: noop,
10
- getSettings: noop,
11
- },
12
- };
5
+ jest.mock(
6
+ '../../../Components/InventorySettings/InventorySettings',
7
+ () => () => <div data-testid="inventory-settings">InventorySettings</div>
8
+ );
13
9
 
14
10
  describe('InventoryAutoUpload', () => {
15
- describe('rendering', () =>
16
- testComponentSnapshotsWithFixtures(InventoryAutoUpload, fixtures));
11
+ const buildProps = (overrides = {}) => ({
12
+ autoUploadEnabled: true,
13
+ setSetting: jest.fn(),
14
+ getSettings: jest.fn(),
15
+ ...overrides,
16
+ });
17
+
18
+ it('renders the heading', () => {
19
+ render(<InventoryAutoUpload {...buildProps()} />);
20
+ expect(screen.getByText('Red Hat Cloud Inventory')).toBeTruthy();
21
+ });
22
+
23
+ it('renders the auto upload switcher', () => {
24
+ render(<InventoryAutoUpload {...buildProps()} />);
25
+ expect(screen.getByText('Inventory Auto Upload')).toBeTruthy();
26
+ });
27
+
28
+ it('renders the advanced settings button', () => {
29
+ render(<InventoryAutoUpload {...buildProps()} />);
30
+ expect(screen.getByRole('button', { name: /Show Advanced Settings/ })).toBeTruthy();
31
+ });
32
+
33
+ it('calls getSettings on mount', () => {
34
+ const props = buildProps();
35
+ render(<InventoryAutoUpload {...props} />);
36
+ expect(props.getSettings).toHaveBeenCalled();
37
+ });
17
38
  });
@@ -1,10 +1,23 @@
1
- import { testSelectorsSnapshotWithFixtures } from '@theforeman/test';
2
- import { inventoryUrl, getInventoryDocsUrl } from '../ForemanInventoryHelpers';
1
+ import { isExitCodeLoading } from '../ForemanInventoryHelpers';
3
2
 
4
- const fixtures = {
5
- 'should return inventory Url': () => inventoryUrl('test_path'),
6
- 'should return inventory docs url': () => getInventoryDocsUrl(),
7
- };
3
+ describe('ForemanInventoryUpload helpers', () => {
4
+ describe('isExitCodeLoading', () => {
5
+ it('returns true when exit code contains "running"', () => {
6
+ expect(isExitCodeLoading('currently running')).toBe(true);
7
+ });
8
8
 
9
- describe('ForemanInventoryUpload helpers', () =>
10
- testSelectorsSnapshotWithFixtures(fixtures));
9
+ it('returns true when exit code contains "restarting"', () => {
10
+ expect(isExitCodeLoading('restarting now')).toBe(true);
11
+ });
12
+
13
+ it('is case-insensitive', () => {
14
+ expect(isExitCodeLoading('RUNNING')).toBe(true);
15
+ expect(isExitCodeLoading('Restarting')).toBe(true);
16
+ });
17
+
18
+ it('returns false when exit code contains neither', () => {
19
+ expect(isExitCodeLoading('exit 0')).toBe(false);
20
+ expect(isExitCodeLoading('completed')).toBe(false);
21
+ });
22
+ });
23
+ });
@@ -1,62 +1,76 @@
1
- import { testActionSnapshotWithFixtures } from '@theforeman/test';
2
1
  import { API } from 'foremanReact/redux/API';
3
2
  import {
4
3
  getInsightsSyncSettings,
5
4
  setInsightsSyncEnabled,
6
5
  } from '../InsightsSettingsActions';
7
- import { rhCloudStateWrapper } from '../../../../ForemanRhCloudTestHelpers';
8
-
9
- const serverMock = {
10
- data: { insightsSyncEnabled: true },
11
- };
6
+ import {
7
+ INSIGHTS_SYNC_SETTING_SET,
8
+ INSIGHTS_SYNC_SETTINGS_GET_SUCCESS,
9
+ } from '../InsightsSettingsConstants';
12
10
 
13
11
  jest.mock('foremanReact/redux/API');
14
- API.get.mockImplementation(() => serverMock);
15
- API.patch.mockImplementation(() => serverMock);
16
-
17
- const runWithGetState = (state, action, params) => dispatch => {
18
- const getState = () => rhCloudStateWrapper({ InsightsCloudSync: state });
19
- action(params)(dispatch, getState);
20
- };
21
-
22
- const fixtures = {
23
- 'should generate INSIGHTS_SYNC_SETTINGS_GET_SUCCESS action': () =>
24
- runWithGetState({ settings: {} }, getInsightsSyncSettings, {}),
25
- 'should handle getInsightsSyncSettings with error ': () => {
26
- API.get.mockImplementationOnce(() =>
27
- Promise.reject(new Error('Network error!'))
28
- );
29
- return runWithGetState({ settings: {} }, getInsightsSyncSettings, {});
30
- },
31
- 'should generate INSIGHTS_SYNC_SETTING_SET action': () =>
32
- runWithGetState(
33
- { settings: { insightsSyncEnabled: false } },
34
- setInsightsSyncEnabled,
35
- true
36
- ),
37
- 'should handle setInsightsSyncEnabled with error ': () => {
38
- API.patch.mockImplementationOnce(() =>
39
- Promise.reject(new Error('Network error!'))
40
- );
41
- return runWithGetState(
42
- { settings: { insightsSyncEnabled: false } },
43
- setInsightsSyncEnabled,
44
- true
45
- );
46
- },
47
- };
48
12
 
49
13
  describe('InsightsSettings actions', () => {
50
- const { location } = window;
14
+ let dispatch;
51
15
 
52
- beforeAll(() => {
53
- delete window.location;
54
- window.location = { href: jest.fn() };
16
+ beforeEach(() => {
17
+ dispatch = jest.fn();
18
+ jest.clearAllMocks();
55
19
  });
56
20
 
57
- afterAll(() => {
58
- window.location = location;
21
+ describe('getInsightsSyncSettings', () => {
22
+ it('dispatches success action with settings on success', async () => {
23
+ API.get.mockResolvedValue({ data: { insightsSyncEnabled: true } });
24
+
25
+ await getInsightsSyncSettings()(dispatch);
26
+
27
+ expect(API.get).toHaveBeenCalledWith('/insights_cloud/settings');
28
+ expect(dispatch).toHaveBeenCalledWith({
29
+ type: INSIGHTS_SYNC_SETTINGS_GET_SUCCESS,
30
+ payload: { settings: { insightsSyncEnabled: true } },
31
+ });
32
+ });
33
+
34
+ it('dispatches error toast on failure', async () => {
35
+ API.get.mockRejectedValue(new Error('Network error!'));
36
+
37
+ await getInsightsSyncSettings()(dispatch);
38
+
39
+ expect(dispatch).toHaveBeenCalledWith({
40
+ type: 'TOASTS_ADD',
41
+ payload: {
42
+ message: { sticky: true, type: 'error', message: 'Network error!' },
43
+ },
44
+ });
45
+ });
59
46
  });
60
47
 
61
- return testActionSnapshotWithFixtures(fixtures);
48
+ describe('setInsightsSyncEnabled', () => {
49
+ it('dispatches setting set action on success', async () => {
50
+ API.patch.mockResolvedValue({ data: { insightsSyncEnabled: true } });
51
+
52
+ await setInsightsSyncEnabled(true)(dispatch);
53
+
54
+ expect(API.patch).toHaveBeenCalledWith('/insights_cloud/settings', {
55
+ insightsSyncEnabled: true,
56
+ });
57
+ expect(dispatch).toHaveBeenCalledWith({
58
+ type: INSIGHTS_SYNC_SETTING_SET,
59
+ payload: { settings: { insightsSyncEnabled: true } },
60
+ });
61
+ });
62
+
63
+ it('dispatches error toast on failure', async () => {
64
+ API.patch.mockRejectedValue(new Error('Network error!'));
65
+
66
+ await setInsightsSyncEnabled(true)(dispatch);
67
+
68
+ expect(dispatch).toHaveBeenCalledWith({
69
+ type: 'TOASTS_ADD',
70
+ payload: {
71
+ message: { sticky: true, type: 'error', message: 'Network error!' },
72
+ },
73
+ });
74
+ });
75
+ });
62
76
  });
@@ -1,18 +1,62 @@
1
1
  import React from 'react';
2
- import { rtlHelpers } from 'foremanReact/common/rtlTestHelpers';
2
+ import { render, screen } from '@testing-library/react';
3
3
  import InsightsTable from '../InsightsTable';
4
4
  import { tableProps } from './fixtures';
5
5
 
6
6
  jest.mock('../../../../common/Hooks/ConfigHooks');
7
+ jest.mock('foremanReact/Root/Context/ForemanContext');
8
+ jest.mock('../Pagination', () => () => null);
7
9
 
8
- const { renderWithStore } = rtlHelpers;
10
+ const buildProps = (overrides = {}) => ({
11
+ ...tableProps,
12
+ fetchInsights: jest.fn(),
13
+ onTableSort: jest.fn(),
14
+ onTableSelect: jest.fn(),
15
+ selectAll: jest.fn(),
16
+ clearAllSelection: jest.fn(),
17
+ ...overrides,
18
+ });
9
19
 
10
20
  describe('InsightsTable', () => {
11
21
  afterEach(() => {
12
22
  jest.clearAllMocks();
13
23
  });
14
24
 
15
- it('renders without crashing', () => {
16
- renderWithStore(<InsightsTable {...tableProps} />);
25
+ it('calls fetchInsights on mount', () => {
26
+ const props = buildProps();
27
+ render(<InsightsTable {...props} />);
28
+
29
+ expect(props.fetchInsights).toHaveBeenCalledTimes(1);
30
+ expect(props.fetchInsights).toHaveBeenCalledWith(
31
+ expect.objectContaining({ page: 1, perPage: 5 })
32
+ );
33
+ });
34
+
35
+ it('renders table with correct aria-label', () => {
36
+ const props = buildProps();
37
+ render(<InsightsTable {...props} />);
38
+
39
+ expect(
40
+ screen.getByRole('grid', { name: /Recommendations Table/ })
41
+ ).toBeTruthy();
42
+ });
43
+
44
+ it('re-fetches when hostname changes', () => {
45
+ const props = buildProps({ hostname: 'host1.example.com' });
46
+ const { rerender } = render(<InsightsTable {...props} />);
47
+
48
+ props.fetchInsights.mockClear();
49
+ rerender(
50
+ <InsightsTable {...props} hostname="host2.example.com" />
51
+ );
52
+
53
+ expect(props.fetchInsights).toHaveBeenCalledTimes(1);
54
+ });
55
+
56
+ it('renders with empty hits', () => {
57
+ const props = buildProps({ hits: [], status: 'RESOLVED' });
58
+ const { container } = render(<InsightsTable {...props} />);
59
+
60
+ expect(container.querySelector('.rh-cloud-recommendations-table')).toBeTruthy();
17
61
  });
18
62
  });
@@ -1,5 +1,4 @@
1
- import { testActionSnapshotWithFixtures } from '@theforeman/test';
2
- import API from 'foremanReact/redux/API';
1
+ import { push } from 'connected-react-router';
3
2
  import {
4
3
  fetchInsights,
5
4
  setSelectAllAlert,
@@ -8,41 +7,133 @@ import {
8
7
  selectAll,
9
8
  clearAllSelection,
10
9
  } from '../InsightsTableActions';
11
- import { hits } from './fixtures';
10
+ import {
11
+ INSIGHTS_SET_SELECTED_IDS,
12
+ INSIGHTS_SET_SELECT_ALL_ALERT,
13
+ INSIGHTS_SET_SELECT_ALL,
14
+ INSIGHTS_HITS_API_KEY,
15
+ INSIGHTS_HITS_PATH,
16
+ } from '../InsightsTableConstants';
12
17
 
13
- jest.mock('foremanReact/redux/API', () => jest.fn());
14
- API.get = jest.fn(({ handleSuccess, ...action }) => {
15
- handleSuccess({ data: { hits } });
16
- return { type: 'get', ...action };
17
- });
18
+ jest.mock('connected-react-router', () => ({
19
+ push: jest.fn(args => ({ type: '@@router/CALL_HISTORY_METHOD', payload: args })),
20
+ }));
18
21
 
19
- const runWithGetState = (state, action, params) => dispatch => {
20
- const getState = () => ({
21
- router: {
22
- location: {
23
- query: {
24
- page: '1',
25
- per_page: '7',
26
- search: '',
27
- sort_by: '',
28
- sort_order: '',
29
- select_all: 'true',
30
- },
22
+ const buildGetState = (queryOverrides = {}) => () => ({
23
+ router: {
24
+ location: {
25
+ query: {
26
+ page: '1',
27
+ per_page: '7',
28
+ search: '',
29
+ sort_by: '',
30
+ sort_order: '',
31
+ select_all: 'false',
32
+ ...queryOverrides,
31
33
  },
32
34
  },
35
+ },
36
+ });
37
+
38
+ describe('InsightsTable actions', () => {
39
+ let dispatch;
40
+
41
+ beforeEach(() => {
42
+ dispatch = jest.fn();
43
+ jest.clearAllMocks();
44
+ });
45
+
46
+ describe('plain action creators', () => {
47
+ it('setSelectAllAlert returns correct action', () => {
48
+ expect(setSelectAllAlert(true)).toEqual({
49
+ type: INSIGHTS_SET_SELECT_ALL_ALERT,
50
+ payload: { showSelectAllAlert: true },
51
+ });
52
+ });
53
+
54
+ it('selectByIds returns correct action', () => {
55
+ const ids = { 1: true, 5: true };
56
+ expect(selectByIds(ids)).toEqual({
57
+ type: INSIGHTS_SET_SELECTED_IDS,
58
+ payload: { selectedIds: ids },
59
+ });
60
+ });
61
+ });
62
+
63
+ describe('setSelectAll', () => {
64
+ it('dispatches select all action and url update', () => {
65
+ setSelectAll(false)(dispatch);
66
+
67
+ const dispatched = dispatch.mock.calls.map(c => c[0]);
68
+ const selectAllAction = dispatched.find(
69
+ a => a && a.type === INSIGHTS_SET_SELECT_ALL
70
+ );
71
+ expect(selectAllAction).toBeTruthy();
72
+ expect(selectAllAction.payload).toEqual({ isAllSelected: false });
73
+ });
74
+ });
75
+
76
+ describe('selectAll', () => {
77
+ it('dispatches setSelectAll with true', () => {
78
+ selectAll()(dispatch);
79
+
80
+ const dispatched = dispatch.mock.calls.map(c => c[0]);
81
+ const selectAllAction = dispatched.find(
82
+ a => a && a.type === INSIGHTS_SET_SELECT_ALL
83
+ );
84
+ expect(selectAllAction).toBeTruthy();
85
+ expect(selectAllAction.payload).toEqual({ isAllSelected: true });
86
+ });
87
+ });
88
+
89
+ describe('clearAllSelection', () => {
90
+ it('dispatches reset ids, clear alert, and deselect all', () => {
91
+ clearAllSelection()(dispatch);
92
+
93
+ expect(dispatch).toHaveBeenCalledWith(
94
+ expect.objectContaining({
95
+ type: INSIGHTS_SET_SELECTED_IDS,
96
+ payload: { selectedIds: {} },
97
+ })
98
+ );
99
+ expect(dispatch).toHaveBeenCalledWith(
100
+ expect.objectContaining({
101
+ type: INSIGHTS_SET_SELECT_ALL_ALERT,
102
+ payload: { showSelectAllAlert: false },
103
+ })
104
+ );
105
+ });
33
106
  });
34
- action(params)(dispatch, getState);
35
- };
36
-
37
- const fixtures = {
38
- 'should fetchInsights': () =>
39
- runWithGetState({}, fetchInsights, { page: 2, perPage: 7 }),
40
- 'should setSelectAllAlert true': () => setSelectAllAlert(true),
41
- 'should selectByIds': () => selectByIds({ 1: true, 5: true }),
42
- 'should setSelectAll false': () => setSelectAll(false),
43
- 'should selectAll': () => selectAll(),
44
- 'should clearAllSelection': () => clearAllSelection(),
45
- };
46
-
47
- describe('insights table actions', () =>
48
- testActionSnapshotWithFixtures(fixtures));
107
+
108
+ describe('fetchInsights', () => {
109
+ it('dispatches url push and API get with correct params', () => {
110
+ const getState = buildGetState();
111
+
112
+ fetchInsights({ page: 2, perPage: 7 })(dispatch, getState);
113
+
114
+ expect(push).toHaveBeenCalled();
115
+
116
+ const apiAction = dispatch.mock.calls.find(
117
+ call => call[0] && call[0].key === INSIGHTS_HITS_API_KEY
118
+ );
119
+ expect(apiAction).toBeTruthy();
120
+ const getArg = apiAction[0];
121
+ expect(getArg.url).toBe(INSIGHTS_HITS_PATH);
122
+ expect(getArg.params.page).toBe(2);
123
+ expect(getArg.params.per_page).toBe(7);
124
+ });
125
+
126
+ it('clears select all alert when isSelectAll is false', () => {
127
+ const getState = buildGetState({ select_all: 'false' });
128
+
129
+ fetchInsights({})(dispatch, getState);
130
+
131
+ expect(dispatch).toHaveBeenCalledWith(
132
+ expect.objectContaining({
133
+ type: INSIGHTS_SET_SELECT_ALL_ALERT,
134
+ payload: { showSelectAllAlert: false },
135
+ })
136
+ );
137
+ });
138
+ });
139
+ });
@@ -1,4 +1,3 @@
1
- import { testSelectorsSnapshotWithFixtures } from '@theforeman/test';
2
1
  import { insightsStateWrapper } from '../../../../ForemanRhCloudTestHelpers';
3
2
  import { routerState, APIState, APIErrorState } from './fixtures';
4
3
  import {
@@ -24,33 +23,100 @@ const state = {
24
23
  ...APIState,
25
24
  ...insightsStateWrapper({
26
25
  table: {
27
- selectedIds: {
28
- '51': true,
29
- },
26
+ selectedIds: { '51': true },
30
27
  showSelectAllAlert: true,
31
28
  isAllSelected: false,
32
29
  },
33
30
  }),
34
31
  };
35
32
 
36
- const fixtures = {
37
- 'should return router query': () => selectQuery(state),
38
- 'should return router search': () => selectSearch(state),
39
- 'should return router page': () => selectPage(state),
40
- 'should return router perPage': () => selectPerPage(state),
41
- 'should return router sort by': () => selectSortBy(state),
42
- 'should return router sort order': () => selectSortOrder(state),
43
- 'should return queryParams': () => selectQueryParams(state),
44
- 'should return API status': () => selectStatus(state),
45
- 'should return API error': () => selectError({ ...state, ...APIErrorState }),
46
- 'should return API hits': () => selectHits(state),
47
- 'should return API item count': () => selectItemCount(state),
48
- 'should return insights table': () => selectInsightsCloudTable(state),
49
- 'should return insights selectedIds': () => selectSelectedIds(state),
50
- 'should return insights isAllSelected': () => selectIsAllSelected(state),
51
- 'should return insights showSelectAllAlert': () =>
52
- selectShowSelectAllAlert(state),
53
- };
33
+ describe('InsightsTable selectors', () => {
34
+ describe('router query selectors', () => {
35
+ it('selectQuery returns the query object', () => {
36
+ expect(selectQuery(state)).toEqual(routerState.router.location.query);
37
+ });
38
+
39
+ it('selectSearch returns URI-decoded search string', () => {
40
+ expect(selectSearch(state)).toBe('total_risk < 3');
41
+ });
42
+
43
+ it('selectPage returns the page as a number', () => {
44
+ expect(selectPage(state)).toBe(1);
45
+ });
46
+
47
+ it('selectPerPage returns per_page as a number', () => {
48
+ expect(selectPerPage(state)).toBe(7);
49
+ });
50
+
51
+ it('selectSortBy returns the sort_by value', () => {
52
+ expect(selectSortBy(state)).toBe('total_risk');
53
+ });
54
+
55
+ it('selectSortOrder returns the sort_order value', () => {
56
+ expect(selectSortOrder(state)).toBe('asc');
57
+ });
58
+
59
+ it('selectQueryParams returns aggregated params object', () => {
60
+ const params = selectQueryParams(state);
61
+ expect(params.page).toBe(1);
62
+ expect(params.perPage).toBe(7);
63
+ expect(params.query).toBe('total_risk < 3');
64
+ expect(params.sortBy).toBe('total_risk');
65
+ expect(params.sortOrder).toBe('asc');
66
+ });
67
+ });
68
+
69
+ describe('API selectors', () => {
70
+ it('selectStatus returns API status', () => {
71
+ expect(selectStatus(state)).toBe('RESOLVED');
72
+ });
73
+
74
+ it('selectError returns error message from error state', () => {
75
+ const errorState = { ...state, ...APIErrorState };
76
+ expect(selectError(errorState)).toBeTruthy();
77
+ });
78
+
79
+ it('selectHits returns hits when status is RESOLVED', () => {
80
+ expect(selectHits(state)).toHaveLength(2);
81
+ });
82
+
83
+ it('selectHits returns empty array when status is not RESOLVED', () => {
84
+ const pendingState = {
85
+ ...state,
86
+ API: {
87
+ INSIGHTS_HITS: {
88
+ ...state.API.INSIGHTS_HITS,
89
+ status: 'PENDING',
90
+ },
91
+ },
92
+ };
93
+ expect(selectHits(pendingState)).toEqual([]);
94
+ });
95
+
96
+ it('selectItemCount returns the item count', () => {
97
+ expect(selectItemCount(state)).toBe(2);
98
+ });
99
+ });
100
+
101
+ describe('table state selectors', () => {
102
+ it('selectInsightsCloudTable returns the table sub-state', () => {
103
+ expect(selectInsightsCloudTable(state)).toEqual({
104
+ selectedIds: { '51': true },
105
+ showSelectAllAlert: true,
106
+ isAllSelected: false,
107
+ });
108
+ });
109
+
110
+ it('selectSelectedIds returns selected IDs', () => {
111
+ expect(selectSelectedIds(state)).toEqual({ '51': true });
112
+ });
113
+
114
+ it('selectIsAllSelected returns false', () => {
115
+ expect(selectIsAllSelected(state)).toBe(false);
116
+ });
54
117
 
55
- describe('InsightsTable selectors', () =>
56
- testSelectorsSnapshotWithFixtures(fixtures));
118
+ it('selectShowSelectAllAlert returns true', () => {
119
+ expect(selectShowSelectAllAlert(state)).toBe(true);
120
+ });
121
+ });
122
+ });