The pipeline admin form could never save
ci/woodpecker/push/woodpecker Pipeline was successful

`ActiveAdmin.register WarpEngine::Pipeline` declared no `permit_params`, so every edit
handed unpermitted attributes to the model and Rails raised ForbiddenAttributesError. That
is not new: the form has been unable to save for as long as it has existed. My flash
message on `update` sat at the top of the traceback and made it look like the cause, which
it was not — and it is gone anyway, because overriding an ActiveAdmin action to say
something is a poor trade for what it can break. The move is written to the log instead.

Adding a spec that would have caught it, in the host app, because that is where the
ActiveAdmin instance lives: it signs in, PUTs the form, and checks both that the record
saves and that the software link moves off the pipeline that had it. Driven the same way
by hand against the development database first — 302, the link moved, the previous holder
left without one.

The engine's other admin resources were checked for the same omission: downloads and
releases are read-only and the file manager posts to its own routes, so pipelines was the
only one affected.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-18 20:41:16 +02:00
co-authored by Claude Opus 5
parent a0a7ff63e1
commit 7ea8303b1a
3 changed files with 73 additions and 14 deletions
@@ -0,0 +1,56 @@
require "rails_helper"
require "warden/test/helpers"
# The pipeline admin form could not save at all: the resource never declared
# `permit_params`, so ActiveAdmin handed unpermitted attributes to the model and Rails
# raised ForbiddenAttributesError on every edit. No model spec could have caught that —
# the fault was one layer up — so the check belongs here, where the host's ActiveAdmin
# instance actually runs.
RSpec.describe "Admin pipelines", type: :request do
include Warden::Test::Helpers
let(:admin) { AdminUser.create!(email: "pipelines-spec@example.org", password: "password123") }
let(:software) { create(:software) }
let!(:holder) do
WarpEngine::Pipeline.create!(woodpecker_repo_id: 990_001, repo_owner: "spec", repo_name: "holder",
platform: "tic80", software: software)
end
let!(:taker) do
WarpEngine::Pipeline.create!(woodpecker_repo_id: 990_002, repo_owner: "spec", repo_name: "taker",
platform: "tic80")
end
before do
Warden.test_mode!
login_as(admin, scope: :admin_user)
end
after { Warden.test_reset! }
# This app keeps forgery protection on in the test environment, and a request spec has
# no rendered form to take a token from. The token is not what is under test here, so it
# is switched off for the duration and put back afterwards.
around do |example|
protection = ActionController::Base.allow_forgery_protection
ActionController::Base.allow_forgery_protection = false
example.run
ActionController::Base.allow_forgery_protection = protection
end
it "saves the form" do
put "/admin/pipelines/#{taker.id}", params: { pipeline: { platform: "godot" } }
expect(response).to have_http_status(:found)
expect(taker.reload.platform).to eq("godot")
end
it "moves the software off the pipeline that had it" do
put "/admin/pipelines/#{taker.id}",
params: { pipeline: { platform: "tic80", software_id: software.id } }
expect(response).to have_http_status(:found)
expect(taker.reload.software).to eq(software)
expect(holder.reload.software).to be_nil
expect(software.reload.pipeline).to eq(taker)
end
end