searchkick_bharthur 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|