es_searchable 0.1.1

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 (65) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +8 -0
  3. data/Gemfile +16 -0
  4. data/Gemfile.lock +145 -0
  5. data/MIT-LICENSE +20 -0
  6. data/README.md +281 -0
  7. data/README.rdoc +3 -0
  8. data/Rakefile +34 -0
  9. data/es_searchable.gemspec +29 -0
  10. data/lib/es_searchable/configurable.rb +43 -0
  11. data/lib/es_searchable/search_collection.rb +191 -0
  12. data/lib/es_searchable/version.rb +3 -0
  13. data/lib/es_searchable.rb +52 -0
  14. data/lib/tasks/es_searchable_tasks.rake +4 -0
  15. data/test/dummy/README.rdoc +28 -0
  16. data/test/dummy/Rakefile +6 -0
  17. data/test/dummy/app/assets/images/.keep +0 -0
  18. data/test/dummy/app/assets/javascripts/application.js +13 -0
  19. data/test/dummy/app/assets/stylesheets/application.css +15 -0
  20. data/test/dummy/app/controllers/application_controller.rb +5 -0
  21. data/test/dummy/app/controllers/concerns/.keep +0 -0
  22. data/test/dummy/app/helpers/application_helper.rb +2 -0
  23. data/test/dummy/app/mailers/.keep +0 -0
  24. data/test/dummy/app/models/.keep +0 -0
  25. data/test/dummy/app/models/concerns/.keep +0 -0
  26. data/test/dummy/app/models/user.rb +14 -0
  27. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  28. data/test/dummy/bin/bundle +3 -0
  29. data/test/dummy/bin/rails +4 -0
  30. data/test/dummy/bin/rake +4 -0
  31. data/test/dummy/bin/setup +29 -0
  32. data/test/dummy/config/application.rb +26 -0
  33. data/test/dummy/config/boot.rb +5 -0
  34. data/test/dummy/config/database.yml +25 -0
  35. data/test/dummy/config/environment.rb +5 -0
  36. data/test/dummy/config/environments/development.rb +41 -0
  37. data/test/dummy/config/environments/production.rb +79 -0
  38. data/test/dummy/config/environments/test.rb +42 -0
  39. data/test/dummy/config/initializers/assets.rb +11 -0
  40. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  41. data/test/dummy/config/initializers/cookies_serializer.rb +3 -0
  42. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  43. data/test/dummy/config/initializers/inflections.rb +16 -0
  44. data/test/dummy/config/initializers/mime_types.rb +4 -0
  45. data/test/dummy/config/initializers/session_store.rb +3 -0
  46. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  47. data/test/dummy/config/locales/en.yml +23 -0
  48. data/test/dummy/config/routes.rb +56 -0
  49. data/test/dummy/config/secrets.yml +22 -0
  50. data/test/dummy/config.ru +4 -0
  51. data/test/dummy/db/migrate/20160304063627_create_users.rb +10 -0
  52. data/test/dummy/db/migrate/20160304100221_add_is_admin_to_users.rb +5 -0
  53. data/test/dummy/db/schema.rb +24 -0
  54. data/test/dummy/lib/assets/.keep +0 -0
  55. data/test/dummy/log/.keep +0 -0
  56. data/test/dummy/public/404.html +67 -0
  57. data/test/dummy/public/422.html +67 -0
  58. data/test/dummy/public/500.html +66 -0
  59. data/test/dummy/public/favicon.ico +0 -0
  60. data/test/dummy/test/fixtures/users.yml +9 -0
  61. data/test/dummy/test/models/user_test.rb +7 -0
  62. data/test/es_searchable/search_collection_test.rb +474 -0
  63. data/test/es_searchable_test.rb +58 -0
  64. data/test/test_helper.rb +38 -0
  65. metadata +270 -0
