foreman_webhooks 0.0.1
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.
- checksums.yaml +7 -0
- data/LICENSE +619 -0
- data/README.md +30 -0
- data/Rakefile +49 -0
- data/app/controllers/api/v2/webhook_templates_controller.rb +110 -0
- data/app/controllers/api/v2/webhooks_controller.rb +61 -0
- data/app/controllers/concerns/foreman_webhooks/controller/parameters/webhook.rb +34 -0
- data/app/controllers/concerns/foreman_webhooks/controller/parameters/webhook_template.rb +34 -0
- data/app/controllers/webhook_templates_controller.rb +5 -0
- data/app/controllers/webhooks_controller.rb +39 -0
- data/app/jobs/foreman_webhooks/deliver_webhook_job.rb +27 -0
- data/app/lib/foreman_webhooks/renderer/scope/webhook_template.rb +36 -0
- data/app/models/webhook.rb +141 -0
- data/app/models/webhook_template.rb +59 -0
- data/app/services/foreman_webhooks/webhook_service.rb +111 -0
- data/app/subscribers/foreman_webhooks/event_subscriber.rb +9 -0
- data/app/views/api/v2/webhook_templates/base.json.rabl +5 -0
- data/app/views/api/v2/webhook_templates/create.json.rabl +5 -0
- data/app/views/api/v2/webhook_templates/index.json.rabl +5 -0
- data/app/views/api/v2/webhook_templates/main.json.rabl +7 -0
- data/app/views/api/v2/webhook_templates/show.json.rabl +11 -0
- data/app/views/api/v2/webhook_templates/update.json.rabl +5 -0
- data/app/views/api/v2/webhooks/base.json.rabl +5 -0
- data/app/views/api/v2/webhooks/create.json.rabl +5 -0
- data/app/views/api/v2/webhooks/index.json.rabl +5 -0
- data/app/views/api/v2/webhooks/main.json.rabl +8 -0
- data/app/views/api/v2/webhooks/show.json.rabl +17 -0
- data/app/views/api/v2/webhooks/update.json.rabl +5 -0
- data/app/views/foreman_webhooks/webhook_templates/ansible_tower_-_host_in_inventory.erb +20 -0
- data/app/views/foreman_webhooks/webhook_templates/empty_payload.erb +6 -0
- data/app/views/foreman_webhooks/webhook_templates/webhook_template_-_payload_default.erb +11 -0
- data/app/views/webhook_templates/_alerts.html.erb +3 -0
- data/app/views/webhook_templates/_custom_tab_headers.html.erb +1 -0
- data/app/views/webhook_templates/_custom_tabs.html.erb +5 -0
- data/app/views/webhook_templates/edit.html.erb +3 -0
- data/app/views/webhook_templates/index.html.erb +29 -0
- data/app/views/webhook_templates/new.html.erb +3 -0
- data/app/views/webhooks/_form.html.erb +37 -0
- data/app/views/webhooks/_templates.html.erb +5 -0
- data/app/views/webhooks/edit.html.erb +3 -0
- data/app/views/webhooks/new.html.erb +3 -0
- data/config/routes.rb +45 -0
- data/db/migrate/20191016100128_create_webhook_targets.rb +13 -0
- data/db/migrate/20200831194208_rename_webhook_targets_to_webhooks.rb +7 -0
- data/db/migrate/20200831194514_add_template_to_webhooks.rb +7 -0
- data/db/migrate/20200907232758_rename_webhook_permissions.rb +22 -0
- data/db/migrate/20200908004234_add_columns_to_webhooks.rb +13 -0
- data/db/migrate/20201014115147_rename_ca_file_column.rb +7 -0
- data/db/migrate/20201109135301_add_http_headers.rb +8 -0
- data/db/seeds.d/95_webhook_templates.rb +7 -0
- data/lib/foreman_webhooks.rb +6 -0
- data/lib/foreman_webhooks/engine.rb +80 -0
- data/lib/foreman_webhooks/version.rb +5 -0
- data/lib/tasks/foreman_webhooks_tasks.rake +47 -0
- data/package.json +45 -0
- data/test/controllers/api/v2/webhook_templates_controller_test.rb +200 -0
- data/test/controllers/api/v2/webhooks_controller_test.rb +108 -0
- data/test/factories/webhook.rb +20 -0
- data/test/factories/webhook_target.rb +9 -0
- data/test/factories/webhook_template.rb +16 -0
- data/test/jobs/foreman_webhooks/deliver_webhook_job_test.rb +17 -0
- data/test/models/webhook_test.rb +38 -0
- data/test/test_plugin_helper.rb +8 -0
- data/test/unit/foreman_webhooks/webhook_service_test.rb +53 -0
- data/webpack/ForemanWebhooks/Routes/ForemanWebhooksRoutes.js +12 -0
- data/webpack/ForemanWebhooks/Routes/Webhooks/WebhooksIndexPage/Components/EmptyWebhooksTable/index.js +29 -0
- data/webpack/ForemanWebhooks/Routes/Webhooks/WebhooksIndexPage/Components/WebhookDeleteModal.js +43 -0
- data/webpack/ForemanWebhooks/Routes/Webhooks/WebhooksIndexPage/Components/WebhooksTable/Components/EnabledCell.js +16 -0
- data/webpack/ForemanWebhooks/Routes/Webhooks/WebhooksIndexPage/Components/WebhooksTable/Components/Formatters/__tests__/__snapshots__/enabledCellFormatter.test.js.snap +7 -0
- data/webpack/ForemanWebhooks/Routes/Webhooks/WebhooksIndexPage/Components/WebhooksTable/Components/Formatters/__tests__/enabledCellFormatter.test.js +7 -0
- data/webpack/ForemanWebhooks/Routes/Webhooks/WebhooksIndexPage/Components/WebhooksTable/Components/Formatters/enabledCellFormatter.js +6 -0
- data/webpack/ForemanWebhooks/Routes/Webhooks/WebhooksIndexPage/Components/WebhooksTable/Components/Formatters/index.js +1 -0
- data/webpack/ForemanWebhooks/Routes/Webhooks/WebhooksIndexPage/Components/WebhooksTable/Components/__tests__/EnabledCell.test.js +14 -0
- data/webpack/ForemanWebhooks/Routes/Webhooks/WebhooksIndexPage/Components/WebhooksTable/Components/__tests__/__snapshots__/EnabledCell.test.js.snap +17 -0
- data/webpack/ForemanWebhooks/Routes/Webhooks/WebhooksIndexPage/Components/WebhooksTable/WebhooksTable.js +75 -0
- data/webpack/ForemanWebhooks/Routes/Webhooks/WebhooksIndexPage/Components/WebhooksTable/WebhooksTableSchema.js +41 -0
- data/webpack/ForemanWebhooks/Routes/Webhooks/WebhooksIndexPage/Components/WebhooksTable/__tests__/WebhooksTable.test.js +57 -0
- data/webpack/ForemanWebhooks/Routes/Webhooks/WebhooksIndexPage/Components/WebhooksTable/__tests__/__snapshots__/WebhooksTable.test.js.snap +115 -0
- data/webpack/ForemanWebhooks/Routes/Webhooks/WebhooksIndexPage/Components/WebhooksTable/index.js +25 -0
- data/webpack/ForemanWebhooks/Routes/Webhooks/WebhooksIndexPage/WebhooksIndexPage.js +87 -0
- data/webpack/ForemanWebhooks/Routes/Webhooks/WebhooksIndexPage/__tests__/WebhooksIndexPage.fixtures.js +74 -0
- data/webpack/ForemanWebhooks/Routes/Webhooks/WebhooksIndexPage/__tests__/WebhooksIndexPage.test.js +21 -0
- data/webpack/ForemanWebhooks/Routes/Webhooks/WebhooksIndexPage/__tests__/__snapshots__/WebhooksIndexPage.test.js.snap +68 -0
- data/webpack/ForemanWebhooks/Routes/Webhooks/WebhooksIndexPage/index.js +51 -0
- data/webpack/ForemanWebhooks/Routes/Webhooks/WebhooksPageActions.js +51 -0
- data/webpack/ForemanWebhooks/Routes/Webhooks/WebhooksPageHelpers.js +29 -0
- data/webpack/ForemanWebhooks/Routes/Webhooks/WebhooksPageSelectors.js +85 -0
- data/webpack/ForemanWebhooks/Routes/Webhooks/__tests__/WebhooksPageHelpers.test.js +20 -0
- data/webpack/ForemanWebhooks/Routes/Webhooks/__tests__/WebhooksPageSelectors.test.js +45 -0
- data/webpack/ForemanWebhooks/Routes/Webhooks/__tests__/__snapshots__/WebhooksPageSelectors.test.js.snap +50 -0
- data/webpack/ForemanWebhooks/Routes/Webhooks/constants.js +13 -0
- data/webpack/__mocks__/foremanReact/common/HOC.js +2 -0
- data/webpack/__mocks__/foremanReact/common/I18n.js +7 -0
- data/webpack/__mocks__/foremanReact/common/helpers.js +7 -0
- data/webpack/__mocks__/foremanReact/common/urlHelpers.js +1 -0
- data/webpack/__mocks__/foremanReact/components/ForemanModal/ForemanModalActions.js +2 -0
- data/webpack/__mocks__/foremanReact/components/ForemanModal/ForemanModalHooks.js +10 -0
- data/webpack/__mocks__/foremanReact/components/ForemanModal/index.js +18 -0
- data/webpack/__mocks__/foremanReact/components/Layout/LayoutActions.js +2 -0
- data/webpack/__mocks__/foremanReact/components/Pagination/PaginationWrapper.js +2 -0
- data/webpack/__mocks__/foremanReact/components/common/EmptyState.js +5 -0
- data/webpack/__mocks__/foremanReact/components/common/table.js +5 -0
- data/webpack/__mocks__/foremanReact/constants.js +24 -0
- data/webpack/__mocks__/foremanReact/redux/API/APISelectors.js +6 -0
- data/webpack/__mocks__/foremanReact/redux/API/index.js +10 -0
- data/webpack/__mocks__/foremanReact/redux/actions/toasts.js +8 -0
- data/webpack/__mocks__/foremanReact/routes/common/PageLayout/PageLayout.js +10 -0
- data/webpack/index.js +0 -0
- data/webpack/routes_index.js +4 -0
- metadata +195 -0
data/webpack/ForemanWebhooks/Routes/Webhooks/WebhooksIndexPage/__tests__/WebhooksIndexPage.test.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { testComponentSnapshotsWithFixtures } from '@theforeman/test';
|
|
2
|
+
import WebhooksIndexPage from '../WebhooksIndexPage';
|
|
3
|
+
|
|
4
|
+
const fixtures = {
|
|
5
|
+
'render with minimal props': {
|
|
6
|
+
fetchAndPush: () => {},
|
|
7
|
+
isLoading: false,
|
|
8
|
+
hasError: false,
|
|
9
|
+
hasData: false,
|
|
10
|
+
itemCount: 0,
|
|
11
|
+
canCreate: true,
|
|
12
|
+
sort: {},
|
|
13
|
+
webhooks: [],
|
|
14
|
+
toasts: [],
|
|
15
|
+
},
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
describe('WebhooksIndexPage', () => {
|
|
19
|
+
describe('redering', () =>
|
|
20
|
+
testComponentSnapshotsWithFixtures(WebhooksIndexPage, fixtures));
|
|
21
|
+
});
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
+
|
|
3
|
+
exports[`WebhooksIndexPage redering render with minimal props 1`] = `
|
|
4
|
+
<PageLayout
|
|
5
|
+
header="Webhooks"
|
|
6
|
+
isLoading={false}
|
|
7
|
+
onBookmarkClick={[Function]}
|
|
8
|
+
onSearch={[Function]}
|
|
9
|
+
searchProps={
|
|
10
|
+
Object {
|
|
11
|
+
"autocomplete": Object {
|
|
12
|
+
"id": "searchBar",
|
|
13
|
+
"searchQuery": "",
|
|
14
|
+
"url": "webhooks/auto_complete_search",
|
|
15
|
+
"useKeyShortcuts": true,
|
|
16
|
+
},
|
|
17
|
+
"bookmarks": Object {
|
|
18
|
+
"canCreateBookmarks": true,
|
|
19
|
+
"documentationUrl": "4.1.5Searching",
|
|
20
|
+
"url": "/api/bookmarks",
|
|
21
|
+
},
|
|
22
|
+
"controller": "webhooks",
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
searchQuery=""
|
|
26
|
+
searchable={true}
|
|
27
|
+
toastNotifications={Array []}
|
|
28
|
+
toolbarButtons={
|
|
29
|
+
<ForwardRef
|
|
30
|
+
to=""
|
|
31
|
+
>
|
|
32
|
+
<Button
|
|
33
|
+
active={false}
|
|
34
|
+
block={false}
|
|
35
|
+
bsClass="btn"
|
|
36
|
+
bsStyle="primary"
|
|
37
|
+
disabled={false}
|
|
38
|
+
>
|
|
39
|
+
Create Webhook
|
|
40
|
+
</Button>
|
|
41
|
+
</ForwardRef>
|
|
42
|
+
}
|
|
43
|
+
>
|
|
44
|
+
<WrappedWebhooksTable
|
|
45
|
+
fetchAndPush={[Function]}
|
|
46
|
+
hasData={false}
|
|
47
|
+
hasError={false}
|
|
48
|
+
isLoading={false}
|
|
49
|
+
itemCount={0}
|
|
50
|
+
message={
|
|
51
|
+
Object {
|
|
52
|
+
"text": "Try to create a new Webhook",
|
|
53
|
+
"type": "empty",
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
pagination={
|
|
57
|
+
Object {
|
|
58
|
+
"page": null,
|
|
59
|
+
"perPage": null,
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
results={Array []}
|
|
63
|
+
setToDelete={[Function]}
|
|
64
|
+
sort={Object {}}
|
|
65
|
+
toDelete={Object {}}
|
|
66
|
+
/>
|
|
67
|
+
</PageLayout>
|
|
68
|
+
`;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { connect } from 'react-redux';
|
|
3
|
+
import { compose, bindActionCreators } from 'redux';
|
|
4
|
+
|
|
5
|
+
import { callOnMount, callOnPopState } from 'foremanReact/common/HOC';
|
|
6
|
+
import { useForemanContext } from 'foremanReact/Root/Context/ForemanContext';
|
|
7
|
+
|
|
8
|
+
import WebhooksIndexPage from './WebhooksIndexPage';
|
|
9
|
+
import * as actions from '../WebhooksPageActions';
|
|
10
|
+
|
|
11
|
+
import {
|
|
12
|
+
selectWebhooks,
|
|
13
|
+
selectPage,
|
|
14
|
+
selectPerPage,
|
|
15
|
+
selectSearch,
|
|
16
|
+
selectSort,
|
|
17
|
+
selectHasData,
|
|
18
|
+
selectHasError,
|
|
19
|
+
selectIsLoading,
|
|
20
|
+
selectSubtotal,
|
|
21
|
+
selectMessage,
|
|
22
|
+
selectCanCreate,
|
|
23
|
+
} from '../WebhooksPageSelectors';
|
|
24
|
+
|
|
25
|
+
const mapStateToProps = state => ({
|
|
26
|
+
webhooks: selectWebhooks(state),
|
|
27
|
+
page: selectPage(state),
|
|
28
|
+
perPage: selectPerPage(state),
|
|
29
|
+
search: selectSearch(state),
|
|
30
|
+
sort: selectSort(state),
|
|
31
|
+
isLoading: selectIsLoading(state),
|
|
32
|
+
hasData: selectHasData(state),
|
|
33
|
+
hasError: selectHasError(state),
|
|
34
|
+
itemCount: selectSubtotal(state),
|
|
35
|
+
message: selectMessage(state),
|
|
36
|
+
canCreate: selectCanCreate(state),
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
const mapDispatchToProps = dispatch => bindActionCreators(actions, dispatch);
|
|
40
|
+
|
|
41
|
+
const callWithToastsContext = Component => props => {
|
|
42
|
+
const { toasts } = useForemanContext();
|
|
43
|
+
return <Component {...props} toasts={toasts} />;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
export default compose(
|
|
47
|
+
connect(mapStateToProps, mapDispatchToProps),
|
|
48
|
+
callWithToastsContext,
|
|
49
|
+
callOnMount(({ initializeWebhooks }) => initializeWebhooks()),
|
|
50
|
+
callOnPopState(({ fetchWebhooks }) => fetchWebhooks())
|
|
51
|
+
)(WebhooksIndexPage);
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import history from 'foremanReact/history';
|
|
2
|
+
import { get } from 'foremanReact/redux/API';
|
|
3
|
+
import { stringifyParams, getParams } from 'foremanReact/common/urlHelpers';
|
|
4
|
+
|
|
5
|
+
import { buildQuery } from './WebhooksPageHelpers';
|
|
6
|
+
import {
|
|
7
|
+
WEBHOOKS_API_PATH,
|
|
8
|
+
WEBHOOKS_PATH,
|
|
9
|
+
WEBHOOKS_API_REQUEST_KEY,
|
|
10
|
+
} from './constants';
|
|
11
|
+
|
|
12
|
+
export const initializeWebhooks = () => dispatch => {
|
|
13
|
+
const params = getParams();
|
|
14
|
+
dispatch(fetchWebhooks(params));
|
|
15
|
+
if (!history.action === 'POP') {
|
|
16
|
+
history.replace({
|
|
17
|
+
pathname: WEBHOOKS_PATH,
|
|
18
|
+
search: stringifyParams(params),
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export const fetchWebhooks = (
|
|
24
|
+
{ page, perPage, searchQuery, sort },
|
|
25
|
+
url = WEBHOOKS_API_PATH
|
|
26
|
+
) => async dispatch => {
|
|
27
|
+
const sortString =
|
|
28
|
+
sort && Object.keys(sort).length > 0 ? `${sort.by} ${sort.order}` : '';
|
|
29
|
+
|
|
30
|
+
return dispatch(
|
|
31
|
+
get({
|
|
32
|
+
key: WEBHOOKS_API_REQUEST_KEY,
|
|
33
|
+
url,
|
|
34
|
+
params: {
|
|
35
|
+
page,
|
|
36
|
+
per_page: perPage,
|
|
37
|
+
search: searchQuery,
|
|
38
|
+
order: sortString,
|
|
39
|
+
},
|
|
40
|
+
})
|
|
41
|
+
);
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
export const fetchAndPush = (params = {}) => (dispatch, getState) => {
|
|
45
|
+
const query = buildQuery(params, getState());
|
|
46
|
+
dispatch(fetchWebhooks(query));
|
|
47
|
+
history.push({
|
|
48
|
+
pathname: WEBHOOKS_PATH,
|
|
49
|
+
search: stringifyParams(query),
|
|
50
|
+
});
|
|
51
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { snakeCase } from 'lodash';
|
|
2
|
+
import { compose } from 'redux';
|
|
3
|
+
import {
|
|
4
|
+
selectSort,
|
|
5
|
+
selectPage,
|
|
6
|
+
selectPerPage,
|
|
7
|
+
selectSearch,
|
|
8
|
+
} from './WebhooksPageSelectors';
|
|
9
|
+
|
|
10
|
+
export const buildQuery = (query, state) => {
|
|
11
|
+
const querySort = pickSort(query, state);
|
|
12
|
+
|
|
13
|
+
return {
|
|
14
|
+
page: query.page || selectPage(state),
|
|
15
|
+
perPage: query.perPage || selectPerPage(state),
|
|
16
|
+
searchQuery:
|
|
17
|
+
query.searchQuery === undefined ? selectSearch(state) : query.searchQuery,
|
|
18
|
+
...(querySort && { sort: querySort }),
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export const pickSort = (query, state) =>
|
|
23
|
+
checkSort(query.sort)
|
|
24
|
+
? transformSort(query.sort)
|
|
25
|
+
: checkSort(compose(transformSort, selectSort)(state));
|
|
26
|
+
|
|
27
|
+
const checkSort = sort => (sort && sort.by && sort.order ? sort : undefined);
|
|
28
|
+
|
|
29
|
+
const transformSort = sort => ({ ...sort, by: snakeCase(sort.by) });
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { camelCase, isEmpty } from 'lodash';
|
|
2
|
+
import Immutable from 'seamless-immutable';
|
|
3
|
+
import { STATUS } from 'foremanReact/constants';
|
|
4
|
+
import { deepPropsToCamelCase } from 'foremanReact/common/helpers';
|
|
5
|
+
import {
|
|
6
|
+
selectAPIErrorMessage,
|
|
7
|
+
selectAPIStatus,
|
|
8
|
+
selectAPIResponse,
|
|
9
|
+
} from 'foremanReact/redux/API/APISelectors';
|
|
10
|
+
|
|
11
|
+
import { WEBHOOKS_API_REQUEST_KEY } from './constants';
|
|
12
|
+
|
|
13
|
+
export const emptyResponse = {
|
|
14
|
+
results: [],
|
|
15
|
+
page: 0,
|
|
16
|
+
perPage: 0,
|
|
17
|
+
search: '',
|
|
18
|
+
sort: {},
|
|
19
|
+
canCreate: false,
|
|
20
|
+
subtotal: 0,
|
|
21
|
+
message: {},
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const selectWebhooksPageResponse = state => {
|
|
25
|
+
const response = deepPropsToCamelCase(
|
|
26
|
+
selectAPIResponse(state, WEBHOOKS_API_REQUEST_KEY)
|
|
27
|
+
);
|
|
28
|
+
if (isEmpty(response)) {
|
|
29
|
+
return Immutable(emptyResponse);
|
|
30
|
+
}
|
|
31
|
+
return response;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export const selectIsLoading = state => {
|
|
35
|
+
const status = selectWebhooksPageStatus(state);
|
|
36
|
+
return !status || status === STATUS.PENDING;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
const selectWebhooksPageStatus = state =>
|
|
40
|
+
selectAPIStatus(state, WEBHOOKS_API_REQUEST_KEY);
|
|
41
|
+
|
|
42
|
+
export const selectHasError = state =>
|
|
43
|
+
selectWebhooksPageStatus(state) === STATUS.ERROR;
|
|
44
|
+
|
|
45
|
+
export const selectWebhooks = state => {
|
|
46
|
+
if (selectHasError(state)) {
|
|
47
|
+
return [];
|
|
48
|
+
}
|
|
49
|
+
return selectWebhooksPageResponse(state).results;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
export const selectHasData = state => {
|
|
53
|
+
const status = selectWebhooksPageStatus(state);
|
|
54
|
+
const results = selectWebhooks(state);
|
|
55
|
+
|
|
56
|
+
return status === STATUS.RESOLVED && results && results.length > 0;
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
export const selectPage = state => selectWebhooksPageResponse(state).page || 1;
|
|
60
|
+
export const selectPerPage = state =>
|
|
61
|
+
selectWebhooksPageResponse(state).perPage || 20;
|
|
62
|
+
export const selectSearch = state => selectWebhooksPageResponse(state).search;
|
|
63
|
+
|
|
64
|
+
export const selectSort = state => {
|
|
65
|
+
const sort = selectWebhooksPageResponse(state).sort || Immutable({});
|
|
66
|
+
if (sort.by && sort.order) {
|
|
67
|
+
return { ...sort, by: camelCase(sort.by) };
|
|
68
|
+
}
|
|
69
|
+
return sort;
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
export const selectCanCreate = state =>
|
|
73
|
+
selectWebhooksPageResponse(state).canCreate || false;
|
|
74
|
+
export const selectSubtotal = state =>
|
|
75
|
+
selectWebhooksPageResponse(state).subtotal || 0;
|
|
76
|
+
export const selectMessage = state => {
|
|
77
|
+
if (selectHasError(state)) {
|
|
78
|
+
const message = {
|
|
79
|
+
type: 'error',
|
|
80
|
+
text: selectAPIErrorMessage(state, WEBHOOKS_API_REQUEST_KEY),
|
|
81
|
+
};
|
|
82
|
+
return message;
|
|
83
|
+
}
|
|
84
|
+
return selectWebhooksPageResponse(state).message;
|
|
85
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { pickSort, buildQuery } from '../WebhooksPageHelpers';
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
querySort,
|
|
5
|
+
pickedQuery,
|
|
6
|
+
queryParams,
|
|
7
|
+
resultParams,
|
|
8
|
+
} from '../WebhooksIndexPage/__tests__/WebhooksIndexPage.fixtures';
|
|
9
|
+
|
|
10
|
+
describe('pickSort', () => {
|
|
11
|
+
it('should pick sort from query', () => {
|
|
12
|
+
expect(pickSort(querySort, {})).toStrictEqual(pickedQuery);
|
|
13
|
+
});
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
describe('buildQuery', () => {
|
|
17
|
+
it('should return params from query if present', () => {
|
|
18
|
+
expect(buildQuery(queryParams, {})).toStrictEqual(resultParams);
|
|
19
|
+
});
|
|
20
|
+
});
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { testSelectorsSnapshotWithFixtures } from '@theforeman/test';
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
selectWebhooks,
|
|
5
|
+
selectPage,
|
|
6
|
+
selectPerPage,
|
|
7
|
+
selectSearch,
|
|
8
|
+
selectSort,
|
|
9
|
+
selectHasData,
|
|
10
|
+
selectHasError,
|
|
11
|
+
selectIsLoading,
|
|
12
|
+
selectSubtotal,
|
|
13
|
+
selectMessage,
|
|
14
|
+
} from '../WebhooksPageSelectors';
|
|
15
|
+
|
|
16
|
+
import {
|
|
17
|
+
stateFactory,
|
|
18
|
+
webhooks,
|
|
19
|
+
} from '../WebhooksIndexPage/__tests__/WebhooksIndexPage.fixtures';
|
|
20
|
+
|
|
21
|
+
const state = stateFactory({
|
|
22
|
+
results: webhooks,
|
|
23
|
+
sort: { by: 'name', order: 'DESC' },
|
|
24
|
+
page: 1,
|
|
25
|
+
perPage: 1,
|
|
26
|
+
search: 'name ~ foo',
|
|
27
|
+
subtotal: 42,
|
|
28
|
+
message: { type: 'error', text: 'This is error' },
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
const fixtures = {
|
|
32
|
+
'should return webhooks': () => selectWebhooks(state),
|
|
33
|
+
'should return page': () => selectPage(state),
|
|
34
|
+
'should return perPage': () => selectPerPage(state),
|
|
35
|
+
'should return search': () => selectSearch(state),
|
|
36
|
+
'should return sort': () => selectSort(state),
|
|
37
|
+
'should return hasData': () => selectHasData(state),
|
|
38
|
+
'should return hasError': () => selectHasError(state),
|
|
39
|
+
'should return isLoading': () => selectIsLoading(state),
|
|
40
|
+
'should return subtotal': () => selectSubtotal(state),
|
|
41
|
+
'should return message': () => selectMessage(state),
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
describe('WebhooksPage selectors', () =>
|
|
45
|
+
testSelectorsSnapshotWithFixtures(fixtures));
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
+
|
|
3
|
+
exports[`WebhooksPage selectors should return hasData 1`] = `false`;
|
|
4
|
+
|
|
5
|
+
exports[`WebhooksPage selectors should return hasError 1`] = `false`;
|
|
6
|
+
|
|
7
|
+
exports[`WebhooksPage selectors should return isLoading 1`] = `true`;
|
|
8
|
+
|
|
9
|
+
exports[`WebhooksPage selectors should return message 1`] = `
|
|
10
|
+
Object {
|
|
11
|
+
"text": "This is error",
|
|
12
|
+
"type": "error",
|
|
13
|
+
}
|
|
14
|
+
`;
|
|
15
|
+
|
|
16
|
+
exports[`WebhooksPage selectors should return page 1`] = `1`;
|
|
17
|
+
|
|
18
|
+
exports[`WebhooksPage selectors should return perPage 1`] = `1`;
|
|
19
|
+
|
|
20
|
+
exports[`WebhooksPage selectors should return search 1`] = `"name ~ foo"`;
|
|
21
|
+
|
|
22
|
+
exports[`WebhooksPage selectors should return sort 1`] = `
|
|
23
|
+
Object {
|
|
24
|
+
"by": "name",
|
|
25
|
+
"order": "DESC",
|
|
26
|
+
}
|
|
27
|
+
`;
|
|
28
|
+
|
|
29
|
+
exports[`WebhooksPage selectors should return subtotal 1`] = `42`;
|
|
30
|
+
|
|
31
|
+
exports[`WebhooksPage selectors should return webhooks 1`] = `
|
|
32
|
+
Array [
|
|
33
|
+
Object {
|
|
34
|
+
"canDelete": true,
|
|
35
|
+
"canEdit": true,
|
|
36
|
+
"enabled": true,
|
|
37
|
+
"id": 1,
|
|
38
|
+
"name": "my-webhook",
|
|
39
|
+
"targetUrl": "https://my-machine.example.com",
|
|
40
|
+
},
|
|
41
|
+
Object {
|
|
42
|
+
"canDelete": false,
|
|
43
|
+
"canEdit": false,
|
|
44
|
+
"enabled": false,
|
|
45
|
+
"id": 2,
|
|
46
|
+
"name": "your-webhook",
|
|
47
|
+
"targetUrl": "https://your-machine.example.com",
|
|
48
|
+
},
|
|
49
|
+
]
|
|
50
|
+
`;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { getControllerSearchProps } from 'foremanReact/constants';
|
|
2
|
+
|
|
3
|
+
export const WEBHOOKS_PAGE_DATA_RESOLVED = 'WEBHOOKS_PAGE_DATA_RESOLVED';
|
|
4
|
+
export const WEBHOOKS_PAGE_DATA_FAILED = 'WEBHOOKS_PAGE_DATA_FAILED';
|
|
5
|
+
export const WEBHOOKS_PAGE_HIDE_LOADING = 'WEBHOOKS_PAGE_HIDE_LOADING';
|
|
6
|
+
export const WEBHOOKS_PAGE_SHOW_LOADING = 'WEBHOOKS_PAGE_SHOW_LOADING';
|
|
7
|
+
export const WEBHOOKS_PAGE_CLEAR_ERROR = 'WEBHOOKS_PAGE_CLEAR_ERROR';
|
|
8
|
+
|
|
9
|
+
export const WEBHOOKS_SEARCH_PROPS = getControllerSearchProps('webhooks');
|
|
10
|
+
export const WEBHOOKS_API_PATH = '/api/v2/webhooks?include_permissions=true';
|
|
11
|
+
export const WEBHOOKS_PATH = '/webhooks';
|
|
12
|
+
export const WEBHOOK_DELETE_MODAL_ID = 'webhookDeleteModal';
|
|
13
|
+
export const WEBHOOKS_API_REQUEST_KEY = 'WEBHOOKS';
|