searchkick_bharthur 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +22 -0
  3. data/.travis.yml +44 -0
  4. data/CHANGELOG.md +360 -0
  5. data/Gemfile +8 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +1443 -0
  8. data/Rakefile +8 -0
  9. data/lib/searchkick/index.rb +662 -0
  10. data/lib/searchkick/logging.rb +185 -0
  11. data/lib/searchkick/middleware.rb +12 -0
  12. data/lib/searchkick/model.rb +105 -0
  13. data/lib/searchkick/query.rb +845 -0
  14. data/lib/searchkick/reindex_job.rb +26 -0
  15. data/lib/searchkick/reindex_v2_job.rb +23 -0
  16. data/lib/searchkick/results.rb +211 -0
  17. data/lib/searchkick/tasks.rb +33 -0
  18. data/lib/searchkick/version.rb +3 -0
  19. data/lib/searchkick.rb +159 -0
  20. data/searchkick.gemspec +28 -0
  21. data/test/aggs_test.rb +115 -0
  22. data/test/autocomplete_test.rb +65 -0
  23. data/test/boost_test.rb +144 -0
  24. data/test/callbacks_test.rb +27 -0
  25. data/test/ci/before_install.sh +21 -0
  26. data/test/dangerous_reindex_test.rb +27 -0
  27. data/test/facets_test.rb +90 -0
  28. data/test/gemfiles/activerecord31.gemfile +7 -0
  29. data/test/gemfiles/activerecord32.gemfile +7 -0
  30. data/test/gemfiles/activerecord40.gemfile +8 -0
  31. data/test/gemfiles/activerecord41.gemfile +8 -0
  32. data/test/gemfiles/activerecord50.gemfile +7 -0
  33. data/test/gemfiles/apartment.gemfile +8 -0
  34. data/test/gemfiles/mongoid2.gemfile +7 -0
  35. data/test/gemfiles/mongoid3.gemfile +6 -0
  36. data/test/gemfiles/mongoid4.gemfile +7 -0
  37. data/test/gemfiles/mongoid5.gemfile +7 -0
  38. data/test/gemfiles/nobrainer.gemfile +6 -0
  39. data/test/highlight_test.rb +63 -0
  40. data/test/index_test.rb +120 -0
  41. data/test/inheritance_test.rb +78 -0
  42. data/test/match_test.rb +227 -0
  43. data/test/misspellings_test.rb +46 -0
  44. data/test/model_test.rb +42 -0
  45. data/test/multi_search_test.rb +22 -0
  46. data/test/multi_tenancy_test.rb +22 -0
  47. data/test/order_test.rb +44 -0
  48. data/test/pagination_test.rb +53 -0
  49. data/test/query_test.rb +13 -0
  50. data/test/records_test.rb +8 -0
  51. data/test/reindex_job_test.rb +31 -0
  52. data/test/reindex_v2_job_test.rb +32 -0
  53. data/test/routing_test.rb +13 -0
  54. data/test/should_index_test.rb +32 -0
  55. data/test/similar_test.rb +28 -0
  56. data/test/sql_test.rb +196 -0
  57. data/test/suggest_test.rb +80 -0
  58. data/test/synonyms_test.rb +54 -0
  59. data/test/test_helper.rb +361 -0
  60. data/test/where_test.rb +171 -0
  61. metadata +231 -0
