foreman_webhooks 4.0.1 → 5.0.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 (74) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/foreman_webhooks/locale/ca/foreman_webhooks.js +1 -1
  3. data/app/assets/javascripts/foreman_webhooks/locale/cs_CZ/foreman_webhooks.js +1 -1
  4. data/app/assets/javascripts/foreman_webhooks/locale/de/foreman_webhooks.js +1 -1
  5. data/app/assets/javascripts/foreman_webhooks/locale/en/foreman_webhooks.js +6 -6
  6. data/app/assets/javascripts/foreman_webhooks/locale/en_GB/foreman_webhooks.js +11 -11
  7. data/app/assets/javascripts/foreman_webhooks/locale/es/foreman_webhooks.js +1 -1
  8. data/app/assets/javascripts/foreman_webhooks/locale/fr/foreman_webhooks.js +74 -74
  9. data/app/assets/javascripts/foreman_webhooks/locale/it/foreman_webhooks.js +1 -1
  10. data/app/assets/javascripts/foreman_webhooks/locale/ja/foreman_webhooks.js +75 -75
  11. data/app/assets/javascripts/foreman_webhooks/locale/ka/foreman_webhooks.js +9 -9
  12. data/app/assets/javascripts/foreman_webhooks/locale/ko/foreman_webhooks.js +80 -80
  13. data/app/assets/javascripts/foreman_webhooks/locale/pl/foreman_webhooks.js +1 -1
  14. data/app/assets/javascripts/foreman_webhooks/locale/pt_BR/foreman_webhooks.js +1 -1
  15. data/app/assets/javascripts/foreman_webhooks/locale/ru/foreman_webhooks.js +1 -1
  16. data/app/assets/javascripts/foreman_webhooks/locale/zh_CN/foreman_webhooks.js +78 -78
  17. data/app/assets/javascripts/foreman_webhooks/locale/zh_TW/foreman_webhooks.js +1 -1
  18. data/lib/foreman_webhooks/engine.rb +1 -1
  19. data/lib/foreman_webhooks/version.rb +1 -1
  20. data/locale/ca/LC_MESSAGES/foreman_webhooks.mo +0 -0
  21. data/locale/ca/foreman_webhooks.po +1 -1
  22. data/locale/cs_CZ/LC_MESSAGES/foreman_webhooks.mo +0 -0
  23. data/locale/cs_CZ/foreman_webhooks.po +1 -1
  24. data/locale/de/LC_MESSAGES/foreman_webhooks.mo +0 -0
  25. data/locale/de/foreman_webhooks.po +1 -1
  26. data/locale/en/LC_MESSAGES/foreman_webhooks.mo +0 -0
  27. data/locale/en/foreman_webhooks.po +9 -9
  28. data/locale/en_GB/LC_MESSAGES/foreman_webhooks.mo +0 -0
  29. data/locale/en_GB/foreman_webhooks.po +12 -12
  30. data/locale/es/LC_MESSAGES/foreman_webhooks.mo +0 -0
  31. data/locale/es/foreman_webhooks.po +1 -1
  32. data/locale/fr/LC_MESSAGES/foreman_webhooks.mo +0 -0
  33. data/locale/fr/foreman_webhooks.po +77 -74
  34. data/locale/it/LC_MESSAGES/foreman_webhooks.mo +0 -0
  35. data/locale/it/foreman_webhooks.po +2 -2
  36. data/locale/ja/LC_MESSAGES/foreman_webhooks.mo +0 -0
  37. data/locale/ja/foreman_webhooks.po +77 -75
  38. data/locale/ka/LC_MESSAGES/foreman_webhooks.mo +0 -0
  39. data/locale/ka/foreman_webhooks.po +9 -9
  40. data/locale/ko/LC_MESSAGES/foreman_webhooks.mo +0 -0
  41. data/locale/ko/foreman_webhooks.po +82 -81
  42. data/locale/pl/LC_MESSAGES/foreman_webhooks.mo +0 -0
  43. data/locale/pl/foreman_webhooks.po +1 -1
  44. data/locale/pt_BR/LC_MESSAGES/foreman_webhooks.mo +0 -0
  45. data/locale/pt_BR/foreman_webhooks.po +1 -1
  46. data/locale/ru/LC_MESSAGES/foreman_webhooks.mo +0 -0
  47. data/locale/ru/foreman_webhooks.po +1 -1
  48. data/locale/zh_CN/LC_MESSAGES/foreman_webhooks.mo +0 -0
  49. data/locale/zh_CN/foreman_webhooks.po +80 -78
  50. data/locale/zh_TW/LC_MESSAGES/foreman_webhooks.mo +0 -0
  51. data/locale/zh_TW/foreman_webhooks.po +1 -1
  52. data/test/integration/webhooks_test.rb +234 -0
  53. data/webpack/ForemanWebhooks/Routes/Webhooks/Components/WebhookForm/Components/FieldConstructor.js +321 -0
  54. data/webpack/ForemanWebhooks/Routes/Webhooks/Components/WebhookForm/Components/WebhookFormTabs.css +23 -4
  55. data/webpack/ForemanWebhooks/Routes/Webhooks/Components/WebhookForm/Components/WebhookFormTabs.js +191 -149
  56. data/webpack/ForemanWebhooks/Routes/Webhooks/Components/WebhookForm/Components/__tests__/FieldConstructor.test.js +216 -0
  57. data/webpack/ForemanWebhooks/Routes/Webhooks/Components/WebhookForm/WebhookForm.js +55 -26
  58. data/webpack/ForemanWebhooks/Routes/Webhooks/Components/WebhookForm/__tests__/WebhookForm.test.js +253 -37
  59. data/webpack/ForemanWebhooks/Routes/Webhooks/Components/WebhookForm/index.js +3 -4
  60. data/webpack/ForemanWebhooks/Routes/Webhooks/WebhooksIndexPage/Components/WebhookCreateModal.js +30 -19
  61. data/webpack/ForemanWebhooks/Routes/Webhooks/WebhooksIndexPage/Components/WebhookDeleteModal.js +52 -18
  62. data/webpack/ForemanWebhooks/Routes/Webhooks/WebhooksIndexPage/Components/WebhookEditModal.js +37 -26
  63. data/webpack/ForemanWebhooks/Routes/Webhooks/WebhooksIndexPage/Components/WebhookTestModal.js +57 -32
  64. data/webpack/ForemanWebhooks/Routes/Webhooks/WebhooksIndexPage/Components/WebhooksTable/Components/NameToEditCell.js +8 -1
  65. data/webpack/ForemanWebhooks/Routes/Webhooks/WebhooksIndexPage/Components/WebhooksTable/Components/__tests__/__snapshots__/EnabledCell.test.js.snap +2 -14
  66. data/webpack/ForemanWebhooks/Routes/Webhooks/WebhooksIndexPage/Components/WebhooksTable/WebhooksTable.js +24 -11
  67. data/webpack/ForemanWebhooks/Routes/Webhooks/WebhooksIndexPage/Components/WebhooksTable/__tests__/__snapshots__/WebhooksTable.test.js.snap +64 -0
  68. data/webpack/ForemanWebhooks/Routes/Webhooks/WebhooksIndexPage/Components/WebhooksTable/index.js +21 -22
  69. data/webpack/ForemanWebhooks/Routes/Webhooks/WebhooksIndexPage/WebhooksIndexPage.js +9 -15
  70. data/webpack/ForemanWebhooks/Routes/Webhooks/WebhooksIndexPage/__tests__/integration.test.js +0 -3
  71. metadata +8 -9
  72. data/webpack/ForemanWebhooks/Routes/Webhooks/Components/WebhookForm/Components/ForemanFormikField.js +0 -152
  73. data/webpack/ForemanWebhooks/Routes/Webhooks/Components/WebhookForm/__tests__/__snapshots__/WebhookForm.test.js.snap +0 -512
  74. data/webpack/ForemanWebhooks/Routes/Webhooks/WebhooksIndexPage/__tests__/__snapshots__/integration.test.js.snap +0 -31
