ruby-on-railsrubyrspecautomated-testsrails-activestorage

How to test active storage dimension validation?


I have installed this gem to validate and test active storage:

gem 'active_storage_validations'
# Asset Model
class Asset < ApplicationRecord
  has_one_attached :portrait

  validates(
    :portrait,
    content_type: ['image/png', 'image/jpeg', 'image/svg+xml'],
    dimension: { width: { in: 8..512 }, height: { in: 8..512 } },
    size: { less_than: 250.kilobytes }
  )
end
# Asset test
require 'rails_helper'

RSpec.describe Asset do
  it { is_expected.to validate_dimensions_of(:portrait).width_between(8..512).height_between(8..512) }
end

However, I get this error in my test, but not out of my test:

Asset validations is expected to validate the image dimensions of :portrait
     Failure/Error: it { is_expected.to validate_dimensions_of(:portrait).width_between(8..512).height_between(8..512) }
     
     NameError:
       uninitialized constant ActiveStorageValidations::Matchers::OpenStruct

Solution

  • Your Issue

    Your issue comes from Here.

    Excerpt:

    module ActiveStorageValidations
      module Matchers
        #...
        def self.mock_metadata(attachment, width, height)
          if Rails.gem_version >= Gem::Version.new('6.0.0')
            # Mock the Metadata class for rails 6
            mock = OpenStruct.new(metadata: { width: width, height: height })
    

    The gem appears to expect OpenStruct to have been required require 'ostruct' (without actually requiring it themselves).

    Add require 'ostruct' to your spec_helper.rb file and it should resolve the issue.

    If so I would also open a ticket with the gem on github.

    Why is this occurring?

    Previous versions of the json gem required OpenStruct. Rails, or more explicitly ActiveSupport, relies on JSON (Source).

    It appears that some other creators of rails gems relied on the asumption that OpenStruct was simply available (due to other gem dependencies); however, as of version 2.7.2 the json gem has made OpenStruct optional (Change Log and Pull Request).

    This means that gems relying on its existence should now require it explicitly, which they probably should have from the start as require has very low overhead when a file has already been required.