Hi guys Can I please get some help to figure out what is going wrong with my RSpec test. I been looking all over the internet and haven't found anything that would point to reason why i'm getting this error.
What i'm trying to do is test that an instance variable has some data from the DB. The error is happening when the test reaches the Fabricator that creates the active record and also the ActiveStorage Blob. I have added the database-cleaner gem but not sure of something is messing up with that or i'm missing something when using RSpec, active storage, and DBcleaner.
What is strange is that I have another test that also creates the same Fabricated Object and I dont get the error you will see below. If I comment out the test below the other test runs just fine. Any help would be really appreciated. Been stuck on this for hours :$
UPDATE: I tried to look into what was happening after the graphic fabricator ran and when I looked into the attachments using the attached? methods each of the files were actually attached. All four files came back as attached true. I thought there would be something going on with the cleaner so I added to the rails_helper to purge all the files after each test is done.
config.after(:each) do
DatabaseCleaner.clean
ActiveStorage::Attachment.all.each { |attachment| attachment.purge }
end
This should grab all attachments and delete the attachment and blobs after each test runs. But this didnt do anything. Still not sure what is happening.
Any help would be appreciated.
Thanks :)
ERROR:
1) Dashboard::VendorDashboardsController GET sales Authenticated assigns instance variable with purchases for that store
Failure/Error: graphic = Fabricate(:graphic, store:store)
ActiveRecord::RecordNotFound:
Couldn't find ActiveStorage::Blob with 'id'=1
# ./spec/controllers/Dashboard/vendor_dashboards_controller_spec.rb:26:in `block (4 levels) in <top (required)>'
RSPEC TEST
it "assigns instance variable with purchases for that store" do
@user = Fabricate(:user)
vendor = Fabricate(:vendor, user:@user)
store = Fabricate(:store, vendor:vendor)
graphic = Fabricate(:graphic, store:store)
purchase_one = Fabricate(:purchase, purchasable_id:graphic.id)
purchase_two = Fabricate(:purchase, purchasable_id:graphic.id)
@user.add_role(:vendor)
login_user(@user)
get :sales
expect(assigns(:sales)).to eq(Purchase.where(store_id:store.id))
end
FABRICATOR
Fabricator(:graphic)do
store
name "Icon Set"
language "Spanish"
standard_license_price 10.00
business_license_price 100.00
reviewed true
status "Approved"
files_included "PSD, CSS"
category "Vectors"
subject "Characters"
support "3 Month Support"
layered true
high_resolution true
pixel_dimensions "2000x2000"
software_required "Illustrator"
thumbnail_image ActiveStorage::Blob.create_after_upload!(io: File.open(Rails.root.join('spec', 'support', 'assets', 'graphics', 'Advertise.png'), 'rb'), filename: 'Advertise.png',content_type: 'image/png').signed_id
main_image ActiveStorage::Blob.create_after_upload!(io: File.open(Rails.root.join('spec', 'support', 'assets', 'graphics', 'Chat.png'), 'rb'), filename: 'Chat.png',content_type: 'image/png').signed_id
product_images ActiveStorage::Blob.create_after_upload!(io: File.open(Rails.root.join('spec', 'support', 'assets', 'graphics', 'Chat.png'), 'rb'), filename: 'Chat.png',content_type: 'image/png').signed_id
graphic_asset_files ActiveStorage::Blob.create_after_upload!(io: File.open(Rails.root.join('spec', 'support', 'assets', 'graphics', 'test_illustrations.zip'), 'rb'), filename: 'test_illustrations.zip',content_type: 'application/zip').signed_id
description "This is the best graphic design"
end
RAILS HELPER FILE
# This file is copied to spec/ when you run 'rails generate rspec:install'
require 'spec_helper'
ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../config/environment', __dir__)
# Prevent database truncation if the environment is production
abort("The Rails environment is running in production mode!") if Rails.env.production?
require 'rspec/rails'
begin
ActiveRecord::Migration.maintain_test_schema!
rescue ActiveRecord::PendingMigrationError => e
puts e.to_s.strip
exit 1
end
RSpec.configure do |config|
# Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
config.fixture_path = "#{::Rails.root}/spec/fixtures"
config.use_transactional_fixtures = false
config.infer_spec_type_from_file_location!
# Filter lines from Rails gems in backtraces.
config.filter_rails_from_backtrace!
config.include Rails.application.routes.url_helpers
config.include Sorcery::TestHelpers::Rails::Controller, type: :controller
config.include Sorcery::TestHelpers::Rails::Integration, type: :feature
config.before(:suite) do
DatabaseCleaner.clean_with(:truncation)
end
config.before(:each) do
DatabaseCleaner.strategy = :truncation
end
config.before(:each, :js => true) do
DatabaseCleaner.strategy = :truncation
end
config.before(:each) do
DatabaseCleaner.start
end
config.after(:each) do
DatabaseCleaner.clean
end
Shoulda::Matchers.configure do |config|
config.integrate do |with|
with.test_framework :rspec
with.library :rails
end
end
end
The problem with your factory is that property values are evaluated just once, at file load time. And then they're reused for all objects.
thumbnail_image ActiveStorage::Blob.create_after_upload!(...).signed_id
Use a block here
thumbnail_image { ActiveStorage::Blob.create_after_upload!(...).signed_id }
This way, for each new fabricated object you'll get its own blob.