@@ -7,13 +7,15 @@
7
7
  # Bryan Kearney <bryan.kearney@gmail.com>, 2023
8
8
  # Amit Upadhye <aupadhye@redhat.com>, 2023
9
9
  # tim123, 2023
10
+ # Ewoud Kohl van Wijngaarden <ewoud+transifex@kohlvanwijngaarden.nl>, 2024
11
+ # Ondřej Gajdušek, 2025
10
12
  #
11
13
  msgid ""
12
14
  msgstr ""
13
- "Project-Id-Version: foreman_webhooks 3.2.0\n"
15
+ "Project-Id-Version: foreman_webhooks 4.0.1\n"
14
16
  "Report-Msgid-Bugs-To: \n"
15
17
  "PO-Revision-Date: 2023-06-05 12:44+0000\n"
16
- "Last-Translator: tim123, 2023\n"
18
+ "Last-Translator: Ondřej Gajdušek, 2025\n"
17
19
  "Language-Team: Chinese (China) (https://app.transifex.com/foreman/teams/114/zh"
18
20
  "_CN/)\n"
19
21
  "MIME-Version: 1.0\n"
@@ -29,31 +31,31 @@ msgid "Additional"
29
31
  msgstr "额外"
30
32
 
31
33
  msgid "Authentication credentials"
