Commit eee9abe4 authored by Bob Van Landuyt's avatar Bob Van Landuyt

Merge branch...

Merge branch '197908-nomethoderror-undefined-method-without_count-for-kaminari-paginatablearray' into 'master'

Fix 500 error in global & group search for blob, wiki_blob and commit search

Closes #197908

See merge request gitlab-org/gitlab!23326
parents b04383b9 9a56deac
---
title: Fix 500 error in global search for blob, wiki_blob and commit search
merge_request: 23326
author:
type: fixed
...@@ -12,14 +12,14 @@ module EE ...@@ -12,14 +12,14 @@ module EE
ELASTICSEARCH_SCOPES = %w(wiki_blobs blobs commits).freeze ELASTICSEARCH_SCOPES = %w(wiki_blobs blobs commits).freeze
override :verify_search_scope! override :verify_search_scope!
def verify_search_scope! def verify_search_scope!(resource:)
if ELASTICSEARCH_SCOPES.include?(params[:scope]) && !elasticsearch? if ELASTICSEARCH_SCOPES.include?(params[:scope]) && !use_elasticsearch?(resource)
render_api_error!({ error: 'Scope not supported without Elasticsearch!' }, 400) render_api_error!({ error: 'Scope not supported without Elasticsearch!' }, 400)
end end
end end
def elasticsearch? def use_elasticsearch?(resource)
::Gitlab::CurrentSettings.elasticsearch_search? ::Gitlab::CurrentSettings.search_using_elasticsearch?(scope: resource)
end end
override :process_results override :process_results
......
...@@ -5,11 +5,10 @@ require 'spec_helper' ...@@ -5,11 +5,10 @@ require 'spec_helper'
describe API::Search do describe API::Search do
set(:user) { create(:user) } set(:user) { create(:user) }
set(:group) { create(:group) } set(:group) { create(:group) }
let(:project) { create(:project, :public, :wiki_repo, name: 'awesome project', group: group) } let(:project) { create(:project, :public, :repository, :wiki_repo, name: 'awesome project', group: group) }
let(:repo_project) { create(:project, :public, :repository, group: group) }
shared_examples 'response is correct' do |schema:, size: 1| shared_examples 'response is correct' do |schema:, size: 1|
it { expect(response).to have_gitlab_http_status(200) } it { expect(response).to have_gitlab_http_status(:ok) }
it { expect(response).to match_response_schema(schema) } it { expect(response).to match_response_schema(schema) }
it { expect(response).to include_limited_pagination_headers } it { expect(response).to include_limited_pagination_headers }
it { expect(json_response.size).to eq(size) } it { expect(json_response.size).to eq(size) }
...@@ -19,27 +18,23 @@ describe API::Search do ...@@ -19,27 +18,23 @@ describe API::Search do
it 'returns 400 error for wiki_blobs scope' do it 'returns 400 error for wiki_blobs scope' do
get api(endpoint, user), params: { scope: 'wiki_blobs', search: 'awesome' } get api(endpoint, user), params: { scope: 'wiki_blobs', search: 'awesome' }
expect(response).to have_gitlab_http_status(400) expect(response).to have_gitlab_http_status(:bad_request)
end end
it 'returns 400 error for blobs scope' do it 'returns 400 error for blobs scope' do
get api(endpoint, user), params: { scope: 'blobs', search: 'monitors' } get api(endpoint, user), params: { scope: 'blobs', search: 'monitors' }
expect(response).to have_gitlab_http_status(400) expect(response).to have_gitlab_http_status(:bad_request)
end end
it 'returns 400 error for commits scope' do it 'returns 400 error for commits scope' do
get api(endpoint, user), params: { scope: 'commits', search: 'folder' } get api(endpoint, user), params: { scope: 'commits', search: 'folder' }
expect(response).to have_gitlab_http_status(400) expect(response).to have_gitlab_http_status(:bad_request)
end end
end end
shared_examples 'elasticsearch enabled' do shared_examples 'elasticsearch enabled' do
before do
stub_ee_application_setting(elasticsearch_search: true, elasticsearch_indexing: true)
end
context 'for wiki_blobs scope', :sidekiq_might_not_need_inline do context 'for wiki_blobs scope', :sidekiq_might_not_need_inline do
before do before do
wiki = create(:project_wiki, project: project) wiki = create(:project_wiki, project: project)
...@@ -56,7 +51,7 @@ describe API::Search do ...@@ -56,7 +51,7 @@ describe API::Search do
context 'for commits scope', :sidekiq_might_not_need_inline do context 'for commits scope', :sidekiq_might_not_need_inline do
before do before do
repo_project.repository.index_commits_and_blobs project.repository.index_commits_and_blobs
Gitlab::Elastic::Helper.refresh_index Gitlab::Elastic::Helper.refresh_index
get api(endpoint, user), params: { scope: 'commits', search: 'folder' } get api(endpoint, user), params: { scope: 'commits', search: 'folder' }
...@@ -67,7 +62,7 @@ describe API::Search do ...@@ -67,7 +62,7 @@ describe API::Search do
context 'for blobs scope', :sidekiq_might_not_need_inline do context 'for blobs scope', :sidekiq_might_not_need_inline do
before do before do
repo_project.repository.index_commits_and_blobs project.repository.index_commits_and_blobs
Gitlab::Elastic::Helper.refresh_index Gitlab::Elastic::Helper.refresh_index
get api(endpoint, user), params: { scope: 'blobs', search: 'monitors' } get api(endpoint, user), params: { scope: 'blobs', search: 'monitors' }
...@@ -77,17 +72,17 @@ describe API::Search do ...@@ -77,17 +72,17 @@ describe API::Search do
context 'filters' do context 'filters' do
it 'by filename' do it 'by filename' do
get api("/projects/#{repo_project.id}/search", user), params: { scope: 'blobs', search: 'mon filename:PROCESS.md' } get api("/projects/#{project.id}/search", user), params: { scope: 'blobs', search: 'mon filename:PROCESS.md' }
expect(response).to have_gitlab_http_status(200) expect(response).to have_gitlab_http_status(:ok)
expect(json_response.size).to eq(1) expect(json_response.size).to eq(1)
expect(json_response.first['path']).to eq('PROCESS.md') expect(json_response.first['path']).to eq('PROCESS.md')
end end
it 'by path' do it 'by path' do
get api("/projects/#{repo_project.id}/search", user), params: { scope: 'blobs', search: 'mon path:markdown' } get api("/projects/#{project.id}/search", user), params: { scope: 'blobs', search: 'mon path:markdown' }
expect(response).to have_gitlab_http_status(200) expect(response).to have_gitlab_http_status(:ok)
expect(json_response.size).to eq(1) expect(json_response.size).to eq(1)
json_response.each do |file| json_response.each do |file|
expect(file['path']).to match(%r[/markdown/]) expect(file['path']).to match(%r[/markdown/])
...@@ -95,9 +90,9 @@ describe API::Search do ...@@ -95,9 +90,9 @@ describe API::Search do
end end
it 'by extension' do it 'by extension' do
get api("/projects/#{repo_project.id}/search", user), params: { scope: 'blobs', search: 'mon extension:md' } get api("/projects/#{project.id}/search", user), params: { scope: 'blobs', search: 'mon extension:md' }
expect(response).to have_gitlab_http_status(200) expect(response).to have_gitlab_http_status(:ok)
expect(json_response.size).to eq(3) expect(json_response.size).to eq(3)
json_response.each do |file| json_response.each do |file|
expect(file['path']).to match(/\A.+\.md\z/) expect(file['path']).to match(/\A.+\.md\z/)
...@@ -108,32 +103,177 @@ describe API::Search do ...@@ -108,32 +103,177 @@ describe API::Search do
end end
describe 'GET /search' do describe 'GET /search' do
let(:endpoint) { '/search' }
context 'with correct params' do context 'with correct params' do
context 'when elasticsearch is disabled' do context 'when elasticsearch is disabled' do
it_behaves_like 'elasticsearch disabled' do it_behaves_like 'elasticsearch disabled'
let(:endpoint) { '/search' }
end
end end
context 'when elasticsearch is enabled', :elastic do context 'when elasticsearch is enabled', :elastic do
it_behaves_like 'elasticsearch enabled' do before do
let(:endpoint) { '/search' } stub_ee_application_setting(elasticsearch_search: true, elasticsearch_indexing: true)
end
context 'when elasticsearch_limit_indexing is on' do
before do
stub_ee_application_setting(elasticsearch_limit_indexing: true)
end
it_behaves_like 'elasticsearch disabled'
end
context 'when elasticsearch_limit_indexing off' do
before do
stub_ee_application_setting(elasticsearch_limit_indexing: false)
end
it_behaves_like 'elasticsearch enabled'
end end
end end
end end
end end
describe "GET /groups/:id/-/search" do describe "GET /groups/:id/-/search" do
let(:endpoint) { "/groups/#{group.id}/-/search" }
context 'with correct params' do context 'with correct params' do
context 'when elasticsearch is disabled' do context 'when elasticsearch is disabled' do
it_behaves_like 'elasticsearch disabled' do it_behaves_like 'elasticsearch disabled'
let(:endpoint) { "/groups/#{group.id}/-/search" } end
context 'when elasticsearch is enabled', :elastic do
before do
stub_ee_application_setting(elasticsearch_search: true, elasticsearch_indexing: true)
end
context 'when elasticsearch_limit_indexing is on' do
before do
stub_ee_application_setting(elasticsearch_limit_indexing: true)
end
context 'when the namespace is indexed' do
before do
create :elasticsearch_indexed_namespace, namespace: group
end
it_behaves_like 'elasticsearch enabled'
end
context 'when the namespace is not indexed' do
it_behaves_like 'elasticsearch disabled'
end
end
context 'when elasticsearch_limit_indexing off' do
before do
stub_ee_application_setting(elasticsearch_limit_indexing: false)
end
it_behaves_like 'elasticsearch enabled'
end
end
end
end
describe "GET /projects/:id/-/search" do
let(:endpoint) { "/projects/#{project.id}/-/search" }
shared_examples_for 'search enabled' do
context 'for wiki_blobs scope' do
before do
wiki = create(:project_wiki, project: project)
create(:wiki_page, wiki: wiki, attrs: { title: 'home', content: "Awesome page" })
get api(endpoint, user), params: { scope: 'wiki_blobs', search: 'awesome' }
end
it_behaves_like 'response is correct', schema: 'public_api/v4/blobs'
end
context 'for commits scope' do
before do
get api(endpoint, user), params: { scope: 'commits', search: 'folder' }
end end
it_behaves_like 'response is correct', schema: 'public_api/v4/commits_details', size: 2
end
context 'for blobs scope' do
before do
get api(endpoint, user), params: { scope: 'blobs', search: 'monitors' }
end
it_behaves_like 'response is correct', schema: 'public_api/v4/blobs', size: 2
context 'filters' do
it 'by filename' do
get api(endpoint, user), params: { scope: 'blobs', search: 'mon filename:PROCESS.md' }
expect(response).to have_gitlab_http_status(:ok)
expect(json_response.size).to eq(2)
expect(json_response.first['path']).to eq('PROCESS.md')
expect(json_response.first['filename']).to eq('PROCESS.md')
end
it 'by path' do
get api(endpoint, user), params: { scope: 'blobs', search: 'mon path:markdown' }
expect(response).to have_gitlab_http_status(:ok)
expect(json_response.size).to eq(8)
end
it 'by extension' do
get api(endpoint, user), params: { scope: 'blobs', search: 'mon extension:md' }
expect(response).to have_gitlab_http_status(:ok)
expect(json_response.size).to eq(11)
end
it 'by ref' do
get api(endpoint, user), params: { scope: 'blobs', search: 'This file is used in tests for ci_environments_status', ref: 'pages-deploy' }
expect(response).to have_gitlab_http_status(:ok)
expect(json_response.size).to eq(1)
end
end
end
end
context 'with correct params' do
context 'when elasticsearch is disabled' do
it_behaves_like 'search enabled'
end end
context 'when elasticsearch is enabled', :elastic do context 'when elasticsearch is enabled', :elastic do
it_behaves_like 'elasticsearch enabled' do before do
let(:endpoint) { "/groups/#{group.id}/-/search" } stub_ee_application_setting(elasticsearch_search: true, elasticsearch_indexing: true)
end
context 'when elasticsearch_limit_indexing is on' do
before do
stub_ee_application_setting(elasticsearch_limit_indexing: true)
end
context 'when the project is indexed' do
before do
create :elasticsearch_indexed_project, project: project
end
it_behaves_like 'elasticsearch enabled'
end
context 'when the project is not indexed' do
it_behaves_like 'search enabled'
end
end
context 'when elasticsearch_limit_indexing off' do
before do
stub_ee_application_setting(elasticsearch_limit_indexing: false)
end
it_behaves_like 'elasticsearch enabled'
end end
end end
end end
......
...@@ -47,7 +47,7 @@ module API ...@@ -47,7 +47,7 @@ module API
SCOPE_ENTITY[params[:scope].to_sym] SCOPE_ENTITY[params[:scope].to_sym]
end end
def verify_search_scope! def verify_search_scope!(resource:)
# In EE we have additional validation requirements for searches. # In EE we have additional validation requirements for searches.
# Defining this method here as a noop allows us to easily extend it in # Defining this method here as a noop allows us to easily extend it in
# EE, without having to modify this file directly. # EE, without having to modify this file directly.
...@@ -73,7 +73,7 @@ module API ...@@ -73,7 +73,7 @@ module API
use :pagination use :pagination
end end
get do get do
verify_search_scope! verify_search_scope!(resource: nil)
check_users_search_allowed! check_users_search_allowed!
present search, with: entity present search, with: entity
...@@ -94,7 +94,7 @@ module API ...@@ -94,7 +94,7 @@ module API
use :pagination use :pagination
end end
get ':id/(-/)search' do get ':id/(-/)search' do
verify_search_scope! verify_search_scope!(resource: user_group)
check_users_search_allowed! check_users_search_allowed!
present search(group_id: user_group.id), with: entity present search(group_id: user_group.id), with: entity
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment