# frozen_string_literal: true
require "rails_helper"

RSpec.describe ActiveAdmin::Filters::ResourceExtension do
  let(:resource) do
    namespace = ActiveAdmin::Namespace.new(ActiveAdmin::Application.new, :admin)
    namespace.register(Post)
  end

  it "should return a Hash" do
    expect(resource.filters).to be_a Hash
  end

  it "should return the defaults if no filters are set" do
    expect(resource.filters.keys).to match_array(
      [
        :author, :body, :category, :created_at, :custom_created_at_searcher, :custom_title_searcher, :custom_searcher_numeric, :position, :published_date, :starred, :taggings, :tags, :title, :updated_at, :foo_id
      ]
    )
  end

  it "should not have defaults when filters are disabled on the resource" do
    resource.filters = false
    expect(resource.filters).to be_empty
  end

  it "should not have defaults when the filters are disabled on the namespace" do
    resource.namespace.filters = false
    expect(resource.filters).to be_empty
  end

  it "should not have defaults when the filters are disabled on the application" do
    resource.namespace.application.filters = false
    expect(resource.filters).to be_empty
  end

  it "should return the defaults without associations if default association filters are disabled on the namespace" do
    resource.namespace.include_default_association_filters = false
    expect(resource.filters.keys).to match_array(
      [
        :body, :created_at, :custom_created_at_searcher, :custom_title_searcher, :custom_searcher_numeric, :position, :published_date, :starred, :title, :updated_at, :foo_id
      ]
    )
  end

  describe "removing a filter" do
    it "should work" do
      expect(resource.filters.keys).to include :author
      resource.remove_filter :author
      expect(resource.filters.keys).to_not include :author
    end

    it "should work as a string" do
      expect(resource.filters.keys).to include :author
      resource.remove_filter "author"
      expect(resource.filters.keys).to_not include :author
    end

    it "should be lazy" do
      expect(resource).to_not receive :default_filters # this hits the DB
      resource.remove_filter :author
    end

    it "should not prevent the default filters from being added" do
      resource.remove_filter :author
      expect(resource.filters).to_not be_empty
    end

    it "should raise an exception when filters are disabled" do
      resource.filters = false
      expect { resource.remove_filter :author }.to raise_error(ActiveAdmin::Filters::Disabled, /Cannot remove a filter/)
    end
  end

  describe "removing a multiple filters inline" do
    it "should work" do
      expect(resource.filters.keys).to include :author, :body
      resource.remove_filter :author, :body
      expect(resource.filters.keys).to_not include :author, :body
    end
  end

  describe "adding a filter" do
    it "should work" do
      resource.add_filter :title
      expect(resource.filters).to eq title: {}
    end

    it "should work as a string" do
      resource.add_filter "title"
      expect(resource.filters).to eq title: {}
    end

    it "should work with specified options" do
      resource.add_filter :title, as: :string
      expect(resource.filters).to eq title: { as: :string }
    end

    it "should override an existing filter" do
      resource.add_filter :title, one: :two
      resource.add_filter :title, three: :four

      expect(resource.filters).to eq title: { three: :four }
    end

    it "should preserve default filters" do
      resource.preserve_default_filters!
      resource.add_filter :count, as: :string

      expect(resource.filters.keys).to match_array(
        [
          :author, :body, :category, :count, :created_at, :custom_created_at_searcher, :custom_title_searcher, :custom_searcher_numeric, :position, :published_date, :starred, :taggings, :tags, :title, :updated_at, :foo_id
        ]
      )
    end

    it "should raise an exception when filters are disabled" do
      resource.filters = false
      expect { resource.add_filter :title }.to raise_error(ActiveAdmin::Filters::Disabled, /Cannot add a filter/)
    end
  end

  it "should reset filters" do
    resource.add_filter :title
    expect(resource.filters.size).to eq 1
    resource.reset_filters!
    expect(resource.filters.size).to be > 1
  end

  it "should add a sidebar section for the filters" do
    expect(resource.sidebar_sections.first.name).to eq "filters"
  end
end
