Add `exclude_unreviewed` param to `GET /api/v2/search` REST API (#11977)

Make it so normal search returns even unreviewed matches, but
autosuggestions do not.

Fix #11960
This commit is contained in:
Eugen Rochko 2019-09-28 01:02:21 +02:00 committed by GitHub
parent 234c729c52
commit ab33c4df94
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 22 additions and 17 deletions

View File

@ -22,7 +22,7 @@ class Api::V2::SearchController < Api::BaseController
params[:q], params[:q],
current_account, current_account,
limit_param(RESULTS_LIMIT), limit_param(RESULTS_LIMIT),
search_params.merge(resolve: truthy_param?(:resolve)) search_params.merge(resolve: truthy_param?(:resolve), exclude_unreviewed: truthy_param?(:exclude_unreviewed))
) )
end end

View File

@ -369,6 +369,7 @@ const fetchComposeSuggestionsTags = throttle((dispatch, getState, token) => {
q: token.slice(1), q: token.slice(1),
resolve: false, resolve: false,
limit: 4, limit: 4,
exclude_unreviewed: true,
}, },
}).then(({ data }) => { }).then(({ data }) => {
dispatch(readyComposeSuggestionsTags(token, data.hashtags)); dispatch(readyComposeSuggestionsTags(token, data.hashtags));

View File

@ -124,16 +124,15 @@ class Tag < ApplicationRecord
end end
end end
def search_for(term, limit = 5, offset = 0) def search_for(term, limit = 5, offset = 0, options = {})
normalized_term = normalize(term.strip).mb_chars.downcase.to_s normalized_term = normalize(term.strip).mb_chars.downcase.to_s
pattern = sanitize_sql_like(normalized_term) + '%' pattern = sanitize_sql_like(normalized_term) + '%'
query = Tag.listable.where(arel_table[:name].lower.matches(pattern))
query = query.where(arel_table[:name].lower.eq(normalized_term).or(arel_table[:reviewed_at].not_eq(nil))) if options[:exclude_unreviewed]
Tag.listable query.order(Arel.sql('length(name) ASC, name ASC'))
.where(arel_table[:name].lower.matches(pattern)) .limit(limit)
.where(arel_table[:name].lower.eq(normalized_term).or(arel_table[:reviewed_at].not_eq(nil))) .offset(offset)
.order(Arel.sql('length(name) ASC, name ASC'))
.limit(limit)
.offset(offset)
end end
def find_normalized(name) def find_normalized(name)

View File

@ -60,7 +60,8 @@ class SearchService < BaseService
TagSearchService.new.call( TagSearchService.new.call(
@query, @query,
limit: @limit, limit: @limit,
offset: @offset offset: @offset,
exclude_unreviewed: @options[:exclude_unreviewed]
) )
end end

View File

@ -2,11 +2,12 @@
class TagSearchService < BaseService class TagSearchService < BaseService
def call(query, options = {}) def call(query, options = {})
@query = query.strip.gsub(/\A#/, '') @query = query.strip.gsub(/\A#/, '')
@offset = options[:offset].to_i @offset = options.delete(:offset).to_i
@limit = options[:limit].to_i @limit = options.delete(:limit).to_i
@options = options
results = from_elasticsearch if Chewy.enabled? results = from_elasticsearch if Chewy.enabled?
results ||= from_database results ||= from_database
results results
@ -72,12 +73,15 @@ class TagSearchService < BaseService
}, },
} }
TagsIndex.query(query).filter(filter).limit(@limit).offset(@offset).objects.compact definition = TagsIndex.query(query)
definition = definition.filter(filter) if @options[:exclude_unreviewed]
definition.limit(@limit).offset(@offset).objects.compact
rescue Faraday::ConnectionFailed, Parslet::ParseFailed rescue Faraday::ConnectionFailed, Parslet::ParseFailed
nil nil
end end
def from_database def from_database
Tag.search_for(@query, @limit, @offset) Tag.search_for(@query, @limit, @offset, @options)
end end
end end

View File

@ -77,10 +77,10 @@ describe SearchService, type: :service do
it 'includes the tag in the results' do it 'includes the tag in the results' do
query = '#tag' query = '#tag'
tag = Tag.new tag = Tag.new
allow(Tag).to receive(:search_for).with('tag', 10, 0).and_return([tag]) allow(Tag).to receive(:search_for).with('tag', 10, 0, exclude_unreviewed: nil).and_return([tag])
results = subject.call(query, nil, 10) results = subject.call(query, nil, 10)
expect(Tag).to have_received(:search_for).with('tag', 10, 0) expect(Tag).to have_received(:search_for).with('tag', 10, 0, exclude_unreviewed: nil)
expect(results).to eq empty_results.merge(hashtags: [tag]) expect(results).to eq empty_results.merge(hashtags: [tag])
end end
it 'does not include tag when starts with @ character' do it 'does not include tag when starts with @ character' do