Testing With Rails ActiveStorage

  Rails  
 Aug 2019

In an app I have been working on recently, I have a report model, with an attachment image, “overview”. This is an image uploaded to the app via the ActiveStorage gem that now ships with Rails.

To test this, I started by checking that when the attachment exists, it is returned properly when fetching the records via the applications Json API.

Set Up Fixtures

First of all, you need some data to work with. The thing to note here is to put the fixtures in the active_storage dir.

# test/fixtures/active_storage/blobs.yml

one:
  id: 1
  key: '111'
  filename: 'broom.png'
  content_type: 'image/png'
  metadata: nil
  byte_size: 1686342
  checksum: "123456789012345678901234"

Now associate those blobs with some records. Note it is polymorphic so you set the record type and record_id. That associates your record from your model, with the blob specified above.

# test/fixtures/active_storage/attachments.yml
one:
  name: 'overview'
  record_type: 'PointOfWorkRiskAssessment'
  record_id: <%= ActiveRecord::FixtureSet.identify(:point_of_work_risk_assessment_one) %>
  blob_id: 1

Check the asset is linked properly in a json_response.

require 'test_helper'
module Api
  class JobsTest < ActionDispatch::IntegrationTest
    include Devise::Test::IntegrationHelpers
    setup do
      @user = users(:user_one)
      @header = {
        'X-User-Email': @user.email,
        'X-User-Token': @user.authentication_token
      }
    end

    test "can see job data" do      
      @job = jobs(:job_one)
      get api_job_path(@job), headers: @header
      json_response = JSON.parse(response.body)
      assert_match /http/, json_response["job"]["workspans"][0]['workspan']['reports'][0]['report']['point_of_work_risk_assessment']['overview']
    end     
  end  
end

Testing that your controllers are processing attachments is also fairly straightforward. Just use fixture_file_upload to create a file and post. Couldn’t be simpler!

require 'test_helper'
module Api
  class ActivitiesControllerTest < ActionDispatch::IntegrationTest
    setup do
      @user = users(:user_one)      
      @header = {
        'X-User-Email': @user.email,
        'X-User-Token': @user.authentication_token
      }
    end


    test "create_activity" do
      file = fixture_file_upload('test/fixtures/files/broom.png', 'image/png')

      activity_params = {
        user_id: @user.id,    
        starts_at:  Time.now - 20.minutes,
        start_image: file
      }
      post api_activities_path,
          headers: @header,
          params: {activity: activity_params}
      assert_response :success

      activity = JSON.parse(@response.body)['activity']      

      assert Activity.find(activity["id"]).start_image.attached?
      assert activity['user_id'] == @user.id
    end
  end
end

Web Development

Got a web project you need doing well? We can help with that!

Find out more