411 lines
11 KiB
Ruby
411 lines
11 KiB
Ruby
|
require 'spec_helper'
|
||
|
|
||
|
describe 'Elasticsearch::Model::Response::Response Kaminari' do
|
||
|
|
||
|
before(:all) do
|
||
|
class ModelClass
|
||
|
include ::Kaminari::ConfigurationMethods
|
||
|
def self.index_name; 'foo'; end
|
||
|
def self.document_type; 'bar'; end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
after(:all) do
|
||
|
remove_classes(ModelClass)
|
||
|
end
|
||
|
|
||
|
let(:response_document) do
|
||
|
{ 'took' => '5', 'timed_out' => false, '_shards' => {'one' => 'OK'},
|
||
|
'hits' => { 'total' => 100, 'hits' => (1..100).to_a.map { |i| { _id: i } } } }
|
||
|
end
|
||
|
|
||
|
let(:search) do
|
||
|
Elasticsearch::Model::Searching::SearchRequest.new(model, '*')
|
||
|
end
|
||
|
|
||
|
let(:response) do
|
||
|
allow(model).to receive(:client).and_return(client)
|
||
|
Elasticsearch::Model::Response::Response.new(model, search, response_document).tap do |resp|
|
||
|
allow(resp).to receive(:client).and_return(client)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
let(:client) do
|
||
|
double('client')
|
||
|
end
|
||
|
|
||
|
shared_examples_for 'a search request that can be paginated' do
|
||
|
|
||
|
describe '#page' do
|
||
|
|
||
|
it 'does not set an initial from and size on the search definition' do
|
||
|
expect(response.search.definition[:from]).to be(nil)
|
||
|
expect(response.search.definition[:size]).to be(nil)
|
||
|
end
|
||
|
|
||
|
context 'when page is called once' do
|
||
|
|
||
|
let(:search_request) do
|
||
|
{ index: index_field, from: 25, size: 25, q: '*', type: type_field}
|
||
|
end
|
||
|
|
||
|
before do
|
||
|
expect(client).to receive(:search).with(search_request).and_return(response_document)
|
||
|
response.page(2).to_a
|
||
|
end
|
||
|
|
||
|
it 'advances the from/size in the search request' do
|
||
|
expect(response.search.definition[:from]).to be(25)
|
||
|
expect(response.search.definition[:size]).to be(25)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
context 'when page is called more than once' do
|
||
|
|
||
|
let(:search_request_one) do
|
||
|
{ index: index_field, from: 25, size: 25, q: '*', type: type_field}
|
||
|
end
|
||
|
|
||
|
let(:search_request_two) do
|
||
|
{ index: index_field, from: 75, size: 25, q: '*', type: type_field}
|
||
|
end
|
||
|
|
||
|
before do
|
||
|
expect(client).to receive(:search).with(search_request_one).and_return(response_document)
|
||
|
response.page(2).to_a
|
||
|
expect(client).to receive(:search).with(search_request_two).and_return(response_document)
|
||
|
response.page(4).to_a
|
||
|
end
|
||
|
|
||
|
it 'advances the from/size in the search request' do
|
||
|
expect(response.search.definition[:from]).to be(75)
|
||
|
expect(response.search.definition[:size]).to be(25)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
context 'when limit is also set' do
|
||
|
|
||
|
before do
|
||
|
response.records
|
||
|
response.results
|
||
|
end
|
||
|
|
||
|
context 'when page is called before limit' do
|
||
|
|
||
|
before do
|
||
|
response.page(3).limit(35)
|
||
|
end
|
||
|
|
||
|
it 'sets the correct values' do
|
||
|
expect(response.search.definition[:size]).to eq(35)
|
||
|
expect(response.search.definition[:from]).to eq(70)
|
||
|
end
|
||
|
|
||
|
it 'resets the instance variables' do
|
||
|
expect(response.instance_variable_get(:@response)).to be(nil)
|
||
|
expect(response.instance_variable_get(:@records)).to be(nil)
|
||
|
expect(response.instance_variable_get(:@results)).to be(nil)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
context 'when limit is called before page' do
|
||
|
|
||
|
before do
|
||
|
response.limit(35).page(3)
|
||
|
end
|
||
|
|
||
|
it 'sets the correct values' do
|
||
|
expect(response.search.definition[:size]).to eq(35)
|
||
|
expect(response.search.definition[:from]).to eq(70)
|
||
|
end
|
||
|
|
||
|
it 'resets the instance variables' do
|
||
|
expect(response.instance_variable_get(:@response)).to be(nil)
|
||
|
expect(response.instance_variable_get(:@records)).to be(nil)
|
||
|
expect(response.instance_variable_get(:@results)).to be(nil)
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
describe '#limit_value' do
|
||
|
|
||
|
context 'when there is no default set' do
|
||
|
|
||
|
it 'uses the limit value from the Kaminari configuration' do
|
||
|
expect(response.limit_value).to eq(Kaminari.config.default_per_page)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
context 'when there is a limit in the search definition' do
|
||
|
|
||
|
let(:search) do
|
||
|
Elasticsearch::Model::Searching::SearchRequest.new(model, '*', size: 10)
|
||
|
end
|
||
|
|
||
|
it 'gets the limit from the search definition' do
|
||
|
expect(response.limit_value).to eq(10)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
context 'when there is a limit in the search body' do
|
||
|
|
||
|
let(:search) do
|
||
|
Elasticsearch::Model::Searching::SearchRequest.new(model, { query: { match_all: {} }, size: 999 })
|
||
|
end
|
||
|
|
||
|
it 'does not use the limit' do
|
||
|
expect(response.limit_value).to be(Kaminari.config.default_per_page)
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
describe '#offset_value' do
|
||
|
|
||
|
context 'when there is no default set' do
|
||
|
|
||
|
it 'uses an offset of 0' do
|
||
|
expect(response.offset_value).to eq(0)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
context 'when there is an offset in the search definition' do
|
||
|
|
||
|
let(:search) do
|
||
|
Elasticsearch::Model::Searching::SearchRequest.new(model, '*', from: 50)
|
||
|
end
|
||
|
|
||
|
it 'gets the limit from the search definition' do
|
||
|
expect(response.offset_value).to eq(50)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
context 'when there is an offset in the search body' do
|
||
|
|
||
|
let(:search) do
|
||
|
Elasticsearch::Model::Searching::SearchRequest.new(model, { query: { match_all: {} }, from: 333 })
|
||
|
end
|
||
|
|
||
|
it 'does not use the offset' do
|
||
|
expect(response.offset_value).to be(0)
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
describe '#limit' do
|
||
|
|
||
|
context 'when a limit is set' do
|
||
|
|
||
|
before do
|
||
|
response.records
|
||
|
response.results
|
||
|
response.limit(35)
|
||
|
end
|
||
|
|
||
|
it 'sets the limit on the search defintiion' do
|
||
|
expect(response.search.definition[:size]).to eq(35)
|
||
|
end
|
||
|
|
||
|
it 'resets the instance variables' do
|
||
|
expect(response.instance_variable_get(:@response)).to be(nil)
|
||
|
expect(response.instance_variable_get(:@records)).to be(nil)
|
||
|
expect(response.instance_variable_get(:@results)).to be(nil)
|
||
|
end
|
||
|
|
||
|
context 'when the limit is provided as a string' do
|
||
|
|
||
|
before do
|
||
|
response.limit('35')
|
||
|
end
|
||
|
|
||
|
it 'coerces the string to an integer' do
|
||
|
expect(response.search.definition[:size]).to eq(35)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
context 'when the limit is an invalid type' do
|
||
|
|
||
|
before do
|
||
|
response.limit('asdf')
|
||
|
end
|
||
|
|
||
|
it 'does not apply the setting' do
|
||
|
expect(response.search.definition[:size]).to eq(35)
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
describe '#offset' do
|
||
|
|
||
|
context 'when an offset is set' do
|
||
|
|
||
|
before do
|
||
|
response.records
|
||
|
response.results
|
||
|
response.offset(15)
|
||
|
end
|
||
|
|
||
|
it 'sets the limit on the search defintiion' do
|
||
|
expect(response.search.definition[:from]).to eq(15)
|
||
|
end
|
||
|
|
||
|
it 'resets the instance variables' do
|
||
|
expect(response.instance_variable_get(:@response)).to be(nil)
|
||
|
expect(response.instance_variable_get(:@records)).to be(nil)
|
||
|
expect(response.instance_variable_get(:@results)).to be(nil)
|
||
|
end
|
||
|
|
||
|
context 'when the offset is provided as a string' do
|
||
|
|
||
|
before do
|
||
|
response.offset('15')
|
||
|
end
|
||
|
|
||
|
it 'coerces the string to an integer' do
|
||
|
expect(response.search.definition[:from]).to eq(15)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
context 'when the offset is an invalid type' do
|
||
|
|
||
|
before do
|
||
|
response.offset('asdf')
|
||
|
end
|
||
|
|
||
|
it 'does not apply the setting' do
|
||
|
expect(response.search.definition[:from]).to eq(0)
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
describe '#total' do
|
||
|
|
||
|
before do
|
||
|
allow(response.results).to receive(:total).and_return(100)
|
||
|
end
|
||
|
|
||
|
it 'returns the total number of hits' do
|
||
|
expect(response.total_count).to eq(100)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
context 'results' do
|
||
|
|
||
|
before do
|
||
|
allow(search).to receive(:execute!).and_return(response_document)
|
||
|
end
|
||
|
|
||
|
describe '#current_page' do
|
||
|
|
||
|
it 'returns the current page' do
|
||
|
expect(response.results.current_page).to eq(1)
|
||
|
end
|
||
|
|
||
|
context 'when a particular page is accessed' do
|
||
|
|
||
|
it 'returns the correct current page' do
|
||
|
expect(response.page(5).results.current_page).to eq(5)
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
describe '#prev_page' do
|
||
|
|
||
|
it 'returns the previous page' do
|
||
|
expect(response.page(1).results.prev_page).to be(nil)
|
||
|
expect(response.page(2).results.prev_page).to be(1)
|
||
|
expect(response.page(3).results.prev_page).to be(2)
|
||
|
expect(response.page(4).results.prev_page).to be(3)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
describe '#next_page' do
|
||
|
|
||
|
it 'returns the previous page' do
|
||
|
expect(response.page(1).results.next_page).to be(2)
|
||
|
expect(response.page(2).results.next_page).to be(3)
|
||
|
expect(response.page(3).results.next_page).to be(4)
|
||
|
expect(response.page(4).results.next_page).to be(nil)
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
context 'records' do
|
||
|
|
||
|
before do
|
||
|
allow(search).to receive(:execute!).and_return(response_document)
|
||
|
end
|
||
|
|
||
|
describe '#current_page' do
|
||
|
|
||
|
it 'returns the current page' do
|
||
|
expect(response.records.current_page).to eq(1)
|
||
|
end
|
||
|
|
||
|
context 'when a particular page is accessed' do
|
||
|
|
||
|
it 'returns the correct current page' do
|
||
|
expect(response.page(5).records.current_page).to eq(5)
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
describe '#prev_page' do
|
||
|
|
||
|
it 'returns the previous page' do
|
||
|
expect(response.page(1).records.prev_page).to be(nil)
|
||
|
expect(response.page(2).records.prev_page).to be(1)
|
||
|
expect(response.page(3).records.prev_page).to be(2)
|
||
|
expect(response.page(4).records.prev_page).to be(3)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
describe '#next_page' do
|
||
|
|
||
|
it 'returns the previous page' do
|
||
|
expect(response.page(1).records.next_page).to be(2)
|
||
|
expect(response.page(2).records.next_page).to be(3)
|
||
|
expect(response.page(3).records.next_page).to be(4)
|
||
|
expect(response.page(4).records.next_page).to be(nil)
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
context 'when the model is a single one' do
|
||
|
|
||
|
let(:model) do
|
||
|
ModelClass
|
||
|
end
|
||
|
|
||
|
let(:type_field) do
|
||
|
'bar'
|
||
|
end
|
||
|
|
||
|
let(:index_field) do
|
||
|
'foo'
|
||
|
end
|
||
|
|
||
|
it_behaves_like 'a search request that can be paginated'
|
||
|
end
|
||
|
|
||
|
context 'when the model is a multimodel' do
|
||
|
|
||
|
let(:model) do
|
||
|
Elasticsearch::Model::Multimodel.new(ModelClass)
|
||
|
end
|
||
|
|
||
|
let(:type_field) do
|
||
|
['bar']
|
||
|
end
|
||
|
|
||
|
let(:index_field) do
|
||
|
['foo']
|
||
|
end
|
||
|
|
||
|
it_behaves_like 'a search request that can be paginated'
|
||
|
end
|
||
|
end
|