Back to Repositories

Validating Media Type Spoof Detection in Paperclip

This test suite validates the MediaTypeSpoofDetectionValidator in Paperclip, ensuring proper detection of spoofed media types in file uploads. The tests verify both automatic validator inclusion and explicit rejection scenarios, while validating error handling and conditional execution.

Test Coverage Overview

The test suite provides comprehensive coverage of the MediaTypeSpoofDetectionValidator functionality in Paperclip:

  • Validator automatic inclusion in attachment configurations
  • Optional validator rejection through configuration
  • Error message handling for detected spoofed media types
  • Conditional validation execution based on attachment state

Implementation Analysis

The testing approach utilizes RSpec’s behavior-driven development patterns with mock objects and stub methods. The implementation leverages RSpec’s before blocks for test setup and mock expectations to verify MediaTypeSpoofDetector interaction patterns.

Key patterns include:
  • Model rebuilding for isolated test states
  • Mock object creation for detector behavior simulation
  • Stub method implementation for controlled testing

Technical Details

Testing tools and configuration:
  • RSpec as the testing framework
  • Paperclip’s built-in test helpers
  • Fixture file handling for media type testing
  • Mock object framework for behavior simulation
  • I18n integration for error message verification

Best Practices Demonstrated

The test suite exemplifies several testing best practices:

  • Isolated test cases with proper setup and teardown
  • Behavioral verification using mock expectations
  • Clear test case organization and naming
  • Comprehensive edge case coverage
  • Efficient test setup reuse through before blocks

thoughtbot/paperclip

spec/paperclip/validators/media_type_spoof_detection_validator_spec.rb

            
require 'spec_helper'

describe Paperclip::Validators::MediaTypeSpoofDetectionValidator do
  before do
    rebuild_model
    @dummy = Dummy.new
  end

  def build_validator(options = {})
    @validator = Paperclip::Validators::MediaTypeSpoofDetectionValidator.new(options.merge(
      attributes: :avatar
    ))
  end

  it "is on the attachment without being explicitly added" do
    assert Dummy.validators_on(:avatar).any?{ |validator| validator.kind == :media_type_spoof_detection }
  end

  it "is not on the attachment when explicitly rejected" do
    rebuild_model validate_media_type: false
    assert Dummy.validators_on(:avatar).none?{ |validator| validator.kind == :media_type_spoof_detection }
  end

  it "returns default error message for spoofed media type" do
    build_validator
    file = File.new(fixture_file("5k.png"), "rb")
    @dummy.avatar.assign(file)

    detector = mock("detector", :spoofed? => true)
    Paperclip::MediaTypeSpoofDetector.stubs(:using).returns(detector)
    @validator.validate(@dummy)

    assert_equal I18n.t("errors.messages.spoofed_media_type"), @dummy.errors[:avatar].first
  end

  it "runs when attachment is dirty" do
    build_validator
    file = File.new(fixture_file("5k.png"), "rb")
    @dummy.avatar.assign(file)
    Paperclip::MediaTypeSpoofDetector.stubs(:using).returns(stub(:spoofed? => false))

    @dummy.valid?

    assert_received(Paperclip::MediaTypeSpoofDetector, :using){|e| e.once }
  end

  it "does not run when attachment is not dirty" do
    Paperclip::MediaTypeSpoofDetector.stubs(:using).never
    @dummy.valid?
    assert_received(Paperclip::MediaTypeSpoofDetector, :using){|e| e.never }
  end
end