32
- msgstr ""
34
+ msgstr "身份验证凭证"
33
35
 
34
36
  msgid "Authorize with Foreman client certificate and validate smart-proxy CA from Settings"
35
- msgstr ""
37
+ msgstr "使用 Foreman 客户端证书授权并从设置验证智能代理 CA"
36
38
 
37
39
  msgid "Change the password"
38
- msgstr ""
40
+ msgstr "修改密码"
39
41
 
40
42
  msgid "Clone a template"
41
- msgstr ""
43
+ msgstr "克隆模板"
42
44
 
43
45
  msgid "Confirm Webhook Deletion"
44
- msgstr ""
46
+ msgstr "确认 Webhook 删除"
45
47
 
46
48
  msgid "Create Template"
47
- msgstr ""
49
+ msgstr "创建模板"
48
50
 
49
51
  msgid "Create Webhook"
50
- msgstr ""
52
+ msgstr "创建 Webhook"
51
53
 
52
54
  msgid "Create a Webhook"
53
- msgstr ""
55
+ msgstr "创建 Webhook"
54
56
 
55
57
  msgid "Create a webhook template"
56
- msgstr ""
58
+ msgstr "创建 webhook 模板"
57
59
 
58
60
  msgid "Credentials"
59
61
  msgstr "凭证"
@@ -62,151 +64,151 @@ msgid "Delete"
62
64
  msgstr "刪除"
63
65
 
64
66
  msgid "Delete a Webhook"
65
- msgstr ""
67
+ msgstr "删除 Webhook"
66
68
 
67
69
  msgid "Delete a webhook template"
68
- msgstr ""
70
+ msgstr "删除 webhook 模板"
69
71
 
70
72
  msgid "Deliver webhook"
71
- msgstr ""
73
+ msgstr "提供 webhook"
72
74
 
73
75
  msgid "Deliver webhook %s"
74
- msgstr ""
76
+ msgstr "提供 webhook %s"
75
77
 
76
78
  msgid "Edit"
77
79
  msgstr "编辑"
78
80
 
79
81
  msgid "Edit %s"
80
- msgstr ""
82
+ msgstr "编辑 %s"
81
83
 
82
84
  msgid "Enabled"
83
85
  msgstr "启用"
84
86
 
85
87
  msgid "Error"
86
- msgstr ""
88
+ msgstr "错误"
87
89
 
88
90
  msgid "Example: %s"
89
- msgstr ""
91
+ msgstr "示例: %s"
90
92
 
91
93
  msgid "Export a webhook template to ERB"