@@ -0,0 +1,474 @@
1
+ require 'test_helper'
2
+
3
+ class SearchCollectionTest < ActiveSupport::TestCase
4
+ setup do
5
+ class Foo
6
+ include EsSearchable
7
+ end
8
+
9
+ @coll = EsSearchable::SearchCollection.new(Foo)
10
+ @full_response = {
11
+ "took"=>1,
12
+ "timed_out"=>false,
13
+ "_shards"=>{"total"=>5, "successful"=>5, "failed"=>0},
14
+ "hits"=> {
15
+ "total"=>2,
16
+ "max_score"=>1.0,
17
+ "hits"=> [
18
+ {
19
+ "_index"=>"outlets",
20
+ "_type"=>"outlet",
21
+ "_id"=>"3",
22
+ "_score"=>1.0,
23
+ "_source"=> {
24
+ "id"=>3,
25
+ "name" => "foo3"
26
+ }
27
+ },
28
+ {
29
+ "_index"=>"outlets",
30
+ "_type"=>"outlet",
31
+ "_id"=>"4",
32
+ "_score"=>1.0,
33
+ "_source"=> {
34
+ "id"=>4,
35
+ "name" => "foo4"
36
+ }
37
+ }
38
+ ]
39
+ }
40
+ }
41
+
42
+ @select_response = {
43
+ "took"=>1,
44
+ "timed_out"=>false,
45
+ "_shards"=>{"total"=>5, "successful"=>5, "failed"=>0},
46
+ "hits"=> {
47
+ "total"=>2,
48
+ "max_score"=>1.0,
49
+ "hits"=> [
50
+ {
51
+ "_index"=>"outlets",
52
+ "_type"=>"outlet",
53
+ "_id"=>"3",
54
+ "_score"=>1.0,
55
+ "fields"=> {
56
+ "id"=>3,
57
+ "name" => "foo3"
58
+ }
59
+ },
60
+ {
61
+ "_index"=>"outlets",
62
+ "_type"=>"outlet",
63
+ "_id"=>"4",
64
+ "_score"=>1.0,
65
+ "fields"=> {
66
+ "id"=>4,
67
+ "name" => "foo4"
68
+ }
69
+ }
70
+ ]
71
+ }
72
+ }
73
+
74
+ end
75
+
76
+
77
+ test "#initialize" do
78
+ assert_equal @coll.instance_variable_get("@klass"), Foo
79
+ end
80
+
81
+ test "::SearchName" do
82
+ assert_equal EsSearchable::SearchCollection::SearchName, {
83
+ and: :must,
84
+ or: :should,
85
+ not: :must_not
86
+ }
87
+ end
88
+
89
+ test "::Attrs" do
90
+ assert_equal EsSearchable::SearchCollection::Attrs, [
91
+ :collections, :response, :count, :time
92
+ ]
93
+ end
94
+
95
+ test "#and" do
96
+ assert_call @coll, :set_filters, [], :must do
97
+ @coll.and({})
98
+ end
99
+
100
+ assert_call @coll, :parse_params, {} do
101
+ @coll.and({})
102
+ end
103
+ end
104
+
105
+ test "#or" do
106
+ assert_call @coll, :set_filters, [], :should do
107
+ @coll.or({})
108
+ end
109
+
110
+ assert_call @coll, :parse_params, {} do
111
+ @coll.or({})
112
+ end
113
+ end
114
+
115
+ test "#not" do
116
+ assert_call @coll, :set_filters, [], :must_not do
117
+ @coll.not({})
118
+ end
119
+
120
+ assert_call @coll, :parse_params, {} do
121
+ @coll.not({})
122
+ end
123
+ end
124
+
125
+ test "#where is alias to #and" do
126
+ assert_equal @coll.where({}), @coll.and({})
127
+ assert_equal @coll.where({id: 1}), @coll.and({id: 1})
128
+ end
129
+
130
+ test "#es_and is alias to #and" do
131
+ assert_equal @coll.es_and({}), @coll.and({})
132
+ assert_equal @coll.es_and({name: :name}), @coll.and({name: :name})
133
+ end
134
+
135
+ test "#like" do
136
+ assert_call @coll, :store_conditions, :query, :must, [] do
137
+ @coll.like({})
138
+ end
139
+
140
+ assert_call @coll, :parse_like_params, :name, 'name' do
141
+ @coll.like({name: 'name'})
142
+ end
143
+ end
144
+
145
+ test "#parse_like_params" do
146
+ assert_equal @coll.parse_like_params(:name, 'foo'), { match: { name: 'foo' } }
147
+
148
+ assert_equal @coll.parse_like_params(:name, {and: 'foo'}), {
149
+ match: {
150
+ name: {
151
+ operator: :and, query: 'foo'
152
+ }
153
+ }
154
+ }
155
+ end
156
+
157
+ test "#select" do
158
+ assert_equal @coll.search_params[:fields], {}
159
+ assert_equal @coll.select(:id, :name), @coll
160
+ assert_equal @coll.search_params[:fields], [:id, :name]
161
+ end
162
+
163
+ test "#limit" do
164
+ assert_equal @coll.search_params[:size], {}
165
+ assert_equal @coll.limit(10), @coll
166
+ assert_equal @coll.search_params[:size], 10
167
+ assert_equal @coll.instance_variable_get('@limit'), 10
168
+ end
169
+
170
+ test "#offset" do
171
+ assert_equal @coll.search_params[:from], {}
172
+ assert_equal @coll.offset(10), @coll
173
+ assert_equal @coll.search_params[:from], 10
174
+ assert_equal @coll.instance_variable_get('@offset'), 10
175
+ end
176
+
177
+ test "#es_method defined by ::SearchMethods alias with prefix es_" do
178
+ EsSearchable::SearchMethods.each do |method|
179
+ params = {}
180
+ es_method = "es_#{method}"
181
+ assert_respond_to @coll, es_method
182
+ assert_equal @coll.send(es_method, params), @coll.send(method, params)
183
+ end
184
+ end
185
+
186
+ test "#collections" do
187
+ assert_call @coll, :load_data do
188
+ @coll.collections
189
+ end
190
+ @coll.stubs(:load_data)
191
+ assert_nil @coll.collections
192
+
193
+ @coll.instance_variable_set '@collections', []
194
+ assert_equal @coll.collections, []
195
+ end
196
+
197
+ test "#response" do
198
+ assert_call @coll, :load_data do
199
+ @coll.response
200
+ end
201
+ @coll.stubs(:load_data)
202
+ assert_nil @coll.response
203
+
204
+ @coll.instance_variable_set '@response', []
205
+ assert_equal @coll.response, []
206
+ end
207
+
208
+ test "#count" do
209
+ assert_call @coll, :load_data do
210
+ @coll.count
211
+ end
212
+ @coll.stubs(:load_data)
213
+ assert_nil @coll.count
214
+
215
+ @coll.instance_variable_set '@count', []
216
+ assert_equal @coll.count, []
217
+ end
218
+
219
+ test "#time" do
220
+ assert_call @coll, :load_data do
221
+ @coll.time
222
+ end
223
+ @coll.stubs(:load_data)
224
+ assert_nil @coll.time
225
+
226
+ @coll.instance_variable_set '@time', []
227
+ assert_equal @coll.time, []
228
+ end
229
+
230
+ test "#load" do
231
+ assert_call @coll, :load_data do
232
+ @coll.load
233
+ end
234
+
235
+ @coll.stubs(:load_data)
236
+ assert_call @coll.instance_variable_get("@klass"), :handle_es_response, @coll do
237
+ @coll.load
238
+ end
239
+ end
240
+
241
+ test "#load_json" do
242
+ assert_call @coll, :load_data do
243
+ @coll.load_json
244
+ end
245
+
246
+ @coll.stubs(:load_data).returns('x1x1x1')
247
+ assert_equal @coll.load_json, 'x1x1x1'
248
+ end
249
+
250
+ test "#each" do
251
+ collections = [1, 2, 3]
252
+ @coll.stubs(:collections).returns(collections)
253
+
254
+ assert_call @coll, :load, return_value: @coll.clone do
255
+ @coll.each {}
256
+ end
257
+
258
+ @coll.stubs(:load).returns(@coll.clone)
259
+ assert_call collections, :each do
260
+ @coll.each {}
261
+ end
262
+
263
+ assert_equal @coll.each {|i| i.to_s}, collections.each {|i| i.to_s}
264
+ end
265
+
266
+ test "#map" do
267
+ collections = [1, 2, 3]
268
+ @coll.stubs(:collections).returns(collections)
269
+
270
+ assert_call @coll, :load, return_value: @coll.clone do
271
+ @coll.map do; end
272
+ end
273
+
274
+ @coll.stubs(:load).returns(@coll.clone)
275
+ assert_call collections, :map do
276
+ @coll.map do; end
277
+ end
278
+
279
+ assert_equal @coll.each {|i| i.to_s}, collections.each {|i| i.to_s}
280
+ end
281
+
282
+ test "#search_params" do
283
+ assert_call @coll, :conditions do
284
+ @coll.search_params
285
+ end
286
+
287
+ @coll.stubs(:conditions).returns('x2x2x2')
288
+ assert_equal @coll.search_params, 'x2x2x2'
289
+ end
290
+
291
+ test "#== return false when search_params not equal" do
292
+ coll = EsSearchable::SearchCollection.new(Foo)
293
+ @coll.stubs(:search_params).returns(1)
294
+ coll.stubs(:search_params).returns(2)
295
+ assert_not_equal @coll, coll
296
+ end
297
+
298
+ test "#== return true when search_params equal" do
299
+ coll = EsSearchable::SearchCollection.new(Foo)
300
+ @coll.stubs(:search_params).returns(1)
301
+ coll.stubs(:search_params).returns(1)
302
+ assert_equal @coll, coll
303
+ end
304
+
305
+ test "#load_data call Foo::es_search" do
306
+ conditions = {}
307
+ @coll.stubs(:conditions).returns(conditions)
308
+ assert_call Foo, :es_search, conditions, return_value: @full_response do
309
+ @coll.send(:load_data)
310
+
311
+ assert_equal @coll.time, 1
312
+ assert_equal @coll.count, 2
313
+ assert_equal @coll.response, @full_response
314
+ assert_equal @coll.collections, [
315
+ {"id"=>3, "name"=>"foo3"}, {"id"=>4, "name"=>"foo4"}
316
+ ]
317
+ end
318
+ end
319
+
320
+ test "#load_data with select conditions" do
321
+ Foo.stubs(:es_search).returns(@select_response)
322
+ @coll.select(:id, :name).send(:load_data)
323
+
324
+ assert_equal @coll.response, @select_response
325
+ assert_equal @coll.collections, [
326
+ {"id"=>3, "name"=>"foo3"}, {"id"=>4, "name"=>"foo4"}
327
+ ]
328
+ end
329
+
330
+ test "#conditions" do
331
+ conditions = @coll.send(:conditions)
332
+ assert_equal conditions, {}
333
+ assert_equal conditions[:a], {}
334
+
335
+ @coll.instance_variable_set '@conditions', 'xxx'
336
+ assert_equal @coll.send(:conditions), 'xxx'
337
+ end
338
+
339
+ test "#set_filters" do
340
+ type = :must
341
+ filters = []
342
+ assert_call @coll, :store_conditions, :filter, type, filters do
343
+ @coll.send(:set_filters, filters, type)
344
+ end
345
+ end
346
+
347
+ test "#set_queries" do
348
+ type = :must
349
+ queries = []
350
+ assert_call @coll, :store_conditions, :query, type, queries do
351
+ @coll.send(:set_queries, queries, type)
352
+ end
353
+ end
354
+
355
+ test "#store_conditions return nil when conditions is blank?" do
356
+ assert_nil @coll.send(:store_conditions, :filter, :must, nil)
357
+ assert_nil @coll.send(:store_conditions, :filter, :must, [])
358
+ assert_nil @coll.send(:store_conditions, :filter, :must, {})
359
+ assert_nil @coll.send(:store_conditions, :filter, :must, '')
360
+ end
361
+
362
+ test "#store_conditions when conditions is empty" do
363
+ conditions = @coll.send(:conditions)
364
+ assert_not conditions[:query][:filtered].key(:filter)
365
+ assert_not conditions[:query][:filtered][:filter][:bool].key(:must)
366
+
367
+ assert_equal conditions[:query][:filtered][:filter][:bool][:must], {}
368
+ @coll.send :store_conditions, :filter, :must, :conds
369
+
370
+ conditions = @coll.send(:conditions)
371
+ assert_equal conditions[:query][:filtered][:filter][:bool][:must], :conds
372
+ end
373
+
374
+ test "#store_conditions when conditions exists " do
375
+ conditions = { query: {
376
+ filtered: {
377
+ filter: {
378
+ bool: {
379
+ must: [{
380
+ terms: {:id=>[3, 4]}
381
+ }]
382
+ }
383
+ }
384
+ }
385
+ }}
386
+
387
+ @coll.instance_variable_set '@conditions', conditions
388
+ @coll.send :store_conditions, :filter, :must, [{terms: {name: 'foo'}}]
389
+ assert_equal conditions[:query][:filtered][:filter][:bool][:must], [
390
+ { terms: {:id=>[3, 4]} }, { terms: {name: 'foo'} }
391
+ ]
392
+ end
393
+
394
+ test "#parse_params return blank? array when params is blank" do
395
+ assert_equal @coll.send(:parse_params, {}), []
396
+ end
397
+
398
+ test "#parse_params when params value is not Array or Hash" do
399
+ assert_equal @coll.send(:parse_params, {name: 'foo'}), [{term: {name: 'foo'}}]
400
+
401
+ assert_equal @coll.send(:parse_params, {name: 'foo', id: 1}), [
402
+ {term: {name: 'foo'}},
403
+ {term: {id: 1}}
404
+ ]
405
+ end
406
+
407
+ test "#parse_params when params value is Array" do
408
+ assert_equal @coll.send(:parse_params, {id: [1, 2]}), [{terms: {id: [1, 2]}}]
409
+ end
410
+
411
+ test "#params when params value is Hash" do
412
+ assert_equal @coll.send(:parse_params, {realname: {like: { and: "zuozuo"} }}), [{
413
+ query: {
414
+ match: {
415
+ realname: {
416
+ operator: :and,
417
+ query: "zuozuo"
418
+ }
419
+ }
420
+ }
421
+ }]
422
+ assert_equal @coll.send(:parse_params, { id: {lt: 202, gt: 200 } }), [{
423
+ range: {
424
+ id: {
425
+ lt: 202, gt: 200
426
+ }
427
+ }
428
+ }]
429
+ assert_equal @coll.send(:parse_params, { tel: 18510705036, or: {email: {like: 'edaixi.com'}, is_admin: true}}), [{
430
+ term: {
431
+ tel: 18510705036
432
+ }
433
+ }, {
434
+ bool: {
435
+ should: [{
436
+ query: {
437
+ match: {
438
+ email: "edaixi.com"
439
+ }
440
+ }
441
+ }, {
442
+ term: {
443
+ is_admin: true
444
+ }
445
+ }]
446
+ }
447
+ }]
448
+ end
449
+
450
+ test "#(.*)_gt|lt|gte|lte" do
451
+ assert_call @coll, :store_conditions, :filter, :must, [{ range: { 'id' => { gt: 10 } } }] do
452
+ @coll.id_gt(10)
453
+ end
454
+
455
+ assert_equal @coll.es_where(id: {gt: 10}), @coll.id_gt(10)
456
+ end
457
+
458
+ test "#(.*)_between" do
459
+ assert_call @coll, :store_conditions, :filter, :must, [{ range: { 'id' => { gte: 10, lte: 20 } } }] do
460
+ @coll.id_between(10, 20)
461
+ end
462
+
463
+ assert_equal @coll.es_where(id: {gte: 10, lte: 20}), @coll.id_between(10, 20)
464
+ end
465
+
466
+ test "#(.*)_like" do
467
+ assert_call @coll, :store_conditions, :query, :must, [match: { 'name' => 'foo' }] do
468
+ @coll.name_like('foo')
469
+ end
470
+
471
+ assert_equal @coll.es_like(name: 'foo'), @coll.name_like('foo')
472
+ assert_equal @coll.es_like(name: { or: 'foo' }), @coll.name_like('foo', :or)
473
+ end
474
+ end
@@ -0,0 +1,58 @@
1
+ require 'test_helper'
2
+
3
+ class EsSearchableTest < ActiveSupport::TestCase
4
+ setup do
5
+ class Foo
6
+ include EsSearchable
7
+ end
8
+ end
9
+
10
+ test "self.es_collection" do
11
+ assert_kind_of EsSearchable::SearchCollection, Foo.es_collection
12
+ end
13
+
14
+ test "self.handle_es_response" do
15
+ assert_equal Foo.handle_es_response('xxxx'), 'xxxx'
16
+ end
17
+
18
+ test "self.client" do
19
+ client = Foo.client
20
+ assert_kind_of Elasticsearch::Transport::Client, Foo.client
21
+
22
+ transport = client.transport
23
+ assert_equal transport.max_retries, EsSearchable.retry_on_failure
24
+ assert_kind_of Logger, transport.logger
25
+ assert_equal transport.options[:reload_on_failure], EsSearchable.reload_on_failure
26
+ assert_equal transport.options[:hosts], EsSearchable.hosts
27
+ end
28
+
29
+ test "self.es_search" do
30
+ Foo.client.stubs(:search).returns('search_result')
31
+ assert_equal Foo.es_search({}), 'search_result'
32
+ end
33
+
34
+ test "self.es_index" do
35
+ Foo.es_index 'index'
36
+ assert_equal Foo.instance_variable_get(:@index), 'index'
37
+
38
+ Foo.es_index nil
39
+ end
40
+
41
+ test 'self.index returns the default index' do
42
+ assert_equal Foo.index, 'foos'
43
+ end
44
+
45
+ test 'self.index returns index setted by self.es_index method' do
46
+ Foo.es_index 'index'
47
+ assert_equal Foo.index, 'index'
48
+ Foo.es_index nil
49
+ end
50
+
51
+ test "delegate SearchMethods to es_collection" do
52
+ EsSearchable::SearchMethods.each do |method|
53
+ assert Foo.respond_to?("es_#{method}")
54
+ assert_equal Foo.send("es_#{method}", {id: 1}).search_params,
55
+ Foo.es_collection.send(method, {id: 1}).search_params
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,38 @@
1
+ # Configure Rails Environment
2
+ ENV["RAILS_ENV"] = "test"
3
+
4
+ require File.expand_path("../../test/dummy/config/environment.rb", __FILE__)
5
+ ActiveRecord::Migrator.migrations_paths = [File.expand_path("../../test/dummy/db/migrate", __FILE__)]
6
+ require "rails/test_help"
7
+ require 'minitest/mock'
8
+ require "mocha/mini_test"
9
+
10
+ # Filter out Minitest backtrace while allowing backtrace from other libraries
11
+ # to be shown.
12
+ Minitest.backtrace_filter = Minitest::BacktraceFilter.new
13
+
14
+ # Load support files
15
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
16
+
17
+ # Load fixtures from the engine
18
+ if ActiveSupport::TestCase.respond_to?(:fixture_path=)
19
+ ActiveSupport::TestCase.fixture_path = File.expand_path("../fixtures", __FILE__)
20
+ ActionDispatch::IntegrationTest.fixture_path = ActiveSupport::TestCase.fixture_path
21
+ ActiveSupport::TestCase.fixtures :all
22
+ end
23
+
24
+ class ActiveSupport::TestCase
25
+ def assert_call obj, method, *args, &blk
26
+ return_value = if args.last && args.last.is_a?(Hash) && args.last.key?(:return_value)
27
+ args.pop[:return_value]
28
+ end
29
+
30
+ mock = MiniTest::Mock.new
31
+ mock.expect(:call, return_value, args)
32
+
33
+ obj.stub(method, mock, &blk)
34
+ mock.verify
35
+ end
36
+
37
+ end
38
+