searchkick_bharthur 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +22 -0
- data/.travis.yml +44 -0
- data/CHANGELOG.md +360 -0
- data/Gemfile +8 -0
- data/LICENSE.txt +22 -0
- data/README.md +1443 -0
- data/Rakefile +8 -0
- data/lib/searchkick/index.rb +662 -0
- data/lib/searchkick/logging.rb +185 -0
- data/lib/searchkick/middleware.rb +12 -0
- data/lib/searchkick/model.rb +105 -0
- data/lib/searchkick/query.rb +845 -0
- data/lib/searchkick/reindex_job.rb +26 -0
- data/lib/searchkick/reindex_v2_job.rb +23 -0
- data/lib/searchkick/results.rb +211 -0
- data/lib/searchkick/tasks.rb +33 -0
- data/lib/searchkick/version.rb +3 -0
- data/lib/searchkick.rb +159 -0
- data/searchkick.gemspec +28 -0
- data/test/aggs_test.rb +115 -0
- data/test/autocomplete_test.rb +65 -0
- data/test/boost_test.rb +144 -0
- data/test/callbacks_test.rb +27 -0
- data/test/ci/before_install.sh +21 -0
- data/test/dangerous_reindex_test.rb +27 -0
- data/test/facets_test.rb +90 -0
- data/test/gemfiles/activerecord31.gemfile +7 -0
- data/test/gemfiles/activerecord32.gemfile +7 -0
- data/test/gemfiles/activerecord40.gemfile +8 -0
- data/test/gemfiles/activerecord41.gemfile +8 -0
- data/test/gemfiles/activerecord50.gemfile +7 -0
- data/test/gemfiles/apartment.gemfile +8 -0
- data/test/gemfiles/mongoid2.gemfile +7 -0
- data/test/gemfiles/mongoid3.gemfile +6 -0
- data/test/gemfiles/mongoid4.gemfile +7 -0
- data/test/gemfiles/mongoid5.gemfile +7 -0
- data/test/gemfiles/nobrainer.gemfile +6 -0
- data/test/highlight_test.rb +63 -0
- data/test/index_test.rb +120 -0
- data/test/inheritance_test.rb +78 -0
- data/test/match_test.rb +227 -0
- data/test/misspellings_test.rb +46 -0
- data/test/model_test.rb +42 -0
- data/test/multi_search_test.rb +22 -0
- data/test/multi_tenancy_test.rb +22 -0
- data/test/order_test.rb +44 -0
- data/test/pagination_test.rb +53 -0
- data/test/query_test.rb +13 -0
- data/test/records_test.rb +8 -0
- data/test/reindex_job_test.rb +31 -0
- data/test/reindex_v2_job_test.rb +32 -0
- data/test/routing_test.rb +13 -0
- data/test/should_index_test.rb +32 -0
- data/test/similar_test.rb +28 -0
- data/test/sql_test.rb +196 -0
- data/test/suggest_test.rb +80 -0
- data/test/synonyms_test.rb +54 -0
- data/test/test_helper.rb +361 -0
- data/test/where_test.rb +171 -0
- metadata +231 -0
data/test/boost_test.rb
ADDED
@@ -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
|
data/test/facets_test.rb
ADDED
@@ -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,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 "<b><em>Hello</em></b>", 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
|
data/test/index_test.rb
ADDED
@@ -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
|