92
- msgstr ""
94
+ msgstr "向 ERB 导出 webhook 模板"
93
95
 
94
96
  msgid "General"
95
- msgstr ""
97
+ msgstr "常规"
96
98
 
97
99
  msgid "HTTP Content Type"
98
- msgstr ""
100
+ msgstr "HTTP 內容类型"
99
101
 
100
102
  msgid "HTTP Headers"
101
- msgstr ""
103
+ msgstr "HTTP 标头"
102
104
 
103
105
  msgid "HTTP Method"
104
- msgstr ""
106
+ msgstr "HTTP 方法"
105
107
 
106
108
  msgid "If unchecked, the webhook will be inactive"
107
- msgstr ""
109
+ msgstr "如果没有选择,webhook 将为不活跃状态"
108
110
 
109
111
  msgid "Import a webhook template"
110
- msgstr ""
112
+ msgstr "导入 webhook 模板"
111
113
 
112
114
  msgid "In case you are using dynamic URL (ERB template), this will not be rendered correctly due to the absence of a real object."
113
- msgstr ""
115
+ msgstr "如果您使用动态 URL (ERB 模板),因为缺少真实的对象,这不会被正确显示。"
114
116
 
115
117
  msgid "List Webhooks"
116
- msgstr ""
118
+ msgstr "列出 Webhook"
117
119
 
118
120
  msgid "List available events for subscription"
119
- msgstr ""
121
+ msgstr "列出订阅的可用事件"
120
122
 
121
123
  msgid "List webhook templates"
122
- msgstr ""
124
+ msgstr "列出 webhook 模板"
123
125
 
124
126
  msgid "Name"
125
- msgstr ""
127
+ msgstr "名称"
126
128
 
127
129
  msgid "No Results"
128
- msgstr ""
130
+ msgstr "没有结果"
129
131
 
130
132
  msgid "Optional CAs in PEM format concatenated to verify the receiver's SSL certificate"
131
- msgstr ""
133
+ msgstr "PEM 格式的可选 CA 连接起来验证接收器的 SSL 证书"
132
134
 
133
135
  msgid "Optional. Must be a JSON object (ERB allowed)"
134
- msgstr ""
136
+ msgstr "可选。必须是 JSON 对象(ERB 允许)"
135
137
 
136
138
  msgid "Password"
137
- msgstr ""
139
+ msgstr "密码"
138
140
 
139
141
  msgid "Payload"
140
- msgstr ""
142
+ msgstr "有效负载"
141
143
 
142
144
  msgid "Please, note that this will not contain actual information or render the attached template."
143
- msgstr ""
145
+ msgstr "请注意,这不包含实际信息或呈现附加的模板。"
144
146
 
145
147
  msgid "Proxy Authorization"
146
- msgstr ""
148
+ msgstr "代理授权"
147
149
 
148
150
  msgid "Show Webhook details"
149
- msgstr ""
151
+ msgstr "显示 Webhook 详情"
150
152
 
151
153
  msgid "Show webhook template details"
152
- msgstr ""
154
+ msgstr "显示 webhook 模板详情"
153
155
 
154
156
  msgid "Snippet"
155
- msgstr ""
157
+ msgstr "程序代码片段"
156
158
 
157
159
  msgid "Start typing to search"
158
- msgstr ""
160
+ msgstr "开始输入来进行搜素"
159
161
 
160
162
  msgid "Subscribe to"
161
- msgstr ""
163
+ msgstr "订阅到"
162
164
 
163
165
  msgid "Target URL"
164
- msgstr ""
166
+ msgstr "目标 URL"
165
167
 
166
168
  msgid "Target URL that should be called by Foreman (ERB allowed)."
167
- msgstr ""
169
+ msgstr "Foreman 应该调用的目标 URL (ERB 允许)。"
168
170
 
169
171
  msgid "Template"
170
- msgstr ""
172
+ msgstr "模板"
171
173
 
172
174
  msgid "Template contents including metadata"
173
- msgstr ""
175
+ msgstr "模板内容包括元数据"
174
176
 
