From e752ff98af748be5820776bfca368a4cc459e9d2 Mon Sep 17 00:00:00 2001 From: Molly Struve Date: Wed, 19 Feb 2020 14:29:16 -0500 Subject: [PATCH] Index ChatChannelMemberships to Elasticsearch (#6162) [deploy] --- app/models/chat_channel_membership.rb | 32 +++++++------ .../chat_channel_membership_serializer.rb | 10 +++++ ...chat_channel_membership_es_index_worker.rb | 12 +++++ ...at_channel_memberships_to_elasticsearch.rb | 7 +++ ...annel_memberships_to_elasticsearch_spec.rb | 11 +++++ spec/models/chat_channel_membership_spec.rb | 45 +++++++++++++++++++ ...channel_membership_es_index_worker_spec.rb | 21 +++++++++ 7 files changed, 125 insertions(+), 13 deletions(-) create mode 100644 app/serializers/search/chat_channel_membership_serializer.rb create mode 100644 app/workers/search/chat_channel_membership_es_index_worker.rb create mode 100644 lib/data_update_scripts/20200218195023_index_chat_channel_memberships_to_elasticsearch.rb create mode 100644 spec/lib/data_update_scripts/index_chat_channel_memberships_to_elasticsearch_spec.rb create mode 100644 spec/models/chat_channel_membership_spec.rb create mode 100644 spec/workers/search/chat_channel_membership_es_index_worker_spec.rb diff --git a/app/models/chat_channel_membership.rb b/app/models/chat_channel_membership.rb index 9db765cc3..b00ced440 100644 --- a/app/models/chat_channel_membership.rb +++ b/app/models/chat_channel_membership.rb @@ -1,5 +1,11 @@ class ChatChannelMembership < ApplicationRecord include AlgoliaSearch + + include Searchable + SEARCH_INDEX_WORKER = Search::ChatChannelMembershipEsIndexWorker + SEARCH_SERIALIZER = Search::ChatChannelMembershipSerializer + SEARCH_CLASS = Search::ChatChannelMembership + belongs_to :chat_channel belongs_to :user @@ -9,6 +15,8 @@ class ChatChannelMembership < ApplicationRecord validates :role, inclusion: { in: %w[member mod] } validate :permission + after_commit :index_to_elasticsearch + algoliasearch index_name: "SecuredChatChannelMembership_#{Rails.env}", auto_index: false do attribute :id, :status, :viewable_by, :chat_channel_id, :last_opened_at, :channel_text, :channel_last_message_at, :channel_status, :channel_type, :channel_username, @@ -18,7 +26,7 @@ class ChatChannelMembership < ApplicationRecord ranking ["desc(channel_last_message_at)"] end - private + delegate :channel_type, to: :chat_channel def channel_last_message_at chat_channel.last_message_at @@ -28,10 +36,6 @@ class ChatChannelMembership < ApplicationRecord chat_channel.status end - def channel_type - chat_channel.channel_type - end - def channel_text "#{chat_channel.channel_name} #{chat_channel.slug} #{chat_channel.channel_human_names}" end @@ -60,14 +64,6 @@ class ChatChannelMembership < ApplicationRecord other_user&.username if chat_channel.channel_type == "direct" end - def channel_color - if chat_channel.channel_type == "direct" - other_user&.decorate&.darker_color - else - "#111111" - end - end - def channel_modified_slug if chat_channel.channel_type == "direct" "@" + other_user&.username @@ -80,6 +76,16 @@ class ChatChannelMembership < ApplicationRecord user_id end + private + + def channel_color + if chat_channel.channel_type == "direct" + other_user&.decorate&.darker_color + else + "#111111" + end + end + def other_user chat_channel.users.where.not(id: user_id).first end diff --git a/app/serializers/search/chat_channel_membership_serializer.rb b/app/serializers/search/chat_channel_membership_serializer.rb new file mode 100644 index 000000000..7ead840a2 --- /dev/null +++ b/app/serializers/search/chat_channel_membership_serializer.rb @@ -0,0 +1,10 @@ +module Search + class ChatChannelMembershipSerializer + include FastJsonapi::ObjectSerializer + + attributes :id, :status, :viewable_by, :chat_channel_id, :last_opened_at, + :channel_text, :channel_last_message_at, :channel_status, + :channel_status, :channel_type, :channel_username, :channel_name, + :channel_image, :channel_modified_slug, :channel_messages_count + end +end diff --git a/app/workers/search/chat_channel_membership_es_index_worker.rb b/app/workers/search/chat_channel_membership_es_index_worker.rb new file mode 100644 index 000000000..3a0323882 --- /dev/null +++ b/app/workers/search/chat_channel_membership_es_index_worker.rb @@ -0,0 +1,12 @@ +module Search + class ChatChannelMembershipEsIndexWorker + include Sidekiq::Worker + + sidekiq_options queue: :high_priority + + def perform(chat_channel_membership_id) + chat_channel_membership = ::ChatChannelMembership.find(chat_channel_membership_id) + chat_channel_membership.index_to_elasticsearch_inline + end + end +end diff --git a/lib/data_update_scripts/20200218195023_index_chat_channel_memberships_to_elasticsearch.rb b/lib/data_update_scripts/20200218195023_index_chat_channel_memberships_to_elasticsearch.rb new file mode 100644 index 000000000..73d5d464e --- /dev/null +++ b/lib/data_update_scripts/20200218195023_index_chat_channel_memberships_to_elasticsearch.rb @@ -0,0 +1,7 @@ +module DataUpdateScripts + class IndexChatChannelMembershipsToElasticsearch + def run + ChatChannelMembership.find_each(&:index_to_elasticsearch_inline) + end + end +end diff --git a/spec/lib/data_update_scripts/index_chat_channel_memberships_to_elasticsearch_spec.rb b/spec/lib/data_update_scripts/index_chat_channel_memberships_to_elasticsearch_spec.rb new file mode 100644 index 000000000..eadfcde58 --- /dev/null +++ b/spec/lib/data_update_scripts/index_chat_channel_memberships_to_elasticsearch_spec.rb @@ -0,0 +1,11 @@ +require "rails_helper" +require Rails.root.join("lib/data_update_scripts/20200218195023_index_chat_channel_memberships_to_elasticsearch.rb") + +describe DataUpdateScripts::IndexChatChannelMembershipsToElasticsearch, elasticsearch: true do + it "indexes chat channel memberships to Elasticsearch" do + chat_channel_membership = FactoryBot.create(:chat_channel_membership) + expect { chat_channel_membership.elasticsearch_doc }.to raise_error(Elasticsearch::Transport::Transport::Errors::NotFound) + described_class.new.run + expect(chat_channel_membership.elasticsearch_doc).not_to be_nil + end +end diff --git a/spec/models/chat_channel_membership_spec.rb b/spec/models/chat_channel_membership_spec.rb new file mode 100644 index 000000000..f5cccf64f --- /dev/null +++ b/spec/models/chat_channel_membership_spec.rb @@ -0,0 +1,45 @@ +require "rails_helper" + +RSpec.describe ChatChannelMembership, type: :model do + let(:chat_channel_membership) { FactoryBot.create(:chat_channel_membership) } + + describe "#index_to_elasticsearch" do + it "enqueues job to index tag to elasticsearch" do + sidekiq_assert_enqueued_with(job: Search::ChatChannelMembershipEsIndexWorker, args: [chat_channel_membership.id]) do + chat_channel_membership.index_to_elasticsearch + end + end + end + + describe "#index_to_elasticsearch_inline" do + it "indexed chat_channel_membership to elasticsearch inline" do + allow(Search::ChatChannelMembership).to receive(:index) + chat_channel_membership.index_to_elasticsearch_inline + expect(Search::ChatChannelMembership).to have_received(:index).with(chat_channel_membership.id, hash_including(:id, :channel_name)) + end + end + + describe "#after_commit" do + it "enqueues job to index chat_channel_membership to elasticsearch" do + chat_channel_membership.save + sidekiq_assert_enqueued_with(job: Search::ChatChannelMembershipEsIndexWorker, args: [chat_channel_membership.id]) do + chat_channel_membership.save + end + end + end + + describe "#serialized_search_hash" do + it "creates a valid serialized hash to send to elasticsearch" do + mapping_keys = Search::ChatChannelMembership::MAPPINGS.dig(:properties).keys + expect(chat_channel_membership.serialized_search_hash.symbolize_keys.keys).to eq(mapping_keys) + end + end + + describe "#elasticsearch_doc" do + it "finds document in elasticsearch", elasticsearch: true do + allow(Search::ChatChannelMembership).to receive(:find_document) + chat_channel_membership.elasticsearch_doc + expect(Search::ChatChannelMembership).to have_received(:find_document) + end + end +end diff --git a/spec/workers/search/chat_channel_membership_es_index_worker_spec.rb b/spec/workers/search/chat_channel_membership_es_index_worker_spec.rb new file mode 100644 index 000000000..c3ebee24f --- /dev/null +++ b/spec/workers/search/chat_channel_membership_es_index_worker_spec.rb @@ -0,0 +1,21 @@ +require "rails_helper" + +RSpec.describe Search::ChatChannelMembershipEsIndexWorker, type: :worker, elasticsearch: true do + let(:worker) { subject } + + include_examples "#enqueues_on_correct_queue", "high_priority", [1] + + it "raises an error if record is not found" do + expect { worker.perform(1234) }.to raise_error(ActiveRecord::RecordNotFound) + end + + it "indexes chat_channel_membership" do + chat_channel_membership = FactoryBot.create(:chat_channel_membership) + expect { chat_channel_membership.elasticsearch_doc }.to raise_error(Elasticsearch::Transport::Transport::Errors::NotFound) + worker.perform(chat_channel_membership.id) + expected_hash = chat_channel_membership.serialized_search_hash.stringify_keys + expect(chat_channel_membership.elasticsearch_doc.dig("_source")).to include( + expected_hash, + ) + end +end