elasticsearch-model 6.0.0 → 6.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile +5 -0
- data/README.md +14 -7
- data/Rakefile +27 -36
- data/elasticsearch-model.gemspec +1 -1
- data/examples/activerecord_mapping_completion.rb +2 -15
- data/gemfiles/3.0.gemfile +6 -1
- data/gemfiles/4.0.gemfile +7 -1
- data/gemfiles/5.0.gemfile +6 -0
- data/lib/elasticsearch/model.rb +15 -8
- data/lib/elasticsearch/model/adapters/active_record.rb +7 -26
- data/lib/elasticsearch/model/indexing.rb +5 -3
- data/lib/elasticsearch/model/naming.rb +6 -1
- data/lib/elasticsearch/model/response.rb +2 -2
- data/lib/elasticsearch/model/response/pagination.rb +2 -192
- data/lib/elasticsearch/model/response/pagination/kaminari.rb +109 -0
- data/lib/elasticsearch/model/response/pagination/will_paginate.rb +95 -0
- data/lib/elasticsearch/model/response/result.rb +1 -1
- data/lib/elasticsearch/model/version.rb +1 -1
- data/spec/elasticsearch/model/adapter_spec.rb +119 -0
- data/spec/elasticsearch/model/adapters/active_record/associations_spec.rb +334 -0
- data/spec/elasticsearch/model/adapters/active_record/basic_spec.rb +340 -0
- data/spec/elasticsearch/model/adapters/active_record/dynamic_index_name_spec.rb +18 -0
- data/spec/elasticsearch/model/adapters/active_record/import_spec.rb +187 -0
- data/spec/elasticsearch/model/adapters/active_record/multi_model_spec.rb +110 -0
- data/spec/elasticsearch/model/adapters/active_record/namespaced_model_spec.rb +38 -0
- data/spec/elasticsearch/model/adapters/active_record/pagination_spec.rb +315 -0
- data/spec/elasticsearch/model/adapters/active_record/parent_child_spec.rb +75 -0
- data/spec/elasticsearch/model/adapters/active_record/serialization_spec.rb +61 -0
- data/spec/elasticsearch/model/adapters/active_record_spec.rb +207 -0
- data/spec/elasticsearch/model/adapters/default_spec.rb +41 -0
- data/spec/elasticsearch/model/adapters/mongoid/basic_spec.rb +267 -0
- data/spec/elasticsearch/model/adapters/mongoid/multi_model_spec.rb +66 -0
- data/spec/elasticsearch/model/adapters/mongoid_spec.rb +235 -0
- data/spec/elasticsearch/model/adapters/multiple_spec.rb +125 -0
- data/spec/elasticsearch/model/callbacks_spec.rb +33 -0
- data/spec/elasticsearch/model/client_spec.rb +66 -0
- data/spec/elasticsearch/model/hash_wrapper_spec.rb +12 -0
- data/spec/elasticsearch/model/importing_spec.rb +214 -0
- data/spec/elasticsearch/model/indexing_spec.rb +918 -0
- data/spec/elasticsearch/model/module_spec.rb +101 -0
- data/spec/elasticsearch/model/multimodel_spec.rb +55 -0
- data/spec/elasticsearch/model/naming_inheritance_spec.rb +184 -0
- data/spec/elasticsearch/model/naming_spec.rb +186 -0
- data/spec/elasticsearch/model/proxy_spec.rb +107 -0
- data/spec/elasticsearch/model/response/aggregations_spec.rb +66 -0
- data/spec/elasticsearch/model/response/base_spec.rb +90 -0
- data/spec/elasticsearch/model/response/pagination/kaminari_spec.rb +410 -0
- data/spec/elasticsearch/model/response/pagination/will_paginate_spec.rb +262 -0
- data/spec/elasticsearch/model/response/records_spec.rb +118 -0
- data/spec/elasticsearch/model/response/response_spec.rb +131 -0
- data/spec/elasticsearch/model/response/result_spec.rb +122 -0
- data/spec/elasticsearch/model/response/results_spec.rb +56 -0
- data/spec/elasticsearch/model/searching_search_request_spec.rb +112 -0
- data/spec/elasticsearch/model/searching_spec.rb +49 -0
- data/spec/elasticsearch/model/serializing_spec.rb +22 -0
- data/spec/spec_helper.rb +161 -0
- data/spec/support/app.rb +21 -0
- data/spec/support/app/answer.rb +33 -0
- data/spec/support/app/article.rb +22 -0
- data/spec/support/app/article_for_pagination.rb +12 -0
- data/spec/support/app/article_with_custom_serialization.rb +13 -0
- data/spec/support/app/article_with_dynamic_index_name.rb +15 -0
- data/spec/support/app/author.rb +9 -0
- data/spec/support/app/authorship.rb +4 -0
- data/spec/support/app/category.rb +3 -0
- data/spec/support/app/comment.rb +3 -0
- data/spec/support/app/episode.rb +11 -0
- data/spec/support/app/image.rb +19 -0
- data/spec/support/app/import_article.rb +12 -0
- data/spec/support/app/mongoid_article.rb +21 -0
- data/spec/support/app/namespaced_book.rb +10 -0
- data/spec/support/app/parent_and_child_searchable.rb +24 -0
- data/spec/support/app/post.rb +14 -0
- data/spec/support/app/question.rb +27 -0
- data/spec/support/app/searchable.rb +48 -0
- data/spec/support/app/series.rb +11 -0
- data/spec/support/model.json +1 -0
- data/{test → spec}/support/model.yml +0 -0
- metadata +129 -86
- data/test/integration/active_record_associations_parent_child_test.rb +0 -188
- data/test/integration/active_record_associations_test.rb +0 -339
- data/test/integration/active_record_basic_test.rb +0 -255
- data/test/integration/active_record_custom_serialization_test.rb +0 -67
- data/test/integration/active_record_import_test.rb +0 -168
- data/test/integration/active_record_namespaced_model_test.rb +0 -56
- data/test/integration/active_record_pagination_test.rb +0 -149
- data/test/integration/dynamic_index_name_test.rb +0 -52
- data/test/integration/mongoid_basic_test.rb +0 -240
- data/test/integration/multiple_models_test.rb +0 -176
- data/test/support/model.json +0 -1
- data/test/test_helper.rb +0 -92
- data/test/unit/adapter_active_record_test.rb +0 -157
- data/test/unit/adapter_default_test.rb +0 -41
- data/test/unit/adapter_mongoid_test.rb +0 -161
- data/test/unit/adapter_multiple_test.rb +0 -106
- data/test/unit/adapter_test.rb +0 -69
- data/test/unit/callbacks_test.rb +0 -31
- data/test/unit/client_test.rb +0 -27
- data/test/unit/hash_wrapper_test.rb +0 -13
- data/test/unit/importing_test.rb +0 -224
- data/test/unit/indexing_test.rb +0 -720
- data/test/unit/module_test.rb +0 -68
- data/test/unit/multimodel_test.rb +0 -38
- data/test/unit/naming_inheritance_test.rb +0 -94
- data/test/unit/naming_test.rb +0 -103
- data/test/unit/proxy_test.rb +0 -98
- data/test/unit/response_aggregations_test.rb +0 -46
- data/test/unit/response_base_test.rb +0 -40
- data/test/unit/response_pagination_kaminari_test.rb +0 -433
- data/test/unit/response_pagination_will_paginate_test.rb +0 -398
- data/test/unit/response_records_test.rb +0 -91
- data/test/unit/response_result_test.rb +0 -90
- data/test/unit/response_results_test.rb +0 -34
- data/test/unit/response_test.rb +0 -104
- data/test/unit/searching_search_request_test.rb +0 -78
- data/test/unit/searching_test.rb +0 -41
- data/test/unit/serializing_test.rb +0 -17
@@ -0,0 +1,107 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Elasticsearch::Model::Proxy do
|
4
|
+
|
5
|
+
before(:all) do
|
6
|
+
class ::DummyProxyModel
|
7
|
+
include Elasticsearch::Model::Proxy
|
8
|
+
|
9
|
+
def self.foo
|
10
|
+
'classy foo'
|
11
|
+
end
|
12
|
+
|
13
|
+
def bar
|
14
|
+
'insta barr'
|
15
|
+
end
|
16
|
+
|
17
|
+
def as_json(options)
|
18
|
+
{foo: 'bar'}
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class ::DummyProxyModelWithCallbacks
|
23
|
+
def self.before_save(&block)
|
24
|
+
(@callbacks ||= {})[block.hash] = block
|
25
|
+
end
|
26
|
+
|
27
|
+
def changes_to_save
|
28
|
+
{:foo => ['One', 'Two']}
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
DummyProxyModelWithCallbacks.__send__ :include, Elasticsearch::Model::Proxy
|
33
|
+
end
|
34
|
+
|
35
|
+
after(:all) do
|
36
|
+
remove_classes(DummyProxyModel, DummyProxyModelWithCallbacks)
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'sets up a proxy method on the class' do
|
40
|
+
expect(DummyProxyModel).to respond_to(:__elasticsearch__)
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'sets up a proxy method on instances' do
|
44
|
+
expect(DummyProxyModel.new).to respond_to(:__elasticsearch__)
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'sets up hooks for before_save callbacks' do
|
48
|
+
expect(DummyProxyModelWithCallbacks).to respond_to(:before_save)
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'delegates methods to the target' do
|
52
|
+
expect(DummyProxyModel.__elasticsearch__).to respond_to(:foo)
|
53
|
+
expect(DummyProxyModel.__elasticsearch__.foo).to eq('classy foo')
|
54
|
+
expect(DummyProxyModel.new.__elasticsearch__).to respond_to(:bar)
|
55
|
+
expect(DummyProxyModel.new.__elasticsearch__.bar).to eq('insta barr')
|
56
|
+
|
57
|
+
expect {
|
58
|
+
DummyProxyModel.__elasticsearch__.xoxo
|
59
|
+
}.to raise_exception(NoMethodError)
|
60
|
+
|
61
|
+
expect {
|
62
|
+
DummyProxyModel.new.__elasticsearch__.xoxo
|
63
|
+
}.to raise_exception(NoMethodError)
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'returns the proxy class from an instance proxy' do
|
67
|
+
expect(DummyProxyModel.new.__elasticsearch__.class.class).to eq(Elasticsearch::Model::Proxy::ClassMethodsProxy)
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'returns the origin class from an instance proxy' do
|
71
|
+
expect(DummyProxyModel.new.__elasticsearch__.klass).to eq(DummyProxyModel)
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'delegates #as_json from the proxy to the target' do
|
75
|
+
expect(DummyProxyModel.new.__elasticsearch__.as_json).to eq(foo: 'bar')
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'includes the proxy in the inspect string' do
|
79
|
+
expect(DummyProxyModel.__elasticsearch__.inspect).to match(/PROXY/)
|
80
|
+
expect(DummyProxyModel.new.__elasticsearch__.inspect).to match(/PROXY/)
|
81
|
+
end
|
82
|
+
|
83
|
+
context 'when instances are cloned' do
|
84
|
+
|
85
|
+
let!(:model) do
|
86
|
+
DummyProxyModel.new
|
87
|
+
end
|
88
|
+
|
89
|
+
let!(:model_target) do
|
90
|
+
model.__elasticsearch__.target
|
91
|
+
end
|
92
|
+
|
93
|
+
let!(:duplicate) do
|
94
|
+
model.dup
|
95
|
+
end
|
96
|
+
|
97
|
+
let!(:duplicate_target) do
|
98
|
+
duplicate.__elasticsearch__.target
|
99
|
+
end
|
100
|
+
|
101
|
+
it 'resets the proxy target' do
|
102
|
+
expect(model).not_to eq(duplicate)
|
103
|
+
expect(model).to eq(model_target)
|
104
|
+
expect(duplicate).to eq(duplicate_target)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Elasticsearch::Model::Response::Aggregations do
|
4
|
+
|
5
|
+
before(:all) do
|
6
|
+
class OriginClass
|
7
|
+
def self.index_name; 'foo'; end
|
8
|
+
def self.document_type; 'bar'; end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
after(:all) do
|
13
|
+
remove_classes(OriginClass)
|
14
|
+
end
|
15
|
+
|
16
|
+
let(:response_document) do
|
17
|
+
{
|
18
|
+
'aggregations' => {
|
19
|
+
'foo' => {'bar' => 10 },
|
20
|
+
'price' => { 'doc_count' => 123,
|
21
|
+
'min' => { 'value' => 1.0},
|
22
|
+
'max' => { 'value' => 99 }
|
23
|
+
}
|
24
|
+
}
|
25
|
+
}
|
26
|
+
end
|
27
|
+
|
28
|
+
let(:search) do
|
29
|
+
Elasticsearch::Model::Searching::SearchRequest.new(OriginClass, '*').tap do |request|
|
30
|
+
allow(request).to receive(:execute!).and_return(response_document)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
let(:aggregations) do
|
35
|
+
Elasticsearch::Model::Response::Response.new(OriginClass, search).aggregations
|
36
|
+
end
|
37
|
+
|
38
|
+
describe 'method delegation' do
|
39
|
+
|
40
|
+
it 'delegates methods to the response document' do
|
41
|
+
expect(aggregations.foo).to be_a(Hashie::Mash)
|
42
|
+
expect(aggregations.foo.bar).to be(10)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe '#doc_count' do
|
47
|
+
|
48
|
+
it 'returns the doc count value from the response document' do
|
49
|
+
expect(aggregations.price.doc_count).to eq(123)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
describe '#min' do
|
54
|
+
|
55
|
+
it 'returns the min value from the response document' do
|
56
|
+
expect(aggregations.price.min.value).to eq(1)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
describe '#max' do
|
61
|
+
|
62
|
+
it 'returns the max value from the response document' do
|
63
|
+
expect(aggregations.price.max.value).to eq(99)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Elasticsearch::Model::Response::Base do
|
4
|
+
|
5
|
+
before(:all) do
|
6
|
+
class DummyBaseClass
|
7
|
+
include Elasticsearch::Model::Response::Base
|
8
|
+
end
|
9
|
+
|
10
|
+
class OriginClass
|
11
|
+
def self.index_name; 'foo'; end
|
12
|
+
def self.document_type; 'bar'; end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
after(:all) do
|
17
|
+
remove_classes(DummyBaseClass, OriginClass)
|
18
|
+
end
|
19
|
+
|
20
|
+
let(:response_document) do
|
21
|
+
{ 'hits' => { 'total' => 123, 'max_score' => 456, 'hits' => [] } }
|
22
|
+
end
|
23
|
+
|
24
|
+
let(:search) do
|
25
|
+
Elasticsearch::Model::Searching::SearchRequest.new(OriginClass, '*').tap do |request|
|
26
|
+
allow(request).to receive(:execute!).and_return(response_document)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
let(:response) do
|
31
|
+
Elasticsearch::Model::Response::Response.new(OriginClass, search)
|
32
|
+
end
|
33
|
+
|
34
|
+
let(:response_base) do
|
35
|
+
DummyBaseClass.new(OriginClass, response)
|
36
|
+
end
|
37
|
+
|
38
|
+
describe '#klass' do
|
39
|
+
|
40
|
+
it 'returns the class' do
|
41
|
+
expect(response.klass).to be(OriginClass)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe '#response' do
|
46
|
+
|
47
|
+
it 'returns the response object' do
|
48
|
+
expect(response_base.response).to eq(response)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe 'response document' do
|
53
|
+
|
54
|
+
it 'returns the response document' do
|
55
|
+
expect(response_base.response.response).to eq(response_document)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe '#total' do
|
60
|
+
|
61
|
+
it 'returns the total' do
|
62
|
+
expect(response_base.total).to eq(123)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
describe '#max_score' do
|
67
|
+
|
68
|
+
it 'returns the total' do
|
69
|
+
expect(response_base.max_score).to eq(456)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
describe '#results' do
|
74
|
+
|
75
|
+
it 'raises a NotImplemented error' do
|
76
|
+
expect {
|
77
|
+
response_base.results
|
78
|
+
}.to raise_exception(Elasticsearch::Model::NotImplemented)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
describe '#records' do
|
83
|
+
|
84
|
+
it 'raises a NotImplemented error' do
|
85
|
+
expect {
|
86
|
+
response_base.records
|
87
|
+
}.to raise_exception(Elasticsearch::Model::NotImplemented)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,410 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'Elasticsearch::Model::Response::Response Kaminari' do
|
4
|
+
|
5
|
+
before(:all) do
|
6
|
+
class ModelClass
|
7
|
+
include ::Kaminari::ConfigurationMethods
|
8
|
+
def self.index_name; 'foo'; end
|
9
|
+
def self.document_type; 'bar'; end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
after(:all) do
|
14
|
+
remove_classes(ModelClass)
|
15
|
+
end
|
16
|
+
|
17
|
+
let(:response_document) do
|
18
|
+
{ 'took' => '5', 'timed_out' => false, '_shards' => {'one' => 'OK'},
|
19
|
+
'hits' => { 'total' => 100, 'hits' => (1..100).to_a.map { |i| { _id: i } } } }
|
20
|
+
end
|
21
|
+
|
22
|
+
let(:search) do
|
23
|
+
Elasticsearch::Model::Searching::SearchRequest.new(model, '*')
|
24
|
+
end
|
25
|
+
|
26
|
+
let(:response) do
|
27
|
+
allow(model).to receive(:client).and_return(client)
|
28
|
+
Elasticsearch::Model::Response::Response.new(model, search, response_document).tap do |resp|
|
29
|
+
allow(resp).to receive(:client).and_return(client)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
let(:client) do
|
34
|
+
double('client')
|
35
|
+
end
|
36
|
+
|
37
|
+
shared_examples_for 'a search request that can be paginated' do
|
38
|
+
|
39
|
+
describe '#page' do
|
40
|
+
|
41
|
+
it 'does not set an initial from and size on the search definition' do
|
42
|
+
expect(response.search.definition[:from]).to be(nil)
|
43
|
+
expect(response.search.definition[:size]).to be(nil)
|
44
|
+
end
|
45
|
+
|
46
|
+
context 'when page is called once' do
|
47
|
+
|
48
|
+
let(:search_request) do
|
49
|
+
{ index: index_field, from: 25, size: 25, q: '*', type: type_field}
|
50
|
+
end
|
51
|
+
|
52
|
+
before do
|
53
|
+
expect(client).to receive(:search).with(search_request).and_return(response_document)
|
54
|
+
response.page(2).to_a
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'advances the from/size in the search request' do
|
58
|
+
expect(response.search.definition[:from]).to be(25)
|
59
|
+
expect(response.search.definition[:size]).to be(25)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
context 'when page is called more than once' do
|
64
|
+
|
65
|
+
let(:search_request_one) do
|
66
|
+
{ index: index_field, from: 25, size: 25, q: '*', type: type_field}
|
67
|
+
end
|
68
|
+
|
69
|
+
let(:search_request_two) do
|
70
|
+
{ index: index_field, from: 75, size: 25, q: '*', type: type_field}
|
71
|
+
end
|
72
|
+
|
73
|
+
before do
|
74
|
+
expect(client).to receive(:search).with(search_request_one).and_return(response_document)
|
75
|
+
response.page(2).to_a
|
76
|
+
expect(client).to receive(:search).with(search_request_two).and_return(response_document)
|
77
|
+
response.page(4).to_a
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'advances the from/size in the search request' do
|
81
|
+
expect(response.search.definition[:from]).to be(75)
|
82
|
+
expect(response.search.definition[:size]).to be(25)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
context 'when limit is also set' do
|
87
|
+
|
88
|
+
before do
|
89
|
+
response.records
|
90
|
+
response.results
|
91
|
+
end
|
92
|
+
|
93
|
+
context 'when page is called before limit' do
|
94
|
+
|
95
|
+
before do
|
96
|
+
response.page(3).limit(35)
|
97
|
+
end
|
98
|
+
|
99
|
+
it 'sets the correct values' do
|
100
|
+
expect(response.search.definition[:size]).to eq(35)
|
101
|
+
expect(response.search.definition[:from]).to eq(70)
|
102
|
+
end
|
103
|
+
|
104
|
+
it 'resets the instance variables' do
|
105
|
+
expect(response.instance_variable_get(:@response)).to be(nil)
|
106
|
+
expect(response.instance_variable_get(:@records)).to be(nil)
|
107
|
+
expect(response.instance_variable_get(:@results)).to be(nil)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
context 'when limit is called before page' do
|
112
|
+
|
113
|
+
before do
|
114
|
+
response.limit(35).page(3)
|
115
|
+
end
|
116
|
+
|
117
|
+
it 'sets the correct values' do
|
118
|
+
expect(response.search.definition[:size]).to eq(35)
|
119
|
+
expect(response.search.definition[:from]).to eq(70)
|
120
|
+
end
|
121
|
+
|
122
|
+
it 'resets the instance variables' do
|
123
|
+
expect(response.instance_variable_get(:@response)).to be(nil)
|
124
|
+
expect(response.instance_variable_get(:@records)).to be(nil)
|
125
|
+
expect(response.instance_variable_get(:@results)).to be(nil)
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
describe '#limit_value' do
|
132
|
+
|
133
|
+
context 'when there is no default set' do
|
134
|
+
|
135
|
+
it 'uses the limit value from the Kaminari configuration' do
|
136
|
+
expect(response.limit_value).to eq(Kaminari.config.default_per_page)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
context 'when there is a limit in the search definition' do
|
141
|
+
|
142
|
+
let(:search) do
|
143
|
+
Elasticsearch::Model::Searching::SearchRequest.new(model, '*', size: 10)
|
144
|
+
end
|
145
|
+
|
146
|
+
it 'gets the limit from the search definition' do
|
147
|
+
expect(response.limit_value).to eq(10)
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
context 'when there is a limit in the search body' do
|
152
|
+
|
153
|
+
let(:search) do
|
154
|
+
Elasticsearch::Model::Searching::SearchRequest.new(model, { query: { match_all: {} }, size: 999 })
|
155
|
+
end
|
156
|
+
|
157
|
+
it 'does not use the limit' do
|
158
|
+
expect(response.limit_value).to be(Kaminari.config.default_per_page)
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
describe '#offset_value' do
|
164
|
+
|
165
|
+
context 'when there is no default set' do
|
166
|
+
|
167
|
+
it 'uses an offset of 0' do
|
168
|
+
expect(response.offset_value).to eq(0)
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
context 'when there is an offset in the search definition' do
|
173
|
+
|
174
|
+
let(:search) do
|
175
|
+
Elasticsearch::Model::Searching::SearchRequest.new(model, '*', from: 50)
|
176
|
+
end
|
177
|
+
|
178
|
+
it 'gets the limit from the search definition' do
|
179
|
+
expect(response.offset_value).to eq(50)
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
context 'when there is an offset in the search body' do
|
184
|
+
|
185
|
+
let(:search) do
|
186
|
+
Elasticsearch::Model::Searching::SearchRequest.new(model, { query: { match_all: {} }, from: 333 })
|
187
|
+
end
|
188
|
+
|
189
|
+
it 'does not use the offset' do
|
190
|
+
expect(response.offset_value).to be(0)
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
describe '#limit' do
|
196
|
+
|
197
|
+
context 'when a limit is set' do
|
198
|
+
|
199
|
+
before do
|
200
|
+
response.records
|
201
|
+
response.results
|
202
|
+
response.limit(35)
|
203
|
+
end
|
204
|
+
|
205
|
+
it 'sets the limit on the search defintiion' do
|
206
|
+
expect(response.search.definition[:size]).to eq(35)
|
207
|
+
end
|
208
|
+
|
209
|
+
it 'resets the instance variables' do
|
210
|
+
expect(response.instance_variable_get(:@response)).to be(nil)
|
211
|
+
expect(response.instance_variable_get(:@records)).to be(nil)
|
212
|
+
expect(response.instance_variable_get(:@results)).to be(nil)
|
213
|
+
end
|
214
|
+
|
215
|
+
context 'when the limit is provided as a string' do
|
216
|
+
|
217
|
+
before do
|
218
|
+
response.limit('35')
|
219
|
+
end
|
220
|
+
|
221
|
+
it 'coerces the string to an integer' do
|
222
|
+
expect(response.search.definition[:size]).to eq(35)
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
context 'when the limit is an invalid type' do
|
227
|
+
|
228
|
+
before do
|
229
|
+
response.limit('asdf')
|
230
|
+
end
|
231
|
+
|
232
|
+
it 'does not apply the setting' do
|
233
|
+
expect(response.search.definition[:size]).to eq(35)
|
234
|
+
end
|
235
|
+
end
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
describe '#offset' do
|
240
|
+
|
241
|
+
context 'when an offset is set' do
|
242
|
+
|
243
|
+
before do
|
244
|
+
response.records
|
245
|
+
response.results
|
246
|
+
response.offset(15)
|
247
|
+
end
|
248
|
+
|
249
|
+
it 'sets the limit on the search defintiion' do
|
250
|
+
expect(response.search.definition[:from]).to eq(15)
|
251
|
+
end
|
252
|
+
|
253
|
+
it 'resets the instance variables' do
|
254
|
+
expect(response.instance_variable_get(:@response)).to be(nil)
|
255
|
+
expect(response.instance_variable_get(:@records)).to be(nil)
|
256
|
+
expect(response.instance_variable_get(:@results)).to be(nil)
|
257
|
+
end
|
258
|
+
|
259
|
+
context 'when the offset is provided as a string' do
|
260
|
+
|
261
|
+
before do
|
262
|
+
response.offset('15')
|
263
|
+
end
|
264
|
+
|
265
|
+
it 'coerces the string to an integer' do
|
266
|
+
expect(response.search.definition[:from]).to eq(15)
|
267
|
+
end
|
268
|
+
end
|
269
|
+
|
270
|
+
context 'when the offset is an invalid type' do
|
271
|
+
|
272
|
+
before do
|
273
|
+
response.offset('asdf')
|
274
|
+
end
|
275
|
+
|
276
|
+
it 'does not apply the setting' do
|
277
|
+
expect(response.search.definition[:from]).to eq(0)
|
278
|
+
end
|
279
|
+
end
|
280
|
+
end
|
281
|
+
end
|
282
|
+
|
283
|
+
describe '#total' do
|
284
|
+
|
285
|
+
before do
|
286
|
+
allow(response.results).to receive(:total).and_return(100)
|
287
|
+
end
|
288
|
+
|
289
|
+
it 'returns the total number of hits' do
|
290
|
+
expect(response.total_count).to eq(100)
|
291
|
+
end
|
292
|
+
end
|
293
|
+
|
294
|
+
context 'results' do
|
295
|
+
|
296
|
+
before do
|
297
|
+
allow(search).to receive(:execute!).and_return(response_document)
|
298
|
+
end
|
299
|
+
|
300
|
+
describe '#current_page' do
|
301
|
+
|
302
|
+
it 'returns the current page' do
|
303
|
+
expect(response.results.current_page).to eq(1)
|
304
|
+
end
|
305
|
+
|
306
|
+
context 'when a particular page is accessed' do
|
307
|
+
|
308
|
+
it 'returns the correct current page' do
|
309
|
+
expect(response.page(5).results.current_page).to eq(5)
|
310
|
+
end
|
311
|
+
end
|
312
|
+
end
|
313
|
+
|
314
|
+
describe '#prev_page' do
|
315
|
+
|
316
|
+
it 'returns the previous page' do
|
317
|
+
expect(response.page(1).results.prev_page).to be(nil)
|
318
|
+
expect(response.page(2).results.prev_page).to be(1)
|
319
|
+
expect(response.page(3).results.prev_page).to be(2)
|
320
|
+
expect(response.page(4).results.prev_page).to be(3)
|
321
|
+
end
|
322
|
+
end
|
323
|
+
|
324
|
+
describe '#next_page' do
|
325
|
+
|
326
|
+
it 'returns the previous page' do
|
327
|
+
expect(response.page(1).results.next_page).to be(2)
|
328
|
+
expect(response.page(2).results.next_page).to be(3)
|
329
|
+
expect(response.page(3).results.next_page).to be(4)
|
330
|
+
expect(response.page(4).results.next_page).to be(nil)
|
331
|
+
end
|
332
|
+
end
|
333
|
+
end
|
334
|
+
|
335
|
+
context 'records' do
|
336
|
+
|
337
|
+
before do
|
338
|
+
allow(search).to receive(:execute!).and_return(response_document)
|
339
|
+
end
|
340
|
+
|
341
|
+
describe '#current_page' do
|
342
|
+
|
343
|
+
it 'returns the current page' do
|
344
|
+
expect(response.records.current_page).to eq(1)
|
345
|
+
end
|
346
|
+
|
347
|
+
context 'when a particular page is accessed' do
|
348
|
+
|
349
|
+
it 'returns the correct current page' do
|
350
|
+
expect(response.page(5).records.current_page).to eq(5)
|
351
|
+
end
|
352
|
+
end
|
353
|
+
end
|
354
|
+
|
355
|
+
describe '#prev_page' do
|
356
|
+
|
357
|
+
it 'returns the previous page' do
|
358
|
+
expect(response.page(1).records.prev_page).to be(nil)
|
359
|
+
expect(response.page(2).records.prev_page).to be(1)
|
360
|
+
expect(response.page(3).records.prev_page).to be(2)
|
361
|
+
expect(response.page(4).records.prev_page).to be(3)
|
362
|
+
end
|
363
|
+
end
|
364
|
+
|
365
|
+
describe '#next_page' do
|
366
|
+
|
367
|
+
it 'returns the previous page' do
|
368
|
+
expect(response.page(1).records.next_page).to be(2)
|
369
|
+
expect(response.page(2).records.next_page).to be(3)
|
370
|
+
expect(response.page(3).records.next_page).to be(4)
|
371
|
+
expect(response.page(4).records.next_page).to be(nil)
|
372
|
+
end
|
373
|
+
end
|
374
|
+
end
|
375
|
+
end
|
376
|
+
|
377
|
+
context 'when the model is a single one' do
|
378
|
+
|
379
|
+
let(:model) do
|
380
|
+
ModelClass
|
381
|
+
end
|
382
|
+
|
383
|
+
let(:type_field) do
|
384
|
+
'bar'
|
385
|
+
end
|
386
|
+
|
387
|
+
let(:index_field) do
|
388
|
+
'foo'
|
389
|
+
end
|
390
|
+
|
391
|
+
it_behaves_like 'a search request that can be paginated'
|
392
|
+
end
|
393
|
+
|
394
|
+
context 'when the model is a multimodel' do
|
395
|
+
|
396
|
+
let(:model) do
|
397
|
+
Elasticsearch::Model::Multimodel.new(ModelClass)
|
398
|
+
end
|
399
|
+
|
400
|
+
let(:type_field) do
|
401
|
+
['bar']
|
402
|
+
end
|
403
|
+
|
404
|
+
let(:index_field) do
|
405
|
+
['foo']
|
406
|
+
end
|
407
|
+
|
408
|
+
it_behaves_like 'a search request that can be paginated'
|
409
|
+
end
|
410
|
+
end
|