foreman_webhooks 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
@@ -0,0 +1,108 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'test_plugin_helper'
|
4
|
+
|
5
|
+
class Api::V2::WebhooksControllerTest < ActionController::TestCase
|
6
|
+
valid_attrs = { name: 'webhook_test', event: 'host_created.event.foreman',
|
7
|
+
target_url: 'https://app.example.com' }
|
8
|
+
|
9
|
+
def setup
|
10
|
+
@webhook = FactoryBot.create(:webhook)
|
11
|
+
@webhook_template = FactoryBot.create(:webhook_template)
|
12
|
+
end
|
13
|
+
|
14
|
+
let(:webhook) { FactoryBot.create(:webhook) }
|
15
|
+
|
16
|
+
test 'should get index' do
|
17
|
+
get :index
|
18
|
+
assert_response :success
|
19
|
+
assert_not_nil assigns(:webhooks)
|
20
|
+
webhooks = ActiveSupport::JSON.decode(@response.body)
|
21
|
+
assert !webhooks.empty?
|
22
|
+
webhook = webhooks['results'].find { |h| h['id'] == @webhook.id }
|
23
|
+
assert_equal @webhook.name, webhook['name']
|
24
|
+
end
|
25
|
+
|
26
|
+
test 'should show individual record' do
|
27
|
+
get :show, params: { id: @webhook.to_param }
|
28
|
+
assert_response :success
|
29
|
+
show_response = ActiveSupport::JSON.decode(@response.body)
|
30
|
+
assert !show_response.empty?
|
31
|
+
assert_equal @webhook.event, show_response['event']
|
32
|
+
end
|
33
|
+
|
34
|
+
test 'should create webhook' do
|
35
|
+
assert_difference('Webhook.unscoped.count') do
|
36
|
+
post :create, params: { webhook: valid_attrs.merge(webhook_template_id: @webhook_template.id) }
|
37
|
+
end
|
38
|
+
assert_response :created
|
39
|
+
response = JSON.parse(@response.body)
|
40
|
+
assert response.key?('name')
|
41
|
+
assert response.key?('event')
|
42
|
+
assert_equal response['name'], valid_attrs[:name]
|
43
|
+
assert_equal response['event'], valid_attrs[:event]
|
44
|
+
end
|
45
|
+
|
46
|
+
test 'should update name' do
|
47
|
+
new_name = 'new webhook name'
|
48
|
+
put :update, params: { id: @webhook.id, webhook: { name: new_name } }
|
49
|
+
assert_response :success
|
50
|
+
response = JSON.parse(@response.body)
|
51
|
+
assert response.key?('name')
|
52
|
+
assert_equal response['name'], new_name
|
53
|
+
end
|
54
|
+
|
55
|
+
test 'should update event' do
|
56
|
+
new_event = 'subnet_created.event.foreman'
|
57
|
+
put :update, params: { id: @webhook.id, webhook: { event: new_event } }
|
58
|
+
assert_response :success
|
59
|
+
response = JSON.parse(@response.body)
|
60
|
+
assert response.key?('event')
|
61
|
+
assert_equal response['event'], new_event
|
62
|
+
end
|
63
|
+
|
64
|
+
test 'should not create with invalid name' do
|
65
|
+
assert_difference('Webhook.unscoped.count', 0) do
|
66
|
+
post :create, params: { webhook: valid_attrs.merge(name: '') }
|
67
|
+
end
|
68
|
+
assert_response :unprocessable_entity
|
69
|
+
end
|
70
|
+
|
71
|
+
test 'should not create with invalid event' do
|
72
|
+
assert_difference('Webhook.unscoped.count', 0) do
|
73
|
+
post :create, params: { webhook: valid_attrs.merge(event: '') }
|
74
|
+
end
|
75
|
+
assert_response :unprocessable_entity
|
76
|
+
end
|
77
|
+
|
78
|
+
test 'should not update with invalid name' do
|
79
|
+
put :update, params: { id: @webhook.id, webhook: { name: '' } }
|
80
|
+
assert_response :unprocessable_entity
|
81
|
+
end
|
82
|
+
|
83
|
+
test 'should not update with invalid event' do
|
84
|
+
put :update, params: { id: @webhook.id, webhook: { event: '' } }
|
85
|
+
assert_response :unprocessable_entity
|
86
|
+
end
|
87
|
+
|
88
|
+
test 'search webhook' do
|
89
|
+
get :index, params: { search: @webhook.name, format: 'json' }
|
90
|
+
assert_response :success, "search webhook name: '#{@webhook.name}'" \
|
91
|
+
" failed with code: #{@response.code}"
|
92
|
+
response = JSON.parse(@response.body)
|
93
|
+
assert_equal response['results'].length, 1
|
94
|
+
assert_equal response['results'][0]['id'], @webhook.id
|
95
|
+
end
|
96
|
+
|
97
|
+
test 'should update webhook' do
|
98
|
+
put :update, params: { id: @webhook.to_param, webhook: valid_attrs }
|
99
|
+
assert_response :success
|
100
|
+
end
|
101
|
+
|
102
|
+
test 'should destroy webhook' do
|
103
|
+
assert_difference('Webhook.unscoped.count', -1) do
|
104
|
+
delete :destroy, params: { id: @webhook.to_param }
|
105
|
+
end
|
106
|
+
assert_response :success
|
107
|
+
end
|
108
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
FactoryBot.define do
|
4
|
+
factory :webhook do
|
5
|
+
sequence(:name) { |n| "Webhook #{n}" }
|
6
|
+
target_url { 'https://hook.example.com/api/callback' }
|
7
|
+
event { 'subnet_created.event.foreman' }
|
8
|
+
enabled { true }
|
9
|
+
webhook_template
|
10
|
+
|
11
|
+
trait :with_template do
|
12
|
+
transient do
|
13
|
+
template { 'template content' }
|
14
|
+
end
|
15
|
+
after(:build) do |webhook, evaluator|
|
16
|
+
webhook.webhook_template = FactoryBot.create(:webhook_template, template: evaluator.template)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
FactoryBot.define do
|
4
|
+
factory :webhook_template do
|
5
|
+
sequence(:name) { |n| "webhook_template#{n}" }
|
6
|
+
sequence(:template) { |n| "template content #{n}" }
|
7
|
+
|
8
|
+
trait :snippet do
|
9
|
+
snippet { true }
|
10
|
+
end
|
11
|
+
|
12
|
+
trait :locked do
|
13
|
+
locked { true }
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'test_plugin_helper'
|
4
|
+
|
5
|
+
module ForemanWebhooks
|
6
|
+
class DeliverWebhookJobTest < ActiveJob::TestCase
|
7
|
+
let(:webhook) { FactoryBot.create(:webhook) }
|
8
|
+
let(:job) do
|
9
|
+
::ForemanWebhooks::DeliverWebhookJob.new(event_name: 'subnet_created', payload: { id: 2 }, webhook_id: webhook.id)
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'executes the webhook service' do
|
13
|
+
::ForemanWebhooks::WebhookService.any_instance.expects(:execute).once
|
14
|
+
job.perform_now
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'test_plugin_helper'
|
4
|
+
|
5
|
+
module ForemanWebhooks
|
6
|
+
class WebhookServiceTest < ActiveSupport::TestCase
|
7
|
+
def setup
|
8
|
+
User.current = users(:admin)
|
9
|
+
end
|
10
|
+
|
11
|
+
let(:webhook) { FactoryBot.create(:webhook) }
|
12
|
+
let(:webhook_template) { FactoryBot.create(:webhook_template) }
|
13
|
+
|
14
|
+
test 'password is saved encrypted when created' do
|
15
|
+
Webhook.any_instance.expects(:encryption_key).at_least_once.returns('25d224dd383e92a7e0c82b8bf7c985e815f34cf5')
|
16
|
+
webhook = Webhook.new(
|
17
|
+
name: 'new12345', target_url: 'https://app.example.com',
|
18
|
+
user: 'username', password: 'abcdef', events: 'host_created.event.foreman',
|
19
|
+
webhook_template_id: webhook_template.id
|
20
|
+
)
|
21
|
+
as_admin do
|
22
|
+
assert webhook.save!
|
23
|
+
end
|
24
|
+
assert_equal webhook.password, 'abcdef'
|
25
|
+
refute_equal webhook.password_in_db, 'abcdef'
|
26
|
+
end
|
27
|
+
|
28
|
+
test 'password is saved encrypted when updated' do
|
29
|
+
webhook.expects(:encryption_key).at_least_once.returns('25d224dd383e92a7e0c82b8bf7c985e815f34cf5')
|
30
|
+
webhook.password = '123456'
|
31
|
+
as_admin do
|
32
|
+
assert webhook.save
|
33
|
+
end
|
34
|
+
assert_equal webhook.password, '123456'
|
35
|
+
refute_equal webhook.password_in_db, '123456'
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'test_plugin_helper'
|
4
|
+
|
5
|
+
module ForemanWebhooks
|
6
|
+
class WebhookServiceTest < ActiveSupport::TestCase
|
7
|
+
let(:event_name) { 'subnet_created' }
|
8
|
+
let(:payload) { { id: 2 } }
|
9
|
+
let(:payload_json) { payload.to_json }
|
10
|
+
let(:webhook) do
|
11
|
+
FactoryBot.build(:webhook, :with_template, template: '<%= payload({id: @payload[:id]}, with_defaults: false) %>')
|
12
|
+
end
|
13
|
+
let(:webhook_service) do
|
14
|
+
WebhookService.new(
|
15
|
+
webhook: webhook,
|
16
|
+
event_name: event_name,
|
17
|
+
payload: payload_json,
|
18
|
+
headers: {},
|
19
|
+
url: webhook.target_url
|
20
|
+
)
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'executes a request to the configured webhook' do
|
24
|
+
expected = { status: :success, message: '', http_status: 200 }
|
25
|
+
|
26
|
+
stub_request(:post, 'https://hook.example.com/api/callback')
|
27
|
+
.with(
|
28
|
+
body: payload_json,
|
29
|
+
headers: {
|
30
|
+
'Content-Type' => 'application/json'
|
31
|
+
}
|
32
|
+
)
|
33
|
+
.to_return(status: 200, body: '', headers: {})
|
34
|
+
|
35
|
+
assert_equal expected, webhook_service.execute
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'handles a failed request' do
|
39
|
+
expected = { status: :error, message: '', http_status: 404 }
|
40
|
+
|
41
|
+
stub_request(:post, 'https://hook.example.com/api/callback')
|
42
|
+
.with(
|
43
|
+
body: payload_json,
|
44
|
+
headers: {
|
45
|
+
'Content-Type' => 'application/json'
|
46
|
+
}
|
47
|
+
)
|
48
|
+
.to_return(status: 404, body: '', headers: {})
|
49
|
+
|
50
|
+
assert_equal expected, webhook_service.execute
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
import React from 'react';
|
2
|
+
import WebhooksIndexPage from './Webhooks/WebhooksIndexPage';
|
3
|
+
|
4
|
+
const ForemanWebhooksRoutes = [
|
5
|
+
{
|
6
|
+
path: '/webhooks',
|
7
|
+
exact: true,
|
8
|
+
render: props => <WebhooksIndexPage {...props} />,
|
9
|
+
},
|
10
|
+
];
|
11
|
+
|
12
|
+
export default ForemanWebhooksRoutes;
|
@@ -0,0 +1,29 @@
|
|
1
|
+
import React from 'react';
|
2
|
+
import PropTypes from 'prop-types';
|
3
|
+
import { translate as __ } from 'foremanReact/common/I18n';
|
4
|
+
import DefaultEmptyState from 'foremanReact/components/common/EmptyState';
|
5
|
+
|
6
|
+
const EmptyWebhooksTable = ({ message: { type, text } }) => (
|
7
|
+
<DefaultEmptyState
|
8
|
+
icon={type === 'error' ? 'error-circle-o' : 'add-circle-o'}
|
9
|
+
header={type === 'error' ? __('Error') : __('No Results')}
|
10
|
+
description={text}
|
11
|
+
documentation={null}
|
12
|
+
/>
|
13
|
+
);
|
14
|
+
|
15
|
+
EmptyWebhooksTable.propTypes = {
|
16
|
+
message: PropTypes.shape({
|
17
|
+
type: PropTypes.oneOf(['empty', 'error']),
|
18
|
+
text: PropTypes.string,
|
19
|
+
}),
|
20
|
+
};
|
21
|
+
|
22
|
+
EmptyWebhooksTable.defaultProps = {
|
23
|
+
message: PropTypes.shape({
|
24
|
+
type: 'empty',
|
25
|
+
text: 'No Results',
|
26
|
+
}),
|
27
|
+
};
|
28
|
+
|
29
|
+
export default EmptyWebhooksTable;
|
data/webpack/ForemanWebhooks/Routes/Webhooks/WebhooksIndexPage/Components/WebhookDeleteModal.js
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
import React from 'react';
|
2
|
+
import PropTypes from 'prop-types';
|
3
|
+
|
4
|
+
import { sprintf, translate as __ } from 'foremanReact/common/I18n';
|
5
|
+
import ForemanModal from 'foremanReact/components/ForemanModal';
|
6
|
+
import { foremanUrl } from 'foremanReact/common/helpers';
|
7
|
+
|
8
|
+
import { WEBHOOK_DELETE_MODAL_ID } from '../../constants';
|
9
|
+
|
10
|
+
const WebhookDeleteModal = ({ toDelete, onSuccess }) => {
|
11
|
+
const { id, name } = toDelete;
|
12
|
+
|
13
|
+
return (
|
14
|
+
<ForemanModal
|
15
|
+
id={WEBHOOK_DELETE_MODAL_ID}
|
16
|
+
title={__('Confirm Webhook Deletion')}
|
17
|
+
enforceFocus
|
18
|
+
submitProps={{
|
19
|
+
url: foremanUrl(`/api/v2/webhooks/${id}`),
|
20
|
+
message: sprintf(__('Webhook %s was successfully deleted'), name),
|
21
|
+
onSuccess,
|
22
|
+
submitBtnProps: {
|
23
|
+
bsStyle: 'danger',
|
24
|
+
btnText: __('Delete'),
|
25
|
+
},
|
26
|
+
}}
|
27
|
+
>
|
28
|
+
{sprintf(__('You are about to delete %s. Are you sure?'), name)}
|
29
|
+
<ForemanModal.Footer />
|
30
|
+
</ForemanModal>
|
31
|
+
);
|
32
|
+
};
|
33
|
+
|
34
|
+
WebhookDeleteModal.propTypes = {
|
35
|
+
toDelete: PropTypes.object,
|
36
|
+
onSuccess: PropTypes.func.isRequired,
|
37
|
+
};
|
38
|
+
|
39
|
+
WebhookDeleteModal.defaultProps = {
|
40
|
+
toDelete: {},
|
41
|
+
};
|
42
|
+
|
43
|
+
export default WebhookDeleteModal;
|
@@ -0,0 +1,16 @@
|
|
1
|
+
import React from 'react';
|
2
|
+
import PropTypes from 'prop-types';
|
3
|
+
import { CheckIcon, BanIcon } from '@patternfly/react-icons';
|
4
|
+
|
5
|
+
const EnabledCell = ({ condition }) =>
|
6
|
+
condition ? <CheckIcon /> : <BanIcon />;
|
7
|
+
|
8
|
+
EnabledCell.propTypes = {
|
9
|
+
condition: PropTypes.bool,
|
10
|
+
};
|
11
|
+
|
12
|
+
EnabledCell.defaultProps = {
|
13
|
+
condition: false,
|
14
|
+
};
|
15
|
+
|
16
|
+
export default EnabledCell;
|
@@ -0,0 +1 @@
|
|
1
|
+
export { default as enabledCellFormatter } from './enabledCellFormatter';
|
@@ -0,0 +1,14 @@
|
|
1
|
+
import { testComponentSnapshotsWithFixtures } from '@theforeman/test';
|
2
|
+
import EnabledCell from '../EnabledCell';
|
3
|
+
|
4
|
+
const fixtures = {
|
5
|
+
'should render blank cell': {
|
6
|
+
condition: false,
|
7
|
+
},
|
8
|
+
'should render marked cell': {
|
9
|
+
condition: true,
|
10
|
+
},
|
11
|
+
};
|
12
|
+
|
13
|
+
describe('EnabledCell', () =>
|
14
|
+
testComponentSnapshotsWithFixtures(EnabledCell, fixtures));
|
@@ -0,0 +1,17 @@
|
|
1
|
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
2
|
+
|
3
|
+
exports[`EnabledCell should render blank cell 1`] = `
|
4
|
+
<BanIcon
|
5
|
+
color="currentColor"
|
6
|
+
noVerticalAlign={false}
|
7
|
+
size="sm"
|
8
|
+
/>
|
9
|
+
`;
|
10
|
+
|
11
|
+
exports[`EnabledCell should render marked cell 1`] = `
|
12
|
+
<CheckIcon
|
13
|
+
color="currentColor"
|
14
|
+
noVerticalAlign={false}
|
15
|
+
size="sm"
|
16
|
+
/>
|
17
|
+
`;
|