Back to Repositories

Validating Attachment Presence Matchers in Paperclip

This test suite validates the presence validation matcher functionality for Paperclip attachments in Ruby applications. It ensures proper validation behavior for file attachments and conditional validation scenarios.

Test Coverage Overview

The test suite comprehensively covers Paperclip’s attachment presence validation functionality.

  • Basic validation presence checking
  • Interaction with other attachment validations
  • Conditional validation using :if clauses
  • Edge cases with nil attachments

Implementation Analysis

The implementation uses RSpec’s behavior-driven development approach with clear context organization. The tests utilize Paperclip’s custom matcher framework for validations, with setup procedures that reset test data between runs.

  • Custom matcher implementation
  • Table and class reset helpers
  • Fixture file handling

Technical Details

  • RSpec testing framework
  • Paperclip::Shoulda::Matchers module
  • Database table manipulation
  • File fixture handling
  • Dynamic class evaluation

Best Practices Demonstrated

The test suite exemplifies several testing best practices for Ruby and RSpec.

  • Isolated test setup using before blocks
  • Clear context separation
  • Helper method extraction
  • Comprehensive validation scenarios
  • Clean test data management

thoughtbot/paperclip

spec/paperclip/matchers/validate_attachment_presence_matcher_spec.rb

            
require 'spec_helper'
require 'paperclip/matchers'

describe Paperclip::Shoulda::Matchers::ValidateAttachmentPresenceMatcher do
  extend Paperclip::Shoulda::Matchers

  before do
    reset_table("dummies") do |d|
      d.string :avatar_file_name
    end
    reset_class "Dummy"
    Dummy.has_attached_file :avatar
    Dummy.do_not_validate_attachment_file_type :avatar
  end

  it "rejects a class with no validation" do
    expect(matcher).to_not accept(Dummy)
  end

  it "accepts a class with a matching validation" do
    Dummy.validates_attachment_presence :avatar
    expect(matcher).to accept(Dummy)
  end

  it "accepts an instance with other attachment validations" do
    reset_table("dummies") do |d|
      d.string :avatar_file_name
      d.string :avatar_content_type
    end
    Dummy.class_eval do
      validates_attachment_presence :avatar
      validates_attachment_content_type :avatar, content_type: 'image/gif'
    end
    dummy = Dummy.new

    dummy.avatar = File.new fixture_file('5k.png')

    expect(matcher).to accept(dummy)
  end

  context "using an :if to control the validation" do
    before do
      Dummy.class_eval do
        validates_attachment_presence :avatar, if: :go
        attr_accessor :go
      end
    end

    it "runs the validation if the control is true" do
      dummy = Dummy.new
      dummy.avatar = nil
      dummy.go = true
      expect(matcher).to accept(dummy)
    end

    it "does not run the validation if the control is false" do
      dummy = Dummy.new
      dummy.avatar = nil
      dummy.go = false
      expect(matcher).to_not accept(dummy)
    end
  end

  private

  def matcher
    self.class.validate_attachment_presence(:avatar)
  end
end