From c49c41a0d7915e5d8dab3b0a13e9b66caed6d3c6 Mon Sep 17 00:00:00 2001 From: Jeremy Daer Date: Mon, 15 Jun 2026 13:18:40 -0700 Subject: [PATCH] Address review: cover DiskController#update in tests Add integration coverage for the disk service PUT now that the initializer relies on it being both session-gated and CSRF-exempt: - unauthenticated PUT -> redirected to login (write blocked) - authenticated PUT with forgery protection enabled and no authenticity token -> 204 (proves the signed-token service PUT stays CSRF-exempt and guards against the concern's protect_from_forgery re-arming it) --- .../direct_uploads_controller_test.rb | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/test/controllers/active_storage/direct_uploads_controller_test.rb b/test/controllers/active_storage/direct_uploads_controller_test.rb index f614f2e..7765839 100644 --- a/test/controllers/active_storage/direct_uploads_controller_test.rb +++ b/test/controllers/active_storage/direct_uploads_controller_test.rb @@ -34,10 +34,46 @@ class ActiveStorage::DirectUploadsControllerTest < ActionDispatch::IntegrationTe assert_response :success end + test "disk update requires authentication" do + put direct_upload_url_for("hello"), params: "hello", headers: { "Content-Type" => "text/plain" } + + assert_redirected_to new_session_url + end + + test "disk update stores bytes for an authenticated session without a CSRF token" do + sign_in :david + url = direct_upload_url_for("hello") + + # Forgery protection is off in test by default; turn it on so this proves the + # signed-token service PUT stays CSRF-exempt even when the concern re-arms it. + with_forgery_protection do + put url, params: "hello", headers: { "Content-Type" => "text/plain" } + end + + assert_response :no_content + end + private def blob_params content = "hello" { filename: "hello.txt", byte_size: content.bytesize, content_type: "text/plain", \ checksum: Digest::MD5.base64digest(content) } end + + def direct_upload_url_for(content) + blob = ActiveStorage::Blob.create_before_direct_upload! \ + filename: "hello.txt", byte_size: content.bytesize, \ + checksum: Digest::MD5.base64digest(content), content_type: "text/plain" + ActiveStorage::Current.set(url_options: { host: "once.campfire.test", protocol: "http" }) do + blob.service_url_for_direct_upload + end + end + + def with_forgery_protection + original = ActionController::Base.allow_forgery_protection + ActionController::Base.allow_forgery_protection = true + yield + ensure + ActionController::Base.allow_forgery_protection = original + end end