# frozen_string_literal: true

RSpec.describe CallbackHell, "with attribute-generated callbacks and validations" do
  def normalization_supported?
    ActiveRecord::Base.respond_to?(:normalizes)
  end
  subject(:foo) { CallbackHell::Collector.new(Foo, mode: :full).collect }
  subject(:bar) { CallbackHell::Collector.new(Bar, mode: :full).collect }

  it "correctly marks the callbacks generated by attributes" do
    skip "Normalization not supported in this Rails version" unless normalization_supported?
    expect(foo).to have_callback(
      callback_name: :before_validate,
      method_name: :cant_modify_encrypted_attributes_when_frozen,
      attribute_generated: true,
      origin: :rails
    )
    expect(foo).to have_callback(
      callback_name: :before_validation,
      method_name: :normalize_changed_in_place_attributes,
      attribute_generated: true,
      origin: :rails
    )
  end

  it "does not cause false positives when it comes to attribute callbacks" do
    expect(foo).to have_callback(
      callback_name: :after_validation,
      method_name: :noop,
      attribute_generated: false,
      origin: :own
    )
    expect(foo).to have_callback(
      callback_name: :after_create,
      method_name: :noop,
      attribute_generated: false,
      origin: :own
    )
  end

  it "correctly marks the validations generated by attributes" do
    expect(foo).to have_validation(
      type: :custom,
      method_name: :cant_modify_encrypted_attributes_when_frozen,
      attribute_generated: true,
      origin: :rails
    )
  end

  context "with mode=default" do
    subject(:foo) { CallbackHell::Collector.new(Foo, mode: :default).collect }

    it "has no attribute callbacks" do
      expect(foo).not_to have_callback(attribute_generated: true)
    end
  end
end
