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.
Files changed (70) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +20 -0
  3. data/CHANGELOG.md +26 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +13 -0
  6. data/README.md +695 -0
  7. data/Rakefile +59 -0
  8. data/elasticsearch-model.gemspec +57 -0
  9. data/examples/activerecord_article.rb +77 -0
  10. data/examples/activerecord_associations.rb +162 -0
  11. data/examples/couchbase_article.rb +66 -0
  12. data/examples/datamapper_article.rb +71 -0
  13. data/examples/mongoid_article.rb +68 -0
  14. data/examples/ohm_article.rb +70 -0
  15. data/examples/riak_article.rb +52 -0
  16. data/gemfiles/3.0.gemfile +12 -0
  17. data/gemfiles/4.0.gemfile +11 -0
  18. data/lib/elasticsearch/model/adapter.rb +145 -0
  19. data/lib/elasticsearch/model/adapters/active_record.rb +104 -0
  20. data/lib/elasticsearch/model/adapters/default.rb +50 -0
  21. data/lib/elasticsearch/model/adapters/mongoid.rb +92 -0
  22. data/lib/elasticsearch/model/callbacks.rb +35 -0
  23. data/lib/elasticsearch/model/client.rb +61 -0
  24. data/lib/elasticsearch/model/ext/active_record.rb +14 -0
  25. data/lib/elasticsearch/model/hash_wrapper.rb +15 -0
  26. data/lib/elasticsearch/model/importing.rb +144 -0
  27. data/lib/elasticsearch/model/indexing.rb +472 -0
  28. data/lib/elasticsearch/model/naming.rb +101 -0
  29. data/lib/elasticsearch/model/proxy.rb +127 -0
  30. data/lib/elasticsearch/model/response/base.rb +44 -0
  31. data/lib/elasticsearch/model/response/pagination.rb +173 -0
  32. data/lib/elasticsearch/model/response/records.rb +69 -0
  33. data/lib/elasticsearch/model/response/result.rb +63 -0
  34. data/lib/elasticsearch/model/response/results.rb +31 -0
  35. data/lib/elasticsearch/model/response.rb +71 -0
  36. data/lib/elasticsearch/model/searching.rb +107 -0
  37. data/lib/elasticsearch/model/serializing.rb +35 -0
  38. data/lib/elasticsearch/model/version.rb +5 -0
  39. data/lib/elasticsearch/model.rb +157 -0
  40. data/test/integration/active_record_associations_parent_child.rb +139 -0
  41. data/test/integration/active_record_associations_test.rb +307 -0
  42. data/test/integration/active_record_basic_test.rb +179 -0
  43. data/test/integration/active_record_custom_serialization_test.rb +62 -0
  44. data/test/integration/active_record_import_test.rb +100 -0
  45. data/test/integration/active_record_namespaced_model_test.rb +49 -0
  46. data/test/integration/active_record_pagination_test.rb +132 -0
  47. data/test/integration/mongoid_basic_test.rb +193 -0
  48. data/test/test_helper.rb +63 -0
  49. data/test/unit/adapter_active_record_test.rb +140 -0
  50. data/test/unit/adapter_default_test.rb +41 -0
  51. data/test/unit/adapter_mongoid_test.rb +102 -0
  52. data/test/unit/adapter_test.rb +69 -0
  53. data/test/unit/callbacks_test.rb +31 -0
  54. data/test/unit/client_test.rb +27 -0
  55. data/test/unit/importing_test.rb +176 -0
  56. data/test/unit/indexing_test.rb +478 -0
  57. data/test/unit/module_test.rb +57 -0
  58. data/test/unit/naming_test.rb +76 -0
  59. data/test/unit/proxy_test.rb +89 -0
  60. data/test/unit/response_base_test.rb +40 -0
  61. data/test/unit/response_pagination_kaminari_test.rb +189 -0
  62. data/test/unit/response_pagination_will_paginate_test.rb +208 -0
  63. data/test/unit/response_records_test.rb +91 -0
  64. data/test/unit/response_result_test.rb +90 -0
  65. data/test/unit/response_results_test.rb +31 -0
  66. data/test/unit/response_test.rb +67 -0
  67. data/test/unit/searching_search_request_test.rb +78 -0
  68. data/test/unit/searching_test.rb +41 -0
  69. data/test/unit/serializing_test.rb +17 -0
  70. metadata +466 -0
