search_flip 2.0.0.beta2 → 2.0.0.beta3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +10 -3
- data/README.md +22 -1
- data/UPDATING.md +21 -5
- data/lib/search_flip/bulk.rb +5 -2
- data/lib/search_flip/connection.rb +29 -19
- data/lib/search_flip/criteria.rb +48 -18
- data/lib/search_flip/http_client.rb +27 -26
- data/lib/search_flip/index.rb +6 -4
- data/lib/search_flip/response.rb +9 -1
- data/lib/search_flip/version.rb +1 -1
- data/search_flip.gemspec +7 -2
- data/spec/delegate_matcher.rb +32 -0
- data/spec/search_flip/aggregation_spec.rb +265 -0
- data/spec/search_flip/bulk_spec.rb +78 -0
- data/spec/search_flip/connection_spec.rb +211 -0
- data/spec/search_flip/criteria_spec.rb +1028 -0
- data/spec/search_flip/http_client_spec.rb +67 -0
- data/spec/search_flip/index_spec.rb +455 -0
- data/spec/search_flip/model_spec.rb +44 -0
- data/spec/search_flip/response_spec.rb +185 -0
- data/spec/search_flip/to_json_spec.rb +29 -0
- data/{test/test_helper.rb → spec/spec_helper.rb} +13 -76
- metadata +30 -39
- data/test/search_flip/aggregation_test.rb +0 -230
- data/test/search_flip/bulk_test.rb +0 -55
- data/test/search_flip/connection_test.rb +0 -161
- data/test/search_flip/criteria_test.rb +0 -879
- data/test/search_flip/http_client_test.rb +0 -35
- data/test/search_flip/index_test.rb +0 -451
- data/test/search_flip/model_test.rb +0 -39
- data/test/search_flip/response_test.rb +0 -137
- data/test/search_flip/to_json_test.rb +0 -30
@@ -0,0 +1,67 @@
|
|
1
|
+
|
2
|
+
require File.expand_path("../spec_helper", __dir__)
|
3
|
+
|
4
|
+
class HttpTestRequest
|
5
|
+
attr_accessor :calls
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
self.calls = []
|
9
|
+
end
|
10
|
+
|
11
|
+
[:via, :basic_auth, :auth].each do |method|
|
12
|
+
define_method method do |*args|
|
13
|
+
dup.tap do |request|
|
14
|
+
request.calls = calls + [[method, args]]
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
RSpec.describe SearchFlip::HTTPClient do
|
21
|
+
describe "delegation" do
|
22
|
+
subject { SearchFlip::HTTPClient }
|
23
|
+
|
24
|
+
[:headers, :via, :basic_auth, :auth].each do |method|
|
25
|
+
it { should delegate(method).to(:new) }
|
26
|
+
end
|
27
|
+
|
28
|
+
[:get, :post, :put, :delete, :head].each do |method|
|
29
|
+
it { should delegate(method).to(:new) }
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
[:get, :put, :delete, :post, :head].each do |method|
|
34
|
+
describe "##{method}" do
|
35
|
+
it "performs the specified request" do
|
36
|
+
stub_request(method, "http://localhost/path").with(body: "body", query: { key: "value" }).to_return(body: "success")
|
37
|
+
|
38
|
+
expect(SearchFlip::HTTPClient.new.send(method, "http://localhost/path", body: "body", params: { key: "value" }).body.to_s).to eq("success")
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
[:via, :basic_auth, :auth].each do |method|
|
44
|
+
describe "##{method}" do
|
45
|
+
it "creates a dupped instance" do
|
46
|
+
client = SearchFlip::HTTPClient.new
|
47
|
+
client.request = HttpTestRequest.new
|
48
|
+
|
49
|
+
client1 = client.send(method, "key1")
|
50
|
+
client2 = client1.send(method, "key2")
|
51
|
+
|
52
|
+
expect(client1.object_id).not_to eq(client2.object_id)
|
53
|
+
end
|
54
|
+
|
55
|
+
it "extends the request" do
|
56
|
+
client = SearchFlip::HTTPClient.new
|
57
|
+
client.request = HttpTestRequest.new
|
58
|
+
|
59
|
+
client1 = client.send(method, "key1")
|
60
|
+
client2 = client1.send(method, "key2")
|
61
|
+
|
62
|
+
expect(client1.request.calls).to eq([[method, ["key1"]]])
|
63
|
+
expect(client2.request.calls).to eq([[method, ["key1"]], [method, ["key2"]]])
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,455 @@
|
|
1
|
+
|
2
|
+
require File.expand_path("../spec_helper", __dir__)
|
3
|
+
|
4
|
+
RSpec.describe SearchFlip::Index do
|
5
|
+
describe "delegation" do
|
6
|
+
subject { ProductIndex }
|
7
|
+
|
8
|
+
methods = [
|
9
|
+
:profile, :where, :where_not, :filter, :range, :match_all, :exists,
|
10
|
+
:exists_not, :post_where, :post_where_not, :post_filter, :post_must,
|
11
|
+
:post_must_not, :post_should, :post_range, :post_exists, :post_exists_not,
|
12
|
+
:aggregate, :scroll, :source, :includes, :eager_load, :preload, :sort, :resort,
|
13
|
+
:order, :reorder, :offset, :limit, :paginate, :page, :per, :search,
|
14
|
+
:find_in_batches, :highlight, :suggest, :custom, :find_each, :failsafe,
|
15
|
+
:total_entries, :total_count, :terminate_after, :timeout, :records, :results,
|
16
|
+
:should, :should_not, :must, :must_not, :find_each_result,
|
17
|
+
:find_results_in_batches
|
18
|
+
]
|
19
|
+
|
20
|
+
methods.each do |method|
|
21
|
+
it { should delegate(method).to(:criteria) }
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe ".serialize" do
|
26
|
+
it "raises a SearchFlip::MethodNotImplemented by default" do
|
27
|
+
klass = Class.new do
|
28
|
+
include SearchFlip::Index
|
29
|
+
end
|
30
|
+
|
31
|
+
expect { klass.serialize(Object.new) }.to raise_error(SearchFlip::MethodNotImplemented)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe ".type_name" do
|
36
|
+
it "raises a SearchFlip::MethodNotImplemented by default" do
|
37
|
+
klass = Class.new do
|
38
|
+
include SearchFlip::Index
|
39
|
+
end
|
40
|
+
|
41
|
+
expect { klass.type_name }.to raise_error(SearchFlip::MethodNotImplemented)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe ".create_index" do
|
46
|
+
it "delegates to connection" do
|
47
|
+
allow(TestIndex.connection).to receive(:create_index).and_call_original
|
48
|
+
|
49
|
+
TestIndex.create_index
|
50
|
+
|
51
|
+
expect(TestIndex.connection).to have_received(:create_index).with("test", {})
|
52
|
+
end
|
53
|
+
|
54
|
+
it "includes the mapping if specified" do
|
55
|
+
mapping = { test: { properties: { id: { type: "long" } } } }
|
56
|
+
|
57
|
+
allow(TestIndex).to receive(:mapping).and_return(mapping)
|
58
|
+
allow(TestIndex.connection).to receive(:create_index).and_call_original
|
59
|
+
|
60
|
+
TestIndex.create_index(include_mapping: true)
|
61
|
+
|
62
|
+
expect(TestIndex.connection).to have_received(:create_index).with("test", mappings: mapping)
|
63
|
+
end
|
64
|
+
|
65
|
+
it "includes the index settings" do
|
66
|
+
allow(TestIndex).to receive(:index_settings).and_return(number_of_shards: 2)
|
67
|
+
allow(TestIndex.connection).to receive(:create_index).and_call_original
|
68
|
+
|
69
|
+
TestIndex.create_index
|
70
|
+
|
71
|
+
expect(TestIndex.connection).to have_received(:create_index).with("test", number_of_shards: 2)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
describe ".index_exists?" do
|
76
|
+
it "delegates to connection" do
|
77
|
+
TestIndex.create_index
|
78
|
+
|
79
|
+
allow(TestIndex.connection).to receive(:index_exists?).and_call_original
|
80
|
+
|
81
|
+
TestIndex.index_exists?
|
82
|
+
|
83
|
+
expect(TestIndex.connection).to have_received(:index_exists?).with("test")
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
describe ".delete_index" do
|
88
|
+
it "delegates to connection" do
|
89
|
+
TestIndex.create_index
|
90
|
+
|
91
|
+
expect(TestIndex.index_exists?).to eq(true)
|
92
|
+
|
93
|
+
allow(TestIndex.connection).to receive(:delete_index).and_call_original
|
94
|
+
|
95
|
+
TestIndex.delete_index
|
96
|
+
|
97
|
+
expect(TestIndex.index_exists?).to eq(false)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
describe ".get_index_settings" do
|
102
|
+
it "delegates to connection" do
|
103
|
+
TestIndex.create_index
|
104
|
+
|
105
|
+
allow(TestIndex.connection).to receive(:get_index_settings).and_call_original
|
106
|
+
|
107
|
+
TestIndex.get_index_settings
|
108
|
+
|
109
|
+
expect(TestIndex.connection).to have_received(:get_index_settings).with("test")
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
describe ".update_index_settings" do
|
114
|
+
it "delegates to connection" do
|
115
|
+
TestIndex.create_index
|
116
|
+
|
117
|
+
allow(TestIndex).to receive(:index_settings).and_return(number_of_replicas: 3)
|
118
|
+
allow(TestIndex.connection).to receive(:update_index_settings).and_call_original
|
119
|
+
|
120
|
+
TestIndex.update_index_settings
|
121
|
+
|
122
|
+
expect(TestIndex.connection).to have_received(:update_index_settings).with("test", number_of_replicas: 3)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
describe ".update_mapping" do
|
127
|
+
it "delegates to connection" do
|
128
|
+
TestIndex.create_index
|
129
|
+
|
130
|
+
mapping = { test: { properties: { id: { type: "long" } } } }
|
131
|
+
|
132
|
+
allow(TestIndex).to receive(:mapping).and_return(mapping)
|
133
|
+
allow(TestIndex.connection).to receive(:update_mapping).and_call_original
|
134
|
+
|
135
|
+
TestIndex.update_mapping
|
136
|
+
|
137
|
+
expect(TestIndex.connection).to have_received(:update_mapping).with("test", "test", mapping)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
describe ".get_mapping" do
|
142
|
+
it "delegates to connection" do
|
143
|
+
TestIndex.create_index
|
144
|
+
TestIndex.update_mapping
|
145
|
+
|
146
|
+
allow(TestIndex.connection).to receive(:get_mapping).and_call_original
|
147
|
+
|
148
|
+
TestIndex.get_mapping
|
149
|
+
|
150
|
+
expect(TestIndex.connection).to have_received(:get_mapping).with("test", "test")
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
describe ".refresh" do
|
155
|
+
it "delegates to connection" do
|
156
|
+
TestIndex.create_index
|
157
|
+
|
158
|
+
allow(TestIndex.connection).to receive(:refresh).and_call_original
|
159
|
+
|
160
|
+
TestIndex.refresh
|
161
|
+
|
162
|
+
expect(TestIndex.connection).to have_received(:refresh).with("test")
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
describe ".index_url" do
|
167
|
+
it "delegates to connection" do
|
168
|
+
allow(TestIndex.connection).to receive(:index_url).and_call_original
|
169
|
+
|
170
|
+
TestIndex.index_url
|
171
|
+
|
172
|
+
expect(TestIndex.connection).to have_received(:index_url).with("test")
|
173
|
+
end
|
174
|
+
|
175
|
+
it "includes the index prefix" do
|
176
|
+
begin
|
177
|
+
SearchFlip::Config[:index_prefix] = "prefix-"
|
178
|
+
|
179
|
+
allow(TestIndex.connection).to receive(:index_url).and_call_original
|
180
|
+
|
181
|
+
TestIndex.index_url
|
182
|
+
|
183
|
+
expect(TestIndex.connection).to have_received(:index_url).with("prefix-test")
|
184
|
+
ensure
|
185
|
+
SearchFlip::Config[:index_prefix] = nil
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
describe ".type_url" do
|
191
|
+
it "delegates to connection" do
|
192
|
+
allow(TestIndex.connection).to receive(:type_url).and_call_original
|
193
|
+
|
194
|
+
TestIndex.type_url
|
195
|
+
|
196
|
+
expect(TestIndex.connection).to have_received(:type_url).with("test", "test")
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
describe ".import" do
|
201
|
+
it "imports an object" do
|
202
|
+
expect { ProductIndex.import create(:product) }.to(change { ProductIndex.total_count }.by(1))
|
203
|
+
end
|
204
|
+
|
205
|
+
it "imports an array of objects" do
|
206
|
+
expect { ProductIndex.import [create(:product), create(:product)] }.to(change { ProductIndex.total_count }.by(2))
|
207
|
+
end
|
208
|
+
|
209
|
+
it "imports a scope" do
|
210
|
+
create_list :product, 2
|
211
|
+
|
212
|
+
expect { ProductIndex.import Product.all }.to(change { ProductIndex.total_count }.by(2))
|
213
|
+
end
|
214
|
+
|
215
|
+
it "allows param options" do
|
216
|
+
products = create_list(:product, 2)
|
217
|
+
|
218
|
+
expect { ProductIndex.import products, {}, version: 1, version_type: "external" }.to(change { ProductIndex.total_count }.by(2))
|
219
|
+
expect { ProductIndex.import products, {}, version: 2, version_type: "external" }.not_to(change { ProductIndex.total_count })
|
220
|
+
expect { ProductIndex.import products, { ignore_errors: [409] }, version: 2, version_type: "external" }.not_to(change { ProductIndex.total_count })
|
221
|
+
expect { ProductIndex.import products, {}, version: 2, version_type: "external" }.to raise_error(SearchFlip::Bulk::Error)
|
222
|
+
end
|
223
|
+
|
224
|
+
it "passes param options" do
|
225
|
+
product = create(:product)
|
226
|
+
|
227
|
+
ProductIndex.import product, {}, version: 10, version_type: "external"
|
228
|
+
|
229
|
+
expect(ProductIndex.get(product.id)["_version"]).to eq(10)
|
230
|
+
end
|
231
|
+
|
232
|
+
it "passes class options" do
|
233
|
+
product = create(:product)
|
234
|
+
|
235
|
+
allow(ProductIndex).to receive(:index_options).and_return(version: 10, version_type: "external")
|
236
|
+
|
237
|
+
ProductIndex.import product
|
238
|
+
|
239
|
+
expect(ProductIndex.get(product.id)["_version"]).to eq(10)
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
|
+
describe ".index" do
|
244
|
+
it "indexes an object" do
|
245
|
+
expect { ProductIndex.index create(:product) }.to(change { ProductIndex.total_count }.by(1))
|
246
|
+
end
|
247
|
+
|
248
|
+
it "indexes an array of objects" do
|
249
|
+
expect { ProductIndex.index [create(:product), create(:product)] }.to(change { ProductIndex.total_count }.by(2))
|
250
|
+
end
|
251
|
+
|
252
|
+
it "indexes a scope" do
|
253
|
+
create_list :product, 2
|
254
|
+
|
255
|
+
expect { ProductIndex.index Product.all }.to(change { ProductIndex.total_count }.by(2))
|
256
|
+
end
|
257
|
+
end
|
258
|
+
|
259
|
+
describe ".create" do
|
260
|
+
it "creates an object" do
|
261
|
+
product = create(:product)
|
262
|
+
|
263
|
+
expect { ProductIndex.create product }.to(change { ProductIndex.total_count }.by(1))
|
264
|
+
expect { ProductIndex.create product }.to raise_error(SearchFlip::Bulk::Error)
|
265
|
+
end
|
266
|
+
|
267
|
+
it "create an array of objects" do
|
268
|
+
products = create_list(:product, 2)
|
269
|
+
|
270
|
+
expect { ProductIndex.create products }.to(change { ProductIndex.total_count }.by(2))
|
271
|
+
expect { ProductIndex.create products }.to raise_error(SearchFlip::Bulk::Error)
|
272
|
+
end
|
273
|
+
|
274
|
+
it "creates a scope of objects" do
|
275
|
+
create_list(:product, 2)
|
276
|
+
|
277
|
+
expect { ProductIndex.create Product.all }.to(change { ProductIndex.total_count }.by(2))
|
278
|
+
expect { ProductIndex.create Product.all }.to raise_error(SearchFlip::Bulk::Error)
|
279
|
+
end
|
280
|
+
|
281
|
+
it "allows respects param options" do
|
282
|
+
products = create_list(:product, 2)
|
283
|
+
|
284
|
+
expect { ProductIndex.create products }.to(change { ProductIndex.total_count }.by(2))
|
285
|
+
expect { ProductIndex.create products, ignore_errors: [409] }.not_to(change { ProductIndex.total_count })
|
286
|
+
|
287
|
+
products = create_list(:product, 2)
|
288
|
+
|
289
|
+
if ProductIndex.connection.version.to_i >= 5
|
290
|
+
expect { ProductIndex.create products, {}, routing: "r1" }.to(change { ProductIndex.total_count }.by(2))
|
291
|
+
|
292
|
+
expect(ProductIndex.get(products.first.id, routing: "r1")["_routing"]).to eq("r1")
|
293
|
+
else
|
294
|
+
expect { ProductIndex.create products, {}, version: 2, version_type: "external" }.to(change { ProductIndex.total_count }.by(2))
|
295
|
+
|
296
|
+
expect(ProductIndex.get(products.first.id)["_version"]).to eq(2)
|
297
|
+
end
|
298
|
+
end
|
299
|
+
|
300
|
+
it "allows respects class options" do
|
301
|
+
products = create_list(:product, 2)
|
302
|
+
|
303
|
+
if ProductIndex.connection.version.to_i >= 5
|
304
|
+
allow(ProductIndex).to receive(:index_options).and_return(routing: "r1")
|
305
|
+
|
306
|
+
expect { ProductIndex.create products }.to(change { ProductIndex.total_count }.by(2))
|
307
|
+
|
308
|
+
expect(ProductIndex.get(products.first.id, routing: "r1")["_routing"]).to eq("r1")
|
309
|
+
else
|
310
|
+
allow(ProductIndex).to receive(:index_options).and_return(version: 2, version_type: "external")
|
311
|
+
|
312
|
+
expect { ProductIndex.create products }.to(change { ProductIndex.total_count }.by(2))
|
313
|
+
|
314
|
+
expect(ProductIndex.get(products.first.id)["_version"]).to eq(2)
|
315
|
+
end
|
316
|
+
end
|
317
|
+
end
|
318
|
+
|
319
|
+
describe ".update" do
|
320
|
+
it "updates an object" do
|
321
|
+
product = create(:product)
|
322
|
+
|
323
|
+
ProductIndex.import product
|
324
|
+
|
325
|
+
expect { ProductIndex.update product }.not_to(change { ProductIndex.total_count })
|
326
|
+
end
|
327
|
+
|
328
|
+
it "updates an array of objects" do
|
329
|
+
products = create_list(:product, 2)
|
330
|
+
|
331
|
+
ProductIndex.import products
|
332
|
+
|
333
|
+
expect { ProductIndex.update products }.not_to(change { ProductIndex.total_count })
|
334
|
+
end
|
335
|
+
|
336
|
+
it "updates a scope of objects" do
|
337
|
+
products = create_list(:product, 2)
|
338
|
+
|
339
|
+
ProductIndex.import products
|
340
|
+
|
341
|
+
expect { ProductIndex.update Product.all }.not_to(change { ProductIndex.total_count })
|
342
|
+
end
|
343
|
+
end
|
344
|
+
|
345
|
+
describe ".delete" do
|
346
|
+
it "deletes an object" do
|
347
|
+
product = create(:product)
|
348
|
+
|
349
|
+
ProductIndex.import product
|
350
|
+
|
351
|
+
expect { ProductIndex.delete product }.to(change { ProductIndex.total_count }.by(-1))
|
352
|
+
end
|
353
|
+
|
354
|
+
it "deletes an array of objects" do
|
355
|
+
products = create_list(:product, 2)
|
356
|
+
|
357
|
+
ProductIndex.import products
|
358
|
+
|
359
|
+
expect { ProductIndex.delete products }.to(change { ProductIndex.total_count }.by(-2))
|
360
|
+
end
|
361
|
+
|
362
|
+
it "deletes a scope of objects" do
|
363
|
+
products = create_list(:product, 2)
|
364
|
+
|
365
|
+
ProductIndex.import products
|
366
|
+
|
367
|
+
expect { ProductIndex.delete Product.all }.to(change { ProductIndex.total_count }.by(-2))
|
368
|
+
end
|
369
|
+
end
|
370
|
+
|
371
|
+
describe ".get" do
|
372
|
+
it "retrieves the document" do
|
373
|
+
product = create(:product)
|
374
|
+
|
375
|
+
ProductIndex.import product
|
376
|
+
|
377
|
+
expect(ProductIndex.get(product.id)["_id"]).to eq(product.id.to_s)
|
378
|
+
end
|
379
|
+
|
380
|
+
it "passes params" do
|
381
|
+
product = create(:product)
|
382
|
+
ProductIndex.import product
|
383
|
+
|
384
|
+
expect(ProductIndex.get(product.id).keys).to include("_source")
|
385
|
+
expect(ProductIndex.get(product.id, _source: false).keys).not_to include("_source")
|
386
|
+
end
|
387
|
+
end
|
388
|
+
|
389
|
+
describe ".scope" do
|
390
|
+
it "adds a scope" do
|
391
|
+
temp_product_index = Class.new(ProductIndex)
|
392
|
+
temp_product_index.scope(:with_title) { |title| where(title: title) }
|
393
|
+
|
394
|
+
expected = create(:product, title: "expected")
|
395
|
+
rejected = create(:product, title: "rejected")
|
396
|
+
|
397
|
+
temp_product_index.import [expected, rejected]
|
398
|
+
|
399
|
+
results = temp_product_index.with_title("expected").records
|
400
|
+
|
401
|
+
expect(results).to eq([expected])
|
402
|
+
end
|
403
|
+
end
|
404
|
+
|
405
|
+
describe ".bulk" do
|
406
|
+
it "imports objects" do
|
407
|
+
bulk = proc do
|
408
|
+
ProductIndex.bulk do |indexer|
|
409
|
+
indexer.index 1, id: 1
|
410
|
+
indexer.index 2, id: 2
|
411
|
+
end
|
412
|
+
end
|
413
|
+
|
414
|
+
expect(&bulk).to(change { ProductIndex.total_count }.by(2))
|
415
|
+
end
|
416
|
+
|
417
|
+
it "respects options" do
|
418
|
+
ProductIndex.bulk do |indexer|
|
419
|
+
indexer.index 1, id: 1
|
420
|
+
indexer.index 2, id: 2
|
421
|
+
end
|
422
|
+
|
423
|
+
bulk = proc do
|
424
|
+
ProductIndex.bulk do |indexer|
|
425
|
+
indexer.index 1, { id: 1 }, version: 1, version_type: "external"
|
426
|
+
indexer.index 2, { id: 2 }, version: 1, version_type: "external"
|
427
|
+
end
|
428
|
+
end
|
429
|
+
|
430
|
+
expect(&bulk).to raise_error(SearchFlip::Bulk::Error)
|
431
|
+
|
432
|
+
bulk = proc do
|
433
|
+
ProductIndex.bulk ignore_errors: [409] do |indexer|
|
434
|
+
indexer.index 1, { id: 1 }, version: 1, version_type: "external"
|
435
|
+
indexer.index 2, { id: 2 }, version: 1, version_type: "external"
|
436
|
+
end
|
437
|
+
end
|
438
|
+
|
439
|
+
expect(&bulk).not_to(change { ProductIndex.total_count })
|
440
|
+
end
|
441
|
+
end
|
442
|
+
|
443
|
+
describe ".connection" do
|
444
|
+
it "returns a SearchFlip::Connection" do
|
445
|
+
expect(ProductIndex.connection).to be_instance_of(SearchFlip::Connection)
|
446
|
+
end
|
447
|
+
|
448
|
+
it "memoizes" do
|
449
|
+
connection = ProductIndex.connection
|
450
|
+
|
451
|
+
expect(ProductIndex.connection).to equal(connection)
|
452
|
+
end
|
453
|
+
end
|
454
|
+
end
|
455
|
+
|
@@ -0,0 +1,44 @@
|
|
1
|
+
|
2
|
+
require File.expand_path("../spec_helper", __dir__)
|
3
|
+
|
4
|
+
class TestProduct < Product
|
5
|
+
include SearchFlip::Model
|
6
|
+
|
7
|
+
notifies_index(ProductIndex)
|
8
|
+
end
|
9
|
+
|
10
|
+
RSpec.describe SearchFlip::Model do
|
11
|
+
describe "#save" do
|
12
|
+
it "imports the record to the index" do
|
13
|
+
expect(ProductIndex.total_count).to eq(0)
|
14
|
+
|
15
|
+
TestProduct.create!
|
16
|
+
|
17
|
+
expect(ProductIndex.total_count).to eq(1)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe "#destroy" do
|
22
|
+
it "delete the record from the index" do
|
23
|
+
test_product = TestProduct.create!
|
24
|
+
|
25
|
+
expect(ProductIndex.total_count).to eq(1)
|
26
|
+
|
27
|
+
test_product.destroy
|
28
|
+
|
29
|
+
expect(ProductIndex.total_count).to eq(0)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "#touch" do
|
34
|
+
it "imports the record to the index" do
|
35
|
+
test_product = Timecop.freeze(Time.parse("2016-01-01 12:00:00")) { TestProduct.create! }
|
36
|
+
|
37
|
+
updated_at = ProductIndex.match_all.results.first.updated_at
|
38
|
+
|
39
|
+
Timecop.freeze(Time.parse("2017-01-01 12:00:00")) { test_product.touch }
|
40
|
+
|
41
|
+
expect(ProductIndex.match_all.results.first.updated_at).not_to eq(updated_at)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|