# frozen_string_literal: true

RSpec.shared_examples "has valid rspec message methods" do
  context "when the matcher returns a failure message to the dev" do
    subject(:configured_matcher) { matcher }

    before do
      case validator_sym
      when :aspect_ratio then matcher.rejecting(:square)
      when :attached then matcher
      when :processable_file then matcher
      when :limit then matcher.min(0).max(6)
      when :content_type then matcher.rejecting("image/png")
      when :dimension then matcher.width(75).height(75)
      when :duration then matcher.less_than_or_equal_to(7.minutes)
      when :size then matcher.less_than_or_equal_to(7.megabytes)
      when :total_size then matcher.less_than_or_equal_to(7.megabytes)
      when :pages then matcher.less_than_or_equal_to(7)
      end
    end


    let(:model_attribute) { :failure_message }
    let(:expected_failure_message) do
      case validator_sym
      when :aspect_ratio
        <<~FAILURE_MESSAGE
          is expected to validate aspect ratio of :#{model_attribute}
        FAILURE_MESSAGE
      when :attached
        <<~FAILURE_MESSAGE
          is expected to validate attachment of :#{model_attribute}
        FAILURE_MESSAGE
      when :processable_file
        <<~FAILURE_MESSAGE
          is expected to validate the processable image of :#{model_attribute}
        FAILURE_MESSAGE
      when :limit
        <<~FAILURE_MESSAGE
          is expected to validate limit file of :#{model_attribute}
            but there seem to have issues with the matcher methods you used, since:
            validation failed when provided with 6 file(s)
            whereas it should have passed
        FAILURE_MESSAGE
      when :content_type
        <<~FAILURE_MESSAGE
          is expected to validate the content types of :#{model_attribute}
            the following content type should be rejected: :image/png
            but :image/png was accepted
        FAILURE_MESSAGE
      when :dimension
        <<~FAILURE_MESSAGE
          is expected to validate dimensions of :#{model_attribute}
            but there seem to have issues with the matcher methods you used, since:
            validation failed when provided with a 74x75px test image
            validation failed when provided with a 76x75px test image
            validation failed when provided with a 75x75px test image
            whereas it should have passed
        FAILURE_MESSAGE
      when :duration
        <<~FAILURE_MESSAGE
          is expected to validate file duration of :#{model_attribute}
            but there seem to have issues with the matcher methods you used, since:
            validation failed when provided with a 419 seconds test file
            whereas it should have passed
        FAILURE_MESSAGE
      when :size
        <<~FAILURE_MESSAGE
          is expected to validate file size of :#{model_attribute}
            but there seem to have issues with the matcher methods you used, since:
            validation failed when provided with a 7340031 bytes test file
            whereas it should have passed
        FAILURE_MESSAGE
      when :total_size
        <<~FAILURE_MESSAGE
          is expected to validate total file size of :#{model_attribute}
            but there seem to have issues with the matcher methods you used, since:
            validation failed when provided with a 7340031 bytes test file
            whereas it should have passed
        FAILURE_MESSAGE
      when :pages
        <<~FAILURE_MESSAGE
          is expected to validate file number of pages of :#{model_attribute}
            but there seem to have issues with the matcher methods you used, since:
            validation failed when provided with a 6 pages test file
            whereas it should have passed
        FAILURE_MESSAGE
      end[0..-2] # to remove last \n generated by the <<~ format
    end

    it { is_expected_to_have_failure_message(expected_failure_message) }
  end

  context "when the matcher returns a negated failure message to the dev" do
    subject(:configured_matcher) { matcher }

    before do
      case validator_sym
      when :aspect_ratio then matcher.allowing(:square)
      when :attached then matcher
      when :processable_file then matcher
      when :limit then matcher.min(1).max(5)
      when :content_type then matcher.allowing("image/png")
      when :dimension then matcher.width(150).height(150)
      when :duration then matcher.less_than_or_equal_to(5.minutes)
      when :size then matcher.less_than_or_equal_to(5.megabytes)
      when :total_size then matcher.less_than_or_equal_to(5.megabytes)
      when :pages then matcher.less_than_or_equal_to(5)
      end
    end


    let(:model_attribute) { :failure_message_when_negated }
    let(:expected_failure_message) do
      case validator_sym
      when :aspect_ratio
        <<~FAILURE_MESSAGE
          is expected not to validate aspect ratio of :#{model_attribute}
        FAILURE_MESSAGE
      when :attached
        <<~FAILURE_MESSAGE
          is expected not to validate attachment of :#{model_attribute}
        FAILURE_MESSAGE
      when :processable_file
        <<~FAILURE_MESSAGE
          is expected not to validate the processable image of :#{model_attribute}
        FAILURE_MESSAGE
      when :limit
        <<~FAILURE_MESSAGE
          is expected not to validate limit file of :#{model_attribute}
            but there seem to have issues with the matcher methods you used, since:
            validation failed when provided with 0 file(s)
            validation failed when provided with 6 file(s)
            whereas it should have passed
        FAILURE_MESSAGE
      when :content_type
        <<~FAILURE_MESSAGE
          is expected not to validate the content types of :#{model_attribute}
        FAILURE_MESSAGE
      when :dimension
        <<~MESSAGE
          is expected not to validate dimensions of :#{model_attribute}
            but there seem to have issues with the matcher methods you used, since:
            validation failed when provided with a 149x150px test image
            validation failed when provided with a 151x150px test image
            validation failed when provided with a 150x149px test image
            validation failed when provided with a 150x151px test image
            whereas it should have passed
        MESSAGE
      when :duration
        <<~FAILURE_MESSAGE
          is expected not to validate file duration of :#{model_attribute}
            but there seem to have issues with the matcher methods you used, since:
            validation failed when provided with a 301 seconds test file
            whereas it should have passed
        FAILURE_MESSAGE
      when :size
        <<~FAILURE_MESSAGE
          is expected not to validate file size of :#{model_attribute}
            but there seem to have issues with the matcher methods you used, since:
            validation failed when provided with a 5242881 bytes test file
            whereas it should have passed
        FAILURE_MESSAGE
      when :total_size
        <<~FAILURE_MESSAGE
          is expected not to validate total file size of :#{model_attribute}
            but there seem to have issues with the matcher methods you used, since:
            validation failed when provided with a 5242881 bytes test file
            whereas it should have passed
        FAILURE_MESSAGE
      when :pages
        <<~FAILURE_MESSAGE
          is expected not to validate file number of pages of :#{model_attribute}
            but there seem to have issues with the matcher methods you used, since:
            validation failed when provided with a 6 pages test file
            whereas it should have passed
        FAILURE_MESSAGE
      end[0..-2] # to remove last \n generated by the <<~ format
    end

    it { is_expected_to_have_failure_message_when_negated(expected_failure_message) }
  end

  context "when the dev asks for a description of the matcher" do
    subject(:description) { matcher.description }

    let(:model_attribute) { :failure_message_when_negated }

    it "returns a string containing the attribute name" do
      expect(subject).to match(/#{model_attribute}/)
    end
  end
end
