Search code examples
ruby-on-railsrspecrails-activestorage

ActiveStorage attachment not associated after reload in specs


I want to test that a file is correctly being attached to a record.

I have a Notification model with a thumbnail.

class Notification < ApplicationRecord
  has_one_attached :thumbnail
end

I'm using sidekiq through active job.

# config/application.rb
module MyApp
  class Application < Rails::Application
    config.active_job.queue_adapter = :sidekiq
  end
end

I have set storage adapter to the local file system and perform jobs immediately

# config/environments/test.rb
Rails.application.configure do
  config.active_storage.service = :test
  config.active_job.queue_adapter = :inline
end

I have the following spec using capybara and selenium:

      it 'creates the model' do
        click_on class: 'create-action'

        attach_file('notification[thumbnail]', Rails.root.join('spec/fixtures/uploads/notification_thumbnail.jpg'))
        fill_in 'notification[title]', with: 'MyString'

        expect do
          click_on 'Create notification'
        end.to change { ActiveStorage::Attachment.count }.by(1)

        new_notification = Notification.order(created_at: :desc).first

        expect(page).to have_content(I18n.t('successfully_created_resource', resource: 'MyString'))

        new_notification.reload

        expect(new_notification.thumbnail).to be_attached
     end

To investigate further I created a simple spec:

    it 'has an attached thumbnail' do
      notification = build(:notification)
      notification.thumbnail = fixture_file_upload(Rails.root.join('spec/fixtures/uploads/notification_thumbnail.jpg'), 'image/jpg')
      notification.save

      puts ActiveStorage::Blob.order(created_at: :desc).first.attachments.inspect
      expect(notification.thumbnail).to be_attached
      expect(notification.reload.thumbnail).to be_attached
    end

The first expectation always passes, the latter sometimes fails.

When looking at the attachment it has record_id 0

#<ActiveRecord::Associations::CollectionProxy [#<ActiveStorage::Attachment id: 1, name: "thumbnail", record_type: "Notification", record_id: 0, blob_id: 1, created_at: "2020-11-30 10:40:28">]>

Can anyone explain this behavior to me and give me pointers on how do avoid it / write tests properly?


Solution

  • While investigating a different bug I realized ActiveStorage was not set up for usage with UUIDs as the big red box in the setup section warns about.

    2.7.0 :001 > "2a".to_i
     => 2
    2.7.0 :002 > "a2".to_i
     => 0