foreman_puppet 11.0.0 → 11.1.0

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 (34) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/concerns/foreman_puppet/extensions/hosts_controller_extensions.rb +1 -1
  3. data/app/controllers/foreman_puppet/api/v2/hosts_bulk_actions_controller.rb +75 -1
  4. data/app/services/concerns/foreman_puppet/extensions/bulk_hosts_manager.rb +18 -0
  5. data/config/api_routes.rb +1 -0
  6. data/db/seeds.d/111_puppet_proxy_feature.rb +1 -1
  7. data/lib/foreman_puppet/register.rb +1 -0
  8. data/lib/foreman_puppet/version.rb +1 -1
  9. data/test/controllers/foreman_puppet/api/v2/hosts_bulk_actions_controller_test.rb +93 -0
  10. data/test/services/foreman_puppet/bulk_hosts_manager_test.rb +45 -0
  11. data/webpack/__mocks__/foremanReact/redux/API/index.js +8 -0
  12. data/webpack/global_index.js +18 -1
  13. data/webpack/src/Extends/Hosts/ActionsBar/index.js +20 -0
  14. data/webpack/src/Extends/Hosts/BulkActions/BulkChangeProxyCommon/__tests__/actions.test.js +0 -7
  15. data/webpack/src/Extends/Hosts/BulkActions/BulkChangePuppetEnvironment/BulkChangePuppetEnvironmentModal.js +239 -0
  16. data/webpack/src/Extends/Hosts/BulkActions/BulkChangePuppetEnvironment/__tests__/BulkChangePuppetEnvironmentModal.test.js +155 -0
  17. data/webpack/src/Extends/Hosts/BulkActions/BulkChangePuppetEnvironment/__tests__/actions.test.js +49 -0
  18. data/webpack/src/Extends/Hosts/BulkActions/BulkChangePuppetEnvironment/__tests__/index.test.js +66 -0
  19. data/webpack/src/Extends/Hosts/BulkActions/BulkChangePuppetEnvironment/actions.js +37 -0
  20. data/webpack/src/Extends/Hosts/BulkActions/BulkChangePuppetEnvironment/index.js +30 -0
  21. data/webpack/src/Extends/Hosts/BulkActions/BulkChangePuppetProxy/__tests__/index.test.js +160 -47
  22. data/webpack/src/Extends/Hosts/BulkActions/BulkRemoveProxyCommon/__tests__/actions.test.js +0 -6
  23. data/webpack/src/Extends/Hosts/BulkActions/BulkRemovePuppetCAProxy/__tests__/index.test.js +136 -39
  24. data/webpack/src/Extends/Hosts/BulkActions/BulkRemovePuppetEnvironment/BulkRemovePuppetEnvironmentModal.js +148 -0
  25. data/webpack/src/Extends/Hosts/BulkActions/BulkRemovePuppetEnvironment/__tests__/BulkRemovePuppetEnvironmentModal.test.js +80 -0
  26. data/webpack/src/Extends/Hosts/BulkActions/BulkRemovePuppetEnvironment/__tests__/index.test.js +66 -0
  27. data/webpack/src/Extends/Hosts/BulkActions/BulkRemovePuppetEnvironment/index.js +30 -0
  28. data/webpack/src/Extends/Hosts/BulkActions/BulkRemovePuppetProxy/__tests__/index.test.js +123 -34
  29. data/webpack/src/Router/routes.fixtures.js +13 -0
  30. data/webpack/src/Router/routes.test.js +68 -8
  31. data/webpack/src/foreman_puppet_host_form.test.js +3 -1
  32. data/webpack/test_setup.js +1 -0
  33. metadata +14 -3
  34. data/webpack/src/Router/__snapshots__/routes.test.js.snap +0 -3
@@ -1,23 +1,35 @@
1
1
  import React from 'react';
2
- import { mount } from '@theforeman/test';
2
+ import { screen, act } from '@testing-library/react';
3
+ import userEvent from '@testing-library/user-event';
4
+ import '@testing-library/jest-dom';
3
5
 
4
6
  import { openBulkModal } from 'foremanReact/common/BulkModalStateHelper';
5
7
  import { ForemanActionsBarContext } from 'foremanReact/components/HostDetails/ActionsBar';
8
+ import { rtlHelpers } from 'foremanReact/common/rtlTestHelpers';
9
+ import { APIActions } from 'foremanReact/redux/API';
10
+ import { foremanUrl } from 'foremanReact/common/helpers';
6
11
 
7
12
  import BulkRemovePuppetProxyScene from '../index';
8
- import BulkRemoveProxyCommon from '../../BulkRemoveProxyCommon';
13
+ import { BULK_REMOVE_PUPPET_PROXY_KEY } from '../../BulkRemoveProxyCommon/actions';
9
14
 
10
- jest.mock('foremanReact/components/HostDetails/ActionsBar', () => ({
11
- ForemanActionsBarContext: jest.requireActual('react').createContext(),
12
- }));
15
+ jest.mock(
16
+ 'foremanReact/components/HostDetails/ActionsBar',
17
+ () => ({
18
+ ForemanActionsBarContext: jest.requireActual('react').createContext(),
19
+ }),
20
+ { virtual: true }
21
+ );
13
22
 
14
- jest.mock('../../BulkRemoveProxyCommon', () => ({
15
- __esModule: true,
16
- default: jest.fn(() => null),
23
+ jest.mock('foremanReact/redux/API', () => ({
24
+ APIActions: {
25
+ put: jest.fn(payload => ({ type: 'MOCK_API_PUT', payload })),
26
+ },
17
27
  }));
18
28
 
29
+ const { renderWithStoreAndI18n } = rtlHelpers;
30
+
19
31
  describe('BulkRemovePuppetProxyScene', () => {
20
- const fetchBulkParams = jest.fn();
32
+ const fetchBulkParams = jest.fn(() => 'name = host1');
21
33
  const refreshTableData = jest.fn();
22
34
  const contextValue = {
23
35
  selectAllHostsMode: false,
@@ -27,38 +39,115 @@ describe('BulkRemovePuppetProxyScene', () => {
27
39
  refreshTableData,
28
40
  };
29
41
 
42
+ const renderScene = (context = contextValue) =>
43
+ renderWithStoreAndI18n(
44
+ <ForemanActionsBarContext.Provider value={context}>
45
+ <BulkRemovePuppetProxyScene />
46
+ </ForemanActionsBarContext.Provider>
47
+ );
48
+
49
+ const openSceneModal = async () => {
50
+ openBulkModal('bulk-remove-puppet-proxy', true);
51
+
52
+ return screen.findByRole('dialog', { name: 'Remove Puppet Proxy' });
53
+ };
54
+
30
55
  beforeEach(() => {
31
- jest.clearAllMocks();
32
56
  openBulkModal('bulk-remove-puppet-proxy', false);
33
57
  });
34
58
 
35
- it('opens with bulk modal state and passes expected props', () => {
36
- openBulkModal('bulk-remove-puppet-proxy', true);
37
- const wrapper = mount(
38
- <ForemanActionsBarContext.Provider value={contextValue}>
39
- <BulkRemovePuppetProxyScene />
40
- </ForemanActionsBarContext.Provider>
59
+ afterEach(() => {
60
+ jest.clearAllMocks();
61
+ });
62
+
63
+ it('does not show the modal when bulk modal state is closed', () => {
64
+ renderScene();
65
+
66
+ expect(
67
+ screen.queryByRole('dialog', { name: 'Remove Puppet Proxy' })
68
+ ).not.toBeInTheDocument();
69
+ });
70
+
71
+ it('shows the modal with a warning for the selected hosts when opened', async () => {
72
+ renderScene();
73
+ await openSceneModal();
74
+
75
+ expect(
76
+ screen.getByText(/Removing the Puppet proxy will affect/)
77
+ ).toBeInTheDocument();
78
+ expect(screen.getByText('2', { selector: 'strong' })).toBeInTheDocument();
79
+ expect(screen.getByText(/selected hosts/)).toBeInTheDocument();
80
+ expect(
81
+ screen.getByRole('button', { name: 'Remove Puppet Proxy' })
82
+ ).toBeInTheDocument();
83
+ expect(screen.getByRole('button', { name: 'Cancel' })).toBeInTheDocument();
84
+ });
85
+
86
+ it('shows the all hosts warning when select all hosts mode is enabled', async () => {
87
+ renderScene({
88
+ ...contextValue,
89
+ selectAllHostsMode: true,
90
+ });
91
+ await openSceneModal();
92
+
93
+ expect(
94
+ screen.getByText(/Removing the Puppet proxy will affect/)
95
+ ).toBeInTheDocument();
96
+ expect(screen.getByText('All', { selector: 'strong' })).toBeInTheDocument();
97
+ expect(screen.getByText(/selected hosts/)).toBeInTheDocument();
98
+ });
99
+
100
+ it('closes the modal when Cancel is clicked', async () => {
101
+ renderScene();
102
+ await openSceneModal();
103
+
104
+ await userEvent.click(screen.getByRole('button', { name: 'Cancel' }));
105
+
106
+ expect(
107
+ screen.queryByRole('dialog', { name: 'Remove Puppet Proxy' })
108
+ ).not.toBeInTheDocument();
109
+ });
110
+
111
+ it('dispatches the bulk remove puppet proxy action when confirmed', async () => {
112
+ renderScene();
113
+ await openSceneModal();
114
+
115
+ await userEvent.click(
116
+ screen.getByRole('button', { name: 'Remove Puppet Proxy' })
41
117
  );
42
118
 
43
- const componentType =
44
- BulkRemoveProxyCommon.default || BulkRemoveProxyCommon;
45
- const props = wrapper.find(componentType).props();
46
-
47
- expect(props).toEqual(
48
- expect.objectContaining({
49
- isCAProxy: false,
50
- selectAllHostsMode: false,
51
- selectedCount: 2,
52
- selectedResults: [1, 2],
53
- fetchBulkParams,
54
- isOpen: true,
55
- closeModal: expect.any(Function),
56
- onSuccess: refreshTableData,
57
- handleErrorMessage: 'Failed to remove Puppet Proxy',
58
- removeMessage: 'Remove Puppet Proxy',
59
- })
119
+ expect(fetchBulkParams).toHaveBeenCalledTimes(1);
120
+ expect(APIActions.put).toHaveBeenCalledWith({
121
+ key: BULK_REMOVE_PUPPET_PROXY_KEY,
122
+ url: foremanUrl('/api/v2/hosts/bulk/remove_puppet_proxy'),
123
+ handleSuccess: expect.any(Function),
124
+ handleError: expect.any(Function),
125
+ params: {
126
+ included: {
127
+ search: 'name = host1',
128
+ },
129
+ ca_proxy: false,
130
+ },
131
+ });
132
+ });
133
+
134
+ it('refreshes table data after a successful bulk remove', async () => {
135
+ renderScene();
136
+ await openSceneModal();
137
+
138
+ await userEvent.click(
139
+ screen.getByRole('button', { name: 'Remove Puppet Proxy' })
60
140
  );
61
141
 
62
- wrapper.unmount();
142
+ const { handleSuccess } = APIActions.put.mock.calls[0][0];
143
+
144
+ act(() => {
145
+ handleSuccess({ data: { message: 'Puppet proxy removed' } });
146
+ });
147
+
148
+ expect(refreshTableData).toHaveBeenCalledTimes(1);
149
+ expect(
150
+ screen.queryByRole('dialog', { name: 'Remove Puppet Proxy' })
151
+ ).not.toBeInTheDocument();
63
152
  });
64
153
  });
@@ -0,0 +1,13 @@
1
+ import React from 'react';
2
+
3
+ export const ExampleRoutePage = () => (
4
+ <h1>Foreman Puppet example route</h1>
5
+ );
6
+
7
+ export const exampleRoutes = {
8
+ example: {
9
+ path: '/foreman_puppet_example',
10
+ exact: true,
11
+ component: ExampleRoutePage,
12
+ },
13
+ };
@@ -1,16 +1,76 @@
1
1
  import React from 'react';
2
- import { shallow } from '@theforeman/test';
2
+ import { createMemoryHistory } from 'history';
3
+ import { Router, Route, Switch } from 'react-router-dom';
4
+ import { screen } from '@testing-library/react';
5
+ import '@testing-library/jest-dom';
3
6
 
4
- import Routes from './routes';
7
+ import routes from './routes';
8
+ import ForemanPuppetRouter from './index';
9
+ import { exampleRoutes } from './routes.fixtures';
10
+ import { rtlHelpers } from 'foremanReact/common/rtlTestHelpers';
11
+
12
+ const { renderWithStore } = rtlHelpers;
13
+
14
+ const renderForemanPuppetRouterAtPath = path => {
15
+ const history = createMemoryHistory({ initialEntries: [path] });
16
+
17
+ return renderWithStore(
18
+ <Router history={history}>
19
+ <ForemanPuppetRouter />
20
+ </Router>
21
+ );
22
+ };
23
+
24
+ const renderRoutesAtPath = (routeMap, path) => {
25
+ const history = createMemoryHistory({ initialEntries: [path] });
26
+
27
+ return renderWithStore(
28
+ <Router history={history}>
29
+ <Switch>
30
+ {Object.entries(routeMap).map(([key, props]) => (
31
+ <Route key={key} {...props} />
32
+ ))}
33
+ </Switch>
34
+ </Router>
35
+ );
36
+ };
5
37
 
6
38
  describe('ForemanPuppetRoutes', () => {
7
- it('should create routes', () => {
8
- Object.entries(Routes).forEach(([key, Route]) => {
9
- const Component = Route.component;
10
- const component = shallow(<Component history={{}} some="props" />);
11
- Route.renderResult = component;
39
+ it('exports an empty routes configuration object', () => {
40
+ expect(routes).toEqual({});
41
+ expect(routes).not.toBeNull();
42
+ expect(Array.isArray(routes)).toBe(false);
43
+ });
44
+
45
+ describe('fixture routes', () => {
46
+ it('defines valid route entries', () => {
47
+ Object.entries(exampleRoutes).forEach(([routeKey, route]) => {
48
+ expect(routeKey).toBeTruthy();
49
+ expect(route).toEqual(
50
+ expect.objectContaining({
51
+ path: expect.any(String),
52
+ component: expect.any(Function),
53
+ })
54
+ );
55
+ });
12
56
  });
13
57
 
14
- expect(Routes).toMatchSnapshot();
58
+ it('renders a fixture route at its path', () => {
59
+ const { path } = exampleRoutes.example;
60
+
61
+ renderRoutesAtPath(exampleRoutes, path);
62
+
63
+ expect(
64
+ screen.getByRole('heading', { name: 'Foreman Puppet example route' })
65
+ ).toBeInTheDocument();
66
+ });
67
+ });
68
+
69
+ describe('ForemanPuppetRouter', () => {
70
+ it('renders without content when no routes are configured', () => {
71
+ const { container } = renderForemanPuppetRouterAtPath('/');
72
+
73
+ expect(container).toBeEmptyDOMElement();
74
+ });
15
75
  });
16
76
  });
@@ -4,6 +4,8 @@ import $ from 'jquery';
4
4
 
5
5
  import { checkForUnavailablePuppetclasses } from './foreman_puppet_host_form';
6
6
 
7
+ const WARNING_RENDER_TIMEOUT = 100;
8
+
7
9
  jest.unmock('jquery');
8
10
  jest.unmock('./foreman_puppet_host_form');
9
11
 
@@ -59,6 +61,6 @@ describe('checkForUnavailablePuppetclasses', () => {
59
61
  checkForUnavailablePuppetclasses();
60
62
  setTimeout(() => {
61
63
  expect($('a .pficon')).toHaveLength(1);
62
- }, 100);
64
+ }, WARNING_RENDER_TIMEOUT);
63
65
  });
64
66
  });
@@ -0,0 +1 @@
1
+ import 'foremanJSTestSetup';
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: foreman_puppet
3
3
  version: !ruby/object:Gem::Version
4
- version: 11.0.0
4
+ version: 11.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ondřej Ezr
@@ -384,6 +384,12 @@ files:
384
384
  - webpack/src/Extends/Hosts/BulkActions/BulkChangeProxyCommon/index.js
385
385
  - webpack/src/Extends/Hosts/BulkActions/BulkChangePuppetCAProxy/__tests__/index.test.js
386
386
  - webpack/src/Extends/Hosts/BulkActions/BulkChangePuppetCAProxy/index.js
387
+ - webpack/src/Extends/Hosts/BulkActions/BulkChangePuppetEnvironment/BulkChangePuppetEnvironmentModal.js
388
+ - webpack/src/Extends/Hosts/BulkActions/BulkChangePuppetEnvironment/__tests__/BulkChangePuppetEnvironmentModal.test.js
389
+ - webpack/src/Extends/Hosts/BulkActions/BulkChangePuppetEnvironment/__tests__/actions.test.js
390
+ - webpack/src/Extends/Hosts/BulkActions/BulkChangePuppetEnvironment/__tests__/index.test.js
391
+ - webpack/src/Extends/Hosts/BulkActions/BulkChangePuppetEnvironment/actions.js
392
+ - webpack/src/Extends/Hosts/BulkActions/BulkChangePuppetEnvironment/index.js
387
393
  - webpack/src/Extends/Hosts/BulkActions/BulkChangePuppetProxy/__tests__/index.test.js
388
394
  - webpack/src/Extends/Hosts/BulkActions/BulkChangePuppetProxy/index.js
389
395
  - webpack/src/Extends/Hosts/BulkActions/BulkRemoveProxyCommon/__tests__/actions.test.js
@@ -391,13 +397,17 @@ files:
391
397
  - webpack/src/Extends/Hosts/BulkActions/BulkRemoveProxyCommon/index.js
392
398
  - webpack/src/Extends/Hosts/BulkActions/BulkRemovePuppetCAProxy/__tests__/index.test.js
393
399
  - webpack/src/Extends/Hosts/BulkActions/BulkRemovePuppetCAProxy/index.js
400
+ - webpack/src/Extends/Hosts/BulkActions/BulkRemovePuppetEnvironment/BulkRemovePuppetEnvironmentModal.js
401
+ - webpack/src/Extends/Hosts/BulkActions/BulkRemovePuppetEnvironment/__tests__/BulkRemovePuppetEnvironmentModal.test.js
402
+ - webpack/src/Extends/Hosts/BulkActions/BulkRemovePuppetEnvironment/__tests__/index.test.js
403
+ - webpack/src/Extends/Hosts/BulkActions/BulkRemovePuppetEnvironment/index.js
394
404
  - webpack/src/Extends/Hosts/BulkActions/BulkRemovePuppetProxy/__tests__/index.test.js
395
405
  - webpack/src/Extends/Hosts/BulkActions/BulkRemovePuppetProxy/index.js
396
406
  - webpack/src/Extends/Hosts/BulkActions/__tests__/toastHelpers.test.js
397
407
  - webpack/src/Extends/Hosts/BulkActions/toastHelpers.js
398
408
  - webpack/src/ForemanPuppet.js
399
- - webpack/src/Router/__snapshots__/routes.test.js.snap
400
409
  - webpack/src/Router/index.js
410
+ - webpack/src/Router/routes.fixtures.js
401
411
  - webpack/src/Router/routes.js
402
412
  - webpack/src/Router/routes.test.js
403
413
  - webpack/src/foreman_class_edit.js
@@ -405,6 +415,7 @@ files:
405
415
  - webpack/src/foreman_puppet_host_form.test.js
406
416
  - webpack/src/index.js
407
417
  - webpack/src/reducers.js
418
+ - webpack/test_setup.js
408
419
  homepage: https://github.com/theforeman/foreman_puppet
409
420
  licenses:
410
421
  - GPL-3.0
@@ -426,7 +437,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
426
437
  - !ruby/object:Gem::Version
427
438
  version: '0'
428
439
  requirements: []
429
- rubygems_version: 4.0.16
440
+ rubygems_version: 4.0.20
430
441
  specification_version: 4
431
442
  summary: Add Puppet features to Foreman
432
443
  test_files:
@@ -1,3 +0,0 @@
1
- // Jest Snapshot v1, https://goo.gl/fbAQLP
2
-
3
- exports[`ForemanPuppetRoutes should create routes 1`] = `Object {}`;