175
177
  msgid "Template name"
176
- msgstr ""
178
+ msgstr "模板名称"
177
179
 
178
180
  msgid "Test"
179
- msgstr ""
181
+ msgstr "测试"
180
182
 
181
183
  msgid "Test a Webhook"
182
- msgstr ""
184
+ msgstr "测试 Webhook"
183
185
 
184
186
  msgid "Test payload will be sent as is. Cant be a JSON object"
185
- msgstr ""
187
+ msgstr "测试有效负载将按原样发送。不能是一个 JSON 对象"
186
188
 
187
189
  msgid "Test webhook"
188
- msgstr ""
190
+ msgstr "测试 webhook"
189
191
 
190
192
  msgid "This template is locked for editing."
191
- msgstr ""
193
+ msgstr "该模板被锁定进行编辑。"
192
194
 
193
195
  msgid "Try to create a new webhook"
194
- msgstr ""
196
+ msgstr "尝试创建新的 webhook"
195
197
 
196
198
  msgid "Type"
197
- msgstr ""
199
+ msgstr "类型"
198
200
 
199
201
  msgid "URL must be valid and schema must be one of: %s"
200
- msgstr ""
202
+ msgstr "URL 必须有效且需要是 %s 之一"
201
203
 
202
204
  msgid "Uncheck this option to disable validation of the receiver's SSL certificate"
203
- msgstr ""
205
+ msgstr "取消这个选项来禁用接收方的 SSL 正式的验证"
204
206
 
205
207
  msgid "Update a Webhook"
206
- msgstr ""
208
+ msgstr "更新 Webhook"
207
209
 
208
210
  msgid "Update a webhook template"
209
- msgstr ""
211
+ msgstr "更新 webhook 模板"
210
212
 
211
213
  msgid "User"
212
214
  msgstr "用户"
@@ -215,64 +217,64 @@ msgid "Verify SSL"
215
217
  msgstr "验证 SSL"
216
218
 
217
219
  msgid "Webhook"
218
- msgstr ""
220
+ msgstr "Webhook"
219
221
 
220
222
  msgid "Webhook %s test was successful"
221
- msgstr ""
223
+ msgstr "Webhook %s 测试成功"
222
224
 
223
225
  msgid "Webhook %s was successfully deleted"
224
- msgstr ""
226
+ msgstr "Webhook %s 被成功删除"
225
227
 
226
228
  msgid "Webhook Templates"
227
- msgstr ""
229
+ msgstr "Webhook 模板"
228
230
 
229
231
  msgid "Webhook template not found while firing webhook '%s'. Possible organization/location mismatch in the webhook template?"
230
- msgstr ""
232
+ msgstr "在触发 Webhook '%s' 时未找到 Webhook 模板。可能 webhook 模板中的机构/位置不匹配?"
231
233
 
232
234
  msgid "Webhook test failed: %s"
233
- msgstr ""
235
+ msgstr "Webhook 测试失败: %s"
234
236
 
235
237
  msgid "Webhook was successfully created."
236
- msgstr ""
238
+ msgstr "Webhook 被成功创建。"
237
239
 
238
240
  msgid "Webhook was successfully updated."
239
- msgstr ""
241
+ msgstr "Webhook 被成功更新。"
240
242
 
241
243
  msgid "WebhookTemplate|Locked"
242
- msgstr ""
244
+ msgstr "Webhook 模板|锁定"
243
245
 
244
246
  msgid "WebhookTemplate|Name"
245
- msgstr ""
247
+ msgstr "Webhook 模板|名称"
246
248
 
247
249
  msgid "WebhookTemplate|Snippet"
248
- msgstr ""
250
+ msgstr "Webhook 模板|代码片段"
249
251
 
250
252
  msgid "Webhooks"
251
- msgstr ""
253
+ msgstr "Webhook"
252
254
 
253
255
  msgid "Whether or not the template is added automatically to new organizations and locations"
254
- msgstr ""
256
+ msgstr "模板是否会自动添加到新的机构和位置"
255
257
 
