diff --git a/app/models/article.rb b/app/models/article.rb index 26f18f860..19200acf6 100644 --- a/app/models/article.rb +++ b/app/models/article.rb @@ -265,7 +265,7 @@ class Article < ApplicationRecord return if remove if record.published && record.tag_list.exclude?("hiring") - Search::IndexJob.perform_later("Article", record.id) + Search::IndexWorker.perform_async("Article", record.id) else Search::RemoveFromIndexJob.perform_later(Article.algolia_index_name, record.id) Search::RemoveFromIndexJob.perform_later("searchables_#{Rails.env}", record.index_id) diff --git a/app/models/comment.rb b/app/models/comment.rb index 05f1ba947..c1d4f70ea 100644 --- a/app/models/comment.rb +++ b/app/models/comment.rb @@ -115,7 +115,7 @@ class Comment < ApplicationRecord return if remove if record.deleted == false - Search::IndexJob.perform_later("Comment", record.id) + Search::IndexWorker.perform_async("Comment", record.id) else Search::RemoveFromIndexJob.perform_later(Comment.algolia_index_name, record.index_id) end diff --git a/app/models/page_view.rb b/app/models/page_view.rb index 7675c8bd8..e565c8528 100644 --- a/app/models/page_view.rb +++ b/app/models/page_view.rb @@ -50,7 +50,7 @@ class PageView < ApplicationRecord if remove Search::RemoveFromIndexJob.perform_later(algolia_index_name, record.id) else - Search::IndexJob.perform_later("PageView", record.id) + Search::IndexWorker.perform_async("PageView", record.id) end end diff --git a/app/models/user.rb b/app/models/user.rb index a87548652..d31f3cbd3 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -205,7 +205,7 @@ class User < ApplicationRecord def self.trigger_delayed_index(record, remove) return if remove - Search::IndexJob.perform_later("User", record.id) + Search::IndexWorker.perform_async("User", record.id) end def tag_line diff --git a/app/workers/search/index_worker.rb b/app/workers/search/index_worker.rb new file mode 100644 index 000000000..7c169e93c --- /dev/null +++ b/app/workers/search/index_worker.rb @@ -0,0 +1,22 @@ +module Search + class IndexWorker + include Sidekiq::Worker + + sidekiq_options queue: :medium_priority, retry: 10 + + VALID_RECORD_TYPES = %w[Comment Article User PageView].freeze + + def perform(record_type, record_id) + unless VALID_RECORD_TYPES.include?(record_type) + raise InvalidRecordType, "Invalid class: #{record_type}. Valid and indexable classes are #{VALID_RECORD_TYPES.join(', ')}" + end + + record = record_type.constantize.find_by(id: record_id) + return unless record + + record.index! + end + end + + class InvalidRecordType < StandardError; end +end diff --git a/spec/models/article_spec.rb b/spec/models/article_spec.rb index ca515e3a4..7b62742b4 100644 --- a/spec/models/article_spec.rb +++ b/spec/models/article_spec.rb @@ -483,9 +483,9 @@ RSpec.describe Article, type: :model do end it "indexes published non-hiring article" do - expect do + sidekiq_assert_enqueued_with(job: Search::IndexWorker, args: ["Article", article.id]) do article.update(published: false) - end.to have_enqueued_job(Search::IndexJob).exactly(:once).with("Article", article.id) + end end it "triggers auto removal from index on destroy" do diff --git a/spec/models/comment_spec.rb b/spec/models/comment_spec.rb index f1f2f0160..ab016a708 100644 --- a/spec/models/comment_spec.rb +++ b/spec/models/comment_spec.rb @@ -339,8 +339,13 @@ RSpec.describe Comment, type: :model do end it "busts the comment cache" do - expect_any_instance_of(Comments::BustCacheWorker).to receive(:perform).with(comment.id) - comment.destroy + # here the comment is destroyed from the test above so we re-create one + new_comment = create(:comment, commentable: article) + + # this replaces the use of expect_any_instance_of which is a RuboCop violation + sidekiq_assert_enqueued_with(job: Comments::BustCacheWorker, args: [new_comment.id]) do + new_comment.destroy + end end end @@ -355,9 +360,9 @@ RSpec.describe Comment, type: :model do context "when deleted is false" do it "checks auto-indexing" do - expect do + sidekiq_assert_enqueued_with(job: Search::IndexWorker, args: ["Comment", comment.id]) do comment.update(body_markdown: "hello") - end.to have_enqueued_job(Search::IndexJob).with("Comment", comment.id) + end end end diff --git a/spec/models/page_view_spec.rb b/spec/models/page_view_spec.rb index 73e39ba28..5b6a56342 100644 --- a/spec/models/page_view_spec.rb +++ b/spec/models/page_view_spec.rb @@ -22,9 +22,9 @@ RSpec.describe PageView, type: :model do describe "indexing" do it "indexes updated records" do - expect do + sidekiq_assert_enqueued_with(job: Search::IndexWorker, args: ["PageView", page_view.id]) do page_view.update(path: "/") - end.to have_enqueued_job(Search::IndexJob).exactly(:once).with("PageView", page_view.id) + end end it "removes deleted records" do diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 63d7411b3..24ad7bcbf 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -620,17 +620,21 @@ RSpec.describe User, type: :model do context "when indexing and deindexing" do it "triggers background auto-indexing when user is saved" do - expect { user.save }.to have_enqueued_job(Search::IndexJob).with("User", user.id) + sidekiq_assert_enqueued_with(job: Search::IndexWorker, args: ["User", user.id]) do + user.save + end end it "doesn't enqueue a job on destroy" do user = build(:user) - perform_enqueued_jobs do + sidekiq_perform_enqueued_jobs do user.save end - expect { user.destroy }.not_to have_enqueued_job(Search::IndexJob) + sidekiq_assert_no_enqueued_jobs(only: Search::IndexWorker) do + user.destroy + end end end diff --git a/spec/workers/search/index_worker_spec.rb b/spec/workers/search/index_worker_spec.rb new file mode 100644 index 000000000..dc1f00c92 --- /dev/null +++ b/spec/workers/search/index_worker_spec.rb @@ -0,0 +1,23 @@ +require "rails_helper" + +RSpec.describe Search::IndexWorker, type: :worker do + let(:worker) { subject } + + include_examples "#enqueues_on_correct_queue", "medium_priority", ["User", 1] + + it "does nothing if there is wrong record type is passed" do + expect { worker.perform("SuperUser", 1) }.to raise_error(Search::InvalidRecordType) + end + + it "doesn't fail if a record is not found" do + expect { worker.perform("Comment", -1) }.not_to raise_error + end + + it "indexes a record if everything is fine" do + user = double + allow(user).to receive(:index!) + allow(User).to receive(:find_by).and_return(user) + worker.perform("User", 1) + expect(user).to have_received(:index!) + end +end