@@ -0,0 +1,144 @@
1
+ require_relative "test_helper"
2
+
3
+ class BoostTest < Minitest::Test
4
+ # conversions
5
+
6
+ def test_conversions
7
+ store [
8
+ {name: "Tomato A", conversions: {"tomato" => 1}},
9
+ {name: "Tomato B", conversions: {"tomato" => 2}},
10
+ {name: "Tomato C", conversions: {"tomato" => 3}}
11
+ ]
12
+ assert_order "tomato", ["Tomato C", "Tomato B", "Tomato A"]
13
+ end
14
+
15
+ def test_conversions_stemmed
16
+ store [
17
+ {name: "Tomato A", conversions: {"tomato" => 1, "tomatos" => 1, "Tomatoes" => 1}},
18
+ {name: "Tomato B", conversions: {"tomato" => 2}}
19
+ ]
20
+ assert_order "tomato", ["Tomato A", "Tomato B"]
21
+ end
22
+
23
+ # global boost
24
+
25
+ def test_boost
26
+ store [
27
+ {name: "Tomato A"},
28
+ {name: "Tomato B", orders_count: 10},
29
+ {name: "Tomato C", orders_count: 100}
30
+ ]
31
+ assert_order "tomato", ["Tomato C", "Tomato B", "Tomato A"], boost: "orders_count"
32
+ end
33
+
34
+ def test_boost_zero
35
+ store [
36
+ {name: "Zero Boost", orders_count: 0}
37
+ ]
38
+ assert_order "zero", ["Zero Boost"], boost: "orders_count"
39
+ end
40
+
41
+ def test_conversions_weight
42
+ store [
43
+ {name: "Product Boost", orders_count: 20},
44
+ {name: "Product Conversions", conversions: {"product" => 10}}
45
+ ]
46
+ assert_order "product", ["Product Conversions", "Product Boost"], boost: "orders_count"
47
+ end
48
+
49
+ def test_user_id
50
+ store [
51
+ {name: "Tomato A"},
52
+ {name: "Tomato B", user_ids: [1, 2, 3]},
53
+ {name: "Tomato C"},
54
+ {name: "Tomato D"}
55
+ ]
56
+ assert_first "tomato", "Tomato B", user_id: 2
57
+ end
58
+
59
+ def test_personalize
60
+ store [
61
+ {name: "Tomato A"},
62
+ {name: "Tomato B", user_ids: [1, 2, 3]},
63
+ {name: "Tomato C"},
64
+ {name: "Tomato D"}
65
+ ]
66
+ assert_first "tomato", "Tomato B", personalize: {user_ids: 2}
67
+ end
68
+
69
+ def test_boost_fields
70
+ store [
71
+ {name: "Red", color: "White"},
72
+ {name: "White", color: "Red Red Red"}
73
+ ]
74
+ assert_order "red", ["Red", "White"], fields: ["name^10", "color"]
75
+ end
76
+
77
+ def test_boost_fields_decimal
78
+ store [
79
+ {name: "Red", color: "White"},
80
+ {name: "White", color: "Red Red Red"}
81
+ ]
82
+ assert_order "red", ["Red", "White"], fields: ["name^10.5", "color"]
83
+ end
84
+
85
+ def test_boost_fields_word_start
86
+ store [
87
+ {name: "Red", color: "White"},
88
+ {name: "White", color: "Red Red Red"}
89
+ ]
90
+ assert_order "red", ["Red", "White"], fields: [{"name^10" => :word_start}, "color"]
91
+ end
92
+
93
+ def test_boost_by
94
+ store [
95
+ {name: "Tomato A"},
96
+ {name: "Tomato B", orders_count: 10},
97
+ {name: "Tomato C", orders_count: 100}
98
+ ]
99
+ assert_order "tomato", ["Tomato C", "Tomato B", "Tomato A"], boost_by: [:orders_count]
100
+ assert_order "tomato", ["Tomato C", "Tomato B", "Tomato A"], boost_by: {orders_count: {factor: 10}}
101
+ end
102
+
103
+ def test_boost_by_boost_mode_multiply
104
+ store [
105
+ {name: "Tomato A", found_rate: 0.9},
106
+ {name: "Tomato B"},
107
+ {name: "Tomato C", found_rate: 0.5}
108
+ ]
109
+
110
+ assert_order "tomato", ["Tomato B", "Tomato A", "Tomato C"], boost_by: {found_rate: {boost_mode: "multiply"}}
111
+ end
112
+
113
+ def test_boost_where
114
+ store [
115
+ {name: "Tomato A"},
116
+ {name: "Tomato B", user_ids: [1, 2]},
117
+ {name: "Tomato C", user_ids: [3]}
118
+ ]
119
+ assert_first "tomato", "Tomato B", boost_where: {user_ids: 2}
120
+ assert_first "tomato", "Tomato B", boost_where: {user_ids: 1..2}
121
+ assert_first "tomato", "Tomato B", boost_where: {user_ids: [1, 4]}
122
+ assert_first "tomato", "Tomato B", boost_where: {user_ids: {value: 2, factor: 10}}
123
+ assert_first "tomato", "Tomato B", boost_where: {user_ids: {value: [1, 4], factor: 10}}
124
+ assert_order "tomato", ["Tomato C", "Tomato B", "Tomato A"], boost_where: {user_ids: [{value: 1, factor: 10}, {value: 3, factor: 20}]}
125
+ end
126
+
127
+ def test_boost_by_distance
128
+ store [
129
+ {name: "San Francisco", latitude: 37.7833, longitude: -122.4167},
130
+ {name: "San Antonio", latitude: 29.4167, longitude: -98.5000},
131
+ {name: "San Marino", latitude: 43.9333, longitude: 12.4667}
132
+ ]
133
+ assert_order "san", ["San Francisco", "San Antonio", "San Marino"], boost_by_distance: {field: :location, origin: [37, -122], scale: "1000mi"}
134
+ end
135
+
136
+ def test_boost_by_distance_hash
137
+ store [
138
+ {name: "San Francisco", latitude: 37.7833, longitude: -122.4167},
139
+ {name: "San Antonio", latitude: 29.4167, longitude: -98.5000},
140
+ {name: "San Marino", latitude: 43.9333, longitude: 12.4667}
141
+ ]
142
+ assert_order "san", ["San Francisco", "San Antonio", "San Marino"], boost_by_distance: {field: :location, origin: {lat: 37, lon: -122}, scale: "1000mi"}
143
+ end
144
+ end
@@ -0,0 +1,27 @@
1
+ require_relative "test_helper"
2
+
3
+ class CallbacksTest < Minitest::Test
4
+ def test_true_create
5
+ Searchkick.callbacks(true) do
6
+ store_names ["Product A", "Product B"]
7
+ end
8
+ Product.searchkick_index.refresh
9
+ assert_search "product", ["Product A", "Product B"]
10
+ end
11
+
12
+ def test_false_create
13
+ Searchkick.callbacks(false) do
14
+ store_names ["Product A", "Product B"]
15
+ end
16
+ Product.searchkick_index.refresh
17
+ assert_search "product", []
18
+ end
19
+
20
+ def test_bulk_create
21
+ Searchkick.callbacks(:bulk) do
22
+ store_names ["Product A", "Product B"]
23
+ end
24
+ Product.searchkick_index.refresh
25
+ assert_search "product", ["Product A", "Product B"]
26
+ end
27
+ end
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/env bash
2
+
3
+ gem install bundler
4
+
5
+ sudo apt-get purge elasticsearch
6
+ if [[ $ELASTICSEARCH_VERSION == 1* ]]; then
7
+ wget https://download.elasticsearch.org/elasticsearch/elasticsearch/elasticsearch-$ELASTICSEARCH_VERSION.deb
8
+ else
9
+ wget https://download.elastic.co/elasticsearch/release/org/elasticsearch/distribution/deb/elasticsearch/$ELASTICSEARCH_VERSION/elasticsearch-$ELASTICSEARCH_VERSION.deb
10
+ fi
11
+ sudo dpkg -i elasticsearch-$ELASTICSEARCH_VERSION.deb
12
+ sudo service elasticsearch start
13
+
14
+ if [ -n "$NOBRAINER" ]; then
15
+ source /etc/lsb-release && echo "deb http://download.rethinkdb.com/apt $DISTRIB_CODENAME main" | sudo tee /etc/apt/sources.list.d/rethinkdb.list
16
+ wget -qO- http://download.rethinkdb.com/apt/pubkey.gpg | sudo apt-key add -
17
+ sudo apt-get update -q
18
+ sudo apt-get install rethinkdb
19
+ sudo cp /etc/rethinkdb/default.conf.sample /etc/rethinkdb/instances.d/instance1.conf
20
+ sudo service rethinkdb restart
21
+ fi
@@ -0,0 +1,27 @@
1
+ require_relative "test_helper"
2
+
3
+ class DangerousReindexTest < Minitest::Test
4
+ def setup
5
+ skip if mongoid2? || nobrainer? || activerecord_below41?
6
+ super
7
+ end
8
+
9
+ def test_dangerous_reindex
10
+ assert_raises(Searchkick::DangerousOperation) { Product.where(id: [1, 2, 3]).reindex }
11
+ end
12
+
13
+ def test_dangerous_index_associations
14
+ Store.create!(name: "Test")
15
+ assert_raises(Searchkick::DangerousOperation) { Store.first.products.reindex }
16
+ end
17
+
18
+ def test_dangerous_reindex_accepted
19
+ store_names ["Product A", "Product B"]
20
+ Product.where(name: "Product A").reindex(accept_danger: true)
21
+ assert_search "product", ["Product A"]
22
+ end
23
+
24
+ def test_dangerous_reindex_inheritance
25
+ assert_raises(Searchkick::DangerousOperation) { Dog.where(id: [1, 2, 3]).reindex }
26
+ end
27
+ end
@@ -0,0 +1,90 @@
1
+ require_relative "test_helper"
2
+
3
+ class FacetsTest < Minitest::Test
4
+ def setup
5
+ skip unless elasticsearch_below20?
6
+ super
7
+ store [
8
+ {name: "Product Show", latitude: 37.7833, longitude: 12.4167, store_id: 1, in_stock: true, color: "blue", price: 21, created_at: 2.days.ago},
9
+ {name: "Product Hide", latitude: 29.4167, longitude: -98.5000, store_id: 2, in_stock: false, color: "green", price: 25, created_at: 2.days.from_now},
10
+ {name: "Product B", latitude: 43.9333, longitude: -122.4667, store_id: 2, in_stock: false, color: "red", price: 5},
11
+ {name: "Foo", latitude: 43.9333, longitude: 12.4667, store_id: 3, in_stock: false, color: "yellow", price: 15}
12
+ ]
13
+ end
14
+
15
+ def test_basic
16
+ assert_equal ({1 => 1, 2 => 2}), store_facet(facets: [:store_id])
17
+ end
18
+
19
+ def test_where
20
+ assert_equal ({1 => 1}), store_facet(facets: {store_id: {where: {in_stock: true}}})
21
+ end
22
+
23
+ def test_field
24
+ assert_equal ({1 => 1, 2 => 2}), store_facet(facets: {store_id: {}})
25
+ assert_equal ({1 => 1, 2 => 2}), store_facet(facets: {store_id: {field: "store_id"}})
26
+ assert_equal ({1 => 1, 2 => 2}), store_facet({facets: {store_id_new: {field: "store_id"}}}, "store_id_new")
27
+ end
28
+
29
+ def test_limit
30
+ facet = Product.search("Product", facets: {store_id: {limit: 1}}).facets["store_id"]
31
+ assert_equal 1, facet["terms"].size
32
+ assert_equal 3, facet["total"]
33
+ assert_equal 1, facet["other"]
34
+ end
35
+
36
+ def test_ranges
37
+ price_ranges = [{to: 10}, {from: 10, to: 20}, {from: 20}]
38
+ facet = Product.search("Product", facets: {price: {ranges: price_ranges}}).facets["price"]
39
+
40
+ assert_equal 3, facet["ranges"].size
41
+ assert_equal 10.0, facet["ranges"][0]["to"]
42
+ assert_equal 20.0, facet["ranges"][2]["from"]
43
+ assert_equal 1, facet["ranges"][0]["count"]
44
+ assert_equal 0, facet["ranges"][1]["count"]
45
+ assert_equal 2, facet["ranges"][2]["count"]
46
+ end
47
+
48
+ def test_ranges_dates
49
+ ranges = [{to: 1.day.ago}, {from: 1.day.ago, to: 1.day.from_now}, {from: 1.day.from_now}]
50
+ facet = Product.search("Product", facets: {created_at: {ranges: ranges}}).facets["created_at"]
51
+
52
+ assert_equal 1, facet["ranges"][0]["count"]
53
+ assert_equal 1, facet["ranges"][1]["count"]
54
+ assert_equal 1, facet["ranges"][2]["count"]
55
+ end
56
+
57
+ def test_where_no_smart_facets
58
+ assert_equal ({2 => 2}), store_facet(where: {color: "red"}, facets: {store_id: {where: {in_stock: false}}})
59
+ end
60
+
61
+ def test_smart_facets
62
+ assert_equal ({1 => 1}), store_facet(where: {in_stock: true}, facets: [:store_id], smart_facets: true)
63
+ end
64
+
65
+ def test_smart_facets_where
66
+ assert_equal ({2 => 1}), store_facet(where: {color: "red"}, facets: {store_id: {where: {in_stock: false}}}, smart_facets: true)
67
+ end
68
+
69
+ def test_smart_facets_skip_facet
70
+ assert_equal ({1 => 1, 2 => 2}), store_facet(where: {store_id: 2}, facets: [:store_id], smart_facets: true)
71
+ end
72
+
73
+ def test_smart_facets_skip_facet_complex
74
+ assert_equal ({1 => 1, 2 => 1}), store_facet(where: {store_id: 2, price: {gt: 5}}, facets: [:store_id], smart_facets: true)
75
+ end
76
+
77
+ def test_stats_facets
78
+ skip if Gem::Version.new(Searchkick.server_version) >= Gem::Version.new("1.4.0")
79
+ options = {where: {store_id: 2}, facets: {store_id: {stats: true}}}
80
+ facets = Product.search("Product", options).facets["store_id"]["terms"]
81
+ expected_facets_keys = %w(term count total_count min max total mean)
82
+ assert_equal expected_facets_keys, facets.first.keys
83
+ end
84
+
85
+ protected
86
+
87
+ def store_facet(options, facet_key = "store_id")
88
+ Hash[Product.search("Product", options).facets[facet_key]["terms"].map { |v| [v["term"], v["count"]] }]
89
+ end
90
+ end
@@ -0,0 +1,7 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in searchkick.gemspec
4
+ gemspec path: "../../"
5
+
6
+ gem "sqlite3"
7
+ gem "activerecord", "~> 3.1.0"
@@ -0,0 +1,7 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in searchkick.gemspec
4
+ gemspec path: "../../"
5
+
6
+ gem "sqlite3"
7
+ gem "activerecord", "~> 3.2.0"
@@ -0,0 +1,8 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in searchkick.gemspec
4
+ gemspec path: "../../"
5
+
6
+ gem "sqlite3"
7
+ gem "activerecord", "~> 4.0.0"
8
+ gem "activejob_backport"
@@ -0,0 +1,8 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in searchkick.gemspec
4
+ gemspec path: "../../"
5
+
6
+ gem "sqlite3"
7
+ gem "activerecord", "~> 4.1.0"
8
+ gem "activejob_backport"
@@ -0,0 +1,7 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in searchkick.gemspec
4
+ gemspec path: "../../"
5
+
6
+ gem "sqlite3"
7
+ gem "activerecord", "~> 5.0.0.rc1"
@@ -0,0 +1,8 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in searchkick.gemspec
4
+ gemspec path: "../../"
5
+
6
+ gem "sqlite3"
7
+ gem "activerecord", "~> 4.2.0"
8
+ gem "apartment"
@@ -0,0 +1,7 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in searchkick.gemspec
4
+ gemspec path: "../../"
5
+
6
+ gem "mongoid", "~> 2"
7
+ gem "bson_ext"
@@ -0,0 +1,6 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in searchkick.gemspec
4
+ gemspec path: "../../"
5
+
6
+ gem "mongoid", "~> 3.1.0"
@@ -0,0 +1,7 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in searchkick.gemspec
4
+ gemspec path: "../../"
5
+
6
+ gem "mongoid", "~> 4.0.0"
7
+ gem "activejob_backport"
@@ -0,0 +1,7 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in searchkick.gemspec
4
+ gemspec path: "../../"
5
+
6
+ gem "mongoid", "~> 5.0.0"
7
+ gem "activejob_backport"
@@ -0,0 +1,6 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in searchkick.gemspec
4
+ gemspec path: "../../"
5
+
6
+ gem "nobrainer", "0.27.0"
@@ -0,0 +1,63 @@
1
+ require_relative "test_helper"
2
+
3
+ class HighlightTest < Minitest::Test
4
+ def test_basic
5
+ store_names ["Two Door Cinema Club"]
6
+ assert_equal "Two Door <em>Cinema</em> Club", Product.search("cinema", fields: [:name], highlight: true).with_details.first[1][:highlight][:name]
7
+ end
8
+
9
+ def test_tag
10
+ store_names ["Two Door Cinema Club"]
11
+ assert_equal "Two Door <strong>Cinema</strong> Club", Product.search("cinema", fields: [:name], highlight: {tag: "<strong>"}).with_details.first[1][:highlight][:name]
12
+ end
13
+
14
+ def test_multiple_fields
15
+ store [{name: "Two Door Cinema Club", color: "Cinema Orange"}]
16
+ highlight = Product.search("cinema", fields: [:name, :color], highlight: true).with_details.first[1][:highlight]
17
+ assert_equal "Two Door <em>Cinema</em> Club", highlight[:name]
18
+ assert_equal "<em>Cinema</em> Orange", highlight[:color]
19
+ end
20
+
21
+ def test_fields
22
+ store [{name: "Two Door Cinema Club", color: "Cinema Orange"}]
23
+ highlight = Product.search("cinema", fields: [:name, :color], highlight: {fields: [:name]}).with_details.first[1][:highlight]
24
+ assert_equal "Two Door <em>Cinema</em> Club", highlight[:name]
25
+ assert_equal nil, highlight[:color]
26
+ end
27
+
28
+ def test_field_options
29
+ store_names ["Two Door Cinema Club are a Northern Irish indie rock band"]
30
+ fragment_size = ENV["MATCH"] == "word_start" ? 26 : 20
31
+ assert_equal "Two Door <em>Cinema</em> Club are", Product.search("cinema", fields: [:name], highlight: {fields: {name: {fragment_size: fragment_size}}}).with_details.first[1][:highlight][:name]
32
+ end
33
+
34
+ def test_multiple_words
35
+ store_names ["Hello World Hello"]
36
+ assert_equal "<em>Hello</em> World <em>Hello</em>", Product.search("hello", fields: [:name], highlight: true).with_details.first[1][:highlight][:name]
37
+ end
38
+
39
+ def test_encoder
40
+ store_names ["<b>Hello</b>"]
41
+ assert_equal "&lt;b&gt;<em>Hello</em>&lt;&#x2F;b&gt;", Product.search("hello", fields: [:name], highlight: {encoder: "html"}, misspellings: false).with_details.first[1][:highlight][:name]
42
+ end
43
+
44
+ def test_json
45
+ skip if ENV["MATCH"] == "word_start"
46
+ store_names ["Two Door Cinema Club"]
47
+ json = {
48
+ query: {
49
+ match: {
50
+ "name.analyzed" => "cinema"
51
+ }
52
+ },
53
+ highlight: {
54
+ pre_tags: ["<strong>"],
55
+ post_tags: ["</strong>"],
56
+ fields: {
57
+ "name.analyzed" => {}
58
+ }
59
+ }
60
+ }
61
+ assert_equal "Two Door <strong>Cinema</strong> Club", Product.search(json: json).with_details.first[1][:highlight][:"name.analyzed"]
62
+ end
63
+ end
@@ -0,0 +1,120 @@
1
+ require_relative "test_helper"
2
+
3
+ class IndexTest < Minitest::Test
4
+ def test_clean_indices
5
+ old_index = Searchkick::Index.new("products_test_20130801000000000")
6
+ different_index = Searchkick::Index.new("items_test_20130801000000000")
7
+
8
+ old_index.delete if old_index.exists?
9
+ different_index.delete if different_index.exists?
10
+
11
+ # create indexes
12
+ old_index.create
13
+ different_index.create
14
+
15
+ Product.clean_indices
16
+
17
+ assert Product.searchkick_index.exists?
18
+ assert different_index.exists?
19
+ assert !old_index.exists?
20
+ end
21
+
22
+ def test_clean_indices_old_format
23
+ old_index = Searchkick::Index.new("products_test_20130801000000")
24
+ old_index.create
25
+
26
+ Product.clean_indices
27
+
28
+ assert !old_index.exists?
29
+ end
30
+
31
+ def test_mapping
32
+ store_names ["Dollar Tree"], Store
33
+ assert_equal [], Store.search(query: {match: {name: "dollar"}}).map(&:name)
34
+ assert_equal ["Dollar Tree"], Store.search(query: {match: {name: "Dollar Tree"}}).map(&:name)
35
+ end
36
+
37
+ def test_json
38
+ store_names ["Dollar Tree"], Store
39
+ assert_equal [], Store.search(query: {match: {name: "dollar"}}).map(&:name)
40
+ assert_equal ["Dollar Tree"], Store.search(json: {query: {match: {name: "Dollar Tree"}}}, load: false).map(&:name)
41
+ end
42
+
43
+ def test_body
44
+ store_names ["Dollar Tree"], Store
45
+ assert_equal [], Store.search(query: {match: {name: "dollar"}}).map(&:name)
46
+ assert_equal ["Dollar Tree"], Store.search(body: {query: {match: {name: "Dollar Tree"}}}, load: false).map(&:name)
47
+ end
48
+
49
+ def test_block
50
+ store_names ["Dollar Tree"]
51
+ products =
52
+ Product.search "boom" do |body|
53
+ body[:query] = {match_all: {}}
54
+ end
55
+ assert_equal ["Dollar Tree"], products.map(&:name)
56
+ end
57
+
58
+ def test_tokens
59
+ assert_equal ["dollar", "dollartre", "tree"], Product.searchkick_index.tokens("Dollar Tree")
60
+ end
61
+
62
+ def test_tokens_analyzer
63
+ assert_equal ["dollar", "tree"], Product.searchkick_index.tokens("Dollar Tree", analyzer: "searchkick_search2")
64
+ end
65
+
66
+ def test_record_not_found
67
+ store_names ["Product A", "Product B"]
68
+ Product.where(name: "Product A").delete_all
69
+ assert_search "product", ["Product B"]
70
+ ensure
71
+ Product.reindex
72
+ end
73
+
74
+ def test_bad_mapping
75
+ Product.searchkick_index.delete
76
+ store_names ["Product A"]
77
+ assert_raises(Searchkick::InvalidQueryError) { Product.search "test" }
78
+ ensure
79
+ Product.reindex
80
+ end
81
+
82
+ def test_remove_blank_id
83
+ store_names ["Product A"]
84
+ Product.searchkick_index.remove(OpenStruct.new)
85
+ assert_search "product", ["Product A"]
86
+ ensure
87
+ Product.reindex
88
+ end
89
+
90
+ def test_missing_index
91
+ assert_raises(Searchkick::MissingIndexError) { Product.search "test", index_name: "not_found" }
92
+ end
93
+
94
+ def test_unsupported_version
95
+ raises_exception = ->(_) { raise Elasticsearch::Transport::Transport::Error.new("[500] No query registered for [multi_match]") }
96
+ Searchkick.client.stub :search, raises_exception do
97
+ assert_raises(Searchkick::UnsupportedVersionError) { Product.search("test") }
98
+ end
99
+ end
100
+
101
+ def test_invalid_query
102
+ assert_raises(Searchkick::InvalidQueryError) { Product.search(query: {boom: true}) }
103
+ end
104
+
105
+ def test_transaction
106
+ skip unless defined?(ActiveRecord)
107
+ Product.transaction do
108
+ store_names ["Product A"]
109
+ raise ActiveRecord::Rollback
110
+ end
111
+ assert_search "product", []
112
+ end
113
+
114
+ def test_analyzed_only
115
+ skip if nobrainer?
116
+ large_value = 10000.times.map { "hello" }.join(" ")
117
+ store [{name: "Product A", alt_description: large_value}]
118
+ assert_search "product", ["Product A"]
119
+ end
120
+ end
@@ -0,0 +1,78 @@
1
+ require_relative "test_helper"
2
+
3
+ class InheritanceTest < Minitest::Test
4
+ def test_child_reindex
5
+ store_names ["Max"], Cat
6
+ assert Dog.reindex
7
+ Animal.searchkick_index.refresh
8
+ assert_equal 1, Animal.search("*").size
9
+ end
10
+
11
+ def test_child_index_name
12
+ assert_equal "animals-#{Date.today.year}", Dog.searchkick_index.name
13
+ end
14
+
15
+ def test_child_search
16
+ store_names ["Bear"], Dog
17
+ store_names ["Bear"], Cat
18
+ assert_equal 1, Dog.search("bear").size
19
+ end
20
+
21
+ def test_parent_search
22
+ store_names ["Bear"], Dog
23
+ store_names ["Bear"], Cat
24
+ assert_equal 2, Animal.search("bear").size
25
+ end
26
+
27
+ def test_force_one_type
28
+ store_names ["Green Bear"], Dog
29
+ store_names ["Blue Bear"], Cat
30
+ assert_equal ["Blue Bear"], Animal.search("bear", type: [Cat]).map(&:name)
31
+ end
32
+
33
+ def test_force_multiple_types
34
+ store_names ["Green Bear"], Dog
35
+ store_names ["Blue Bear"], Cat
36
+ store_names ["Red Bear"], Animal
37
+ assert_equal ["Green Bear", "Blue Bear"], Animal.search("bear", type: [Dog, Cat]).map(&:name)
38
+ end
39
+
40
+ def test_child_autocomplete
41
+ store_names ["Max"], Cat
42
+ store_names ["Mark"], Dog
43
+ assert_equal ["Max"], Cat.search("ma", fields: [:name], autocomplete: true).map(&:name)
44
+ end
45
+
46
+ def test_parent_autocomplete
47
+ store_names ["Max"], Cat
48
+ store_names ["Bear"], Dog
49
+ assert_equal ["Bear"], Animal.search("bea", fields: [:name], autocomplete: true).map(&:name).sort
50
+ end
51
+
52
+ # def test_child_suggest
53
+ # store_names ["Shark"], Cat
54
+ # store_names ["Sharp"], Dog
55
+ # assert_equal ["shark"], Cat.search("shar", fields: [:name], suggest: true).suggestions
56
+ # end
57
+
58
+ def test_parent_suggest
59
+ store_names ["Shark"], Cat
60
+ store_names ["Tiger"], Dog
61
+ assert_equal ["tiger"], Animal.search("tige", fields: [:name], suggest: true).suggestions.sort
62
+ end
63
+
64
+ def test_reindex
65
+ store_names ["Bear A"], Cat
66
+ store_names ["Bear B"], Dog
67
+ Animal.reindex
68
+ assert_equal 1, Dog.search("bear").size
69
+ end
70
+
71
+ # TODO move somewhere better
72
+
73
+ def test_multiple_indices
74
+ store_names ["Product A"]
75
+ store_names ["Product B"], Animal
76
+ assert_search "product", ["Product A", "Product B"], index_name: [Product.searchkick_index.name, Animal.searchkick_index.name], conversions: false
77
+ end
78
+ end