Created
May 28, 2020 13:09
-
-
Save shin1ohno/3f05cafec758e23d93a4286cf9c2440d to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git c/app/controllers/api/trending_searches_controller.rb w/app/controllers/api/trending_searches_controller.rb | |
new file mode 100644 | |
index 0000000000..b0f8303079 | |
--- /dev/null | |
+++ w/app/controllers/api/trending_searches_controller.rb | |
@@ -0,0 +1,29 @@ | |
+module Api | |
+ class TrendingSearchesController < BaseController | |
+ def index | |
+ if Experiment.enabled?(feature) && broad_query_present? | |
+ render json: trending_searches(query) | |
+ else | |
+ render_feature_unavailable_error(feature) | |
+ end | |
+ end | |
+ | |
+ private | |
+ | |
+ def trending_searches(query) | |
+ Search::TrendingSearch.for(query: query, limit: params[:limit]) | |
+ end | |
+ | |
+ def broad_query_present? | |
+ Search::BroadQueries.include?(query) | |
+ end | |
+ | |
+ def query | |
+ @_query ||= QueryNormalizer.normalize(params[:query]) | |
+ end | |
+ | |
+ def feature | |
+ :trending_search | |
+ end | |
+ end | |
+end | |
diff --git c/app/models/search/trending_search.rb w/app/models/search/trending_search.rb | |
new file mode 100644 | |
index 0000000000..2416e14e01 | |
--- /dev/null | |
+++ w/app/models/search/trending_search.rb | |
@@ -0,0 +1,19 @@ | |
+module Search | |
+ class TrendingSearch < Base | |
+ include ActiveModel::Serialization | |
+ | |
+ uri "trending_searches" | |
+ | |
+ def self.for(query:, limit: nil) | |
+ where({ query: query, limit: limit }.compact) | |
+ end | |
+ | |
+ def recipes | |
+ Recipe.where_with_order(recipe_ids) | |
+ end | |
+ | |
+ def recipe_ids | |
+ self["recipes"].map { |recipe| recipe[:id] } | |
+ end | |
+ end | |
+end | |
diff --git c/app/serializers/search/trending_search_serializer.rb w/app/serializers/search/trending_search_serializer.rb | |
new file mode 100644 | |
index 0000000000..24355b7db9 | |
--- /dev/null | |
+++ w/app/serializers/search/trending_search_serializer.rb | |
@@ -0,0 +1,6 @@ | |
+module Search | |
+ class TrendingSearchSerializer < BaseSerializer | |
+ attributes :requested_query | |
+ embed :recipes | |
+ end | |
+end | |
diff --git c/config/initializers/feature_toggles.rb w/config/initializers/feature_toggles.rb | |
index cfc7425384..ad29c89406 100644 | |
--- c/config/initializers/feature_toggles.rb | |
+++ w/config/initializers/feature_toggles.rb | |
@@ -944,3 +944,10 @@ Experiment.add(:clustered_search, evaluate_on: "2020-07-01", owner: "ps-2x") do | |
ExperimentGroup.new(name: :clustered_search, percentage: 50, id: Current.user&.id).active? | |
end | |
+ | |
+Experiment.add(:trending_search, evaluate_on: "2020-07-01", owner: "ps-2x") do | |
+ return false unless I18n.locale == :id | |
+ return true if Rails.env.staging? | |
+ | |
+ ExperimentGroup.new(name: :trending_search, percentage: 50, id: Current.user&.id).active? | |
+end | |
diff --git c/config/routes.api.rb w/config/routes.api.rb | |
index 5c601f940e..17ab5d6ed0 100644 | |
--- c/config/routes.api.rb | |
+++ w/config/routes.api.rb | |
@@ -70,6 +70,8 @@ Rails.application.routes.draw do | |
resources :invitations, only: :create | |
resources :clustered_searches, only: :index | |
+ resources :trending_searches, only: :index | |
+ | |
resources :contests, only: %i(index show) do | |
collection do | |
resources :followees, only: :index, to: "contests_followees#index" | |
diff --git c/spec/factories/search/trending_search_factory.rb w/spec/factories/search/trending_search_factory.rb | |
new file mode 100644 | |
index 0000000000..b46ab50241 | |
--- /dev/null | |
+++ w/spec/factories/search/trending_search_factory.rb | |
@@ -0,0 +1,19 @@ | |
+FactoryBot.define do | |
+ factory :trending_search, class: Hash do | |
+ skip_create | |
+ | |
+ initialize_with do | |
+ attributes | |
+ end | |
+ | |
+ original_query { "query" } | |
+ recipes { [] } | |
+ total_count { 0 } | |
+ | |
+ after(:create) do |obj| | |
+ obj[:recipes].map do |recipe| | |
+ { type: "recipes", id: recipe.id } | |
+ end | |
+ end | |
+ end | |
+end | |
diff --git c/spec/models/search/trending_search_spec.rb w/spec/models/search/trending_search_spec.rb | |
new file mode 100644 | |
index 0000000000..a2c66488ab | |
--- /dev/null | |
+++ w/spec/models/search/trending_search_spec.rb | |
@@ -0,0 +1,26 @@ | |
+require "rails_helper" | |
+ | |
+module Search | |
+ describe TrendingSearch do | |
+ let(:requested_query) { "query" } | |
+ let(:recipes) { create_list(:recipe, 2) } | |
+ let!(:endpoint) do | |
+ stub_global(:get, "/trending_searches"). | |
+ with(query: { query: requested_query }).to_return_json( | |
+ { | |
+ result: [ | |
+ { | |
+ recipes: recipes.map { |r| { type: "recipe", id: r.id } }, | |
+ requested_query: requested_query | |
+ } | |
+ ] | |
+ } | |
+ ) | |
+ end | |
+ | |
+ it "get the recipe ids from search" do | |
+ result = Search::TrendingSearch.for(query: "query") | |
+ expect(result.first.recipes.map(&:id)).to eq(recipes.map(&:id)) | |
+ end | |
+ end | |
+end | |
diff --git c/spec/requests/api/trending_searches_spec.rb w/spec/requests/api/trending_searches_spec.rb | |
new file mode 100644 | |
index 0000000000..1fd420e016 | |
--- /dev/null | |
+++ w/spec/requests/api/trending_searches_spec.rb | |
@@ -0,0 +1,52 @@ | |
+require "rails_helper" | |
+ | |
+resource "Trending Searches" do | |
+ explanation "Return a list of trending recipes for a requested query. Trending means fresh and cooked recently." | |
+ parameter :query, "Search query that from client." | |
+ parameter :limit, "Specify the number of recipes. Result could be fewer than this." | |
+ | |
+ let(:requested_query) { "query" } | |
+ let(:recipes) { create_list(:recipe, 2) } | |
+ let!(:endpoint) do | |
+ stub_global(:get, "/trending_searches"). | |
+ with(query: { query: requested_query }).to_return_json( | |
+ { | |
+ result: [ | |
+ { | |
+ recipes: recipes.map { |r| { type: "recipe", id: r.id } }, | |
+ requested_query: requested_query | |
+ } | |
+ ] | |
+ } | |
+ ) | |
+ end | |
+ | |
+ before do | |
+ enable_feature(:trending_search) | |
+ Search::BroadQueries.data = [{ query: requested_query }] | |
+ end | |
+ | |
+ get "/:version/trending_searches" do | |
+ example "List the recipes", document: true do | |
+ do_request query: requested_query | |
+ | |
+ expect(endpoint).to have_been_requested | |
+ expect_json_response("result/0/recipes/0").to include(id: recipes[0].id) | |
+ expect_json_response("result/0/recipes/1").to include(id: recipes[1].id) | |
+ end | |
+ | |
+ context "When the query is not targeted one" do | |
+ before do | |
+ Search::BroadQueries.data = [] | |
+ end | |
+ | |
+ it "returns a 404 error when the query is not in the broad query allowlist" do | |
+ do_request query: "query" | |
+ | |
+ expect(endpoint).to_not have_been_requested | |
+ expect(status).to eq(404) | |
+ end | |
+ end | |
+ end | |
+end | |
+ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment