elastic_searchable 1.5 → 1.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,30 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ require 'yaml'
4
+ require 'byebug'
5
+
6
+ begin
7
+ Bundler.setup
8
+ rescue Bundler::BundlerError => e
9
+ $stderr.puts e.message
10
+ $stderr.puts "Run `bundle install` to install missing gems"
11
+ exit e.status_code
12
+ end
13
+ require 'rspec/matchers'
14
+
15
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
16
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
17
+
18
+ require 'elastic_searchable'
19
+ require 'prefactory'
20
+
21
+ SINGLE_NODE_CLUSTER_CONFIG = {
22
+ 'number_of_replicas' => 0,
23
+ 'number_of_shards' => 1
24
+ }
25
+
26
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
27
+
28
+ RSpec.configure do |config|
29
+ config.include Prefactory
30
+ end
@@ -0,0 +1,6 @@
1
+ class Blog < ActiveRecord::Base
2
+ elastic_searchable :if => proc {|b| b.should_index? }, :index_options => SINGLE_NODE_CLUSTER_CONFIG
3
+ def should_index?
4
+ false
5
+ end
6
+ end
@@ -0,0 +1,10 @@
1
+ class Book < ActiveRecord::Base
2
+ elastic_searchable
3
+ after_percolate :on_percolated
4
+ def on_percolated
5
+ @percolated = percolations
6
+ end
7
+ def percolated
8
+ @percolated
9
+ end
10
+ end
@@ -0,0 +1,3 @@
1
+ sqlite:
2
+ adapter: sqlite3
3
+ database: spec/elastic_searchable.sqlite3
@@ -0,0 +1,4 @@
1
+ class Friend < ActiveRecord::Base
2
+ belongs_to :book
3
+ elastic_searchable :json => {:include => {:book => {:only => :title}}, :only => :name}, :index_options => SINGLE_NODE_CLUSTER_CONFIG
4
+ end
@@ -0,0 +1,6 @@
1
+ class MaxPageSizeClass < ActiveRecord::Base
2
+ elastic_searchable :index_options => SINGLE_NODE_CLUSTER_CONFIG
3
+ def self.max_per_page
4
+ 1
5
+ end
6
+ end
@@ -0,0 +1,26 @@
1
+ class Post < ActiveRecord::Base
2
+ Post.class_eval do
3
+ elastic_searchable :index_options => SINGLE_NODE_CLUSTER_CONFIG
4
+ after_index :indexed
5
+ after_index :indexed_on_create, :on => :create
6
+ after_index :indexed_on_update, :on => :update
7
+ def indexed
8
+ @indexed = true
9
+ end
10
+ def indexed?
11
+ @indexed
12
+ end
13
+ def indexed_on_create
14
+ @indexed_on_create = true
15
+ end
16
+ def indexed_on_create?
17
+ @indexed_on_create
18
+ end
19
+ def indexed_on_update
20
+ @indexed_on_update = true
21
+ end
22
+ def indexed_on_update?
23
+ @indexed_on_update
24
+ end
25
+ end
26
+ end
File without changes
@@ -0,0 +1,8 @@
1
+ class User < ActiveRecord::Base
2
+ elastic_searchable :index_options => {
3
+ 'number_of_replicas' => 0,
4
+ 'number_of_shards' => 1,
5
+ "analysis.analyzer.default.tokenizer" => 'standard',
6
+ "analysis.analyzer.default.filter" => ["standard", "lowercase", 'porterStem']},
7
+ :mapping => {:properties => {:name => {:type => 'string', :index => 'not_analyzed'}}}
8
+ end
metadata CHANGED
@@ -1,158 +1,153 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: elastic_searchable
3
3
  version: !ruby/object:Gem::Version
4
- version: '1.5'
5
- prerelease:
4
+ version: '1.6'
6
5
  platform: ruby
7
6
  authors:
8
7
  - Ryan Sonnek
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-08-05 00:00:00.000000000 Z
11
+ date: 2014-09-09 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: activerecord
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
- - - ! '>='
17
+ - - ">="
20
18
  - !ruby/object:Gem::Version
21
19
  version: 3.0.5
22
20
  type: :runtime
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
- - - ! '>='
24
+ - - ">="
28
25
  - !ruby/object:Gem::Version
29
26
  version: 3.0.5
30
27
  - !ruby/object:Gem::Dependency
31
28
  name: httparty
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
- - - ! '>='
31
+ - - ">="
36
32
  - !ruby/object:Gem::Version
37
33
  version: 0.6.0
38
34
  type: :runtime
39
35
  prerelease: false
40
36
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
37
  requirements:
43
- - - ! '>='
38
+ - - ">="
44
39
  - !ruby/object:Gem::Version
45
40
  version: 0.6.0
46
41
  - !ruby/object:Gem::Dependency
47
42
  name: backgrounded
48
43
  requirement: !ruby/object:Gem::Requirement
49
- none: false
50
44
  requirements:
51
- - - ~>
45
+ - - "~>"
52
46
  - !ruby/object:Gem::Version
53
47
  version: 0.7.0
54
48
  type: :runtime
55
49
  prerelease: false
56
50
  version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
51
  requirements:
59
- - - ~>
52
+ - - "~>"
60
53
  - !ruby/object:Gem::Version
61
54
  version: 0.7.0
62
55
  - !ruby/object:Gem::Dependency
63
56
  name: multi_json
64
57
  requirement: !ruby/object:Gem::Requirement
65
- none: false
66
58
  requirements:
67
- - - ! '>='
59
+ - - ">="
68
60
  - !ruby/object:Gem::Version
69
61
  version: 1.0.0
70
62
  type: :runtime
71
63
  prerelease: false
72
64
  version_requirements: !ruby/object:Gem::Requirement
73
- none: false
74
65
  requirements:
75
- - - ! '>='
66
+ - - ">="
76
67
  - !ruby/object:Gem::Version
77
68
  version: 1.0.0
78
69
  - !ruby/object:Gem::Dependency
79
70
  name: rake
80
71
  requirement: !ruby/object:Gem::Requirement
81
- none: false
82
72
  requirements:
83
- - - '='
73
+ - - ">="
84
74
  - !ruby/object:Gem::Version
85
- version: 0.9.2.2
75
+ version: '0'
86
76
  type: :development
87
77
  prerelease: false
88
78
  version_requirements: !ruby/object:Gem::Requirement
89
- none: false
90
79
  requirements:
91
- - - '='
80
+ - - ">="
92
81
  - !ruby/object:Gem::Version
93
- version: 0.9.2.2
82
+ version: '0'
94
83
  - !ruby/object:Gem::Dependency
95
84
  name: sqlite3
96
85
  requirement: !ruby/object:Gem::Requirement
97
- none: false
98
86
  requirements:
99
- - - ! '>='
87
+ - - ">="
100
88
  - !ruby/object:Gem::Version
101
89
  version: '0'
102
90
  type: :development
103
91
  prerelease: false
104
92
  version_requirements: !ruby/object:Gem::Requirement
105
- none: false
106
93
  requirements:
107
- - - ! '>='
94
+ - - ">="
108
95
  - !ruby/object:Gem::Version
109
96
  version: '0'
110
97
  - !ruby/object:Gem::Dependency
111
98
  name: pry
112
99
  requirement: !ruby/object:Gem::Requirement
113
- none: false
114
100
  requirements:
115
- - - '='
101
+ - - ">="
116
102
  - !ruby/object:Gem::Version
117
- version: 0.9.6.2
103
+ version: '0'
118
104
  type: :development
119
105
  prerelease: false
120
106
  version_requirements: !ruby/object:Gem::Requirement
121
- none: false
122
107
  requirements:
123
- - - '='
108
+ - - ">="
124
109
  - !ruby/object:Gem::Version
125
- version: 0.9.6.2
110
+ version: '0'
126
111
  - !ruby/object:Gem::Dependency
127
- name: shoulda
112
+ name: rspec
128
113
  requirement: !ruby/object:Gem::Requirement
129
- none: false
130
114
  requirements:
131
- - - '='
115
+ - - ">="
132
116
  - !ruby/object:Gem::Version
133
- version: 2.11.3
117
+ version: '0'
134
118
  type: :development
135
119
  prerelease: false
136
120
  version_requirements: !ruby/object:Gem::Requirement
137
- none: false
138
121
  requirements:
139
- - - '='
122
+ - - ">="
140
123
  - !ruby/object:Gem::Version
141
- version: 2.11.3
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: byebug
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
142
139
  - !ruby/object:Gem::Dependency
143
- name: mocha
140
+ name: prefactory
144
141
  requirement: !ruby/object:Gem::Requirement
145
- none: false
146
142
  requirements:
147
- - - ! '>='
143
+ - - ">="
148
144
  - !ruby/object:Gem::Version
149
145
  version: '0'
150
146
  type: :development
151
147
  prerelease: false
152
148
  version_requirements: !ruby/object:Gem::Requirement
153
- none: false
154
149
  requirements:
155
- - - ! '>='
150
+ - - ">="
156
151
  - !ruby/object:Gem::Version
157
152
  version: '0'
158
153
  description: integrate the elastic search engine with rails
@@ -162,9 +157,10 @@ executables: []
162
157
  extensions: []
163
158
  extra_rdoc_files: []
164
159
  files:
165
- - .document
166
- - .gitignore
167
- - .rvmrc
160
+ - ".document"
161
+ - ".gitignore"
162
+ - ".rvmrc"
163
+ - ".travis.yml"
168
164
  - CONTRIBUTORS.txt
169
165
  - Gemfile
170
166
  - LICENSE.txt
@@ -180,36 +176,47 @@ files:
180
176
  - lib/elastic_searchable/paginator.rb
181
177
  - lib/elastic_searchable/queries.rb
182
178
  - lib/elastic_searchable/version.rb
183
- - test/database.yml
184
- - test/helper.rb
185
- - test/setup_database.rb
186
- - test/test_elastic_searchable.rb
179
+ - spec/elastic_searchable_spec.rb
180
+ - spec/spec_helper.rb
181
+ - spec/support/blog.rb
182
+ - spec/support/book.rb
183
+ - spec/support/database.yml
184
+ - spec/support/friend.rb
185
+ - spec/support/max_page_size_class.rb
186
+ - spec/support/post.rb
187
+ - spec/support/setup_database.rb
188
+ - spec/support/user.rb
187
189
  homepage: http://github.com/socialcast/elastic_searchable
188
190
  licenses: []
191
+ metadata: {}
189
192
  post_install_message:
190
193
  rdoc_options: []
191
194
  require_paths:
192
195
  - lib
193
196
  required_ruby_version: !ruby/object:Gem::Requirement
194
- none: false
195
197
  requirements:
196
- - - ! '>='
198
+ - - ">="
197
199
  - !ruby/object:Gem::Version
198
200
  version: '0'
199
201
  required_rubygems_version: !ruby/object:Gem::Requirement
200
- none: false
201
202
  requirements:
202
- - - ! '>='
203
+ - - ">="
203
204
  - !ruby/object:Gem::Version
204
205
  version: '0'
205
206
  requirements: []
206
207
  rubyforge_project: elastic_searchable
207
- rubygems_version: 1.8.24
208
+ rubygems_version: 2.2.2
208
209
  signing_key:
209
- specification_version: 3
210
+ specification_version: 4
210
211
  summary: elastic search for activerecord
211
212
  test_files:
212
- - test/database.yml
213
- - test/helper.rb
214
- - test/setup_database.rb
215
- - test/test_elastic_searchable.rb
213
+ - spec/elastic_searchable_spec.rb
214
+ - spec/spec_helper.rb
215
+ - spec/support/blog.rb
216
+ - spec/support/book.rb
217
+ - spec/support/database.yml
218
+ - spec/support/friend.rb
219
+ - spec/support/max_page_size_class.rb
220
+ - spec/support/post.rb
221
+ - spec/support/setup_database.rb
222
+ - spec/support/user.rb
data/test/database.yml DELETED
@@ -1,3 +0,0 @@
1
- sqlite:
2
- adapter: sqlite3
3
- database: test/elastic_searchable.sqlite3
data/test/helper.rb DELETED
@@ -1,37 +0,0 @@
1
- require 'rubygems'
2
- require 'bundler'
3
- begin
4
- Bundler.setup(:default, :development)
5
- rescue Bundler::BundlerError => e
6
- $stderr.puts e.message
7
- $stderr.puts "Run `bundle install` to install missing gems"
8
- exit e.status_code
9
- end
10
- require 'test/unit'
11
- require 'shoulda'
12
- require 'mocha/setup'
13
- require 'pry'
14
-
15
- $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
16
- $LOAD_PATH.unshift(File.dirname(__FILE__))
17
- require 'elastic_searchable'
18
- require 'setup_database'
19
-
20
- class DeprecationLogger < Logger
21
- def format_message(severity, timestamp, progname, msg)
22
- "#{severity} #{msg}\n"
23
- end
24
- end
25
-
26
- DEPRECATION_LOGGER = DeprecationLogger.new(File.join(File.dirname(__FILE__), "/deprecations.log"))
27
- ActiveSupport::Deprecation.debug = false
28
- ActiveSupport::Deprecation::DEFAULT_BEHAVIORS[:deprecation_log] = lambda { |message, callstack|
29
- DEPRECATION_LOGGER.warn(message)
30
- }
31
- ActiveSupport::Deprecation.behavior = :deprecation_log
32
-
33
- class Test::Unit::TestCase
34
- def delete_index
35
- ElasticSearchable.delete '/elastic_searchable' rescue nil
36
- end
37
- end
@@ -1,626 +0,0 @@
1
- require File.join(File.dirname(__FILE__), 'helper')
2
-
3
- class TestElasticSearchable < Test::Unit::TestCase
4
- def setup
5
- delete_index
6
- end
7
- # ElasticSearchable.debug_output
8
- SINGLE_NODE_CLUSTER_CONFIG = {'number_of_replicas' => 0, 'number_of_shards' => 1}
9
-
10
- context 'non elastic activerecord class' do
11
- class Parent < ActiveRecord::Base
12
- end
13
- setup do
14
- @clazz = Parent
15
- end
16
- should 'not respond to elastic_options' do
17
- assert !@clazz.respond_to?(:elastic_options)
18
- end
19
- end
20
- context 'instance of non-elastic_searchable activerecord class' do
21
- class Parent < ActiveRecord::Base
22
- end
23
- setup do
24
- @instance = Parent.new
25
- end
26
- should 'not respond to percolations' do
27
- assert !@instance.respond_to?(:percolations)
28
- end
29
- end
30
-
31
- class Post < ActiveRecord::Base
32
- elastic_searchable :index_options => SINGLE_NODE_CLUSTER_CONFIG
33
- after_index :indexed
34
- after_index :indexed_on_create, :on => :create
35
- after_index :indexed_on_update, :on => :update
36
- def indexed
37
- @indexed = true
38
- end
39
- def indexed?
40
- @indexed
41
- end
42
- def indexed_on_create
43
- @indexed_on_create = true
44
- end
45
- def indexed_on_create?
46
- @indexed_on_create
47
- end
48
- def indexed_on_update
49
- @indexed_on_update = true
50
- end
51
- def indexed_on_update?
52
- @indexed_on_update
53
- end
54
- end
55
- context 'activerecord class with default elastic_searchable config' do
56
- setup do
57
- @clazz = Post
58
- end
59
- should 'respond to :search' do
60
- assert @clazz.respond_to?(:search)
61
- end
62
- should 'define elastic_options' do
63
- assert @clazz.elastic_options
64
- end
65
- should 'respond to :percolations' do
66
- assert @clazz.new.respond_to?(:percolations)
67
- assert_equal [], @clazz.new.percolations
68
- end
69
- end
70
-
71
- context 'Model.request with invalid url' do
72
- should 'raise error' do
73
- assert_raises ElasticSearchable::ElasticError do
74
- ElasticSearchable.request :get, '/elastic_searchable/foobar/notfound'
75
- end
76
- end
77
- end
78
-
79
- context 'Model.create_index' do
80
- setup do
81
- Post.create_index
82
- Post.refresh_index
83
- @status = ElasticSearchable.request :get, '/elastic_searchable/_status'
84
- end
85
- should 'have created index' do
86
- assert @status['ok']
87
- end
88
- end
89
-
90
- context 'Model.create' do
91
- setup do
92
- @post = Post.create :title => 'foo', :body => "bar"
93
- end
94
- should 'have fired after_index callback' do
95
- assert @post.indexed?
96
- end
97
- should 'have fired after_index_on_create callback' do
98
- assert @post.indexed_on_create?
99
- end
100
- should 'not have fired after_index_on_update callback' do
101
- assert !@post.indexed_on_update?
102
- end
103
- end
104
-
105
- context 'Model.update' do
106
- setup do
107
- Post.create :title => 'foo', :body => 'bar'
108
- @post = Post.last
109
- @post.title = 'baz'
110
- @post.save
111
- end
112
- should 'have fired after_index callback' do
113
- assert @post.indexed?
114
- end
115
- should 'not have fired after_index_on_create callback' do
116
- assert !@post.indexed_on_create?
117
- end
118
- should 'have fired after_index_on_update callback' do
119
- assert @post.indexed_on_update?
120
- end
121
- end
122
-
123
- context 'Model.create within ElasticSearchable.offline block' do
124
- setup do
125
- ElasticSearchable.offline do
126
- @post = Post.create :title => 'foo', :body => "bar"
127
- end
128
- end
129
- should 'not have fired after_index callback' do
130
- assert !@post.indexed?
131
- end
132
- should 'not have fired after_index_on_create callback' do
133
- assert !@post.indexed_on_create?
134
- end
135
- should 'not have fired after_index_on_update callback' do
136
- assert !@post.indexed_on_update?
137
- end
138
- end
139
-
140
- context 'with empty index when multiple database records' do
141
- setup do
142
- Post.delete_all
143
- Post.create_index
144
- @first_post = Post.create :title => 'foo', :body => "first bar"
145
- @second_post = Post.create :title => 'foo', :body => "second bar"
146
- Post.delete_index
147
- Post.create_index
148
- end
149
- should 'not raise error if error occurs reindexing model' do
150
- ElasticSearchable.expects(:request).raises(ElasticSearchable::ElasticError.new('faux error'))
151
- assert_nothing_raised do
152
- Post.reindex
153
- end
154
- end
155
- should 'not raise error if destroying one instance' do
156
- Logger.any_instance.expects(:warn)
157
- assert_nothing_raised do
158
- @first_post.destroy
159
- end
160
- end
161
- context 'Model.reindex' do
162
- setup do
163
- Post.reindex :per_page => 1, :scope => Post.order('body desc')
164
- Post.refresh_index
165
- end
166
- should 'have reindexed both records' do
167
- assert_nothing_raised do
168
- ElasticSearchable.request :get, "/elastic_searchable/posts/#{@first_post.id}"
169
- ElasticSearchable.request :get, "/elastic_searchable/posts/#{@second_post.id}"
170
- end
171
- end
172
- end
173
- end
174
-
175
- context 'with index containing multiple results' do
176
- setup do
177
- Post.create_index
178
- @first_post = Post.create :title => 'foo', :body => "first bar"
179
- @second_post = Post.create :title => 'foo', :body => "second bar"
180
- Post.refresh_index
181
- end
182
-
183
- context 'searching on a term that returns one result' do
184
- setup do
185
- @results = Post.search 'first'
186
- end
187
- should 'find created object' do
188
- assert_contains @results, @first_post
189
- end
190
- should 'be paginated' do
191
- assert_equal 1, @results.current_page
192
- assert_equal Post.per_page, @results.per_page
193
- assert_nil @results.previous_page
194
- assert_nil @results.next_page
195
- end
196
- should 'have populated hit' do
197
- assert_equal @results.first.hit['_id'], @first_post.id.to_s
198
- end
199
- end
200
- context 'searching on a term that returns multiple results' do
201
- setup do
202
- @results = Post.search 'foo'
203
- end
204
- should 'have populated hit on each record with the correct hit json' do
205
- assert_equal @results.first.hit['_id'], @first_post.id.to_s
206
- assert_equal @results.last.hit['_id'], @second_post.id.to_s
207
- end
208
- end
209
-
210
- context 'searching for results using a query Hash' do
211
- setup do
212
- @results = Post.search({
213
- :filtered => {
214
- :query => {
215
- :term => {:title => 'foo'},
216
- },
217
- :filter => {
218
- :or => [
219
- {:term => {:body => 'second'}},
220
- {:term => {:body => 'third'}}
221
- ]
222
- }
223
- }
224
- })
225
- end
226
- should 'find only the object which ' do
227
- assert_does_not_contain @results, @first_post
228
- assert_contains @results, @second_post
229
- end
230
- end
231
-
232
- context 'when per_page is a string' do
233
- setup do
234
- @results = Post.search 'foo', :per_page => 1.to_s, :sort => 'id'
235
- end
236
- should 'find first object' do
237
- assert_contains @results, @first_post
238
- end
239
- end
240
-
241
- context 'searching for second page using will_paginate params' do
242
- setup do
243
- @results = Post.search 'foo', :page => 2, :per_page => 1, :sort => 'id'
244
- end
245
- should 'not find objects from first page' do
246
- assert_does_not_contain @results, @first_post
247
- end
248
- should 'find second object' do
249
- assert_contains @results, @second_post
250
- end
251
- should 'be paginated' do
252
- assert_equal 2, @results.current_page
253
- assert_equal 1, @results.per_page
254
- assert_equal 1, @results.previous_page
255
- assert_nil @results.next_page
256
- end
257
- end
258
-
259
- context 'sorting search results' do
260
- setup do
261
- @results = Post.search 'foo', :sort => 'id:desc'
262
- end
263
- should 'sort results correctly' do
264
- assert_equal @second_post, @results.first
265
- assert_equal @first_post, @results.last
266
- end
267
- end
268
-
269
- context 'advanced sort options' do
270
- setup do
271
- @results = Post.search 'foo', :sort => [{:id => 'desc'}]
272
- end
273
- should 'sort results correctly' do
274
- assert_equal @second_post, @results.first
275
- assert_equal @first_post, @results.last
276
- end
277
- end
278
-
279
- context 'destroying one object' do
280
- setup do
281
- @first_post.destroy
282
- Post.refresh_index
283
- end
284
- should 'be removed from the index' do
285
- @request = ElasticSearchable.get "/elastic_searchable/posts/#{@first_post.id}"
286
- assert @request.response.is_a?(Net::HTTPNotFound), @request.inspect
287
- end
288
- end
289
- end
290
-
291
- context 'deleting a record without updating the index' do
292
-
293
- context 'backfilling partial result pages' do
294
- setup do
295
- @posts = (1..8).map do |i|
296
- Post.create :title => 'foo', :body => "#{i} bar"
297
- end
298
- Post.refresh_index
299
-
300
- @removed_posts = []
301
- @posts.each_with_index do |post, i|
302
- if i % 2 == 1
303
- @removed_posts << post
304
- post.delete
305
- Post.expects(:delete_id_from_index_backgrounded).with(post.id)
306
- end
307
- end
308
-
309
- assert_nothing_raised do
310
- @results = Post.search 'foo', :size => 4, :sort => 'id:desc'
311
- end
312
- end
313
- # should 'not raise an exception' do end
314
- # should 'trigger deletion of bad index records' do end
315
- should 'backfill the first page with results from other pages' do
316
- assert_equal((@posts - @removed_posts).reverse, @results)
317
- end
318
- should 'adjust total hit count to exclude invalid results encountered from repaging' do
319
- assert_equal 4, @results.total_entries
320
- end
321
- end
322
-
323
- end
324
-
325
- class Blog < ActiveRecord::Base
326
- elastic_searchable :if => proc {|b| b.should_index? }, :index_options => SINGLE_NODE_CLUSTER_CONFIG
327
- def should_index?
328
- false
329
- end
330
- end
331
- context 'activerecord class with optional :if=>proc configuration' do
332
- context 'when creating new instance' do
333
- setup do
334
- Blog.any_instance.expects(:reindex).never
335
- @blog = Blog.create! :title => 'foo'
336
- end
337
- should 'not index record' do end #see expectations
338
- should 'not be found in elasticsearch' do
339
- @request = ElasticSearchable.get "/elastic_searchable/blogs/#{@blog.id}"
340
- assert @request.response.is_a?(Net::HTTPNotFound), @request.inspect
341
- end
342
- end
343
- end
344
-
345
- class User < ActiveRecord::Base
346
- elastic_searchable :index_options => {
347
- 'number_of_replicas' => 0,
348
- 'number_of_shards' => 1,
349
- "analysis.analyzer.default.tokenizer" => 'standard',
350
- "analysis.analyzer.default.filter" => ["standard", "lowercase", 'porterStem']},
351
- :mapping => {:properties => {:name => {:type => 'string', :index => 'not_analyzed'}}}
352
- end
353
- context 'activerecord class with :index_options and :mapping' do
354
- context 'creating index' do
355
- setup do
356
- User.create_index
357
- end
358
- should 'have used custom index_options' do
359
- @status = ElasticSearchable.request :get, '/elastic_searchable/_settings'
360
- @status['elastic_searchable']['settings'].delete('index.version.created')
361
- expected = {
362
- "index.number_of_replicas" => "0",
363
- "index.number_of_shards" => "1",
364
- "index.analysis.analyzer.default.tokenizer" => "standard",
365
- "index.analysis.analyzer.default.filter.0" => "standard",
366
- "index.analysis.analyzer.default.filter.1" => "lowercase",
367
- "index.analysis.analyzer.default.filter.2" => "porterStem"
368
- }
369
- assert_equal expected, @status['elastic_searchable']['settings'], @status.inspect
370
- end
371
- should 'have set mapping' do
372
- @status = ElasticSearchable.request :get, '/elastic_searchable/users/_mapping'
373
- expected = {
374
- "name"=> {"type"=>"string", "index"=>"not_analyzed"}
375
- }
376
- assert_equal expected, @status['users']['properties'], @status.inspect
377
- end
378
- end
379
- end
380
-
381
- class Friend < ActiveRecord::Base
382
- belongs_to :book
383
- elastic_searchable :json => {:include => {:book => {:only => :title}}, :only => :name}, :index_options => SINGLE_NODE_CLUSTER_CONFIG
384
- end
385
- context 'activerecord class with optional :json config' do
386
- context 'creating index' do
387
- setup do
388
- Friend.create_index
389
- @book = Book.create! :isbn => '123abc', :title => 'another world'
390
- @friend = Friend.new :name => 'bob', :favorite_color => 'red'
391
- @friend.book = @book
392
- @friend.save!
393
- Friend.refresh_index
394
- end
395
- should 'index json with configuration' do
396
- @response = ElasticSearchable.request :get, "/elastic_searchable/friends/#{@friend.id}"
397
- # should not index:
398
- # friend.favorite_color
399
- # book.isbn
400
- expected = {
401
- "name" => 'bob',
402
- 'book' => {'title' => 'another world'}
403
- }
404
- assert_equal expected, @response['_source'], @response.inspect
405
- end
406
- end
407
- end
408
-
409
- context 'updating ElasticSearchable.default_index' do
410
- setup do
411
- ElasticSearchable.default_index = 'my_new_index'
412
- end
413
- teardown do
414
- ElasticSearchable.default_index = ElasticSearchable::DEFAULT_INDEX
415
- end
416
- should 'change default index' do
417
- assert_equal 'my_new_index', ElasticSearchable.default_index
418
- end
419
- end
420
-
421
- class Book < ActiveRecord::Base
422
- elastic_searchable
423
- after_percolate :on_percolated
424
- def on_percolated
425
- @percolated = percolations
426
- end
427
- def percolated
428
- @percolated
429
- end
430
- end
431
- context 'Book class with after_percolate callback' do
432
- context 'with created index' do
433
- setup do
434
- Book.create_index
435
- end
436
- context "when index has configured percolation" do
437
- setup do
438
- ElasticSearchable.request :put, '/_percolator/elastic_searchable/myfilter', :json_body => {:query => {:query_string => {:query => 'foo' }}}
439
- ElasticSearchable.request :post, '/_percolator/_refresh'
440
- end
441
- context 'creating an object that does not match the percolation' do
442
- setup do
443
- Book.any_instance.expects(:on_percolated).never
444
- @book = Book.create! :title => 'bar'
445
- end
446
- should 'not percolate the record' do end #see expectations
447
- end
448
- context 'creating an object that matches the percolation' do
449
- setup do
450
- @book = Book.create :title => "foo"
451
- end
452
- should 'return percolated matches in the callback' do
453
- assert_equal ['myfilter'], @book.percolated
454
- end
455
- end
456
- context 'percolating a non-persisted object' do
457
- setup do
458
- @matches = Book.new(:title => 'foo').percolate
459
- end
460
- should 'return percolated matches' do
461
- assert_equal ['myfilter'], @matches
462
- end
463
- end
464
- context "with multiple percolators" do
465
- setup do
466
- ElasticSearchable.request :put, '/_percolator/elastic_searchable/greenfilter', :json_body => { :color => 'green', :query => {:query_string => {:query => 'foo' }}}
467
- ElasticSearchable.request :put, '/_percolator/elastic_searchable/bluefilter', :json_body => { :color => 'blue', :query => {:query_string => {:query => 'foo' }}}
468
- ElasticSearchable.request :post, '/_percolator/_refresh'
469
- end
470
- context 'percolating a non-persisted object with no limitation' do
471
- setup do
472
- @matches = Book.new(:title => 'foo').percolate
473
- end
474
- should 'return all percolated matches' do
475
- assert_equal ['bluefilter','greenfilter','myfilter'], @matches.sort
476
- end
477
- end
478
- context 'percolating a non-persisted object with limitations' do
479
- setup do
480
- @matches = Book.new(:title => 'foo').percolate( { :term => { :color => 'green' }} )
481
- end
482
- should 'return limited percolated matches' do
483
- assert_equal ['greenfilter'], @matches
484
- end
485
- end
486
- end
487
- end
488
- end
489
- end
490
-
491
- class MaxPageSizeClass < ActiveRecord::Base
492
- elastic_searchable :index_options => SINGLE_NODE_CLUSTER_CONFIG
493
- def self.max_per_page
494
- 1
495
- end
496
- end
497
- context 'with 2 MaxPageSizeClass instances' do
498
- setup do
499
- MaxPageSizeClass.create_index
500
- @first = MaxPageSizeClass.create! :name => 'foo one'
501
- @second = MaxPageSizeClass.create! :name => 'foo two'
502
- MaxPageSizeClass.refresh_index
503
- end
504
- context 'MaxPageSizeClass.search with default options and WillPaginate' do
505
- setup do
506
- ElasticSearchable::Paginator.handler = ElasticSearchable::Pagination::WillPaginate
507
- @results = MaxPageSizeClass.search 'foo'
508
- end
509
- should 'have one per page' do
510
- assert_equal 1, @results.per_page
511
- end
512
- should 'return one instance' do
513
- assert_equal 1, @results.length
514
- end
515
- should 'have second page' do
516
- assert_equal 2, @results.total_entries
517
- end
518
- end
519
-
520
- context 'MaxPageSizeClass.search with default options and Kaminari' do
521
- setup do
522
- ElasticSearchable::Paginator.handler = ElasticSearchable::Pagination::Kaminari
523
- @results = MaxPageSizeClass.search 'foo'
524
- end
525
- should 'have one per page' do
526
- assert_equal 1, @results.per_page
527
- end
528
- should 'return one instance' do
529
- assert_equal 1, @results.length
530
- end
531
- should 'have second page' do
532
- assert_equal 2, @results.total_entries
533
- end
534
- should 'have a total of 2 pages' do
535
- assert_equal 2, @results.num_pages
536
- end
537
- end
538
-
539
- context "escape_query" do
540
- should "escape exclamation marks" do
541
- queryString = '!'
542
- result = ElasticSearchable.escape_query(queryString)
543
- assert_equal '\!', result
544
- end
545
-
546
- should "escape ^" do
547
- queryString = '^'
548
- result = ElasticSearchable.escape_query(queryString)
549
- assert_equal '\^', result
550
- end
551
-
552
- should "escape +" do
553
- queryString = '+'
554
- result = ElasticSearchable.escape_query(queryString)
555
- assert_equal '\+', result
556
- end
557
-
558
- should "escape -" do
559
- queryString = '-'
560
- result = ElasticSearchable.escape_query(queryString)
561
- assert_equal '\-', result
562
- end
563
-
564
- should "escape (" do
565
- queryString = '('
566
- result = ElasticSearchable.escape_query(queryString)
567
- assert_equal '\(', result
568
- end
569
-
570
- should "escape )" do
571
- queryString = ')'
572
- result = ElasticSearchable.escape_query(queryString)
573
- assert_equal '\)', result
574
- end
575
-
576
- should "escape {" do
577
- queryString = '}'
578
- result = ElasticSearchable.escape_query(queryString)
579
- assert_equal '\}', result
580
- end
581
-
582
- should "escape [" do
583
- queryString = '['
584
- result = ElasticSearchable.escape_query(queryString)
585
- assert_equal '\[', result
586
- end
587
-
588
- should "escape ]" do
589
- queryString = ']'
590
- result = ElasticSearchable.escape_query(queryString)
591
- assert_equal '\]', result
592
- end
593
-
594
- should 'escape "' do
595
- queryString = '"'
596
- result = ElasticSearchable.escape_query(queryString)
597
- assert_equal '\"', result
598
- end
599
-
600
- should "escape ~" do
601
- queryString = '~'
602
- result = ElasticSearchable.escape_query(queryString)
603
- assert_equal '\~', result
604
- end
605
-
606
- should "escape *" do
607
- queryString = '*'
608
- result = ElasticSearchable.escape_query(queryString)
609
- assert_equal '\*', result
610
- end
611
-
612
- should "escape :" do
613
- queryString = ':'
614
- result = ElasticSearchable.escape_query(queryString)
615
- assert_equal '\:', result
616
- end
617
-
618
- should "escape ?" do
619
- queryString = '?'
620
- result = ElasticSearchable.escape_query(queryString)
621
- assert_equal '\?', result
622
- end
623
- end
624
- end
625
- end
626
-