mirror of
https://github.com/discourse/discourse.git
synced 2024-12-16 20:03:42 +08:00
e3925278e2
https://meta.discourse.org/t/search-logs-page/73281/11?u=techapj This commit adds following features: - support for tracking click through to user, tag and category - new filter for search type (header, full page) This commit also removes "most viewed topic" field from search logs page because we are now tracking multiple click through entities, so topic is not a special entity anymore. This also improves query perf. The query now takes `20.5ms` to runs, as opposed to `655.9ms` previously.
295 lines
8.3 KiB
Ruby
295 lines
8.3 KiB
Ruby
require 'rails_helper'
|
|
|
|
describe SearchController do
|
|
|
|
context "integration" do
|
|
before do
|
|
SearchIndexer.enable
|
|
end
|
|
|
|
it "can search correctly" do
|
|
my_post = Fabricate(:post, raw: 'this is my really awesome post')
|
|
|
|
get :query, params: {
|
|
term: 'awesome', include_blurb: true
|
|
}, format: :json
|
|
|
|
expect(response).to be_success
|
|
data = JSON.parse(response.body)
|
|
expect(data['posts'][0]['id']).to eq(my_post.id)
|
|
expect(data['posts'][0]['blurb']).to eq('this is my really awesome post')
|
|
expect(data['topics'][0]['id']).to eq(my_post.topic_id)
|
|
end
|
|
|
|
it 'performs the query with a type filter' do
|
|
user = Fabricate(:user)
|
|
my_post = Fabricate(:post, raw: "#{user.username} is a cool person")
|
|
|
|
get :query, params: {
|
|
term: user.username, type_filter: 'topic'
|
|
}, format: :json
|
|
|
|
expect(response).to be_success
|
|
data = JSON.parse(response.body)
|
|
|
|
expect(data['posts'][0]['id']).to eq(my_post.id)
|
|
expect(data['users']).to be_blank
|
|
|
|
get :query, params: {
|
|
term: user.username, type_filter: 'user'
|
|
}, format: :json
|
|
|
|
expect(response).to be_success
|
|
data = JSON.parse(response.body)
|
|
|
|
expect(data['posts']).to be_blank
|
|
expect(data['users'][0]['id']).to eq(user.id)
|
|
end
|
|
|
|
context 'searching by topic id' do
|
|
it 'should not be restricted by minimum search term length' do
|
|
SiteSetting.min_search_term_length = 20000
|
|
|
|
post = Fabricate(:post)
|
|
|
|
get :query, params: {
|
|
term: post.topic_id,
|
|
type_filter: 'topic',
|
|
search_for_id: true
|
|
}, format: :json
|
|
|
|
expect(response).to be_success
|
|
data = JSON.parse(response.body)
|
|
|
|
expect(data['topics'][0]['id']).to eq(post.topic_id)
|
|
end
|
|
|
|
it "should return the right result" do
|
|
user = Fabricate(:user)
|
|
my_post = Fabricate(:post, raw: "#{user.username} is a cool person")
|
|
|
|
get :query, params: {
|
|
term: my_post.topic_id,
|
|
type_filter: 'topic',
|
|
search_for_id: true
|
|
}, format: :json
|
|
|
|
expect(response).to be_success
|
|
data = JSON.parse(response.body)
|
|
|
|
expect(data['topics'][0]['id']).to eq(my_post.topic_id)
|
|
end
|
|
end
|
|
end
|
|
|
|
context "#query" do
|
|
it "logs the search term" do
|
|
SiteSetting.log_search_queries = true
|
|
get :query, params: { term: 'wookie' }, format: :json
|
|
|
|
expect(response).to be_success
|
|
expect(SearchLog.where(term: 'wookie')).to be_present
|
|
|
|
json = JSON.parse(response.body)
|
|
search_log_id = json['grouped_search_result']['search_log_id']
|
|
expect(search_log_id).to be_present
|
|
|
|
log = SearchLog.where(id: search_log_id).first
|
|
expect(log).to be_present
|
|
expect(log.term).to eq('wookie')
|
|
end
|
|
|
|
it "doesn't log when disabled" do
|
|
SiteSetting.log_search_queries = false
|
|
get :query, params: { term: 'wookie' }, format: :json
|
|
expect(response).to be_success
|
|
expect(SearchLog.where(term: 'wookie')).to be_blank
|
|
end
|
|
end
|
|
|
|
context "#show" do
|
|
it "logs the search term" do
|
|
SiteSetting.log_search_queries = true
|
|
get :show, params: { q: 'bantha' }, format: :json
|
|
expect(response).to be_success
|
|
expect(SearchLog.where(term: 'bantha')).to be_present
|
|
end
|
|
|
|
it "doesn't log when disabled" do
|
|
SiteSetting.log_search_queries = false
|
|
get :show, params: { q: 'bantha' }, format: :json
|
|
expect(response).to be_success
|
|
expect(SearchLog.where(term: 'bantha')).to be_blank
|
|
end
|
|
end
|
|
|
|
context "search context" do
|
|
it "raises an error with an invalid context type" do
|
|
expect do
|
|
get :query, params: {
|
|
term: 'test', search_context: { type: 'security', id: 'hole' }
|
|
}, format: :json
|
|
end.to raise_error(Discourse::InvalidParameters)
|
|
end
|
|
|
|
it "raises an error with a missing id" do
|
|
expect do
|
|
get :query,
|
|
params: { term: 'test', search_context: { type: 'user' } },
|
|
format: :json
|
|
end.to raise_error(Discourse::InvalidParameters)
|
|
end
|
|
|
|
context "with a user" do
|
|
let(:user) { Fabricate(:user) }
|
|
|
|
it "raises an error if the user can't see the context" do
|
|
Guardian.any_instance.expects(:can_see?).with(user).returns(false)
|
|
get :query, params: {
|
|
term: 'test', search_context: { type: 'user', id: user.username }
|
|
}, format: :json
|
|
|
|
expect(response).not_to be_success
|
|
end
|
|
|
|
it 'performs the query with a search context' do
|
|
get :query, params: {
|
|
term: 'test', search_context: { type: 'user', id: user.username }
|
|
}, format: :json
|
|
|
|
expect(response).to be_success
|
|
end
|
|
end
|
|
|
|
end
|
|
|
|
context "#click" do
|
|
it "doesn't work wthout the necessary parameters" do
|
|
expect do
|
|
post :click, format: :json
|
|
end.to raise_error(ActionController::ParameterMissing)
|
|
end
|
|
|
|
it "doesn't record the click for a different user" do
|
|
log_in(:user)
|
|
|
|
_, search_log_id = SearchLog.log(
|
|
term: 'kitty',
|
|
search_type: :header,
|
|
user_id: -10,
|
|
ip_address: '127.0.0.1'
|
|
)
|
|
|
|
post :click, params: {
|
|
search_log_id: search_log_id,
|
|
search_result_id: 12345,
|
|
search_result_type: 'topic'
|
|
}
|
|
|
|
expect(response).to be_success
|
|
expect(SearchLog.find(search_log_id).search_result_id).to be_blank
|
|
end
|
|
|
|
it "records the click for a logged in user" do
|
|
user = log_in(:user)
|
|
|
|
_, search_log_id = SearchLog.log(
|
|
term: 'foobar',
|
|
search_type: :header,
|
|
user_id: user.id,
|
|
ip_address: '127.0.0.1'
|
|
)
|
|
|
|
post :click, params: {
|
|
search_log_id: search_log_id,
|
|
search_result_id: 12345,
|
|
search_result_type: 'user'
|
|
}, format: :json
|
|
|
|
expect(response).to be_success
|
|
expect(SearchLog.find(search_log_id).search_result_id).to eq(12345)
|
|
expect(SearchLog.find(search_log_id).search_result_type).to eq(SearchLog.search_result_types[:user])
|
|
end
|
|
|
|
it "records the click for an anonymous user" do
|
|
request.remote_addr = '192.168.0.1';
|
|
|
|
_, search_log_id = SearchLog.log(
|
|
term: 'kitty',
|
|
search_type: :header,
|
|
ip_address: '192.168.0.1'
|
|
)
|
|
|
|
post :click, params: {
|
|
search_log_id: search_log_id,
|
|
search_result_id: 22222,
|
|
search_result_type: 'topic'
|
|
}, format: :json
|
|
|
|
expect(response).to be_success
|
|
expect(SearchLog.find(search_log_id).search_result_id).to eq(22222)
|
|
expect(SearchLog.find(search_log_id).search_result_type).to eq(SearchLog.search_result_types[:topic])
|
|
end
|
|
|
|
it "doesn't record the click for a different IP" do
|
|
request.stubs(:remote_ip).returns('192.168.0.2')
|
|
|
|
_, search_log_id = SearchLog.log(
|
|
term: 'kitty',
|
|
search_type: :header,
|
|
ip_address: '192.168.0.1'
|
|
)
|
|
|
|
post :click, params: {
|
|
search_log_id: search_log_id,
|
|
search_result_id: 22222,
|
|
search_result_type: 'topic'
|
|
}
|
|
|
|
expect(response).to be_success
|
|
expect(SearchLog.find(search_log_id).search_result_id).to be_blank
|
|
end
|
|
|
|
it "records the click for search result type category" do
|
|
request.remote_addr = '192.168.0.1';
|
|
|
|
_, search_log_id = SearchLog.log(
|
|
term: 'dev',
|
|
search_type: :header,
|
|
ip_address: '192.168.0.1'
|
|
)
|
|
|
|
post :click, params: {
|
|
search_log_id: search_log_id,
|
|
search_result_id: 23456,
|
|
search_result_type: 'category'
|
|
}, format: :json
|
|
|
|
expect(response).to be_success
|
|
expect(SearchLog.find(search_log_id).search_result_id).to eq(23456)
|
|
expect(SearchLog.find(search_log_id).search_result_type).to eq(SearchLog.search_result_types[:category])
|
|
end
|
|
|
|
it "records the click for search result type tag" do
|
|
request.remote_addr = '192.168.0.1';
|
|
tag = Fabricate(:tag, name: 'test')
|
|
|
|
_, search_log_id = SearchLog.log(
|
|
term: 'test',
|
|
search_type: :header,
|
|
ip_address: '192.168.0.1'
|
|
)
|
|
|
|
post :click, params: {
|
|
search_log_id: search_log_id,
|
|
search_result_id: tag.name,
|
|
search_result_type: 'tag'
|
|
}, format: :json
|
|
|
|
expect(response).to be_success
|
|
expect(SearchLog.find(search_log_id).search_result_id).to eq(tag.id)
|
|
expect(SearchLog.find(search_log_id).search_result_type).to eq(SearchLog.search_result_types[:tag])
|
|
end
|
|
end
|
|
end
|