search_flip 2.0.0.beta2 → 2.0.0.beta3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,265 @@
1
+
2
+ require File.expand_path("../spec_helper", __dir__)
3
+
4
+ RSpec.describe SearchFlip::Aggregation do
5
+ describe "#where" do
6
+ it "sets up the constraints correctly for the aggregation and is chainable" do
7
+ product1 = create(:product, category: "category1", title: "title", description: "description")
8
+ product2 = create(:product, category: "category2", title: "title", description: "description")
9
+ product3 = create(:product, category: "category1", title: "title", description: "description")
10
+ product4 = create(:product, category: "category2", title: "title", description: "other")
11
+ product5 = create(:product, category: "category1", title: "other", description: "description")
12
+
13
+ ProductIndex.import [product1, product2, product3, product4, product5]
14
+
15
+ query = ProductIndex.aggregate(category: {}) do |aggregation|
16
+ aggregation.where(title: "title").where(description: "description").aggregate(:category)
17
+ end
18
+
19
+ aggregations = query.aggregations(:category).category.buckets.each_with_object({}) { |bucket, hash| hash[bucket[:key]] = bucket.doc_count }
20
+
21
+ expect(aggregations).to eq("category1" => 2, "category2" => 1)
22
+ end
23
+
24
+ it "works with arrays" do
25
+ product1 = create(:product, category: "category1", title: "title1", description: "description1")
26
+ product2 = create(:product, category: "category2", title: "title2", description: "description2")
27
+ product3 = create(:product, category: "category1", title: "title3", description: "description3")
28
+ product4 = create(:product, category: "category2", title: "title4", description: "other")
29
+ product5 = create(:product, category: "category1", title: "other", description: "description")
30
+
31
+ ProductIndex.import [product1, product2, product3, product4, product5]
32
+
33
+ query = ProductIndex.aggregate(category: {}) do |aggregation|
34
+ aggregation
35
+ .where(title: ["title1", "title2", "title3", "title4"])
36
+ .where(description: ["description1", "description2", "description3"])
37
+ .aggregate(:category)
38
+ end
39
+
40
+ aggregations = query.aggregations(:category).category.buckets.each_with_object({}) { |bucket, hash| hash[bucket[:key]] = bucket.doc_count }
41
+
42
+ expect(aggregations).to eq("category1" => 2, "category2" => 1)
43
+ end
44
+
45
+ it "works with ranges" do
46
+ product1 = create(:product, category: "category1", title: "title1", price: 100)
47
+ product2 = create(:product, category: "category2", title: "title2", price: 150)
48
+ product3 = create(:product, category: "category1", title: "title3", price: 200)
49
+ product4 = create(:product, category: "category2", title: "title4", price: 250)
50
+ product5 = create(:product, category: "category1", title: "other", price: 200)
51
+
52
+ ProductIndex.import [product1, product2, product3, product4, product5]
53
+
54
+ query = ProductIndex.aggregate(category: {}) do |aggregation|
55
+ aggregation.where(title: "title1".."title3").where(price: 100..200).aggregate(:category)
56
+ end
57
+
58
+ aggregations = query.aggregations(:category).category.buckets.each_with_object({}) { |bucket, hash| hash[bucket[:key]] = bucket.doc_count }
59
+
60
+ expect(aggregations).to eq("category1" => 2, "category2" => 1)
61
+ end
62
+ end
63
+
64
+ describe "#where_not" do
65
+ it "sets up the constraints correctly for the aggregation and is chainable" do
66
+ product1 = create(:product, category: "category1", title: "title1")
67
+ product2 = create(:product, category: "category2", title: "title2")
68
+ product3 = create(:product, category: "category1", title: "title3")
69
+ product4 = create(:product, category: "category2", title: "title4")
70
+ product5 = create(:product, category: "category1", title: "title5")
71
+
72
+ ProductIndex.import [product1, product2, product3, product4, product5]
73
+
74
+ query = ProductIndex.aggregate(category: {}) do |aggregation|
75
+ aggregation.where_not(title: "title4").where_not(title: "title5").aggregate(:category)
76
+ end
77
+
78
+ aggregations = query.aggregations(:category).category.buckets.each_with_object({}) { |bucket, hash| hash[bucket[:key]] = bucket.doc_count }
79
+
80
+ expect(aggregations).to eq("category1" => 2, "category2" => 1)
81
+ end
82
+
83
+ it "works with arrays" do
84
+ product1 = create(:product, category: "category1", title: "title1")
85
+ product2 = create(:product, category: "category2", title: "title2")
86
+ product3 = create(:product, category: "category1", title: "title3")
87
+ product4 = create(:product, category: "category2", title: "title4")
88
+ product5 = create(:product, category: "category1", title: "title5")
89
+ product6 = create(:product, category: "category2", title: "title6")
90
+ product7 = create(:product, category: "category1", title: "title7")
91
+
92
+ ProductIndex.import [product1, product2, product3, product4, product5, product6, product7]
93
+
94
+ query = ProductIndex.aggregate(category: {}) do |aggregation|
95
+ aggregation.where_not(title: ["title1", "title2"]).where_not(title: ["title6", "title7"]).aggregate(:category)
96
+ end
97
+
98
+ aggregations = query.aggregations(:category).category.buckets.each_with_object({}) { |bucket, hash| hash[bucket[:key]] = bucket.doc_count }
99
+
100
+ expect(aggregations).to eq("category1" => 2, "category2" => 1)
101
+ end
102
+
103
+ it "works with ranges" do
104
+ product1 = create(:product, category: "category1", title: "title1", price: 100)
105
+ product2 = create(:product, category: "category2", title: "title2", price: 150)
106
+ product3 = create(:product, category: "category1", title: "title3", price: 200)
107
+ product4 = create(:product, category: "category2", title: "title4", price: 250)
108
+ product5 = create(:product, category: "category1", title: "title5", price: 300)
109
+ product6 = create(:product, category: "category2", title: "title6", price: 350)
110
+ product7 = create(:product, category: "category1", title: "title7", price: 400)
111
+
112
+ ProductIndex.import [product1, product2, product3, product4, product5, product6, product7]
113
+
114
+ query = ProductIndex.aggregate(category: {}) do |aggregation|
115
+ aggregation.where_not(price: 100..150).where_not(title: "title6".."title7").aggregate(:category)
116
+ end
117
+
118
+ aggregations = query.aggregations(:category).category.buckets.each_with_object({}) { |bucket, hash| hash[bucket[:key]] = bucket.doc_count }
119
+
120
+ expect(aggregations).to eq("category1" => 2, "category2" => 1)
121
+ end
122
+ end
123
+
124
+ describe "#filter" do
125
+ it "sets up the constraints correctly for the aggregation and is chainable" do
126
+ product1 = create(:product, category: "category1", title: "title", price: 100)
127
+ product2 = create(:product, category: "category2", title: "title", price: 150)
128
+ product3 = create(:product, category: "category1", title: "title", price: 200)
129
+ product4 = create(:product, category: "category2", title: "other", price: 200)
130
+ product5 = create(:product, category: "category1", title: "title", price: 250)
131
+
132
+ ProductIndex.import [product1, product2, product3, product4, product5]
133
+
134
+ query = ProductIndex.aggregate(category: {}) do |aggregation|
135
+ aggregation.filter(range: { price: { gte: 100, lte: 200 } }).filter(term: { title: "title" }).aggregate(:category)
136
+ end
137
+
138
+ aggregations = query.aggregations(:category).category.buckets.each_with_object({}) { |bucket, hash| hash[bucket[:key]] = bucket.doc_count }
139
+
140
+ expect(aggregations).to eq("category1" => 2, "category2" => 1)
141
+ end
142
+ end
143
+
144
+ describe "#range" do
145
+ it "sets up the constraints correctly for the aggregation and is chainable" do
146
+ product1 = create(:product, category: "category1", title: "title1", price: 100)
147
+ product2 = create(:product, category: "category2", title: "title2", price: 150)
148
+ product3 = create(:product, category: "category1", title: "title3", price: 200)
149
+ product4 = create(:product, category: "category2", title: "title4", price: 250)
150
+ product5 = create(:product, category: "category1", title: "title5", price: 300)
151
+ product6 = create(:product, category: "category2", title: "title6", price: 350)
152
+ product7 = create(:product, category: "category1", title: "title7", price: 400)
153
+
154
+ ProductIndex.import [product1, product2, product3, product4, product5, product6, product7]
155
+
156
+ query = ProductIndex.aggregate(category: {}) do |aggregation|
157
+ aggregation.range(:price, gte: 100, lte: 200).range(:title, gte: "title1", lte: "title3").aggregate(:category)
158
+ end
159
+
160
+ aggregations = query.aggregations(:category).category.buckets.each_with_object({}) { |bucket, hash| hash[bucket[:key]] = bucket.doc_count }
161
+
162
+ expect(aggregations).to eq("category1" => 2, "category2" => 1)
163
+ end
164
+ end
165
+
166
+ describe "#match_all" do
167
+ it "sets up the constraints correctly for the aggregation and is chainable" do
168
+ product1 = create(:product, category: "category1")
169
+ product2 = create(:product, category: "category2")
170
+ product3 = create(:product, category: "category1")
171
+
172
+ ProductIndex.import [product1, product2, product3]
173
+
174
+ query = ProductIndex.aggregate(category: {}) do |aggregation|
175
+ aggregation.match_all.aggregate(:category)
176
+ end
177
+
178
+ aggregations = query.aggregations(:category).category.buckets.each_with_object({}) { |bucket, hash| hash[bucket[:key]] = bucket.doc_count }
179
+
180
+ expect(aggregations).to eq("category1" => 2, "category2" => 1)
181
+ end
182
+ end
183
+
184
+ describe "#exists" do
185
+ it "sets up the constraints correctly for the aggregation and is chainable" do
186
+ product1 = create(:product, category: "category1", title: "title1", price: 10)
187
+ product2 = create(:product, category: "category2", title: "title2")
188
+ product3 = create(:product, category: "category1", title: "title3", price: 20)
189
+ product4 = create(:product, category: "category2", title: "title4", price: 30)
190
+ product5 = create(:product, category: "category1", price: 40)
191
+
192
+ ProductIndex.import [product1, product2, product3, product4, product5]
193
+
194
+ query = ProductIndex.aggregate(category: {}) do |aggregation|
195
+ aggregation.exists(:title).exists(:price).aggregate(:category)
196
+ end
197
+
198
+ aggregations = query.aggregations(:category).category.buckets.each_with_object({}) { |bucket, hash| hash[bucket[:key]] = bucket.doc_count }
199
+
200
+ expect(aggregations).to eq("category1" => 2, "category2" => 1)
201
+ end
202
+ end
203
+
204
+ describe "#exists_not" do
205
+ it "sets up the constraints correctly for the aggregation and is chainable" do
206
+ product1 = create(:product, category: "category1")
207
+ product2 = create(:product, category: "category2", title: "title2")
208
+ product3 = create(:product, category: "category1")
209
+ product4 = create(:product, category: "category2")
210
+ product5 = create(:product, category: "category1", price: 40)
211
+
212
+ ProductIndex.import [product1, product2, product3, product4, product5]
213
+
214
+ query = ProductIndex.aggregate(category: {}) do |aggregation|
215
+ aggregation.exists_not(:title).exists_not(:price).aggregate(:category)
216
+ end
217
+
218
+ aggregations = query.aggregations(:category).category.buckets.each_with_object({}) { |bucket, hash| hash[bucket[:key]] = bucket.doc_count }
219
+
220
+ expect(aggregations).to eq("category1" => 2, "category2" => 1)
221
+ end
222
+ end
223
+
224
+ describe "#aggregate" do
225
+ it "aggregates within an aggregation" do
226
+ product1 = create(:product, category: "category1", title: "title1", price: 10)
227
+ product2 = create(:product, category: "category1", title: "title2", price: 15)
228
+ product3 = create(:product, category: "category1", title: "title1", price: 20)
229
+ product4 = create(:product, category: "category2", title: "title2", price: 25)
230
+ product5 = create(:product, category: "category2", title: "title1", price: 30)
231
+ product6 = create(:product, category: "category2", title: "title2", price: 35)
232
+
233
+ ProductIndex.import [product1, product2, product3, product4, product5, product6]
234
+
235
+ query = ProductIndex.aggregate(:category) do |aggregation|
236
+ aggregation.aggregate(:title) do |aggregation2|
237
+ aggregation2.aggregate(price: { sum: { field: "price" } })
238
+ end
239
+ end
240
+
241
+ aggregations = query.aggregations(:category).each_with_object({}) do |(key, agg), hash|
242
+ hash[key] = agg.doc_count
243
+ end
244
+
245
+ expect(aggregations).to eq("category1" => 3, "category2" => 3)
246
+
247
+ aggregations = query.aggregations(:category)["category1"].title.buckets.each_with_object({}) do |bucket, hash|
248
+ hash[bucket[:key]] = bucket.doc_count
249
+ end
250
+
251
+ expect(aggregations).to eq("title1" => 2, "title2" => 1)
252
+
253
+ aggregations = query.aggregations(:category)["category2"].title.buckets.each_with_object({}) do |bucket, hash|
254
+ hash[bucket[:key]] = bucket.doc_count
255
+ end
256
+
257
+ expect(aggregations).to eq("title1" => 1, "title2" => 2)
258
+
259
+ expect(query.aggregations(:category)["category1"].title.buckets.detect { |bucket| bucket[:key] == "title1" }.price.value).to eq(30)
260
+ expect(query.aggregations(:category)["category1"].title.buckets.detect { |bucket| bucket[:key] == "title2" }.price.value).to eq(15)
261
+ expect(query.aggregations(:category)["category2"].title.buckets.detect { |bucket| bucket[:key] == "title1" }.price.value).to eq(30)
262
+ expect(query.aggregations(:category)["category2"].title.buckets.detect { |bucket| bucket[:key] == "title2" }.price.value).to eq(60)
263
+ end
264
+ end
265
+ end
@@ -0,0 +1,78 @@
1
+
2
+ require File.expand_path("../spec_helper", __dir__)
3
+
4
+ RSpec.describe SearchFlip::Bulk do
5
+ describe "#bulk" do
6
+ it "uses bulk mode" do
7
+ product1, product2 = create_list(:product, 2)
8
+
9
+ expect(ProductIndex.total_count).to eq(0)
10
+
11
+ ProductIndex.bulk do |bulk|
12
+ bulk.create product1.id, ProductIndex.serialize(product1)
13
+ bulk.create product2.id, ProductIndex.serialize(product1)
14
+ end
15
+
16
+ expect(ProductIndex.total_count).to eq(2)
17
+
18
+ ProductIndex.bulk do |bulk|
19
+ bulk.delete product1.id
20
+ bulk.delete product2.id
21
+ end
22
+
23
+ expect(ProductIndex.total_count).to eq(0)
24
+ end
25
+
26
+ it "accepts and passes options" do
27
+ product1, product2 = create_list(:product, 2)
28
+
29
+ ProductIndex.import [product1, product2]
30
+
31
+ block = lambda do
32
+ ProductIndex.bulk do |bulk|
33
+ bulk.create product1.id, ProductIndex.serialize(product1)
34
+ bulk.create product2.id, ProductIndex.serialize(product1)
35
+ end
36
+ end
37
+
38
+ expect(&block).to raise_error(SearchFlip::Bulk::Error)
39
+
40
+ ProductIndex.bulk(ignore_errors: [409]) do |bulk|
41
+ bulk.create product1.id, ProductIndex.serialize(product1)
42
+ bulk.create product2.id, ProductIndex.serialize(product1)
43
+ end
44
+ end
45
+
46
+ it "accepts and passes item options" do
47
+ product = create(:product)
48
+
49
+ ProductIndex.bulk do |bulk|
50
+ bulk.index product.id, ProductIndex.serialize(product), version: 1, version_type: "external_gt"
51
+ end
52
+
53
+ block = lambda do
54
+ ProductIndex.bulk do |bulk|
55
+ bulk.index product.id, ProductIndex.serialize(product), version: 1, version_type: "external_gt"
56
+ end
57
+ end
58
+
59
+ expect(&block).to raise_error(SearchFlip::Bulk::Error)
60
+ end
61
+
62
+ it "uses the specified http_client" do
63
+ product = create(:product)
64
+
65
+ stub_request(:put, "#{ProductIndex.type_url}/_bulk?filter_path=errors")
66
+ .with(headers: { "X-Header" => "Value" })
67
+ .to_return(status: 500)
68
+
69
+ block = lambda do
70
+ ProductIndex.bulk http_client: ProductIndex.connection.http_client.headers("X-Header" => "Value") do |bulk|
71
+ bulk.index product.id, ProductIndex.serialize(product)
72
+ end
73
+ end
74
+
75
+ expect(&block).to raise_error(SearchFlip::ResponseError)
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,211 @@
1
+
2
+ require File.expand_path("../spec_helper", __dir__)
3
+
4
+ RSpec.describe SearchFlip::Connection do
5
+ describe "#base_url" do
6
+ it "returns the correct url" do
7
+ expect(SearchFlip::Connection.new(base_url: "base url").base_url).to eq("base url")
8
+ end
9
+ end
10
+
11
+ describe "#msearch" do
12
+ it "sends multiple queries and returns all responses" do
13
+ ProductIndex.import create(:product)
14
+ CommentIndex.import create(:comment)
15
+
16
+ responses = SearchFlip::Connection.new.msearch([ProductIndex.match_all, CommentIndex.match_all])
17
+
18
+ expect(responses.size).to eq(2)
19
+ expect(responses[0].total_entries).to eq(1)
20
+ expect(responses[1].total_entries).to eq(1)
21
+ end
22
+ end
23
+
24
+ describe "#update_aliases" do
25
+ it "changes the aliases" do
26
+ connection = SearchFlip::Connection.new
27
+
28
+ connection.update_aliases(actions: [add: { index: "products", alias: "alias1" }])
29
+ expect(connection.get_aliases(alias_name: "alias1").keys).to eq(["products"])
30
+
31
+ connection.update_aliases(actions: [remove: { index: "products", alias: "alias1" }])
32
+ expect(connection.alias_exists?("alias1")).to eq(false)
33
+ end
34
+ end
35
+
36
+ describe "#get_aliases" do
37
+ it "returns the specified aliases" do
38
+ begin
39
+ connection = SearchFlip::Connection.new
40
+
41
+ connection.update_aliases(actions: [
42
+ { add: { index: "comments", alias: "alias1" } },
43
+ { add: { index: "products", alias: "alias2" } },
44
+ { add: { index: "products", alias: "alias3" } }
45
+ ])
46
+
47
+ expect(connection.get_aliases.keys.to_set).to eq(["comments", "products"].to_set)
48
+ expect(connection.get_aliases["products"]["aliases"].keys.to_set).to eq(["alias2", "alias3"].to_set)
49
+ expect(connection.get_aliases["comments"]["aliases"].keys).to eq(["alias1"])
50
+ expect(connection.get_aliases(index_name: "products").keys).to eq(["products"])
51
+ expect(connection.get_aliases(index_name: "comments,products").keys.to_set).to eq(["comments", "products"].to_set)
52
+ expect(connection.get_aliases(alias_name: "alias1,alias2").keys.to_set).to eq(["comments", "products"].to_set)
53
+ expect(connection.get_aliases(alias_name: "alias1,alias2")["products"]["aliases"].keys).to eq(["alias2"])
54
+ ensure
55
+ connection.update_aliases(actions: [
56
+ { remove: { index: "comments", alias: "alias1" } },
57
+ { remove: { index: "products", alias: "alias2" } },
58
+ { remove: { index: "products", alias: "alias3" } }
59
+ ])
60
+ end
61
+ end
62
+ end
63
+
64
+ describe "#alias_exists?" do
65
+ it "returns whether or not the specified alias exists?" do
66
+ begin
67
+ connection = SearchFlip::Connection.new
68
+
69
+ expect(connection.alias_exists?(:some_alias)).to eq(false)
70
+
71
+ connection.update_aliases(actions: [add: { index: "products", alias: "some_alias" }])
72
+
73
+ expect(connection.alias_exists?(:some_alias)).to eq(true)
74
+ ensure
75
+ connection.update_aliases(actions: [remove: { index: "products", alias: "some_alias" }])
76
+ end
77
+ end
78
+ end
79
+
80
+ describe "#get_indices" do
81
+ it "returns the specified indices" do
82
+ connection = SearchFlip::Connection.new
83
+
84
+ expect(connection.get_indices.map { |index| index["index"] }.to_set).to eq(["comments", "products"].to_set)
85
+ expect(connection.get_indices("com*").map { |index| index["index"] }).to eq(["comments"])
86
+ end
87
+ end
88
+
89
+ describe "#create_index" do
90
+ it "creates the specified index" do
91
+ begin
92
+ connection = SearchFlip::Connection.new
93
+
94
+ expect(connection.index_exists?("index_name")).to eq(false)
95
+
96
+ connection.create_index("index_name")
97
+
98
+ expect(connection.index_exists?("index_name")).to eq(true)
99
+ ensure
100
+ connection.delete_index("index_name") if connection.index_exists?("index_name")
101
+ end
102
+ end
103
+
104
+ it "respects a payload" do
105
+ connection = SearchFlip::Connection.new
106
+
107
+ connection.create_index("index_name", settings: { number_of_shards: 3 })
108
+
109
+ expect(connection.get_index_settings("index_name")["index_name"]["settings"]["index"]["number_of_shards"]).to eq("3")
110
+ ensure
111
+ connection.delete_index("index_name") if connection.index_exists?("index_name")
112
+ end
113
+ end
114
+
115
+ describe "#update_index_settings" do
116
+ it "updates the index settings" do
117
+ begin
118
+ connection = SearchFlip::Connection.new
119
+
120
+ connection.create_index("index_name")
121
+ connection.update_index_settings("index_name", settings: { number_of_replicas: 3 })
122
+
123
+ expect(connection.get_index_settings("index_name")["index_name"]["settings"]["index"]["number_of_replicas"]).to eq("3")
124
+ ensure
125
+ connection.delete_index("index_name") if connection.index_exists?("index_name")
126
+ end
127
+ end
128
+ end
129
+
130
+ describe "#get_index_settings" do
131
+ it "fetches the index settings" do
132
+ begin
133
+ connection = SearchFlip::Connection.new
134
+
135
+ connection.create_index("index_name", settings: { number_of_shards: 3 })
136
+
137
+ expect(connection.get_index_settings("index_name")["index_name"]["settings"]["index"]["number_of_shards"]).to eq("3")
138
+ ensure
139
+ connection.delete_index("index_name") if connection.index_exists?("index_name")
140
+ end
141
+ end
142
+ end
143
+
144
+ describe "#update_mapping" do
145
+ it "updates the mapping of an index" do
146
+ begin
147
+ connection = SearchFlip::Connection.new
148
+
149
+ mapping = { "type_name" => { "properties" => { "id" => { "type" => "long" } } } }
150
+
151
+ connection.create_index("index_name")
152
+ connection.update_mapping("index_name", "type_name", mapping)
153
+
154
+ expect(connection.get_mapping("index_name", "type_name")).to eq("index_name" => { "mappings" => mapping })
155
+ ensure
156
+ connection.delete_index("index_name") if connection.index_exists?("index_name")
157
+ end
158
+ end
159
+ end
160
+
161
+ describe "#delete_index" do
162
+ it "deletes the specified index" do
163
+ begin
164
+ connection = SearchFlip::Connection.new
165
+
166
+ connection.create_index("index_name")
167
+ expect(connection.index_exists?("index_name")).to eq(true)
168
+
169
+ connection.delete_index("index_name")
170
+ expect(connection.index_exists?("index_name")).to eq(false)
171
+ ensure
172
+ connection.delete_index("index_name") if connection.index_exists?("index_name")
173
+ end
174
+ end
175
+ end
176
+
177
+ describe "#refresh" do
178
+ it "refreshes all or the specified indices" do
179
+ begin
180
+ connection = SearchFlip::Connection.new
181
+
182
+ connection.create_index("index1")
183
+ connection.create_index("index2")
184
+
185
+ expect(connection.refresh).to be_truthy
186
+ expect(connection.refresh("index1")).to be_truthy
187
+ expect(connection.refresh(["index1", "index2"])).to be_truthy
188
+ ensure
189
+ connection.delete_index("index1") if connection.index_exists?("index1")
190
+ connection.delete_index("index2") if connection.index_exists?("index2")
191
+ end
192
+ end
193
+ end
194
+
195
+ describe "#index_url" do
196
+ it "returns the index url for the specified index" do
197
+ connection = SearchFlip::Connection.new(base_url: "base_url")
198
+
199
+ expect(connection.index_url("index_name")).to eq("base_url/index_name")
200
+ end
201
+ end
202
+
203
+ describe "#type_url" do
204
+ it "returns the type url for the specified index and type" do
205
+ connection = SearchFlip::Connection.new(base_url: "base_url")
206
+
207
+ expect(connection.type_url("index_name", "type_name")).to eq("base_url/index_name/type_name")
208
+ end
209
+ end
210
+ end
211
+