From 3fdb87ee66ce0a7d963164ffd6be02511bc21089 Mon Sep 17 00:00:00 2001 From: Anna Buianova Date: Wed, 26 Jan 2022 20:51:15 +0300 Subject: [PATCH] Added "Tags" category to search results (#16265) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Added tag search to nav menu * Added tag search * Improved tags search results view * Removed commented lines from the controller * Fix specs for Search::Tag * Prepare for tags search pagination * Fixed Search::Tag specs * styling Co-authored-by: Paweł Ludwiczak --- .../javascripts/utilities/buildArticleHTML.js | 25 +++++++++++++++++++ app/controllers/search_controller.rb | 10 +++++--- app/serializers/search/tag_serializer.rb | 1 + app/services/search/tag.rb | 12 +++++++-- .../articles_search/_nav_menu.html.erb | 3 +++ config/locales/views/misc/en.yml | 1 + spec/requests/search_spec.rb | 20 +++++++++++++++ spec/services/search/tag_spec.rb | 14 +++++------ 8 files changed, 74 insertions(+), 12 deletions(-) diff --git a/app/assets/javascripts/utilities/buildArticleHTML.js b/app/assets/javascripts/utilities/buildArticleHTML.js index 0c5451327..14f8e1ab9 100644 --- a/app/assets/javascripts/utilities/buildArticleHTML.js +++ b/app/assets/javascripts/utilities/buildArticleHTML.js @@ -3,6 +3,31 @@ /* eslint-disable no-multi-str */ function buildArticleHTML(article) { + var tagIcon = ``; + if (article && article.class_name === 'Tag') { + return `
+
+ + ${tagIcon} + +
+

+ + ${article.name} + +

+ ${ + article.short_summary + ? `
${article.short_summary}
` + : '' + } +
+
+
`; + } + if (article && article.class_name === 'PodcastEpisode') { return `
diff --git a/app/controllers/search_controller.rb b/app/controllers/search_controller.rb index f229e8f6a..6c422b98b 100644 --- a/app/controllers/search_controller.rb +++ b/app/controllers/search_controller.rb @@ -51,8 +51,7 @@ class SearchController < ApplicationController ].freeze def tags - result = Search::Tag.search_documents(params[:name]) - + result = Search::Tag.search_documents(term: params[:name]) render json: { result: result } end @@ -134,8 +133,13 @@ class SearchController < ApplicationController ) elsif class_name.Article? search_postgres_article + elsif class_name.Tag? + Search::Tag.search_documents( + term: feed_params[:search_fields], + page: feed_params[:page], + per_page: feed_params[:per_page], + ) end - render json: { result: result } end diff --git a/app/serializers/search/tag_serializer.rb b/app/serializers/search/tag_serializer.rb index 2a1add0b1..10c70d169 100644 --- a/app/serializers/search/tag_serializer.rb +++ b/app/serializers/search/tag_serializer.rb @@ -1,5 +1,6 @@ module Search class TagSerializer < ApplicationSerializer + attribute :class_name, -> { "Tag" } attributes :id, :name, :hotness_score, :supported, :short_summary, :rules_html, :bg_color_hex attribute :badge do |tag| if tag.badge diff --git a/app/services/search/tag.rb b/app/services/search/tag.rb index fea614f90..2ef637072 100644 --- a/app/services/search/tag.rb +++ b/app/services/search/tag.rb @@ -2,8 +2,16 @@ module Search class Tag ATTRIBUTES = %i[id name hotness_score rules_html supported short_summary bg_color_hex badge_id].freeze - def self.search_documents(term) - results = ::Tag.search_by_name(term).supported.includes(:badge).reorder(hotness_score: :desc).select(*ATTRIBUTES) + DEFAULT_PER_PAGE = 60 + MAX_PER_PAGE = 100 + + def self.search_documents( + page: 0, + per_page: DEFAULT_PER_PAGE, + term: nil + ) + results = ::Tag.search_by_name(term).supported.includes(:badge) + .reorder(hotness_score: :desc).page(page).per(per_page).select(*ATTRIBUTES) serialize(results) end diff --git a/app/views/stories/articles_search/_nav_menu.html.erb b/app/views/stories/articles_search/_nav_menu.html.erb index c1a0da2a5..cc676c179 100644 --- a/app/views/stories/articles_search/_nav_menu.html.erb +++ b/app/views/stories/articles_search/_nav_menu.html.erb @@ -8,6 +8,9 @@
  • <%= t("views.search.nav.people") %>
  • +
  • + <%= t("views.search.nav.tags") %> +
  • <%= t("views.search.nav.comments") %>
  • diff --git a/config/locales/views/misc/en.yml b/config/locales/views/misc/en.yml index 80fd9c2ec..809fc870d 100644 --- a/config/locales/views/misc/en.yml +++ b/config/locales/views/misc/en.yml @@ -85,6 +85,7 @@ en: people: People comments: Comments my_posts: My posts only + tags: Tags sort: aria_label: Search result sort options relevance: Most Relevant diff --git a/spec/requests/search_spec.rb b/spec/requests/search_spec.rb index 4c4212f92..61eb2090d 100644 --- a/spec/requests/search_spec.rb +++ b/spec/requests/search_spec.rb @@ -219,6 +219,26 @@ RSpec.describe "Search", type: :request, proper_status: true do expect(response.parsed_body["result"].first).to include("body_text" => podcast_episode.body_text) end end + + context "when using searching for tags" do + let!(:tag) { create(:tag, name: "webdev") } + + it "returns the correct keys for tags" do + get search_feed_content_path(search_fields: "web", class_name: "Tag") + expect(response.parsed_body["result"]).to be_present + end + + it "supports the search params for tags" do + get search_feed_content_path( + search_fields: "web", + class_name: "Tag", + page: 0, + per_page: 1, + ) + + expect(response.parsed_body["result"].first).to include("name" => tag.name) + end + end end describe "GET /search/reactions" do diff --git a/spec/services/search/tag_spec.rb b/spec/services/search/tag_spec.rb index 6b2e7050d..1c943bfac 100644 --- a/spec/services/search/tag_spec.rb +++ b/spec/services/search/tag_spec.rb @@ -5,29 +5,29 @@ RSpec.describe Search::Tag, type: :service do it "does not find non supported tags" do tag = create(:tag, supported: false) - expect(described_class.search_documents(tag.name)).to be_empty + expect(described_class.search_documents(term: tag.name)).to be_empty end it "returns data in the expected format" do tag = create(:tag, supported: true) - result = described_class.search_documents(tag.name) + result = described_class.search_documents(term: tag.name) expect(result.first.keys).to match_array( - %i[id name hotness_score rules_html supported short_summary badge bg_color_hex], + %i[id name class_name hotness_score rules_html supported short_summary badge bg_color_hex], ) end it "finds a tag by its name" do tag = create(:tag, supported: true) - expect(described_class.search_documents(tag.name)).to be_present + expect(described_class.search_documents(term: tag.name)).to be_present end it "finds a tag by a partial name" do tag = create(:tag, supported: true) - expect(described_class.search_documents(tag.name.first(1))).to be_present + expect(described_class.search_documents(term: tag.name.first(1))).to be_present end it "finds multiple tags whose names have common parts", :aggregate_failures do @@ -35,7 +35,7 @@ RSpec.describe Search::Tag, type: :service do javascript = create(:tag, name: "javascript") ruby = create(:tag, name: "ruby") - result = described_class.search_documents("jav") + result = described_class.search_documents(term: "jav") tags = result.pluck(:name) expect(tags).to include(java.name) @@ -55,7 +55,7 @@ RSpec.describe Search::Tag, type: :service do tag1.save! tag2.save! - result = described_class.search_documents("jav") + result = described_class.search_documents(term: "jav") tags = result.pluck(:name) expect(tags).to eq([tag2.name, tag1.name])