elasticsearch-model-queryable 0.1.5
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 +7 -0
- data/.gitignore +20 -0
- data/CHANGELOG.md +26 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +13 -0
- data/README.md +695 -0
- data/Rakefile +59 -0
- data/elasticsearch-model.gemspec +57 -0
- data/examples/activerecord_article.rb +77 -0
- data/examples/activerecord_associations.rb +162 -0
- data/examples/couchbase_article.rb +66 -0
- data/examples/datamapper_article.rb +71 -0
- data/examples/mongoid_article.rb +68 -0
- data/examples/ohm_article.rb +70 -0
- data/examples/riak_article.rb +52 -0
- data/gemfiles/3.0.gemfile +12 -0
- data/gemfiles/4.0.gemfile +11 -0
- data/lib/elasticsearch/model/adapter.rb +145 -0
- data/lib/elasticsearch/model/adapters/active_record.rb +104 -0
- data/lib/elasticsearch/model/adapters/default.rb +50 -0
- data/lib/elasticsearch/model/adapters/mongoid.rb +92 -0
- data/lib/elasticsearch/model/callbacks.rb +35 -0
- data/lib/elasticsearch/model/client.rb +61 -0
- data/lib/elasticsearch/model/ext/active_record.rb +14 -0
- data/lib/elasticsearch/model/hash_wrapper.rb +15 -0
- data/lib/elasticsearch/model/importing.rb +144 -0
- data/lib/elasticsearch/model/indexing.rb +472 -0
- data/lib/elasticsearch/model/naming.rb +101 -0
- data/lib/elasticsearch/model/proxy.rb +127 -0
- data/lib/elasticsearch/model/response/base.rb +44 -0
- data/lib/elasticsearch/model/response/pagination.rb +173 -0
- data/lib/elasticsearch/model/response/records.rb +69 -0
- data/lib/elasticsearch/model/response/result.rb +63 -0
- data/lib/elasticsearch/model/response/results.rb +31 -0
- data/lib/elasticsearch/model/response.rb +71 -0
- data/lib/elasticsearch/model/searching.rb +107 -0
- data/lib/elasticsearch/model/serializing.rb +35 -0
- data/lib/elasticsearch/model/version.rb +5 -0
- data/lib/elasticsearch/model.rb +157 -0
- data/test/integration/active_record_associations_parent_child.rb +139 -0
- data/test/integration/active_record_associations_test.rb +307 -0
- data/test/integration/active_record_basic_test.rb +179 -0
- data/test/integration/active_record_custom_serialization_test.rb +62 -0
- data/test/integration/active_record_import_test.rb +100 -0
- data/test/integration/active_record_namespaced_model_test.rb +49 -0
- data/test/integration/active_record_pagination_test.rb +132 -0
- data/test/integration/mongoid_basic_test.rb +193 -0
- data/test/test_helper.rb +63 -0
- data/test/unit/adapter_active_record_test.rb +140 -0
- data/test/unit/adapter_default_test.rb +41 -0
- data/test/unit/adapter_mongoid_test.rb +102 -0
- data/test/unit/adapter_test.rb +69 -0
- data/test/unit/callbacks_test.rb +31 -0
- data/test/unit/client_test.rb +27 -0
- data/test/unit/importing_test.rb +176 -0
- data/test/unit/indexing_test.rb +478 -0
- data/test/unit/module_test.rb +57 -0
- data/test/unit/naming_test.rb +76 -0
- data/test/unit/proxy_test.rb +89 -0
- data/test/unit/response_base_test.rb +40 -0
- data/test/unit/response_pagination_kaminari_test.rb +189 -0
- data/test/unit/response_pagination_will_paginate_test.rb +208 -0
- data/test/unit/response_records_test.rb +91 -0
- data/test/unit/response_result_test.rb +90 -0
- data/test/unit/response_results_test.rb +31 -0
- data/test/unit/response_test.rb +67 -0
- data/test/unit/searching_search_request_test.rb +78 -0
- data/test/unit/searching_test.rb +41 -0
- data/test/unit/serializing_test.rb +17 -0
- metadata +466 -0
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class Elasticsearch::Model::ModuleTest < Test::Unit::TestCase
|
4
|
+
context "The main module" do
|
5
|
+
|
6
|
+
context "client" do
|
7
|
+
should "have a default" do
|
8
|
+
client = Elasticsearch::Model.client
|
9
|
+
assert_not_nil client
|
10
|
+
assert_instance_of Elasticsearch::Transport::Client, client
|
11
|
+
end
|
12
|
+
|
13
|
+
should "be settable" do
|
14
|
+
begin
|
15
|
+
Elasticsearch::Model.client = "Foobar"
|
16
|
+
assert_equal "Foobar", Elasticsearch::Model.client
|
17
|
+
ensure
|
18
|
+
Elasticsearch::Model.client = nil
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context "when included in module/class, " do
|
24
|
+
class ::DummyIncludingModel; end
|
25
|
+
class ::DummyIncludingModelWithSearchMethodDefined
|
26
|
+
def self.search(query, options={})
|
27
|
+
"SEARCH"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
should "include and set up the proxy" do
|
32
|
+
DummyIncludingModel.__send__ :include, Elasticsearch::Model
|
33
|
+
|
34
|
+
assert_respond_to DummyIncludingModel, :__elasticsearch__
|
35
|
+
assert_respond_to DummyIncludingModel.new, :__elasticsearch__
|
36
|
+
end
|
37
|
+
|
38
|
+
should "delegate important methods to the proxy" do
|
39
|
+
DummyIncludingModel.__send__ :include, Elasticsearch::Model
|
40
|
+
|
41
|
+
assert_respond_to DummyIncludingModel, :search
|
42
|
+
assert_respond_to DummyIncludingModel, :mappings
|
43
|
+
assert_respond_to DummyIncludingModel, :settings
|
44
|
+
assert_respond_to DummyIncludingModel, :index_name
|
45
|
+
assert_respond_to DummyIncludingModel, :document_type
|
46
|
+
assert_respond_to DummyIncludingModel, :import
|
47
|
+
end
|
48
|
+
|
49
|
+
should "not override existing method" do
|
50
|
+
DummyIncludingModelWithSearchMethodDefined.__send__ :include, Elasticsearch::Model
|
51
|
+
|
52
|
+
assert_equal 'SEARCH', DummyIncludingModelWithSearchMethodDefined.search('foo')
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class Elasticsearch::Model::NamingTest < Test::Unit::TestCase
|
4
|
+
context "Naming module" do
|
5
|
+
class ::DummyNamingModel
|
6
|
+
extend ActiveModel::Naming
|
7
|
+
|
8
|
+
extend Elasticsearch::Model::Naming::ClassMethods
|
9
|
+
include Elasticsearch::Model::Naming::InstanceMethods
|
10
|
+
end
|
11
|
+
|
12
|
+
module ::MyNamespace
|
13
|
+
class DummyNamingModelInNamespace
|
14
|
+
extend ActiveModel::Naming
|
15
|
+
|
16
|
+
extend Elasticsearch::Model::Naming::ClassMethods
|
17
|
+
include Elasticsearch::Model::Naming::InstanceMethods
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
should "return the default index_name" do
|
22
|
+
assert_equal 'dummy_naming_models', DummyNamingModel.index_name
|
23
|
+
assert_equal 'dummy_naming_models', DummyNamingModel.new.index_name
|
24
|
+
end
|
25
|
+
|
26
|
+
should "return the sanitized default index_name for namespaced model" do
|
27
|
+
assert_equal 'my_namespace-dummy_naming_model_in_namespaces', ::MyNamespace::DummyNamingModelInNamespace.index_name
|
28
|
+
assert_equal 'my_namespace-dummy_naming_model_in_namespaces', ::MyNamespace::DummyNamingModelInNamespace.new.index_name
|
29
|
+
end
|
30
|
+
|
31
|
+
should "return the default document_type" do
|
32
|
+
assert_equal 'dummy_naming_model', DummyNamingModel.document_type
|
33
|
+
assert_equal 'dummy_naming_model', DummyNamingModel.new.document_type
|
34
|
+
end
|
35
|
+
|
36
|
+
should "set and return the index_name" do
|
37
|
+
DummyNamingModel.index_name 'foobar'
|
38
|
+
assert_equal 'foobar', DummyNamingModel.index_name
|
39
|
+
|
40
|
+
d = DummyNamingModel.new
|
41
|
+
d.index_name 'foobar_d'
|
42
|
+
assert_equal 'foobar_d', d.index_name
|
43
|
+
end
|
44
|
+
|
45
|
+
should "set the index_name with setter" do
|
46
|
+
DummyNamingModel.index_name = 'foobar_index_S'
|
47
|
+
assert_equal 'foobar_index_S', DummyNamingModel.index_name
|
48
|
+
|
49
|
+
d = DummyNamingModel.new
|
50
|
+
d.index_name = 'foobar_index_s'
|
51
|
+
assert_equal 'foobar_index_s', d.index_name
|
52
|
+
|
53
|
+
assert_equal 'foobar_index_S', DummyNamingModel.index_name
|
54
|
+
end
|
55
|
+
|
56
|
+
should "set and return the document_type" do
|
57
|
+
DummyNamingModel.document_type 'foobar'
|
58
|
+
assert_equal 'foobar', DummyNamingModel.document_type
|
59
|
+
|
60
|
+
d = DummyNamingModel.new
|
61
|
+
d.document_type 'foobar_d'
|
62
|
+
assert_equal 'foobar_d', d.document_type
|
63
|
+
end
|
64
|
+
|
65
|
+
should "set the document_type with setter" do
|
66
|
+
DummyNamingModel.document_type = 'foobar_type_S'
|
67
|
+
assert_equal 'foobar_type_S', DummyNamingModel.document_type
|
68
|
+
|
69
|
+
d = DummyNamingModel.new
|
70
|
+
d.document_type = 'foobar_type_s'
|
71
|
+
assert_equal 'foobar_type_s', d.document_type
|
72
|
+
|
73
|
+
assert_equal 'foobar_type_S', DummyNamingModel.document_type
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class Elasticsearch::Model::SearchTest < Test::Unit::TestCase
|
4
|
+
context "Searching module" do
|
5
|
+
class ::DummyProxyModel
|
6
|
+
include Elasticsearch::Model::Proxy
|
7
|
+
|
8
|
+
def self.foo
|
9
|
+
'classy foo'
|
10
|
+
end
|
11
|
+
|
12
|
+
def bar
|
13
|
+
'insta barr'
|
14
|
+
end
|
15
|
+
|
16
|
+
def as_json(options)
|
17
|
+
{foo: 'bar'}
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
class ::DummyProxyModelWithCallbacks
|
22
|
+
def self.before_save(&block)
|
23
|
+
(@callbacks ||= {})[block.hash] = block
|
24
|
+
end
|
25
|
+
|
26
|
+
def changed_attributes; [:foo]; end
|
27
|
+
|
28
|
+
def changes
|
29
|
+
{:foo => ['One', 'Two']}
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
should "setup the class proxy method" do
|
34
|
+
assert_respond_to DummyProxyModel, :__elasticsearch__
|
35
|
+
end
|
36
|
+
|
37
|
+
should "setup the instance proxy method" do
|
38
|
+
assert_respond_to DummyProxyModel.new, :__elasticsearch__
|
39
|
+
end
|
40
|
+
|
41
|
+
should "register the hook for before_save callback" do
|
42
|
+
::DummyProxyModelWithCallbacks.expects(:before_save).returns(true)
|
43
|
+
DummyProxyModelWithCallbacks.__send__ :include, Elasticsearch::Model::Proxy
|
44
|
+
end
|
45
|
+
|
46
|
+
should "set the @__changed_attributes variable before save" do
|
47
|
+
instance = ::DummyProxyModelWithCallbacks.new
|
48
|
+
instance.__elasticsearch__.expects(:instance_variable_set).with do |name, value|
|
49
|
+
assert_equal :@__changed_attributes, name
|
50
|
+
assert_equal({foo: 'Two'}, value)
|
51
|
+
true
|
52
|
+
end
|
53
|
+
|
54
|
+
::DummyProxyModelWithCallbacks.__send__ :include, Elasticsearch::Model::Proxy
|
55
|
+
|
56
|
+
::DummyProxyModelWithCallbacks.instance_variable_get(:@callbacks).each do |n,b|
|
57
|
+
instance.instance_eval(&b)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
should "delegate methods to the target" do
|
62
|
+
assert_respond_to DummyProxyModel.__elasticsearch__, :foo
|
63
|
+
assert_respond_to DummyProxyModel.new.__elasticsearch__, :bar
|
64
|
+
|
65
|
+
assert_raise(NoMethodError) { DummyProxyModel.__elasticsearch__.xoxo }
|
66
|
+
assert_raise(NoMethodError) { DummyProxyModel.new.__elasticsearch__.xoxo }
|
67
|
+
|
68
|
+
assert_equal 'classy foo', DummyProxyModel.__elasticsearch__.foo
|
69
|
+
assert_equal 'insta barr', DummyProxyModel.new.__elasticsearch__.bar
|
70
|
+
end
|
71
|
+
|
72
|
+
should "return the proxy class from instance proxy" do
|
73
|
+
assert_equal Elasticsearch::Model::Proxy::ClassMethodsProxy, DummyProxyModel.new.__elasticsearch__.class.class
|
74
|
+
end
|
75
|
+
|
76
|
+
should "return the origin class from instance proxy" do
|
77
|
+
assert_equal DummyProxyModel, DummyProxyModel.new.__elasticsearch__.klass
|
78
|
+
end
|
79
|
+
|
80
|
+
should "delegate as_json from the proxy to target" do
|
81
|
+
assert_equal({foo: 'bar'}, DummyProxyModel.new.__elasticsearch__.as_json)
|
82
|
+
end
|
83
|
+
|
84
|
+
should "have inspect method indicating the proxy" do
|
85
|
+
assert_match /PROXY/, DummyProxyModel.__elasticsearch__.inspect
|
86
|
+
assert_match /PROXY/, DummyProxyModel.new.__elasticsearch__.inspect
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class Elasticsearch::Model::BaseTest < Test::Unit::TestCase
|
4
|
+
context "Response base module" do
|
5
|
+
class OriginClass
|
6
|
+
def self.index_name; 'foo'; end
|
7
|
+
def self.document_type; 'bar'; end
|
8
|
+
end
|
9
|
+
|
10
|
+
class DummyBaseClass
|
11
|
+
include Elasticsearch::Model::Response::Base
|
12
|
+
end
|
13
|
+
|
14
|
+
RESPONSE = { 'hits' => { 'total' => 123, 'max_score' => 456, 'hits' => [] } }
|
15
|
+
|
16
|
+
setup do
|
17
|
+
@search = Elasticsearch::Model::Searching::SearchRequest.new OriginClass, '*'
|
18
|
+
@response = Elasticsearch::Model::Response::Response.new OriginClass, @search
|
19
|
+
@search.stubs(:execute!).returns(RESPONSE)
|
20
|
+
end
|
21
|
+
|
22
|
+
should "access klass, response, total and max_score" do
|
23
|
+
r = DummyBaseClass.new OriginClass, @response
|
24
|
+
|
25
|
+
assert_equal OriginClass, r.klass
|
26
|
+
assert_equal @response, r.response
|
27
|
+
assert_equal RESPONSE, r.response.response
|
28
|
+
assert_equal 123, r.total
|
29
|
+
assert_equal 456, r.max_score
|
30
|
+
end
|
31
|
+
|
32
|
+
should "have abstract methods results and records" do
|
33
|
+
r = DummyBaseClass.new OriginClass, @response
|
34
|
+
|
35
|
+
assert_raise(Elasticsearch::Model::NotImplemented) { |e| r.results }
|
36
|
+
assert_raise(Elasticsearch::Model::NotImplemented) { |e| r.records }
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,189 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class Elasticsearch::Model::ResponsePaginationKaminariTest < Test::Unit::TestCase
|
4
|
+
context "Response pagination" do
|
5
|
+
class ModelClass
|
6
|
+
include ::Kaminari::ConfigurationMethods
|
7
|
+
|
8
|
+
def self.index_name; 'foo'; end
|
9
|
+
def self.document_type; 'bar'; end
|
10
|
+
end
|
11
|
+
|
12
|
+
RESPONSE = { 'took' => '5', 'timed_out' => false, '_shards' => {'one' => 'OK'},
|
13
|
+
'hits' => { 'total' => 100, 'hits' => (1..100).to_a.map { |i| { _id: i } } } }
|
14
|
+
|
15
|
+
setup do
|
16
|
+
@search = Elasticsearch::Model::Searching::SearchRequest.new ModelClass, '*'
|
17
|
+
@response = Elasticsearch::Model::Response::Response.new ModelClass, @search, RESPONSE
|
18
|
+
@response.klass.stubs(:client).returns mock('client')
|
19
|
+
end
|
20
|
+
|
21
|
+
should "have pagination methods" do
|
22
|
+
assert_respond_to @response, :page
|
23
|
+
assert_respond_to @response, :limit_value
|
24
|
+
assert_respond_to @response, :offset_value
|
25
|
+
assert_respond_to @response, :limit
|
26
|
+
assert_respond_to @response, :offset
|
27
|
+
assert_respond_to @response, :total_count
|
28
|
+
end
|
29
|
+
|
30
|
+
context "#page method" do
|
31
|
+
should "advance the from/size" do
|
32
|
+
@response.klass.client
|
33
|
+
.expects(:search)
|
34
|
+
.with do |definition|
|
35
|
+
assert_equal 25, definition[:from]
|
36
|
+
assert_equal 25, definition[:size]
|
37
|
+
true
|
38
|
+
end
|
39
|
+
.returns(RESPONSE)
|
40
|
+
|
41
|
+
assert_nil @response.search.definition[:from]
|
42
|
+
assert_nil @response.search.definition[:size]
|
43
|
+
|
44
|
+
@response.page(2).to_a
|
45
|
+
assert_equal 25, @response.search.definition[:from]
|
46
|
+
assert_equal 25, @response.search.definition[:size]
|
47
|
+
end
|
48
|
+
|
49
|
+
should "advance the from/size further" do
|
50
|
+
@response.klass.client
|
51
|
+
.expects(:search)
|
52
|
+
.with do |definition|
|
53
|
+
assert_equal 75, definition[:from]
|
54
|
+
assert_equal 25, definition[:size]
|
55
|
+
true
|
56
|
+
end
|
57
|
+
.returns(RESPONSE)
|
58
|
+
|
59
|
+
@response.page(4).to_a
|
60
|
+
assert_equal 75, @response.search.definition[:from]
|
61
|
+
assert_equal 25, @response.search.definition[:size]
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
context "limit/offset readers" do
|
66
|
+
should "return the default" do
|
67
|
+
assert_equal Kaminari.config.default_per_page, @response.limit_value
|
68
|
+
assert_equal 0, @response.offset_value
|
69
|
+
end
|
70
|
+
|
71
|
+
should "return the value from URL parameters" do
|
72
|
+
search = Elasticsearch::Model::Searching::SearchRequest.new ModelClass, '*', size: 10, from: 50
|
73
|
+
@response = Elasticsearch::Model::Response::Response.new ModelClass, search, RESPONSE
|
74
|
+
|
75
|
+
assert_equal 10, @response.limit_value
|
76
|
+
assert_equal 50, @response.offset_value
|
77
|
+
end
|
78
|
+
|
79
|
+
should "ignore the value from request body" do
|
80
|
+
search = Elasticsearch::Model::Searching::SearchRequest.new ModelClass,
|
81
|
+
{ query: { match_all: {} }, from: 333, size: 999 }
|
82
|
+
@response = Elasticsearch::Model::Response::Response.new ModelClass, search, RESPONSE
|
83
|
+
|
84
|
+
assert_equal Kaminari.config.default_per_page, @response.limit_value
|
85
|
+
assert_equal 0, @response.offset_value
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
context "limit setter" do
|
90
|
+
setup do
|
91
|
+
@response.records
|
92
|
+
@response.results
|
93
|
+
end
|
94
|
+
|
95
|
+
should "set the values" do
|
96
|
+
@response.limit(35)
|
97
|
+
assert_equal 35, @response.search.definition[:size]
|
98
|
+
end
|
99
|
+
|
100
|
+
should "reset the variables" do
|
101
|
+
@response.limit(35)
|
102
|
+
|
103
|
+
assert_nil @response.instance_variable_get(:@response)
|
104
|
+
assert_nil @response.instance_variable_get(:@records)
|
105
|
+
assert_nil @response.instance_variable_get(:@results)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
context "with the page() and limit() methods" do
|
110
|
+
setup do
|
111
|
+
@response.records
|
112
|
+
@response.results
|
113
|
+
end
|
114
|
+
|
115
|
+
should "set the values" do
|
116
|
+
@response.page(3).limit(35)
|
117
|
+
assert_equal 35, @response.search.definition[:size]
|
118
|
+
assert_equal 70, @response.search.definition[:from]
|
119
|
+
end
|
120
|
+
|
121
|
+
should "set the values when limit is called first" do
|
122
|
+
@response.limit(35).page(3)
|
123
|
+
assert_equal 35, @response.search.definition[:size]
|
124
|
+
assert_equal 70, @response.search.definition[:from]
|
125
|
+
end
|
126
|
+
|
127
|
+
should "reset the instance variables" do
|
128
|
+
@response.page(3).limit(35)
|
129
|
+
|
130
|
+
assert_nil @response.instance_variable_get(:@response)
|
131
|
+
assert_nil @response.instance_variable_get(:@records)
|
132
|
+
assert_nil @response.instance_variable_get(:@results)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
context "offset setter" do
|
137
|
+
setup do
|
138
|
+
@response.records
|
139
|
+
@response.results
|
140
|
+
end
|
141
|
+
|
142
|
+
should "set the values" do
|
143
|
+
@response.offset(15)
|
144
|
+
assert_equal 15, @response.search.definition[:from]
|
145
|
+
end
|
146
|
+
|
147
|
+
should "reset the variables" do
|
148
|
+
@response.offset(35)
|
149
|
+
|
150
|
+
assert_nil @response.instance_variable_get(:@response)
|
151
|
+
assert_nil @response.instance_variable_get(:@records)
|
152
|
+
assert_nil @response.instance_variable_get(:@results)
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
context "total" do
|
157
|
+
should "return the number of hits" do
|
158
|
+
@response.expects(:results).returns(mock('results', total: 100))
|
159
|
+
assert_equal 100, @response.total_count
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
context "results" do
|
164
|
+
setup do
|
165
|
+
@search.stubs(:execute!).returns RESPONSE
|
166
|
+
end
|
167
|
+
|
168
|
+
should "return current page and total count" do
|
169
|
+
assert_equal 1, @response.page(1).results.current_page
|
170
|
+
assert_equal 100, @response.results.total_count
|
171
|
+
|
172
|
+
assert_equal 5, @response.page(5).results.current_page
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
context "records" do
|
177
|
+
setup do
|
178
|
+
@search.stubs(:execute!).returns RESPONSE
|
179
|
+
end
|
180
|
+
|
181
|
+
should "return current page and total count" do
|
182
|
+
assert_equal 1, @response.page(1).records.current_page
|
183
|
+
assert_equal 100, @response.records.total_count
|
184
|
+
|
185
|
+
assert_equal 5, @response.page(5).records.current_page
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
@@ -0,0 +1,208 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'will_paginate'
|
3
|
+
require 'will_paginate/collection'
|
4
|
+
|
5
|
+
class Elasticsearch::Model::ResponsePaginationWillPaginateTest < Test::Unit::TestCase
|
6
|
+
context "Response pagination" do
|
7
|
+
class ModelClass
|
8
|
+
def self.index_name; 'foo'; end
|
9
|
+
def self.document_type; 'bar'; end
|
10
|
+
|
11
|
+
# WillPaginate adds this method to models (see WillPaginate::PerPage module)
|
12
|
+
def self.per_page
|
13
|
+
33
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
# Subsclass Response so we can include WillPaginate module without conflicts with Kaminari.
|
18
|
+
class WillPaginateResponse < Elasticsearch::Model::Response::Response
|
19
|
+
include Elasticsearch::Model::Response::Pagination::WillPaginate
|
20
|
+
end
|
21
|
+
|
22
|
+
RESPONSE = { 'took' => '5', 'timed_out' => false, '_shards' => {'one' => 'OK'},
|
23
|
+
'hits' => { 'total' => 100, 'hits' => (1..100).to_a.map { |i| { _id: i } } } }
|
24
|
+
|
25
|
+
setup do
|
26
|
+
@search = Elasticsearch::Model::Searching::SearchRequest.new ModelClass, '*'
|
27
|
+
@response = WillPaginateResponse.new ModelClass, @search, RESPONSE
|
28
|
+
@response.klass.stubs(:client).returns mock('client')
|
29
|
+
|
30
|
+
@expected_methods = [
|
31
|
+
# methods needed by WillPaginate::CollectionMethods
|
32
|
+
:current_page,
|
33
|
+
:offset,
|
34
|
+
:per_page,
|
35
|
+
:total_entries,
|
36
|
+
:length,
|
37
|
+
|
38
|
+
# methods defined by WillPaginate::CollectionMethods
|
39
|
+
:total_pages,
|
40
|
+
:previous_page,
|
41
|
+
:next_page,
|
42
|
+
:out_of_bounds?,
|
43
|
+
]
|
44
|
+
end
|
45
|
+
|
46
|
+
should "have pagination methods" do
|
47
|
+
assert_respond_to @response, :paginate
|
48
|
+
|
49
|
+
@expected_methods.each do |method|
|
50
|
+
assert_respond_to @response, method
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
context "response.results" do
|
55
|
+
should "have pagination methods" do
|
56
|
+
@expected_methods.each do |method|
|
57
|
+
assert_respond_to @response.results, method
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
context "response.records" do
|
63
|
+
should "have pagination methods" do
|
64
|
+
@expected_methods.each do |method|
|
65
|
+
@response.klass.stubs(:find).returns([])
|
66
|
+
assert_respond_to @response.records, method
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
context "#offset method" do
|
72
|
+
should "calculate offset using current_page and per_page" do
|
73
|
+
@response.per_page(3).page(3)
|
74
|
+
assert_equal 6, @response.offset
|
75
|
+
end
|
76
|
+
end
|
77
|
+
context "#length method" do
|
78
|
+
should "return count of paginated results" do
|
79
|
+
@response.per_page(3).page(3)
|
80
|
+
assert_equal 3, @response.length
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
context "#paginate method" do
|
85
|
+
should "set from/size using defaults" do
|
86
|
+
@response.klass.client
|
87
|
+
.expects(:search)
|
88
|
+
.with do |definition|
|
89
|
+
assert_equal 0, definition[:from]
|
90
|
+
assert_equal 33, definition[:size]
|
91
|
+
true
|
92
|
+
end
|
93
|
+
.returns(RESPONSE)
|
94
|
+
|
95
|
+
assert_nil @response.search.definition[:from]
|
96
|
+
assert_nil @response.search.definition[:size]
|
97
|
+
|
98
|
+
@response.paginate(page: nil).to_a
|
99
|
+
assert_equal 0, @response.search.definition[:from]
|
100
|
+
assert_equal 33, @response.search.definition[:size]
|
101
|
+
end
|
102
|
+
|
103
|
+
should "set from/size using default per_page" do
|
104
|
+
@response.klass.client
|
105
|
+
.expects(:search)
|
106
|
+
.with do |definition|
|
107
|
+
assert_equal 33, definition[:from]
|
108
|
+
assert_equal 33, definition[:size]
|
109
|
+
true
|
110
|
+
end
|
111
|
+
.returns(RESPONSE)
|
112
|
+
|
113
|
+
assert_nil @response.search.definition[:from]
|
114
|
+
assert_nil @response.search.definition[:size]
|
115
|
+
|
116
|
+
@response.paginate(page: 2).to_a
|
117
|
+
assert_equal 33, @response.search.definition[:from]
|
118
|
+
assert_equal 33, @response.search.definition[:size]
|
119
|
+
end
|
120
|
+
|
121
|
+
should "set from/size using custom page and per_page" do
|
122
|
+
@response.klass.client
|
123
|
+
.expects(:search)
|
124
|
+
.with do |definition|
|
125
|
+
assert_equal 18, definition[:from]
|
126
|
+
assert_equal 9, definition[:size]
|
127
|
+
true
|
128
|
+
end
|
129
|
+
.returns(RESPONSE)
|
130
|
+
|
131
|
+
assert_nil @response.search.definition[:from]
|
132
|
+
assert_nil @response.search.definition[:size]
|
133
|
+
|
134
|
+
@response.paginate(page: 3, per_page: 9).to_a
|
135
|
+
assert_equal 18, @response.search.definition[:from]
|
136
|
+
assert_equal 9, @response.search.definition[:size]
|
137
|
+
end
|
138
|
+
|
139
|
+
should "search for first page if specified page is < 1" do
|
140
|
+
@response.klass.client
|
141
|
+
.expects(:search)
|
142
|
+
.with do |definition|
|
143
|
+
assert_equal 0, definition[:from]
|
144
|
+
assert_equal 33, definition[:size]
|
145
|
+
true
|
146
|
+
end
|
147
|
+
.returns(RESPONSE)
|
148
|
+
|
149
|
+
assert_nil @response.search.definition[:from]
|
150
|
+
assert_nil @response.search.definition[:size]
|
151
|
+
|
152
|
+
@response.paginate(page: "-1").to_a
|
153
|
+
assert_equal 0, @response.search.definition[:from]
|
154
|
+
assert_equal 33, @response.search.definition[:size]
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
context "#page and #per_page shorthand methods" do
|
159
|
+
should "set from/size using default per_page" do
|
160
|
+
@response.page(5)
|
161
|
+
assert_equal 132, @response.search.definition[:from]
|
162
|
+
assert_equal 33, @response.search.definition[:size]
|
163
|
+
end
|
164
|
+
|
165
|
+
should "set from/size when calling #page then #per_page" do
|
166
|
+
@response.page(5).per_page(3)
|
167
|
+
assert_equal 12, @response.search.definition[:from]
|
168
|
+
assert_equal 3, @response.search.definition[:size]
|
169
|
+
end
|
170
|
+
|
171
|
+
should "set from/size when calling #per_page then #page" do
|
172
|
+
@response.per_page(3).page(5)
|
173
|
+
assert_equal 12, @response.search.definition[:from]
|
174
|
+
assert_equal 3, @response.search.definition[:size]
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
context "#current_page method" do
|
179
|
+
should "return 1 by default" do
|
180
|
+
@response.paginate({})
|
181
|
+
assert_equal 1, @response.current_page
|
182
|
+
end
|
183
|
+
|
184
|
+
should "return current page number" do
|
185
|
+
@response.paginate(page: 3, per_page: 9)
|
186
|
+
assert_equal 3, @response.current_page
|
187
|
+
end
|
188
|
+
|
189
|
+
should "return nil if not pagination set" do
|
190
|
+
assert_equal nil, @response.current_page
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
context "#per_page method" do
|
195
|
+
should "return value set in paginate call" do
|
196
|
+
@response.paginate(per_page: 8)
|
197
|
+
assert_equal 8, @response.per_page
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
context "#total_entries method" do
|
202
|
+
should "return total from response" do
|
203
|
+
@response.expects(:results).returns(mock('results', total: 100))
|
204
|
+
assert_equal 100, @response.total_entries
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|