search_flip 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,825 @@
1
+
2
+ require File.expand_path("../../test_helper", __FILE__)
3
+
4
+ class SearchFlip::CriteriaTest < SearchFlip::TestCase
5
+ should_delegate_methods :total_entries, :current_page, :previous_page, :prev_page, :next_page, :first_page?, :last_page?, :out_of_range?,
6
+ :total_pages, :hits, :ids, :count, :size, :length, :took, :aggregations, :suggestions, :scope, :results, :records, :scroll_id, :raw_response,
7
+ to: :response, subject: SearchFlip::Criteria.new(target: ProductIndex)
8
+
9
+ def test_merge
10
+ product1 = create(:product, price: 100, category: "category1")
11
+ product2 = create(:product, price: 200, category: "category2")
12
+ product3 = create(:product, price: 300, category: "category1")
13
+
14
+ ProductIndex.import [product1, product2, product3]
15
+
16
+ query = ProductIndex.where(price: 50 .. 250).aggregate(:category).merge(ProductIndex.where(category: "category1"))
17
+
18
+ assert_includes query.records, product1
19
+ refute_includes query.records, product2
20
+ refute_includes query.records, product3
21
+ end
22
+
23
+ def test_criteria
24
+ criteria = ProductIndex.criteria
25
+
26
+ assert criteria.criteria === criteria
27
+ end
28
+
29
+ def test_timeout
30
+ query = ProductIndex.timeout("1s")
31
+
32
+ assert_equal "1s", query.request[:timeout]
33
+
34
+ query.execute
35
+ end
36
+
37
+ def test_terminate_after
38
+ query = ProductIndex.terminate_after(1)
39
+
40
+ assert_equal 1, query.request[:terminate_after]
41
+
42
+ query.execute
43
+ end
44
+
45
+ def test_where
46
+ product1 = create(:product, price: 100, category: "category1")
47
+ product2 = create(:product, price: 200, category: "category2")
48
+ product3 = create(:product, price: 300, category: "category1")
49
+
50
+ ProductIndex.import [product1, product2, product3]
51
+
52
+ query1 = ProductIndex.where(price: 100 .. 200)
53
+ query2 = query1.where(category: "category1")
54
+
55
+ assert_includes query1.records, product1
56
+ assert_includes query1.records, product2
57
+ refute_includes query1.records, product3
58
+
59
+ assert_includes query2.records, product1
60
+ refute_includes query2.records, product2
61
+ refute_includes query2.records, product3
62
+ end
63
+
64
+ def test_where_with_array
65
+ expected1 = create(:product, title: "expected1")
66
+ expected2 = create(:product, title: "expected2")
67
+ rejected = create(:product, title: "rejected")
68
+
69
+ ProductIndex.import [expected1, expected2, rejected]
70
+
71
+ records = ProductIndex.where(title: ["expected1", "expected2"]).records
72
+
73
+ assert_includes records, expected1
74
+ assert_includes records, expected2
75
+ refute_includes records, rejected
76
+ end
77
+
78
+ def test_where_with_range
79
+ expected1 = create(:product, price: 100)
80
+ expected2 = create(:product, price: 200)
81
+ rejected = create(:product, price: 300)
82
+
83
+ ProductIndex.import [expected1, expected2, rejected]
84
+
85
+ records = ProductIndex.where(price: 100 .. 200).records
86
+
87
+ assert_includes records, expected1
88
+ assert_includes records, expected2
89
+ refute_includes records, rejected
90
+ end
91
+
92
+ def test_where_with_nil
93
+ expected = create(:product, price: nil)
94
+ rejected = create(:product, price: 100)
95
+
96
+ ProductIndex.import [expected, rejected]
97
+
98
+ records = ProductIndex.where(price: nil).records
99
+
100
+ assert_includes records, expected
101
+ refute_includes records, rejected
102
+ end
103
+
104
+ def test_where_not
105
+ product1 = create(:product, price: 100, category: "category1")
106
+ product2 = create(:product, price: 200, category: "category2")
107
+ product3 = create(:product, price: 300, category: "category1")
108
+
109
+ ProductIndex.import [product1, product2, product3]
110
+
111
+ query1 = ProductIndex.where_not(price: 250 .. 350)
112
+ query2 = query1.where_not(category: "category2")
113
+
114
+ assert_includes query1.records, product1
115
+ assert_includes query1.records, product2
116
+ refute_includes query1.records, product3
117
+
118
+ assert_includes query2.records, product1
119
+ refute_includes query2.records, product2
120
+ refute_includes query2.records, product3
121
+ end
122
+
123
+ def test_where_not_with_array
124
+ expected = create(:product, title: "expected")
125
+ rejected1 = create(:product, title: "rejected1")
126
+ rejected2 = create(:product, title: "rejected2")
127
+
128
+ ProductIndex.import [expected, rejected1, rejected2]
129
+
130
+ records = ProductIndex.where_not(title: ["rejected1", "rejected2"]).records
131
+
132
+ assert_includes records, expected
133
+ refute_includes records, rejected1
134
+ refute_includes records, rejected2
135
+ end
136
+
137
+ def test_where_not_with_range
138
+ expected = create(:product, price: 100)
139
+ rejected1 = create(:product, price: 200)
140
+ rejected2 = create(:product, price: 300)
141
+
142
+ ProductIndex.import [expected, rejected1, rejected2]
143
+
144
+ records = ProductIndex.where_not(price: 200 .. 300).records
145
+
146
+ assert_includes records, expected
147
+ refute_includes records, rejected1
148
+ refute_includes records, rejected2
149
+ end
150
+
151
+ def test_where_not_with_nil
152
+ expected = create(:product, price: 100)
153
+ rejected = create(:product, price: nil)
154
+
155
+ ProductIndex.import [expected, rejected]
156
+
157
+ records = ProductIndex.where_not(price: nil).records
158
+
159
+ assert_includes records, expected
160
+ refute_includes records, rejected
161
+ end
162
+
163
+ def test_filter
164
+ product1 = create(:product, price: 100, category: "category1")
165
+ product2 = create(:product, price: 200, category: "category2")
166
+ product3 = create(:product, price: 300, category: "category1")
167
+
168
+ ProductIndex.import [product1, product2, product3]
169
+
170
+ query1 = ProductIndex.filter(range: { price: { gte: 100, lte: 200 }})
171
+ query2 = query1.filter(term: { category: "category1" })
172
+
173
+ assert_includes query1.records, product1
174
+ assert_includes query1.records, product2
175
+ refute_includes query1.records, product3
176
+
177
+ assert_includes query2.records, product1
178
+ refute_includes query2.records, product2
179
+ refute_includes query2.records, product3
180
+ end
181
+
182
+ def test_range
183
+ product1 = create(:product, price: 100)
184
+ product2 = create(:product, price: 200)
185
+ product3 = create(:product, price: 300)
186
+
187
+ ProductIndex.import [product1, product2, product3]
188
+
189
+ query1 = ProductIndex.range(:price, gte: 100, lte: 200)
190
+ query2 = query1.range(:price, gte: 200, lte: 300)
191
+
192
+ assert_includes query1.records, product1
193
+ assert_includes query1.records, product2
194
+ refute_includes query1.records, product3
195
+
196
+ refute_includes query2.records, product1
197
+ assert_includes query2.records, product2
198
+ refute_includes query2.records, product3
199
+ end
200
+
201
+ def test_match_all
202
+ expected1 = create(:product)
203
+ expected2 = create(:product)
204
+
205
+ ProductIndex.import [expected1, expected2]
206
+
207
+ records = ProductIndex.match_all.records
208
+
209
+ assert_includes records, expected1
210
+ assert_includes records, expected2
211
+ end
212
+
213
+ def test_exists
214
+ product1 = create(:product, title: "title1", description: "description1")
215
+ product2 = create(:product, title: "title2", description: nil)
216
+ product3 = create(:product, title: nil, description: "description2")
217
+
218
+ ProductIndex.import [product1, product2, product3]
219
+
220
+ query1 = ProductIndex.exists(:title)
221
+ query2 = query1.exists(:description)
222
+
223
+ assert_includes query1.records, product1
224
+ assert_includes query1.records, product2
225
+ refute_includes query1.records, product3
226
+
227
+ assert_includes query2.records, product1
228
+ refute_includes query2.records, product2
229
+ refute_includes query2.records, product3
230
+ end
231
+
232
+ def test_exists_not
233
+ product1 = create(:product, title: nil, description: nil)
234
+ product2 = create(:product, title: nil, description: "description2")
235
+ product3 = create(:product, title: "title3", description: "description3")
236
+
237
+ ProductIndex.import [product1, product2, product3]
238
+
239
+ query1 = ProductIndex.exists_not(:title)
240
+ query2 = query1.exists_not(:description)
241
+
242
+ assert_includes query1.records, product1
243
+ assert_includes query1.records, product2
244
+ refute_includes query1.records, product3
245
+
246
+ assert_includes query2.records, product1
247
+ refute_includes query2.records, product2
248
+ refute_includes query2.records, product3
249
+ end
250
+
251
+ def test_post_search
252
+ return if SearchFlip.version.to_i < 2
253
+
254
+ product1 = create(:product, title: "title1", category: "category1")
255
+ product2 = create(:product, title: "title2", category: "category2")
256
+ product3 = create(:product, title: "title3", category: "category1")
257
+
258
+ ProductIndex.import [product1, product2, product3]
259
+
260
+ query1 = ProductIndex.aggregate(:category).post_search("title1 OR title2")
261
+ query2 = query1.post_search("category1")
262
+
263
+ assert_includes query1.records, product1
264
+ assert_includes query1.records, product2
265
+ refute_includes query1.records, product3
266
+
267
+ assert_includes query2.records, product1
268
+ refute_includes query2.records, product2
269
+ refute_includes query2.records, product3
270
+
271
+ assert_equal Hash["category1" => 2, "category2" => 1], query1.aggregations(:category).each_with_object({}) { |(key, agg), hash| hash[key] = agg.doc_count }
272
+ assert_equal Hash["category1" => 2, "category2" => 1], query2.aggregations(:category).each_with_object({}) { |(key, agg), hash| hash[key] = agg.doc_count }
273
+ end
274
+
275
+ def test_post_where
276
+ product1 = create(:product, price: 100, category: "category1")
277
+ product2 = create(:product, price: 200, category: "category2")
278
+ product3 = create(:product, price: 300, category: "category1")
279
+
280
+ ProductIndex.import [product1, product2, product3]
281
+
282
+ query1 = ProductIndex.aggregate(:category).post_where(price: 100 .. 200)
283
+ query2 = query1.post_where(category: "category1")
284
+
285
+ assert_includes query1.records, product1
286
+ assert_includes query1.records, product2
287
+ refute_includes query1.records, product3
288
+
289
+ assert_includes query2.records, product1
290
+ refute_includes query2.records, product2
291
+ refute_includes query2.records, product3
292
+
293
+ assert_equal Hash["category1" => 2, "category2" => 1], query1.aggregations(:category).each_with_object({}) { |(key, agg), hash| hash[key] = agg.doc_count }
294
+ assert_equal Hash["category1" => 2, "category2" => 1], query2.aggregations(:category).each_with_object({}) { |(key, agg), hash| hash[key] = agg.doc_count }
295
+ end
296
+
297
+ def test_post_where_with_array
298
+ expected1 = create(:product, title: "expected1", category: "category1")
299
+ expected2 = create(:product, title: "expected2", category: "category2")
300
+ rejected = create(:product, title: "rejected", category: "category1")
301
+
302
+ ProductIndex.import [expected1, expected2, rejected]
303
+
304
+ query = ProductIndex.aggregate(:category).post_where(title: ["expected1", "expected2"])
305
+
306
+ assert_includes query.records, expected1
307
+ assert_includes query.records, expected2
308
+ refute_includes query.records, rejected
309
+
310
+ assert_equal Hash["category1" => 2, "category2" => 1], query.aggregations(:category).each_with_object({}) { |(key, agg), hash| hash[key] = agg.doc_count }
311
+ end
312
+
313
+ def test_post_where_with_range
314
+ expected1 = create(:product, price: 100, category: "category1")
315
+ expected2 = create(:product, price: 200, category: "category2")
316
+ rejected = create(:product, price: 300, category: "category1")
317
+
318
+ ProductIndex.import [expected1, expected2, rejected]
319
+
320
+ query = ProductIndex.aggregate(:category).post_where(price: 100 .. 200)
321
+
322
+ assert_includes query.records, expected1
323
+ assert_includes query.records, expected2
324
+ refute_includes query.records, rejected
325
+
326
+ assert_equal Hash["category1" => 2, "category2" => 1], query.aggregations(:category).each_with_object({}) { |(key, agg), hash| hash[key] = agg.doc_count }
327
+ end
328
+
329
+ def test_post_where_not
330
+ product1 = create(:product, price: 100, category: "category1")
331
+ product2 = create(:product, price: 200, category: "category2")
332
+ product3 = create(:product, price: 300, category: "category1")
333
+
334
+ ProductIndex.import [product1, product2, product3]
335
+
336
+ query1 = ProductIndex.aggregate(:category).post_where_not(price: 250 .. 350)
337
+ query2 = query1.post_where_not(category: "category2")
338
+
339
+ assert_includes query1.records, product1
340
+ assert_includes query1.records, product2
341
+ refute_includes query1.records, product3
342
+
343
+ assert_includes query2.records, product1
344
+ refute_includes query2.records, product2
345
+ refute_includes query2.records, product3
346
+
347
+ assert_equal Hash["category1" => 2, "category2" => 1], query1.aggregations(:category).each_with_object({}) { |(key, agg), hash| hash[key] = agg.doc_count }
348
+ assert_equal Hash["category1" => 2, "category2" => 1], query2.aggregations(:category).each_with_object({}) { |(key, agg), hash| hash[key] = agg.doc_count }
349
+ end
350
+
351
+ def test_post_where_not_with_array
352
+ expected = create(:product, title: "expected", category: "category1")
353
+ rejected1 = create(:product, title: "rejected1", category: "category2")
354
+ rejected2 = create(:product, title: "rejected2", category: "category1")
355
+
356
+ ProductIndex.import [expected, rejected1, rejected2]
357
+
358
+ query = ProductIndex.aggregate(:category).post_where_not(title: ["rejected1", "rejected2"])
359
+
360
+ assert_includes query.records, expected
361
+ refute_includes query.records, rejected1
362
+ refute_includes query.records, rejected2
363
+
364
+ assert_equal Hash["category1" => 2, "category2" => 1], query.aggregations(:category).each_with_object({}) { |(key, agg), hash| hash[key] = agg.doc_count }
365
+ end
366
+
367
+ def test_post_where_not_with_range
368
+ expected = create(:product, price: 100, category: "category1")
369
+ rejected1 = create(:product, price: 200, category: "category2")
370
+ rejected2 = create(:product, price: 300, category: "category1")
371
+
372
+ ProductIndex.import [expected, rejected1, rejected2]
373
+
374
+ query = ProductIndex.aggregate(:category).post_where_not(price: 200 .. 300)
375
+
376
+ assert_includes query.records, expected
377
+ refute_includes query.records, rejected1
378
+ refute_includes query.records, rejected2
379
+
380
+ assert_equal Hash["category1" => 2, "category2" => 1], query.aggregations(:category).each_with_object({}) { |(key, agg), hash| hash[key] = agg.doc_count }
381
+ end
382
+
383
+ def test_post_filter
384
+ product1 = create(:product, price: 100, category: "category1")
385
+ product2 = create(:product, price: 200, category: "category2")
386
+ product3 = create(:product, price: 300, category: "category1")
387
+
388
+ ProductIndex.import [product1, product2, product3]
389
+
390
+ query1 = ProductIndex.aggregate(:category).post_filter(range: { price: { gte: 100, lte: 200 }})
391
+ query2 = query1.post_filter(term: { category: "category1" })
392
+
393
+ assert_includes query1.records, product1
394
+ assert_includes query1.records, product2
395
+ refute_includes query1.records, product3
396
+
397
+ assert_includes query2.records, product1
398
+ refute_includes query2.records, product2
399
+ refute_includes query2.records, product3
400
+
401
+ assert_equal Hash["category1" => 2, "category2" => 1], query1.aggregations(:category).each_with_object({}) { |(key, agg), hash| hash[key] = agg.doc_count }
402
+ assert_equal Hash["category1" => 2, "category2" => 1], query2.aggregations(:category).each_with_object({}) { |(key, agg), hash| hash[key] = agg.doc_count }
403
+ end
404
+
405
+ def test_post_range
406
+ product1 = create(:product, price: 100, category: "category1")
407
+ product2 = create(:product, price: 200, category: "category2")
408
+ product3 = create(:product, price: 300, category: "category1")
409
+
410
+ ProductIndex.import [product1, product2, product3]
411
+
412
+ query1 = ProductIndex.aggregate(:category).post_range(:price, gte: 100, lte: 200)
413
+ query2 = query1.post_range(:price, gte: 200, lte: 300)
414
+
415
+ assert_includes query1.records, product1
416
+ assert_includes query1.records, product2
417
+ refute_includes query1.records, product3
418
+
419
+ refute_includes query2.records, product1
420
+ assert_includes query2.records, product2
421
+ refute_includes query2.records, product3
422
+
423
+ assert_equal Hash["category1" => 2, "category2" => 1], query1.aggregations(:category).each_with_object({}) { |(key, agg), hash| hash[key] = agg.doc_count }
424
+ assert_equal Hash["category1" => 2, "category2" => 1], query2.aggregations(:category).each_with_object({}) { |(key, agg), hash| hash[key] = agg.doc_count }
425
+ end
426
+
427
+ def test_post_exists
428
+ product1 = create(:product, title: "title1", description: "description1", category: "category1")
429
+ product2 = create(:product, title: "title2", description: nil, category: "category2")
430
+ product3 = create(:product, title: nil, description: "description2", category: "category1")
431
+
432
+ ProductIndex.import [product1, product2, product3]
433
+
434
+ query1 = ProductIndex.aggregate(:category).post_exists(:title)
435
+ query2 = query1.post_exists(:description)
436
+
437
+ assert_includes query1.records, product1
438
+ assert_includes query1.records, product2
439
+ refute_includes query1.records, product3
440
+
441
+ assert_includes query2.records, product1
442
+ refute_includes query2.records, product2
443
+ refute_includes query2.records, product3
444
+
445
+ assert_equal Hash["category1" => 2, "category2" => 1], query1.aggregations(:category).each_with_object({}) { |(key, agg), hash| hash[key] = agg.doc_count }
446
+ assert_equal Hash["category1" => 2, "category2" => 1], query2.aggregations(:category).each_with_object({}) { |(key, agg), hash| hash[key] = agg.doc_count }
447
+ end
448
+
449
+ def test_post_exists_not
450
+ product1 = create(:product, title: nil, description: nil, category: "category1")
451
+ product2 = create(:product, title: nil, description: "description2", category: "category2")
452
+ product3 = create(:product, title: "title3", description: "description3", category: "category1")
453
+
454
+ ProductIndex.import [product1, product2, product3]
455
+
456
+ query1 = ProductIndex.aggregate(:category).post_exists_not(:title)
457
+ query2 = query1.post_exists_not(:description)
458
+
459
+ assert_includes query1.records, product1
460
+ assert_includes query1.records, product2
461
+ refute_includes query1.records, product3
462
+
463
+ assert_includes query2.records, product1
464
+ refute_includes query2.records, product2
465
+ refute_includes query2.records, product3
466
+
467
+ assert_equal Hash["category1" => 2, "category2" => 1], query1.aggregations(:category).each_with_object({}) { |(key, agg), hash| hash[key] = agg.doc_count }
468
+ assert_equal Hash["category1" => 2, "category2" => 1], query2.aggregations(:category).each_with_object({}) { |(key, agg), hash| hash[key] = agg.doc_count }
469
+ end
470
+
471
+ def test_aggregate
472
+ ProductIndex.import create_list(:product, 3, category: "category1", price: 10)
473
+ ProductIndex.import create_list(:product, 2, category: "category2", price: 20)
474
+ ProductIndex.import create_list(:product, 1, category: "category3", price: 30)
475
+
476
+ query = ProductIndex.aggregate(:category, size: 2).aggregate(price_sum: { sum: { field: "price" }})
477
+
478
+ category_aggregations = query.aggregations(:category).each_with_object({}) { |(key, agg), hash| hash[key] = agg.doc_count }
479
+ price_aggregation = query.aggregations(:price_sum).value
480
+
481
+ assert_equal Hash["category1" => 3, "category2" => 2], category_aggregations
482
+ assert_equal 100, price_aggregation
483
+ end
484
+
485
+ def test_aggregate_with_hash
486
+ ProductIndex.import create_list(:product, 3, category: "category1")
487
+ ProductIndex.import create_list(:product, 2, category: "category2")
488
+ ProductIndex.import create_list(:product, 1, category: "category3")
489
+
490
+ aggregations = ProductIndex.aggregate(category: { terms: { field: :category }}).aggregations(:category).each_with_object({}) { |(key, agg), hash| hash[key] = agg.doc_count }
491
+
492
+ assert_equal Hash["category1" => 3, "category2" => 2, "category3" => 1], aggregations
493
+ end
494
+
495
+ def test_aggregate_with_subaggregation
496
+ ProductIndex.import create_list(:product, 3, category: "category1", price: 15)
497
+ ProductIndex.import create_list(:product, 2, category: "category2", price: 20)
498
+ ProductIndex.import create_list(:product, 1, category: "category3", price: 25)
499
+
500
+ query = ProductIndex.aggregate(:category) do |aggregation|
501
+ aggregation.aggregate(price_sum: { sum: { field: "price" }})
502
+ end
503
+
504
+ category_aggregations = query.aggregations(:category).each_with_object({}) { |(key, agg), hash| hash[key] = agg.doc_count }
505
+ price_sum_aggregations = query.aggregations(:category).each_with_object({}) { |(key, agg), hash| hash[key] = agg.price_sum.value }
506
+
507
+ assert_equal Hash["category1" => 3, "category2" => 2, "category3" => 1], category_aggregations
508
+ assert_equal Hash["category1" => 45, "category2" => 40, "category3" => 25], price_sum_aggregations
509
+ end
510
+
511
+ def test_profile
512
+ return if SearchFlip.version.to_i < 2
513
+
514
+ assert_not_nil ProductIndex.profile(true).raw_response["profile"]
515
+ end
516
+
517
+ def test_scroll
518
+ products = create_list(:product, 15)
519
+
520
+ ProductIndex.import products
521
+
522
+ criteria = ProductIndex.limit(10).scroll(timeout: "1m")
523
+
524
+ result = []
525
+ iterations = 0
526
+
527
+ until criteria.records.empty?
528
+ result += criteria.records
529
+ iterations += 1
530
+
531
+ criteria = criteria.scroll(id: criteria.scroll_id, timeout: "1m")
532
+ end
533
+
534
+ assert_equal result.to_set, products.to_set
535
+ assert_equal 2, iterations
536
+ end
537
+
538
+ def test_delete
539
+ product1, product2, product3 = create_list(:product, 3)
540
+
541
+ ProductIndex.import [product1, product2, product3]
542
+
543
+ assert_difference "ProductIndex.total_entries", -2 do
544
+ ProductIndex.where(id: [product1.id, product2.id]).delete
545
+ end
546
+ end
547
+
548
+ def test_source
549
+ product = create(:product, title: "Title", price: 10)
550
+
551
+ ProductIndex.import product
552
+
553
+ results = ProductIndex.where(id: product.id).results
554
+
555
+ assert_present results.first.id
556
+ assert_equal "Title", results.first.title
557
+ assert_equal 10, results.first.price
558
+
559
+ results = ProductIndex.where(id: product.id).source([:id, :price]).results
560
+
561
+ assert_present results.first.id
562
+ assert_blank results.first.title
563
+ assert_present results.first.price
564
+ end
565
+
566
+ def test_includes
567
+ user = create(:user)
568
+ comments = create_list(:comment, 2)
569
+ product = create(:product, user: user, comments: comments)
570
+
571
+ ProductIndex.import product
572
+
573
+ record = ProductIndex.includes(:user).includes(:comments).records.first
574
+
575
+ assert_not_nil record
576
+ assert_equal user, record.user
577
+ assert_equal comments.to_set, record.comments.to_set
578
+ end
579
+
580
+ def test_eager_load
581
+ user = create(:user)
582
+ comments = create_list(:comment, 2)
583
+ product = create(:product, user: user, comments: comments)
584
+
585
+ ProductIndex.import product
586
+
587
+ record = ProductIndex.eager_load(:user).eager_load(:comments).records.first
588
+
589
+ assert_not_nil record
590
+ assert_equal user, record.user
591
+ assert_equal comments.to_set, record.comments.to_set
592
+ end
593
+
594
+ def test_preload
595
+ user = create(:user)
596
+ comments = create_list(:comment, 2)
597
+ product = create(:product, user: user, comments: comments)
598
+
599
+ ProductIndex.import product
600
+
601
+ record = ProductIndex.preload(:user).preload(:comments).records.first
602
+
603
+ assert_not_nil record
604
+ assert_equal user, record.user
605
+ assert_equal comments.to_set, record.comments.to_set
606
+ end
607
+
608
+ def test_sort
609
+ product1 = create(:product, rank: 2, price: 100)
610
+ product2 = create(:product, rank: 2, price: 90)
611
+ product3 = create(:product, rank: 1, price: 120)
612
+ product4 = create(:product, rank: 0, price: 110)
613
+
614
+ ProductIndex.import [product1, product2, product3, product4]
615
+
616
+ assert_equal [product2, product1, product3, product4], ProductIndex.sort({ rank: :desc }, { price: :asc }).records
617
+ assert_equal [product2, product1, product3, product4], ProductIndex.sort(rank: :desc).sort(:price).records
618
+ assert_equal [product2, product1, product4, product3], ProductIndex.sort(:price).sort(rank: :desc).records
619
+ end
620
+
621
+ def test_resort
622
+ product1 = create(:product, rank: 2, price: 100)
623
+ product2 = create(:product, rank: 2, price: 90)
624
+ product3 = create(:product, rank: 1, price: 120)
625
+ product4 = create(:product, rank: 0, price: 110)
626
+
627
+ ProductIndex.import [product1, product2, product3, product4]
628
+
629
+ assert_equal [product2, product1, product3, product4], ProductIndex.sort(:price).resort({ rank: :desc }, { price: :asc }).records
630
+ assert_equal [product2, product1, product4, product3], ProductIndex.sort(rank: :desc).resort(:price).records
631
+ end
632
+
633
+ def test_offset
634
+ product1 = create(:product, rank: 1)
635
+ product2 = create(:product, rank: 2)
636
+ product3 = create(:product, rank: 3)
637
+
638
+ ProductIndex.import [product1, product2, product3]
639
+
640
+ query = ProductIndex.sort(:rank).offset(1)
641
+
642
+ assert_equal [product2, product3], query.records
643
+ assert_equal [product3], query.offset(2).records
644
+ end
645
+
646
+ def test_limit
647
+ product1 = create(:product, rank: 1)
648
+ product2 = create(:product, rank: 2)
649
+ product3 = create(:product, rank: 3)
650
+
651
+ ProductIndex.import [product1, product2, product3]
652
+
653
+ query = ProductIndex.sort(:rank).limit(1)
654
+
655
+ assert_equal [product1], query.records
656
+ assert_equal [product1, product2], query.limit(2).records
657
+ end
658
+
659
+ def test_paginate
660
+ product1 = create(:product, rank: 1)
661
+ product2 = create(:product, rank: 2)
662
+ product3 = create(:product, rank: 3)
663
+
664
+ ProductIndex.import [product1, product2, product3]
665
+
666
+ query = ProductIndex.sort(:rank).paginate(page: 1, per_page: 2)
667
+
668
+ assert_equal [product1, product2], query.records
669
+ assert_equal [product3], query.paginate(page: 2, per_page: 2).records
670
+ end
671
+
672
+ def test_page
673
+ assert_equal 0, ProductIndex.page(1).offset_value
674
+ assert_equal 30, ProductIndex.page(2).offset_value
675
+ assert_equal 100, ProductIndex.page(3).per(50).offset_value
676
+ end
677
+
678
+ def test_per
679
+ assert_equal 50, ProductIndex.per(50).limit_value
680
+ end
681
+
682
+ def test_search
683
+ product1 = create(:product, title: "Title1", description: "Description1", price: 10)
684
+ product2 = create(:product, title: "Title2", description: "Description2", price: 20)
685
+ product3 = create(:product, title: "Title3", description: "Description2", price: 30)
686
+
687
+ ProductIndex.import [product1, product2, product3]
688
+
689
+ assert_equal [product1, product3].to_set, ProductIndex.search("Title1 OR Title3").records.to_set
690
+ assert_equal [product1, product3].to_set, ProductIndex.search("Title1 Title3", default_operator: :OR).records.to_set
691
+ assert_equal [product1], ProductIndex.search("Title1 OR Title2").search("Title1 OR Title3").records
692
+ assert_equal [product1], ProductIndex.search("Title1 OR Title3").where(price: 5 .. 15).records
693
+ end
694
+
695
+ def test_unscope
696
+ product1 = create(:product, title: "Title1", description: "Description1", price: 10)
697
+ product2 = create(:product, title: "Title2", description: "Description2", price: 20)
698
+ product3 = create(:product, title: "Title3", description: "Description2", price: 30)
699
+
700
+ ProductIndex.import [product1, product2, product3]
701
+
702
+ assert_equal [product1], ProductIndex.search("Title1 OR Title2").search("Title1 OR Title3").records
703
+ assert_equal [product1, product3].to_set, ProductIndex.search("Title1 OR Title2").unscope(:search).search("Title1 OR Title3").records.to_set
704
+ end
705
+
706
+ def test_highlight
707
+ product1 = create(:product, title: "Title1 highlight", description: "Description1 highlight")
708
+ product2 = create(:product, title: "Title2 highlight", description: "Description2 highlight")
709
+
710
+ ProductIndex.import [product1, product2]
711
+
712
+ results = ProductIndex.sort(:id).highlight([:title, :description]).search("title:highlight description:highlight").results
713
+
714
+ assert_equal ["Title1 <em>highlight</em>"], results[0].highlight.title
715
+ assert_equal ["Description1 <em>highlight</em>"], results[0].highlight.description
716
+
717
+ assert_equal ["Title2 <em>highlight</em>"], results[1].highlight.title
718
+ assert_equal ["Description2 <em>highlight</em>"], results[1].highlight.description
719
+
720
+ results = ProductIndex.sort(:id).highlight([:title, :description], require_field_match: false).search("highlight").results
721
+
722
+ assert_equal ["Title1 <em>highlight</em>"], results[0].highlight.title
723
+ assert_equal ["Description1 <em>highlight</em>"], results[0].highlight.description
724
+
725
+ assert_equal ["Title2 <em>highlight</em>"], results[1].highlight.title
726
+ assert_equal ["Description2 <em>highlight</em>"], results[1].highlight.description
727
+
728
+ results = ProductIndex.sort(:id).highlight(:title, require_field_match: true).highlight(:description, require_field_match: true).search("title:highlight").results
729
+
730
+ assert_equal ["Title1 <em>highlight</em>"], results[0].highlight.title
731
+ assert_nil results[0].highlight.description
732
+
733
+ assert_equal ["Title2 <em>highlight</em>"], results[1].highlight.title
734
+ assert_nil results[1].highlight.description
735
+ end
736
+
737
+ def test_suggest
738
+ product = create(:product, title: "Title", description: "Description")
739
+
740
+ ProductIndex.import product
741
+
742
+ assert_equal "description", ProductIndex.suggest(:suggestion, text: "Desciption", term: { field: "description" }).suggestions(:suggestion).first["text"]
743
+ end
744
+
745
+ def test_find_in_batches
746
+ expected1 = create(:product, title: "expected", rank: 1)
747
+ expected2 = create(:product, title: "expected", rank: 2)
748
+ expected3 = create(:product, title: "expected", rank: 3)
749
+ rejected = create(:product, title: "rejected")
750
+
751
+ create :product, title: "rejected"
752
+
753
+ ProductIndex.import [expected1, expected2, expected3, rejected]
754
+
755
+ assert_equal [[expected1, expected2], [expected3]], ProductIndex.where(title: "expected").sort(:rank).find_in_batches(batch_size: 2).to_a
756
+ end
757
+
758
+ def test_find_each
759
+ expected1 = create(:product, title: "expected", rank: 1)
760
+ expected2 = create(:product, title: "expected", rank: 2)
761
+ expected3 = create(:product, title: "expected", rank: 3)
762
+ rejected = create(:product, title: "rejected")
763
+
764
+ create :product, title: "rejected"
765
+
766
+ ProductIndex.import [expected1, expected2, expected3, rejected]
767
+
768
+ assert_equal [expected1, expected2, expected3], ProductIndex.where(title: "expected").sort(:rank).find_each(batch_size: 2).to_a
769
+ end
770
+
771
+ def test_failsafe
772
+ assert_raises SearchFlip::ResponseError do
773
+ ProductIndex.search("syntax/error").records
774
+ end
775
+
776
+ query = ProductIndex.failsafe(true).search("syntax/error")
777
+
778
+ assert_equal [], query.records
779
+ assert_equal 0, query.total_entries
780
+ end
781
+
782
+ def test_fresh
783
+ create :product
784
+
785
+ query = ProductIndex.criteria.tap(&:records)
786
+
787
+ assert_not_nil query.instance_variable_get(:@response)
788
+
789
+ refute query.fresh === query
790
+ assert_nil query.fresh.instance_variable_get(:@response)
791
+ end
792
+
793
+ def test_respond_to?
794
+ temp_index = Class.new(ProductIndex)
795
+
796
+ refute temp_index.criteria.respond_to?(:test_scope)
797
+
798
+ temp_index.scope(:test_scope) { match_all }
799
+
800
+ assert temp_index.criteria.respond_to?(:test_scope)
801
+ end
802
+
803
+ def test_method_missing
804
+ temp_index = Class.new(ProductIndex)
805
+
806
+ expected = create(:product, title: "expected")
807
+ rejected = create(:product, title: "rejected")
808
+
809
+ temp_index.import [expected, rejected]
810
+
811
+ temp_index.scope(:with_title) { |title| where(title: title) }
812
+
813
+ records = temp_index.criteria.with_title("expected").records
814
+
815
+ assert_includes records, expected
816
+ refute_includes records, rejected
817
+ end
818
+
819
+ def test_custom
820
+ request = ProductIndex.custom(custom_key: "custom_value").request
821
+
822
+ assert_equal "custom_value", request[:custom_key]
823
+ end
824
+ end
825
+