256
258
  msgid "Whether or not the template is locked for editing"
257
- msgstr ""
259
+ msgstr "此模板是否被锁定用于编辑"
258
260
 
259
261
  msgid "Will be sent as is"
260
- msgstr ""
262
+ msgstr "将按原样发送"
261
263
 
262
264
  msgid "X509 Certification Authorities"
263
- msgstr ""
265
+ msgstr "X509 认证颁发机构"
264
266
 
265
267
  msgid "X509 Certification Authorities concatenated in PEM format"
266
- msgstr ""
268
+ msgstr "以 PEM 格式串联的 X509 认证颁发机构"
267
269
 
268
270
  msgid "You are about to delete %s. Are you sure?"
269
- msgstr ""
271
+ msgstr "您将要删除 %s。您确定吗?"
270
272
 
271
273
  msgid "You are about to test %s webhook."
272
- msgstr ""
274
+ msgstr "您要测试 %s webhook。"
273
275
 
274
276
  msgid "You can specify below a custom payload to test the webhook with."
275
- msgstr ""
277
+ msgstr "您可以指定以下一个自定义有效负载来测试 Webhook。"
276
278
 
277
279
  msgid "is required"
278
280
  msgstr "是必需的"
@@ -9,7 +9,7 @@
9
9
  #
10
10
  msgid ""
11
11
  msgstr ""
12
- "Project-Id-Version: foreman_webhooks 3.2.0\n"
12
+ "Project-Id-Version: foreman_webhooks 4.0.1\n"
13
13
  "Report-Msgid-Bugs-To: \n"
14
14
  "PO-Revision-Date: 2023-06-05 12:44+0000\n"
15
15
  "Last-Translator: 0868a4d1af5275b3f70b0a6dac4c99a4, 2023\n"
@@ -0,0 +1,234 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../test_plugin_helper'
4
+ require 'integration_test_helper'
5
+
6
+ class WebhooksIntegrationTest < IntegrationTestWithJavascript
7
+ let(:webhook_template) { FactoryBot.create(:webhook_template, name: 'Test Template') }
8
+ let(:second_template) { FactoryBot.create(:webhook_template, name: 'Second Template') }
9
+
10
+ setup do
11
+ webhook_template
12
+ second_template
13
+ end
14
+
15
+ test 'create webhook and verify via UI' do
16
+ hook_name = "TestWebhook"
17
+ subscribe_to = 'Host Created'
18
+ target_url = 'http://example.com/webhook'
19
+ http_method = 'GET'
20
+ username = 'testuser'
21
+ password = 'testpass123'
22
+
23
+ visit '/webhooks'
24
+ assert_selector 'h1', text: 'Webhooks'
25
+
26
+ click_button 'Create new'
27
+ assert_selector '.pf-v5-c-modal-box'
28
+
29
+ fill_in_typeahead('id-event', subscribe_to)
30
+ fill_in 'id-name', with: hook_name
31
+ fill_in 'id-target_url', with: target_url
32
+ fill_in_typeahead('id-webhook_template_id', webhook_template.name)
33
+ fill_in_typeahead('id-http_method', http_method)
34
+ uncheck_checkbox('id-enabled')
35
+
36
+ click_tab('Credentials')
37
+ fill_in 'id-user', with: username
38
+ fill_in 'id-password', with: password
39
+ check_checkbox('id-proxy_authorization')
40
+ uncheck_checkbox('id-verify_ssl')
41
+
42
+ click_submit_button
43
+ wait_for_success_toast
44
+
45
+ visit '/webhooks'
46
+ wait_for_ajax
47
+ click_webhook_name(hook_name)
48
+ assert_selector '.pf-v5-c-modal-box'
49
+
50
+ assert_field_value('id-name', hook_name)
51
+ assert_typeahead_value('id-event', subscribe_to)
52
+ assert_field_value('id-target_url', target_url)
53
+ assert_typeahead_value('id-webhook_template_id', webhook_template.name)
54
+ assert_typeahead_value('id-http_method', http_method)
55
+ assert_checkbox_unchecked('id-enabled')
56
+
57
+ click_tab('Credentials')
58
+ assert_field_value('id-user', username)
59
+ assert_checkbox_checked('id-proxy_authorization')
60
+ assert_checkbox_unchecked('id-verify_ssl')
61
+
62
+ click_cancel_button
63
+ assert_no_selector '.pf-v5-c-modal-box'
64
+
65
+ webhook = Webhook.find_by(name: hook_name)
66
+ assert webhook, "Webhook '#{hook_name}' was not created"
67
+ assert webhook.password.present?, 'Password was not saved to database'
68
+ end
69
+
70
+ test 'update webhook and verify via UI' do
71
+ webhook = FactoryBot.create(:webhook,
72
+ name: 'ExistingWebhook',
73
+ target_url: 'http://old.example.com/webhook',
74
+ http_method: 'POST',
75
+ webhook_template: webhook_template,
76
+ user: 'olduser',
77
+ password: 'oldpass123',
78
+ enabled: false)
79
+
80
+ new_hook_name = "UpdatedWebhook"
81
+ new_subscribe_to = 'Host Destroyed'
82
+ new_target_url = 'http://newexample.com/webhook'
83
+ new_http_method = 'PUT'
84
+
85
+ visit '/webhooks'
86
+ wait_for_ajax
87
+ click_webhook_name(webhook.name)
88
+ assert_selector '.pf-v5-c-modal-box'
89
+
90
+ fill_in_typeahead('id-event', new_subscribe_to)
91
+ fill_in 'id-name', with: '', fill_options: { clear: :backspace }
92
+ fill_in 'id-name', with: new_hook_name
93
+ fill_in 'id-target_url', with: '', fill_options: { clear: :backspace }
94
+ fill_in 'id-target_url', with: new_target_url
95
+ fill_in_typeahead('id-webhook_template_id', second_template.name)
96
+ fill_in_typeahead('id-http_method', new_http_method)
97
+ check_checkbox('id-enabled')
98
+
99
+ click_submit_button
100
+ wait_for_success_toast
101
+
102
+ visit '/webhooks'
103
+ wait_for_ajax
104
+ click_webhook_name(new_hook_name)
105
+ assert_selector '.pf-v5-c-modal-box'
106
+
107
+ assert_field_value('id-name', new_hook_name)
108
+ assert_typeahead_value('id-event', new_subscribe_to)
109
+ assert_field_value('id-target_url', new_target_url)
110
+ assert_typeahead_value('id-webhook_template_id', second_template.name)
111
+ assert_typeahead_value('id-http_method', new_http_method)
112
+ assert_checkbox_checked('id-enabled')
113
+
114
+ click_cancel_button
115
+ assert_no_selector '.pf-v5-c-modal-box'
116
+
117
+ webhook.reload
118
+ assert webhook.password.present?, 'Password was cleared after update'
119
+ end
120
+
121
+ test 'delete webhook via UI' do
122
+ webhook = FactoryBot.create(:webhook,
123
+ name: 'WebhookToDelete',
124
+ target_url: 'http://example.com/webhook',
125
+ http_method: 'POST',
126
+ webhook_template: webhook_template)
127
+
128
+ visit '/webhooks'
129
+ wait_for_ajax
130
+ click_webhook_delete_button(webhook.name)
131
+ assert_selector '#webhookDeleteModal'
132
+ click_delete_confirm_button
133
+ wait_for_success_toast
134
+ assert_no_selector '#webhookDeleteModal'
135
+
136
+ assert_no_selector :xpath, "//tr[contains(., '#{webhook.name}')]"
137
+ assert_nil Webhook.find_by(name: webhook.name), "Webhook should be deleted"
138
+ end
139
+
140
+ private
141
+
142
+ def click_tab(tab_name)
143
+ tab_id = case tab_name
144
+ when 'General' then 'webhook-form-tab-general'
145
+ when 'Credentials' then 'webhook-form-tab-creds'
146
+ when 'Additional' then 'webhook-form-tab-add'
147
+ else raise "Unknown tab: #{tab_name}"
148
+ end
149
+ tab_button = find(:ouia_component_id, tab_id)
150
+ page.execute_script('arguments[0].click()', tab_button.native)
151
+ end
152
+
153
+ def fill_in_typeahead(field_id, value)
154
+ input = find("##{field_id}")
155
+ input.click
156
+ input.send_keys([:control, 'a'])
157
+ input.send_keys(:backspace)
158
+ input.send_keys(value)
159
+ # Wait for dropdown to appear with matching option
160
+ assert_selector '[role="option"]', text: value
161
+ find('[role="option"]', text: value, match: :prefer_exact).click
162
+ # Wait for dropdown to close
163
+ assert_no_selector '[role="listbox"]'
164
+ end
165
+
166
+ def check_checkbox(field_id)
167
+ checkbox = find("##{field_id}", visible: :all)
168
+ return if checkbox.checked?
169
+ page.execute_script("document.getElementById('#{field_id}').click()")
170
+ end
171
+
172
+ def uncheck_checkbox(field_id)
173
+ checkbox = find("##{field_id}", visible: :all)
174
+ return unless checkbox.checked?
175
+ page.execute_script("document.getElementById('#{field_id}').click()")
176
+ end
177
+
178
+ def click_submit_button
179
+ modal = find('.pf-v5-c-modal-box', wait: 10)
180
+ button = modal.find(:ouia_component_id, 'submit-webhook-form', wait: 10, visible: :all)
181
+ wait_for { !button.disabled? }
182
+ page.execute_script('arguments[0].scrollIntoView({block: "center"})', button.native)
183
+ page.execute_script('arguments[0].click()', button.native)
184
+ end
185
+
186
+ def click_cancel_button
187
+ modal = find('.pf-v5-c-modal-box', wait: 10)
188
+ button = modal.find('button', text: 'Cancel', match: :first, wait: 10, visible: :all)
189
+ page.execute_script('arguments[0].scrollIntoView({block: "center"})', button.native)
190
+ page.execute_script('arguments[0].click()', button.native)
191
+ end
192
+
193
+ def click_webhook_name(name)
194
+ row = find(:xpath, "//tbody//tr[contains(., '#{name}')]", wait: 15, match: :first)
195
+ within(row) do
196
+ button = find(:ouia_component_id, 'name-edit-active-button', wait: 10)
197
+ page.execute_script('arguments[0].click()', button.native)
198
+ end
199
+ end
200
+
201
+ def click_webhook_delete_button(name)
202
+ row = find(:xpath, "//tbody//tr[contains(., '#{name}')]", wait: 15, match: :first)
203
+ within(row) do
204
+ find('button', text: 'Delete', match: :first).click
205
+ end
206
+ end
207
+
208
+ def click_delete_confirm_button
209
+ within('#webhookDeleteModal') do
210
+ find('button', text: 'Delete', match: :first).click
211
+ end
212
+ end
213
+
214
+ def assert_field_value(field_id, expected_value)
215
+ assert page.has_field?(field_id, with: expected_value),
216
+ "Field #{field_id} expected '#{expected_value}'"
217
+ end
218
+
219
+ def assert_typeahead_value(field_id, expected_value)
220
+ field = find("##{field_id}")
221
+ assert_includes field.value, expected_value,
222
+ "Typeahead #{field_id} expected to contain '#{expected_value}' but was '#{field.value}'"
223
+ end
224
+
225
+ def assert_checkbox_checked(field_id)
226
+ assert page.has_checked_field?(field_id, visible: :all),
227
+ "Checkbox #{field_id} expected to be checked"
228
+ end
229
+
230
+ def assert_checkbox_unchecked(field_id)
231
+ assert page.has_unchecked_field?(field_id, visible: :all),
232
+ "Checkbox #{field_id} expected to be unchecked"
233
+ end
234
+ end