@@ -0,0 +1,176 @@
1
+ require 'test_helper'
2
+
3
+ class Elasticsearch::Model::ImportingTest < Test::Unit::TestCase
4
+ context "Importing module" do
5
+ class ::DummyImportingModel
6
+ end
7
+
8
+ module ::DummyImportingAdapter
9
+ module ImportingMixin
10
+ def __find_in_batches(options={}, &block)
11
+ yield if block_given?
12
+ end
13
+ def __transform
14
+ lambda {|a|}
15
+ end
16
+ end
17
+
18
+ def importing_mixin
19
+ ImportingMixin
20
+ end; module_function :importing_mixin
21
+ end
22
+
23
+ should "include methods from the module and adapter" do
24
+ Elasticsearch::Model::Adapter.expects(:from_class)
25
+ .with(DummyImportingModel)
26
+ .returns(DummyImportingAdapter)
27
+
28
+ DummyImportingModel.__send__ :include, Elasticsearch::Model::Importing
29
+
30
+ assert_respond_to DummyImportingModel, :import
31
+ assert_respond_to DummyImportingModel, :__find_in_batches
32
+ end
33
+
34
+ should "call the client when importing" do
35
+ Elasticsearch::Model::Adapter.expects(:from_class)
36
+ .with(DummyImportingModel)
37
+ .returns(DummyImportingAdapter)
38
+
39
+ DummyImportingModel.__send__ :include, Elasticsearch::Model::Importing
40
+
41
+ client = mock('client')
42
+ client.expects(:bulk).returns({'items' => []})
43
+
44
+ DummyImportingModel.expects(:client).returns(client)
45
+ DummyImportingModel.expects(:index_name).returns('foo')
46
+ DummyImportingModel.expects(:document_type).returns('foo')
47
+ DummyImportingModel.stubs(:__batch_to_bulk)
48
+ assert_equal 0, DummyImportingModel.import
49
+ end
50
+
51
+ should "return the number of errors" do
52
+ Elasticsearch::Model::Adapter.expects(:from_class)
53
+ .with(DummyImportingModel)
54
+ .returns(DummyImportingAdapter)
55
+
56
+ DummyImportingModel.__send__ :include, Elasticsearch::Model::Importing
57
+
58
+ client = mock('client')
59
+ client.expects(:bulk).returns({'items' => [ {'index' => {}}, {'index' => {'error' => 'FAILED'}} ]})
60
+
61
+ DummyImportingModel.stubs(:client).returns(client)
62
+ DummyImportingModel.stubs(:index_name).returns('foo')
63
+ DummyImportingModel.stubs(:document_type).returns('foo')
64
+ DummyImportingModel.stubs(:__batch_to_bulk)
65
+
66
+ assert_equal 1, DummyImportingModel.import
67
+ end
68
+
69
+ should "return an array of error elements" do
70
+ Elasticsearch::Model::Adapter.expects(:from_class)
71
+ .with(DummyImportingModel)
72
+ .returns(DummyImportingAdapter)
73
+
74
+ DummyImportingModel.__send__ :include, Elasticsearch::Model::Importing
75
+
76
+ client = mock('client')
77
+ client.expects(:bulk).returns({'items' => [ {'index' => {}}, {'index' => {'error' => 'FAILED'}} ]})
78
+
79
+ DummyImportingModel.stubs(:client).returns(client)
80
+ DummyImportingModel.stubs(:index_name).returns('foo')
81
+ DummyImportingModel.stubs(:document_type).returns('foo')
82
+ DummyImportingModel.stubs(:__batch_to_bulk)
83
+
84
+ assert_equal [{'index' => {'error' => 'FAILED'}}], DummyImportingModel.import(return: 'errors')
85
+ end
86
+
87
+ should "yield the response" do
88
+ Elasticsearch::Model::Adapter.expects(:from_class)
89
+ .with(DummyImportingModel)
90
+ .returns(DummyImportingAdapter)
91
+
92
+ DummyImportingModel.__send__ :include, Elasticsearch::Model::Importing
93
+
94
+ client = mock('client')
95
+ client.expects(:bulk).returns({'items' => [ {'index' => {}}, {'index' => {'error' => 'FAILED'}} ]})
96
+
97
+ DummyImportingModel.stubs(:client).returns(client)
98
+ DummyImportingModel.stubs(:index_name).returns('foo')
99
+ DummyImportingModel.stubs(:document_type).returns('foo')
100
+ DummyImportingModel.stubs(:__batch_to_bulk)
101
+
102
+ DummyImportingModel.import do |response|
103
+ assert_equal 2, response['items'].size
104
+ end
105
+ end
106
+
107
+ should "delete and create the index with the force option" do
108
+ DummyImportingModel.expects(:__find_in_batches).with do |options|
109
+ assert_equal 'bar', options[:foo]
110
+ assert_nil options[:force]
111
+ true
112
+ end
113
+
114
+ DummyImportingModel.expects(:create_index!).with do |options|
115
+ assert_equal true, options[:force]
116
+ true
117
+ end
118
+
119
+ DummyImportingModel.expects(:index_name).returns('foo')
120
+ DummyImportingModel.expects(:document_type).returns('foo')
121
+
122
+ DummyImportingModel.import force: true, foo: 'bar'
123
+ end
124
+
125
+ should "allow passing a different index / type" do
126
+ Elasticsearch::Model::Adapter.expects(:from_class)
127
+ .with(DummyImportingModel)
128
+ .returns(DummyImportingAdapter)
129
+
130
+ DummyImportingModel.__send__ :include, Elasticsearch::Model::Importing
131
+
132
+ client = mock('client')
133
+
134
+ client
135
+ .expects(:bulk)
136
+ .with do |options|
137
+ assert_equal 'my-new-index', options[:index]
138
+ assert_equal 'my-other-type', options[:type]
139
+ true
140
+ end
141
+ .returns({'items' => [ {'index' => {} }]})
142
+
143
+ DummyImportingModel.stubs(:client).returns(client)
144
+ DummyImportingModel.stubs(:__batch_to_bulk)
145
+
146
+ DummyImportingModel.import index: 'my-new-index', type: 'my-other-type'
147
+ end
148
+
149
+ should "use the default transform from adapter" do
150
+ client = mock('client', bulk: {'items' => []})
151
+ transform = lambda {|a|}
152
+
153
+ DummyImportingModel.stubs(:client).returns(client)
154
+ DummyImportingModel.expects(:__transform).returns(transform)
155
+ DummyImportingModel.expects(:__batch_to_bulk).with(anything, transform)
156
+
157
+ DummyImportingModel.import index: 'foo', type: 'bar'
158
+ end
159
+
160
+ should "use the transformer from options" do
161
+ client = mock('client', bulk: {'items' => []})
162
+ transform = lambda {|a|}
163
+
164
+ DummyImportingModel.stubs(:client).returns(client)
165
+ DummyImportingModel.expects(:__batch_to_bulk).with(anything, transform)
166
+
167
+ DummyImportingModel.import index: 'foo', type: 'bar', transform: transform
168
+ end
169
+
170
+ should "raise an ArgumentError if transform doesn't respond to the call method" do
171
+ assert_raise ArgumentError do
172
+ DummyImportingModel.import index: 'foo', type: 'bar', transform: "not_callable"
173
+ end
174
+ end
175
+ end
176
+ end
@@ -0,0 +1,478 @@
1
+ require 'test_helper'
2
+
3
+ class Elasticsearch::Model::IndexingTest < Test::Unit::TestCase
4
+ context "Indexing module: " do
5
+ class ::DummyIndexingModel
6
+ extend ActiveModel::Naming
7
+ extend Elasticsearch::Model::Naming::ClassMethods
8
+ extend Elasticsearch::Model::Indexing::ClassMethods
9
+
10
+ def self.foo
11
+ 'bar'
12
+ end
13
+ end
14
+
15
+ context "Settings class" do
16
+ should "be convertible to hash" do
17
+ hash = { foo: 'bar' }
18
+ settings = Elasticsearch::Model::Indexing::Settings.new hash
19
+ assert_equal hash, settings.to_hash
20
+ assert_equal settings.to_hash, settings.as_json
21
+ end
22
+ end
23
+
24
+ context "Settings method" do
25
+ should "initialize the index settings" do
26
+ assert_instance_of Elasticsearch::Model::Indexing::Settings, DummyIndexingModel.settings
27
+ end
28
+
29
+ should "update and return the index settings" do
30
+ DummyIndexingModel.settings foo: 'boo'
31
+ DummyIndexingModel.settings bar: 'bam'
32
+
33
+ assert_equal( {foo: 'boo', bar: 'bam'}, DummyIndexingModel.settings.to_hash)
34
+ end
35
+
36
+ should "evaluate the block" do
37
+ DummyIndexingModel.expects(:foo)
38
+
39
+ DummyIndexingModel.settings do
40
+ foo
41
+ end
42
+ end
43
+ end
44
+
45
+ context "Mappings class" do
46
+ should "initialize the index mappings" do
47
+ assert_instance_of Elasticsearch::Model::Indexing::Mappings, DummyIndexingModel.mappings
48
+ end
49
+
50
+ should "raise an exception when not passed type" do
51
+ assert_raise ArgumentError do
52
+ Elasticsearch::Model::Indexing::Mappings.new
53
+ end
54
+ end
55
+
56
+ should "be convertible to hash" do
57
+ mappings = Elasticsearch::Model::Indexing::Mappings.new :mytype, { foo: 'bar' }
58
+ assert_equal( { :mytype => { foo: 'bar', :properties => {} } }, mappings.to_hash )
59
+ assert_equal mappings.to_hash, mappings.as_json
60
+ end
61
+
62
+ should "define properties" do
63
+ mappings = Elasticsearch::Model::Indexing::Mappings.new :mytype
64
+ assert_respond_to mappings, :indexes
65
+
66
+ mappings.indexes :foo, { type: 'boolean', include_in_all: false }
67
+ assert_equal 'boolean', mappings.to_hash[:mytype][:properties][:foo][:type]
68
+ end
69
+
70
+ should "define type as string by default" do
71
+ mappings = Elasticsearch::Model::Indexing::Mappings.new :mytype
72
+
73
+ mappings.indexes :bar, {}
74
+ assert_equal 'string', mappings.to_hash[:mytype][:properties][:bar][:type]
75
+ end
76
+
77
+ should "define embedded properties" do
78
+ mappings = Elasticsearch::Model::Indexing::Mappings.new :mytype
79
+
80
+ mappings.indexes :foo do
81
+ indexes :bar
82
+ end
83
+
84
+ mappings.indexes :multi, type: 'multi_field' do
85
+ indexes :multi, analyzer: 'snowball'
86
+ indexes :raw, analyzer: 'keyword'
87
+ end
88
+
89
+ assert_equal 'object', mappings.to_hash[:mytype][:properties][:foo][:type]
90
+ assert_equal 'string', mappings.to_hash[:mytype][:properties][:foo][:properties][:bar][:type]
91
+
92
+ assert_equal 'multi_field', mappings.to_hash[:mytype][:properties][:multi][:type]
93
+ assert_equal 'snowball', mappings.to_hash[:mytype][:properties][:multi][:fields][:multi][:analyzer]
94
+ assert_equal 'keyword', mappings.to_hash[:mytype][:properties][:multi][:fields][:raw][:analyzer]
95
+ end
96
+
97
+ should "define multi_field properties" do
98
+ end
99
+ end
100
+
101
+ context "Mappings method" do
102
+ should "initialize the index mappings" do
103
+ assert_instance_of Elasticsearch::Model::Indexing::Mappings, DummyIndexingModel.mappings
104
+ end
105
+
106
+ should "update and return the index mappings" do
107
+ DummyIndexingModel.mappings foo: 'boo' do; end
108
+ DummyIndexingModel.mappings bar: 'bam' do; end
109
+ assert_equal( { dummy_indexing_model: { foo: "boo", bar: "bam", properties: {} } },
110
+ DummyIndexingModel.mappings.to_hash )
111
+ end
112
+
113
+ should "evaluate the block" do
114
+ DummyIndexingModel.mappings.expects(:indexes).with(:foo).returns(true)
115
+
116
+ DummyIndexingModel.mappings do
117
+ indexes :foo
118
+ end
119
+ end
120
+ end
121
+
122
+ context "Instance methods" do
123
+ class ::DummyIndexingModelWithCallbacks
124
+ extend Elasticsearch::Model::Indexing::ClassMethods
125
+ include Elasticsearch::Model::Indexing::InstanceMethods
126
+
127
+ def self.before_save(&block)
128
+ (@callbacks ||= {})[block.hash] = block
129
+ end
130
+
131
+ def changed_attributes; [:foo]; end
132
+
133
+ def changes
134
+ {:foo => ['One', 'Two']}
135
+ end
136
+ end
137
+
138
+ class ::DummyIndexingModelWithCallbacksAndCustomAsIndexedJson
139
+ extend Elasticsearch::Model::Indexing::ClassMethods
140
+ include Elasticsearch::Model::Indexing::InstanceMethods
141
+
142
+ def self.before_save(&block)
143
+ (@callbacks ||= {})[block.hash] = block
144
+ end
145
+
146
+ def changed_attributes; [:foo, :bar]; end
147
+
148
+ def changes
149
+ {:foo => ['A', 'B'], :bar => ['C', 'D']}
150
+ end
151
+
152
+ def as_indexed_json(options={})
153
+ { :foo => 'B' }
154
+ end
155
+ end
156
+
157
+ should "register before_save callback when included" do
158
+ ::DummyIndexingModelWithCallbacks.expects(:before_save).returns(true)
159
+ ::DummyIndexingModelWithCallbacks.__send__ :include, Elasticsearch::Model::Indexing::InstanceMethods
160
+ end
161
+
162
+ should "set the @__changed_attributes variable before save" do
163
+ instance = ::DummyIndexingModelWithCallbacks.new
164
+ instance.expects(:instance_variable_set).with do |name, value|
165
+ assert_equal :@__changed_attributes, name
166
+ assert_equal({foo: 'Two'}, value)
167
+ true
168
+ end
169
+
170
+ ::DummyIndexingModelWithCallbacks.__send__ :include, Elasticsearch::Model::Indexing::InstanceMethods
171
+
172
+ ::DummyIndexingModelWithCallbacks.instance_variable_get(:@callbacks).each do |n,b|
173
+ instance.instance_eval(&b)
174
+ end
175
+ end
176
+
177
+ should "have the index_document method" do
178
+ client = mock('client')
179
+ instance = ::DummyIndexingModelWithCallbacks.new
180
+
181
+ client.expects(:index).with do |payload|
182
+ assert_equal 'foo', payload[:index]
183
+ assert_equal 'bar', payload[:type]
184
+ assert_equal '1', payload[:id]
185
+ assert_equal 'JSON', payload[:body]
186
+ true
187
+ end
188
+
189
+ instance.expects(:client).returns(client)
190
+ instance.expects(:as_indexed_json).returns('JSON')
191
+ instance.expects(:index_name).returns('foo')
192
+ instance.expects(:document_type).returns('bar')
193
+ instance.expects(:id).returns('1')
194
+
195
+ instance.index_document
196
+ end
197
+
198
+ should "pass extra options to the index_document method to client.index" do
199
+ client = mock('client')
200
+ instance = ::DummyIndexingModelWithCallbacks.new
201
+
202
+ client.expects(:index).with do |payload|
203
+ assert_equal 'A', payload[:parent]
204
+ true
205
+ end
206
+
207
+ instance.expects(:client).returns(client)
208
+ instance.expects(:as_indexed_json).returns('JSON')
209
+ instance.expects(:index_name).returns('foo')
210
+ instance.expects(:document_type).returns('bar')
211
+ instance.expects(:id).returns('1')
212
+
213
+ instance.index_document(parent: 'A')
214
+ end
215
+
216
+ should "have the delete_document method" do
217
+ client = mock('client')
218
+ instance = ::DummyIndexingModelWithCallbacks.new
219
+
220
+ client.expects(:delete).with do |payload|
221
+ assert_equal 'foo', payload[:index]
222
+ assert_equal 'bar', payload[:type]
223
+ assert_equal '1', payload[:id]
224
+ true
225
+ end
226
+
227
+ instance.expects(:client).returns(client)
228
+ instance.expects(:index_name).returns('foo')
229
+ instance.expects(:document_type).returns('bar')
230
+ instance.expects(:id).returns('1')
231
+
232
+ instance.delete_document()
233
+ end
234
+
235
+ should "pass extra options to the delete_document method to client.delete" do
236
+ client = mock('client')
237
+ instance = ::DummyIndexingModelWithCallbacks.new
238
+
239
+ client.expects(:delete).with do |payload|
240
+ assert_equal 'A', payload[:parent]
241
+ true
242
+ end
243
+
244
+ instance.expects(:client).returns(client)
245
+ instance.expects(:id).returns('1')
246
+ instance.expects(:index_name).returns('foo')
247
+ instance.expects(:document_type).returns('bar')
248
+
249
+ instance.delete_document(parent: 'A')
250
+ end
251
+
252
+ should "update the document by re-indexing when no changes are present" do
253
+ client = mock('client')
254
+ instance = ::DummyIndexingModelWithCallbacks.new
255
+
256
+ # Reset the fake `changes`
257
+ instance.instance_variable_set(:@__changed_attributes, nil)
258
+
259
+ instance.expects(:index_document)
260
+ instance.update_document
261
+ end
262
+
263
+ should "update the document by partial update when changes are present" do
264
+ client = mock('client')
265
+ instance = ::DummyIndexingModelWithCallbacks.new
266
+
267
+ # Set the fake `changes` hash
268
+ instance.instance_variable_set(:@__changed_attributes, {foo: 'bar'})
269
+
270
+ client.expects(:update).with do |payload|
271
+ assert_equal 'foo', payload[:index]
272
+ assert_equal 'bar', payload[:type]
273
+ assert_equal '1', payload[:id]
274
+ assert_equal({foo: 'bar'}, payload[:body][:doc])
275
+ true
276
+ end
277
+
278
+ instance.expects(:client).returns(client)
279
+ instance.expects(:index_name).returns('foo')
280
+ instance.expects(:document_type).returns('bar')
281
+ instance.expects(:id).returns('1')
282
+
283
+ instance.update_document
284
+ end
285
+
286
+ should "exclude attributes not contained in custom as_indexed_json during partial update" do
287
+ client = mock('client')
288
+ instance = ::DummyIndexingModelWithCallbacksAndCustomAsIndexedJson.new
289
+
290
+ # Set the fake `changes` hash
291
+ instance.instance_variable_set(:@__changed_attributes, {'foo' => 'B', 'bar' => 'D' })
292
+
293
+ client.expects(:update).with do |payload|
294
+ assert_equal({:foo => 'B'}, payload[:body][:doc])
295
+ true
296
+ end
297
+
298
+ instance.expects(:client).returns(client)
299
+ instance.expects(:index_name).returns('foo')
300
+ instance.expects(:document_type).returns('bar')
301
+ instance.expects(:id).returns('1')
302
+
303
+ instance.update_document
304
+ end
305
+
306
+ should "get attributes from as_indexed_json during partial update" do
307
+ client = mock('client')
308
+ instance = ::DummyIndexingModelWithCallbacksAndCustomAsIndexedJson.new
309
+
310
+ instance.instance_variable_set(:@__changed_attributes, { 'foo' => { 'bar' => 'BAR'} })
311
+ # Overload as_indexed_json
312
+ instance.expects(:as_indexed_json).returns({ 'foo' => 'BAR' })
313
+
314
+ client.expects(:update).with do |payload|
315
+ assert_equal({'foo' => 'BAR'}, payload[:body][:doc])
316
+ true
317
+ end
318
+
319
+ instance.expects(:client).returns(client)
320
+ instance.expects(:index_name).returns('foo')
321
+ instance.expects(:document_type).returns('bar')
322
+ instance.expects(:id).returns('1')
323
+
324
+ instance.update_document
325
+ end
326
+ end
327
+
328
+ context "Re-creating the index" do
329
+ class ::DummyIndexingModelForRecreate
330
+ extend ActiveModel::Naming
331
+ extend Elasticsearch::Model::Naming::ClassMethods
332
+ extend Elasticsearch::Model::Indexing::ClassMethods
333
+
334
+ settings index: { number_of_shards: 1 } do
335
+ mappings do
336
+ indexes :foo, analyzer: 'keyword'
337
+ end
338
+ end
339
+ end
340
+
341
+ should "delete the index without raising exception" do
342
+ client = stub('client')
343
+ indices = stub('indices')
344
+ client.stubs(:indices).returns(indices)
345
+
346
+ indices.expects(:delete).returns({}).then.raises(Exception).at_least_once
347
+
348
+ DummyIndexingModelForRecreate.expects(:client).returns(client).at_least_once
349
+
350
+ assert_nothing_raised do
351
+ DummyIndexingModelForRecreate.delete_index!
352
+ DummyIndexingModelForRecreate.delete_index!
353
+ end
354
+ end
355
+
356
+ should "create the index with correct settings and mappings when it doesn't exist" do
357
+ client = stub('client')
358
+ indices = stub('indices')
359
+ client.stubs(:indices).returns(indices)
360
+
361
+ indices.expects(:exists).returns(false)
362
+
363
+ indices.expects(:create).with do |payload|
364
+ assert_equal 'dummy_indexing_model_for_recreates', payload[:index]
365
+ assert_equal 1, payload[:body][:settings][:index][:number_of_shards]
366
+ assert_equal 'keyword', payload[:body][:mappings][:dummy_indexing_model_for_recreate][:properties][:foo][:analyzer]
367
+ true
368
+ end.returns({})
369
+
370
+ DummyIndexingModelForRecreate.expects(:client).returns(client).at_least_once
371
+
372
+ assert_nothing_raised { DummyIndexingModelForRecreate.create_index! }
373
+ end
374
+
375
+ should "not create the index when it exists" do
376
+ client = stub('client')
377
+ indices = stub('indices')
378
+ client.stubs(:indices).returns(indices)
379
+
380
+ indices.expects(:exists).returns(true)
381
+
382
+ indices.expects(:create).never
383
+
384
+ DummyIndexingModelForRecreate.expects(:client).returns(client).at_least_once
385
+
386
+ assert_nothing_raised { DummyIndexingModelForRecreate.create_index! }
387
+ end
388
+
389
+ should "not raise exception during index creation" do
390
+ client = stub('client')
391
+ indices = stub('indices')
392
+ client.stubs(:indices).returns(indices)
393
+
394
+ indices.expects(:exists).returns(false)
395
+ indices.expects(:create).raises(Exception).at_least_once
396
+
397
+ DummyIndexingModelForRecreate.expects(:client).returns(client).at_least_once
398
+
399
+ assert_nothing_raised do
400
+ DummyIndexingModelForRecreate.create_index!
401
+ end
402
+ end
403
+
404
+ should "delete the index first with the force option" do
405
+ client = stub('client')
406
+ indices = stub('indices')
407
+ client.stubs(:indices).returns(indices)
408
+
409
+ indices.expects(:delete).returns({})
410
+ indices.expects(:exists).returns(false)
411
+ indices.expects(:create).returns({}).at_least_once
412
+
413
+ DummyIndexingModelForRecreate.expects(:client).returns(client).at_least_once
414
+
415
+ assert_nothing_raised do
416
+ DummyIndexingModelForRecreate.create_index! force: true
417
+ end
418
+ end
419
+
420
+ should "refresh the index without raising exception" do
421
+ client = stub('client')
422
+ indices = stub('indices')
423
+ client.stubs(:indices).returns(indices)
424
+
425
+ indices.expects(:refresh).returns({}).then.raises(Exception).at_least_once
426
+
427
+ DummyIndexingModelForRecreate.expects(:client).returns(client).at_least_once
428
+
429
+ assert_nothing_raised do
430
+ DummyIndexingModelForRecreate.refresh_index!
431
+ DummyIndexingModelForRecreate.refresh_index!
432
+ end
433
+ end
434
+
435
+ context "with a custom index name" do
436
+ setup do
437
+ @client = stub('client')
438
+ @indices = stub('indices')
439
+ @client.stubs(:indices).returns(@indices)
440
+ DummyIndexingModelForRecreate.expects(:client).returns(@client).at_least_once
441
+ end
442
+
443
+ should "create the custom index" do
444
+ @indices.expects(:exists).with do |arguments|
445
+ assert_equal 'custom-foo', arguments[:index]
446
+ true
447
+ end
448
+
449
+ @indices.expects(:create).with do |arguments|
450
+ assert_equal 'custom-foo', arguments[:index]
451
+ true
452
+ end
453
+
454
+ DummyIndexingModelForRecreate.create_index! index: 'custom-foo'
455
+ end
456
+
457
+ should "delete the custom index" do
458
+ @indices.expects(:delete).with do |arguments|
459
+ assert_equal 'custom-foo', arguments[:index]
460
+ true
461
+ end
462
+
463
+ DummyIndexingModelForRecreate.delete_index! index: 'custom-foo'
464
+ end
465
+
466
+ should "refresh the custom index" do
467
+ @indices.expects(:refresh).with do |arguments|
468
+ assert_equal 'custom-foo', arguments[:index]
469
+ true
470
+ end
471
+
472
+ DummyIndexingModelForRecreate.refresh_index! index: 'custom-foo'
473
+ end
474
+ end
475
+ end
476
+
477
+ end
478
+ end