Searchkick: RSpec setup

218 Views Asked by At

I have successfully integrated Searchkick to my Rails 7 app in order to allow the user to search and filter Products. I am starting to write out the RSpec tests now and I'm very confused about the right setup.

The doc says:

Add to your spec/spec_helper.rb:

RSpec.configure do |config|
  config.before(:suite) do
    # reindex models
    Product.reindex

    # and disable callbacks
    Searchkick.disable_callbacks
  end

  config.around(:each, search: true) do |example|
    Searchkick.callbacks(nil) do
      example.run
    end
  end
end

And use:

describe Product, search: true do
  it "searches" do
    Product.create!(name: "Apple")
    Product.search_index.refresh
    assert_equal ["Apple"], Product.search("apple").map(&:name)
  end
end

Factory Bot: Use a trait and an after create hook for each indexed model:

FactoryBot.define do
  factory :product do
    # ...

    # Note: This should be the last trait in the list so `reindex` is called
    # after all the other callbacks complete.
    trait :reindex do
      after(:create) do |product, _evaluator|
        product.reindex(refresh: true)
      end
    end
  end
end

# use it
FactoryBot.create(:product, :some_trait, :reindex, some_attribute: "foo")

However, it's unclear to me what exactly these do, and why this is the recommended setup. Particularly, my questions are:

  1. If I make the Product.reindex only to run before each suite as the doc suggests, then I see these warnings when running my tests that call the search: [searchkick] WARNING: Records in search index do not exist in database: Product 1234, ..., as if the search index didn't clear from one test to another. What's the way around that? I noticed that if I put Product.reindex in a before(:each) block for all my searchkick-related unit tests, it suppresses those warnings but makes the tests REALLY slow even if I just have 3 Products per unit test at most. What am I missing?

  2. Why does the doc suggest adding Searchkick.callbacks(nil) do block AS WELL as calling product.reindex(refresh: true) AS WELL as Product.search_index.refresh? Isn't the first line supposed to enable callbacks which should keep the index updated already?

  3. Why am I still seeing Enqueued Searchkick::ReindexV2Job logs printed out during the tests even if I disabled callbacks? Update: I figured out this is because in another model (Address) I have a callback that does: self.owner.reindex(mode: :async). I guess this is not affected by the Searchkick.disable_callbacks option.

0

There are 0 best solutions below