I read many Q&A and posts on the web and tried each proposed solution without coming up to a working one for RSpec request testing with ActiveStorage and FactoryBot.
As of now, I've the code:
# factories/user.rb
factory :registered_user, :class => User do
sequence(:email) { |n| "foobar_#{n}@email.com" }
...
factory :invalid_user, :class => User do
email { '!!!' }
...
# I'm trying to make this (or similar) to work
picture { Rack::Test::UploadedFile.new(Rails.root.join('spec/factories/files/pictures/image-INVALID-size-too-big.jpg'), 'image/jpeg') }
end
end
# requests/users/images_spec.rb
RSpec.describe 'Users image requests', :type => :request do
describe 'test request at users_image_path' do
before(:each) do
@regular_user = FactoryBot.create(:regular_user)
login_as(@regular_user, :scope => :user) # Devise ruby-gem
end
subject(:user) { @regular_user }
let(:invalid_user_params) {
ActionController::Parameters.new(:picture => FactoryBot.attributes_for(:invalid_user)[:picture]).permit!
# Also tried this without success:
# { :picture => FactoryBot.attributes_for(:invalid_user)[:picture] }
}
it 'status :unprocessable_entity' do
patch users_image_path(:user => invalid_user_params, :as => :html
expect(response).to have_http_status(:unprocessable_entity)
end
end
end
By running the above spec I get the error:
ActiveSupport::MessageVerifier::InvalidSignature: mismatched digest
The logs
... when running the above spec:
Started PATCH "/users/image?user%5Bpicture%5D=%23%3CRack%3A%3ATest%3A%3AUploadedFile%3A0x0000000122758d98%3E" for 127.0.0.1 at 2024-01-09 09:07:41 +0100
[ActiveJob] Enqueued ActiveStorage::AnalyzeJob (Job ID: 835acb7e-3d89-45b5-9f1e-be2ab4f7b9cd) to Test(default) with arguments: #<GlobalID:0x000000012108d488 @uri=#<URI::GID gid://my-app/ActiveStorage::Blob/95>>
Processing by Users::ImagesController#update as HTML
Parameters: {"user"=>{"picture"=>"#<Rack::Test::UploadedFile:0x0000000122758d98>"}}
... when uploading the file manually in the browser:
Started PATCH "/users/image" for 127.0.0.1 at 2024-01-09 07:03:08 +0100
Processing by Users::ImagesController#update as HTML
Parameters: {"authenticity_token"=>"[FILTERED]", "user"=>{"picture"=>#<ActionDispatch::Http::UploadedFile:0x0000000121786190 @tempfile=#<Tempfile:/var/folders/74/bpsjzpcx73vd5601bgrny37w0000gn/T/RackMultipart20240109-45321-1ccx6n.jpg>, @content_type="image/jpeg", @original_filename="image-INVALID-size-too-big", @headers="Content-Disposition: form-data; name=\"user[picture]\"; filename=\"image-INVALID-size-too-big\"\r\nContent-Type: image/jpeg\r\n">}, "commit"=>"Update picture"}
How to make things to work?
Parameters have to go into patch
instead of a url helper:
let(:invalid_user_params) {
# permitted params are on the other side of the request, not here
{picture: Rack::Test::UploadedFile.new(Rails.root.join("spec/test.png"), "image/png")}
}
it "status :unprocessable_entity" do
# v
patch(users_image_path, params: {user: invalid_user_params})
expect(response).to have_http_status(:unprocessable_entity)
end
https://api.rubyonrails.org/classes/ActionDispatch/Integration/RequestHelpers.html#method-i-patch