debian-mirror-gitlab/elasticsearch-model/spec/elasticsearch/model/adapters/active_record/basic_spec.rb
2020-03-13 15:44:24 +05:30

340 lines
9.6 KiB
Ruby

require 'spec_helper'
describe Elasticsearch::Model::Adapter::ActiveRecord do
before(:all) do
ActiveRecord::Schema.define(:version => 1) do
create_table :articles do |t|
t.string :title
t.string :body
t.integer :clicks, :default => 0
t.datetime :created_at, :default => 'NOW()'
end
end
Article.delete_all
Article.__elasticsearch__.create_index!(force: true)
Article.create!(title: 'Test', body: '', clicks: 1)
Article.create!(title: 'Testing Coding', body: '', clicks: 2)
Article.create!(title: 'Coding', body: '', clicks: 3)
Article.__elasticsearch__.refresh_index!
end
describe 'indexing a document' do
let(:search_result) do
Article.search('title:test')
end
it 'allows searching for documents' do
expect(search_result.results.size).to be(2)
expect(search_result.records.size).to be(2)
end
end
describe '#results' do
let(:search_result) do
Article.search('title:test')
end
it 'returns an instance of Response::Result' do
expect(search_result.results.first).to be_a(Elasticsearch::Model::Response::Result)
end
it 'prooperly loads the document' do
expect(search_result.results.first.title).to eq('Test')
end
context 'when the result contains other data' do
let(:search_result) do
Article.search(query: { match: { title: 'test' } }, highlight: { fields: { title: {} } })
end
it 'allows access to the Elasticsearch result' do
expect(search_result.results.first.title).to eq('Test')
expect(search_result.results.first.title?).to be(true)
expect(search_result.results.first.boo?).to be(false)
expect(search_result.results.first.highlight?).to be(true)
expect(search_result.results.first.highlight.title?).to be(true)
expect(search_result.results.first.highlight.boo?).to be(false)
end
end
end
describe '#records' do
let(:search_result) do
Article.search('title:test')
end
it 'returns an instance of the model' do
expect(search_result.records.first).to be_a(Article)
end
it 'prooperly loads the document' do
expect(search_result.records.first.title).to eq('Test')
end
end
describe 'Enumerable' do
let(:search_result) do
Article.search('title:test')
end
it 'allows iteration over results' do
expect(search_result.results.map(&:_id)).to eq(['1', '2'])
end
it 'allows iteration over records' do
expect(search_result.records.map(&:id)).to eq([1, 2])
end
end
describe '#id' do
let(:search_result) do
Article.search('title:test')
end
it 'returns the id' do
expect(search_result.results.first.id).to eq('1')
end
end
describe '#id' do
let(:search_result) do
Article.search('title:test')
end
it 'returns the type' do
expect(search_result.results.first.type).to eq('article')
end
end
describe '#each_with_hit' do
let(:search_result) do
Article.search('title:test')
end
it 'returns the record with the Elasticsearch hit' do
search_result.records.each_with_hit do |r, h|
expect(h._score).not_to be_nil
expect(h._source.title).not_to be_nil
end
end
end
describe 'search results order' do
let(:search_result) do
Article.search(query: { match: { title: 'code' }}, sort: { clicks: :desc })
end
it 'preserves the search results order when accessing a single record' do
expect(search_result.records[0].clicks).to be(3)
expect(search_result.records[1].clicks).to be(2)
expect(search_result.records.first).to eq(search_result.records[0])
end
it 'preserves the search results order for the list of records' do
search_result.records.each_with_hit do |r, h|
expect(r.id.to_s).to eq(h._id)
end
search_result.records.map_with_hit do |r, h|
expect(r.id.to_s).to eq(h._id)
end
end
end
describe 'a paged collection' do
let(:search_result) do
Article.search(query: { match: { title: { query: 'test' } } },
size: 2,
from: 1)
end
it 'applies the paged options to the search' do
expect(search_result.results.size).to eq(1)
expect(search_result.results.first.title).to eq('Testing Coding')
expect(search_result.records.size).to eq(1)
expect(search_result.records.first.title).to eq('Testing Coding')
end
end
describe '#destroy' do
before do
Article.create!(title: 'destroy', body: '', clicks: 1)
Article.__elasticsearch__.refresh_index!
Article.where(title: 'destroy').first.destroy
Article.__elasticsearch__.refresh_index!
end
let(:search_result) do
Article.search('title:test')
end
it 'removes the document from the index' do
expect(Article.count).to eq(3)
expect(search_result.results.size).to eq(2)
expect(search_result.records.size).to eq(2)
end
end
describe 'full document updates' do
before do
article = Article.create!(title: 'update', body: '', clicks: 1)
Article.__elasticsearch__.refresh_index!
article.title = 'Writing'
article.save
Article.__elasticsearch__.refresh_index!
end
let(:search_result) do
Article.search('title:write')
end
it 'applies the update' do
expect(search_result.results.size).to eq(1)
expect(search_result.records.size).to eq(1)
end
end
describe 'attribute updates' do
before do
article = Article.create!(title: 'update', body: '', clicks: 1)
Article.__elasticsearch__.refresh_index!
article.title = 'special'
article.save
Article.__elasticsearch__.refresh_index!
end
let(:search_result) do
Article.search('title:special')
end
it 'applies the update' do
expect(search_result.results.size).to eq(1)
expect(search_result.records.size).to eq(1)
end
end
describe '#save' do
before do
article = Article.create!(title: 'save', body: '', clicks: 1)
ActiveRecord::Base.transaction do
article.body = 'dummy'
article.save
article.title = 'special'
article.save
end
article.__elasticsearch__.update_document
Article.__elasticsearch__.refresh_index!
end
let(:search_result) do
Article.search('body:dummy')
end
it 'applies the save' do
expect(search_result.results.size).to eq(1)
expect(search_result.records.size).to eq(1)
end
end
describe 'a DSL search' do
let(:search_result) do
Article.search(query: { match: { title: { query: 'test' } } })
end
it 'returns the results' do
expect(search_result.results.size).to eq(2)
expect(search_result.records.size).to eq(2)
end
end
describe 'chaining SQL queries on response.records' do
let(:search_result) do
Article.search(query: { match: { title: { query: 'test' } } })
end
it 'executes the SQL request with the chained query criteria' do
expect(search_result.records.size).to eq(2)
expect(search_result.records.where(title: 'Test').size).to eq(1)
expect(search_result.records.where(title: 'Test').first.title).to eq('Test')
end
end
describe 'ordering of SQL queries' do
context 'when order is called on the ActiveRecord query' do
let(:search_result) do
Article.search query: { match: { title: { query: 'test' } } }
end
it 'allows the SQL query to be ordered independent of the Elasticsearch results order', unless: active_record_at_least_4? do
expect(search_result.records.order('title DESC').first.title).to eq('Testing Coding')
expect(search_result.records.order('title DESC')[0].title).to eq('Testing Coding')
end
it 'allows the SQL query to be ordered independent of the Elasticsearch results order', if: active_record_at_least_4? do
expect(search_result.records.order(title: :desc).first.title).to eq('Testing Coding')
expect(search_result.records.order(title: :desc)[0].title).to eq('Testing Coding')
end
end
context 'when more methods are chained on the ActiveRecord query' do
let(:search_result) do
Article.search query: {match: {title: {query: 'test'}}}
end
it 'allows the SQL query to be ordered independent of the Elasticsearch results order', if: active_record_at_least_4? do
expect(search_result.records.distinct.order(title: :desc).first.title).to eq('Testing Coding')
expect(search_result.records.distinct.order(title: :desc)[0].title).to eq('Testing Coding')
end
end
end
describe 'access to the response via methods' do
let(:search_result) do
Article.search(query: { match: { title: { query: 'test' } } },
aggregations: {
dates: { date_histogram: { field: 'created_at', interval: 'hour' } },
clicks: { global: {}, aggregations: { min: { min: { field: 'clicks' } } } }
},
suggest: { text: 'tezt', title: { term: { field: 'title', suggest_mode: 'always' } } })
end
it 'allows document keys to be access via methods' do
expect(search_result.aggregations.dates.buckets.first.doc_count).to eq(2)
expect(search_result.aggregations.clicks.doc_count).to eq(6)
expect(search_result.aggregations.clicks.min.value).to eq(1.0)
expect(search_result.aggregations.clicks.max).to be_nil
expect(search_result.suggestions.title.first.options.size).to eq(1)
expect(search_result.suggestions.terms).to eq(['test'])
end
end
end