Files
openproject/modules/webhooks/spec/features/manage_webhooks_spec.rb
T
Alexander Brandon Coles e8767481e9 [#70166] Fix accessibility errors found by ERB Lint (#21503)
* Fix GitHub/NoTitleAttribute, LinkHasHref errors

- Replaces `title` attribute with `aria-label` for interactive elements.
- Removes `title` from non-interactive elements.
- Converts `<a>` tags without proper `href` to `<button>` elements,
  using Primer `Button`/`IconButton` where possible.

# Conflicts:
#	app/views/custom_fields/_custom_options.html.erb
#	spec/features/admin/custom_fields/shared_custom_field_expectations.rb
#	spec/features/admin/custom_fields/work_packages/list_spec.rb

* Fix Autocomplete missing errors

* Fix GitHub/NoPositiveTabIndex errors

Removes all positive `tabindex` values.

* Fix Rails/LinkToBlank errors

* Replace toast with Primer Banner on LDAP form

* Add frozen_string_literal

* Ignore erb lint for deprecated files

* Fix linting errors in repository module

* Fix linting errors in budgets and custom actions

* Fix linting errors in member form and 2fa

* Fix linting errors in mcost types and wiki help and storages

* Fix linting errors in multi select filters, ifc viewer, and unsupported browser banner

* Fix failing spec

* Use Primer banner instead of op-toast where ever it is possible

* Use octicon instead of op_icon

* Fix failing tests

* Use no-decoration-on-hover for button links and change the button with only an icon to primer icon button

* Keep webhook response modal activation selector class-based

* use icon button for edit of hourly rate

---------

Co-authored-by: Behrokh Satarnejad <b.satarnejad@openproject.com>
2026-05-07 10:31:10 +02:00

139 lines
4.7 KiB
Ruby

# frozen_string_literal: true
require "spec_helper"
RSpec.describe "Manage webhooks through UI", :js, :selenium do
before do
login_as user
end
context "as regular user" do
let(:user) { create(:user) }
it "forbids accessing the webhooks management view" do
visit admin_outgoing_webhooks_path
expect(page).to have_text "[Error 403]"
end
end
context "as admin" do
let(:user) { create(:admin) }
let!(:project) { create(:project) }
it "allows the management flow" do
visit admin_outgoing_webhooks_path
expect(page).to have_css(".generic-table--empty-row")
# Visit inline create
find(".wp-inline-create--add-link").click
SeleniumHubWaiter.wait
# Fill in elements
fill_in "webhook_name", with: "My webhook"
fill_in "webhook_url", with: "http://example.org"
# Check one event
find('.form--check-box[value="work_package:created"]').set true
# Create
click_on "Create"
#
# 1st webhook created
#
expect_flash(message: I18n.t(:notice_successful_create))
expect(page).to have_css(".webhooks--outgoing-webhook-row .name", text: "My webhook")
webhook = Webhooks::Webhook.last
expect(webhook.event_names).to eq %w(work_package:created)
expect(webhook.all_projects).to be_truthy
expect(page).to have_css(".webhooks--outgoing-webhook-row .enabled .icon-yes")
expect(page).to have_css(".webhooks--outgoing-webhook-row .selected_projects", text: "All projects")
expect(page).to have_css(".webhooks--outgoing-webhook-row .events", text: "Work packages")
expect(page).to have_css(".webhooks--outgoing-webhook-row .description", text: webhook.description)
SeleniumHubWaiter.wait
# Edit this webhook
find(".webhooks--outgoing-webhook-row-#{webhook.id} .icon-edit").click
SeleniumHubWaiter.wait
# Check the other event
find('.form--check-box[value="work_package:created"]').set false
find('.form--check-box[value="work_package:updated"]').set true
# Check a subset of projects
choose "webhook_project_ids_selection"
find(".webhooks--selected-project-ids[value='#{project.id}']").set true
click_on "Save"
expect_flash(message: I18n.t(:notice_successful_update))
expect(page).to have_css(".webhooks--outgoing-webhook-row .name", text: "My webhook")
webhook = Webhooks::Webhook.last
expect(webhook.event_names).to eq %w(work_package:updated)
expect(webhook.projects.all).to eq [project]
expect(webhook.all_projects).to be_falsey
SeleniumHubWaiter.wait
# Delete webhook
accept_confirm do
find(".webhooks--outgoing-webhook-row-#{webhook.id} .icon-delete").click
end
expect_flash(message: I18n.t(:notice_successful_delete))
expect(page).to have_css(".generic-table--empty-row")
end
context "with existing webhook" do
let!(:webhook) { create(:webhook, name: "testing") }
let!(:log) { create(:webhook_log, response_headers: { test: :foo }, webhook:) }
it "shows the delivery" do
visit admin_outgoing_webhooks_path
SeleniumHubWaiter.wait
find(".webhooks--outgoing-webhook-row .name a", text: "testing").click
expect(page).to have_css(".on-off-status.-enabled")
expect(page).to have_css("td.event_name", text: "foo")
expect(page).to have_css("td.response_code", text: "200")
# Open modal
SeleniumHubWaiter.wait
find("td.response_body").click_on "Show"
page.within(".spot-modal") do
expect(page).to have_css(".webhooks--response-headers strong", text: "test")
expect(page).to have_css(".webhooks--response-body", text: log.response_body)
end
end
context "with multiple logs" do
let!(:log2) { create(:webhook_log, response_body: "This is the second log", webhook:) }
let!(:log3) { create(:webhook_log, response_body: "This is the third log", webhook:) }
it "shows the response of the log being clicked" do
visit admin_outgoing_webhook_path(webhook)
# Open modal
SeleniumHubWaiter.wait
all("tbody tr").each do |row_element|
matching_log = nil
within(row_element) do
id = find("td.id").text.to_i
matching_log = [log, log2, log3].find { |l| l.id == id }
find("td.response_body").click_on "Show"
end
page.within(".spot-modal") do
expect(page).to have_css(".webhooks--response-body", text: matching_log.response_body)
click_button("Close")
end
end
end
end
end
end
end