search_flip 3.3.0 → 3.6.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 021f5dd6d172381d777444631e96f2ebff0759b002f38b9ca555f844184d5dd9
4
- data.tar.gz: ded7bbcab491ca187a68214377aa1f6ab2e3774739224744181aca16cf81e504
3
+ metadata.gz: a241c0ab86244a53caab6b7d8dbcd8f441d9e7fc40837cc9afa7f57e6c7e5da0
4
+ data.tar.gz: f42562bd8af88780accd33c91c112c9f81b42de8945aa956c118b7faff75c6f6
5
5
  SHA512:
6
- metadata.gz: adc9acf973b399aa0595bdc42705516f9a13cb4cfbd18b5ee5db613d8c91261c3bba80834848b8079c4569431dfcbcff0368787b5edeb42f517e864721a54bef
7
- data.tar.gz: 0b8769e3c59d1953036b2fc1618cfbd15db7bc4d19beef0a71e24aeb82830b499eff820e061b397ee20c15d4942941df69cc4dff2b20e4b35119193e78af74b7
6
+ metadata.gz: ad60516d947d060ca1fe049a80059c18e9deb76f7c380b0279cd11cd5b5e0fb811d3a46a12220fd731b793ce1a6728f23e6cb242410f584d040e874a2bed7d78
7
+ data.tar.gz: 415962179b2e3ead79296851746b5f4892bdfbce64d09ae6ef2a2f0df83fa265b1c00a8a549d42013911eaff7ecc0b0460d20ef5c72d096f070d1adce4d0797c
@@ -12,15 +12,17 @@ jobs:
12
12
  - docker.elastic.co/elasticsearch/elasticsearch:6.7.0
13
13
  - docker.elastic.co/elasticsearch/elasticsearch:7.0.0
14
14
  - docker.elastic.co/elasticsearch/elasticsearch:7.11.2
15
+ - docker.elastic.co/elasticsearch/elasticsearch:8.1.1
15
16
  ruby:
16
- - 2.5
17
17
  - 2.6
18
18
  - 2.7
19
+ - 3.0
19
20
  services:
20
21
  elasticsearch:
21
22
  image: ${{ matrix.elasticsearch }}
22
23
  env:
23
24
  discovery.type: single-node
25
+ xpack.security.enabled: false
24
26
  ports:
25
27
  - 9200:9200
26
28
  steps:
@@ -30,6 +32,5 @@ jobs:
30
32
  ruby-version: ${{ matrix.ruby }}
31
33
  - run: gem install bundler
32
34
  - run: bundle
33
- - run: sleep 10
34
35
  - run: bundle exec rspec
35
36
  - run: bundle exec rubocop
data/.rubocop.yml CHANGED
@@ -3,6 +3,9 @@ AllCops:
3
3
  TargetRubyVersion: 2.5
4
4
  SuggestExtensions: false
5
5
 
6
+ Gemspec/RequireMFA:
7
+ Enabled: false
8
+
6
9
  Layout/EmptyLineBetweenDefs:
7
10
  EmptyLineBetweenClassDefs: false
8
11
 
data/CHANGELOG.md CHANGED
@@ -1,6 +1,19 @@
1
1
 
2
2
  # CHANGELOG
3
3
 
4
+ ## v3.6.0
5
+
6
+ * Support Elasticsearch v8
7
+
8
+ ## v3.5.0
9
+
10
+ * Add `SearchFlip::Criteria#http_timeout` to allow specifying timeouts on
11
+ a query level
12
+
13
+ ## v3.4.0
14
+
15
+ * Expose `Http#timeout` via `SearchFlip::HTTPClient`
16
+
4
17
  ## v3.3.0
5
18
 
6
19
  * Update httprb
data/README.md CHANGED
@@ -698,6 +698,14 @@ Specify a timeout to limit query processing time:
698
698
  CommentIndex.timeout("3s").execute
699
699
  ```
700
700
 
701
+ * `http_timeout`
702
+
703
+ Specify a http timeout for the request which will be send to Elasticsearch:
704
+
705
+ ```ruby
706
+ CommentIndex.http_timeout(3).execute
707
+ ```
708
+
701
709
  * `terminate_after`
702
710
 
703
711
  Activate early query termination to stop query processing after the specified
@@ -756,7 +764,7 @@ end
756
764
  This allows to use different clusters per index e.g. when migrating indices to
757
765
  new versions of Elasticsearch.
758
766
 
759
- You can specify basic auth, additional headers, etc via:
767
+ You can specify basic auth, additional headers, request timeouts, etc via:
760
768
 
761
769
  ```ruby
762
770
  http_client = SearchFlip::HTTPClient.new
@@ -773,6 +781,9 @@ http_client = http_client.via("proxy.host", 8080)
773
781
  # Custom headers
774
782
  http_client = http_client.headers(key: "value")
775
783
 
784
+ # Timeouts
785
+ http_client = http_client.timeout(20)
786
+
776
787
  SearchFlip::Connection.new(base_url: "...", http_client: http_client)
777
788
  ```
778
789
 
data/docker-compose.yml CHANGED
@@ -4,5 +4,6 @@ services:
4
4
  image: $ES_IMAGE
5
5
  environment:
6
6
  - discovery.type=single-node
7
+ - xpack.security.enabled=false
7
8
  ports:
8
9
  - 9200:9200
@@ -64,7 +64,7 @@ module SearchFlip
64
64
  def msearch(criterias)
65
65
  payload = criterias.flat_map do |criteria|
66
66
  [
67
- SearchFlip::JSON.generate(index: criteria.target.index_name_with_prefix, type: criteria.target.type_name),
67
+ SearchFlip::JSON.generate(index: criteria.target.index_name_with_prefix, **(version.to_i < 8 ? { type: criteria.target.type_name } : {})),
68
68
  SearchFlip::JSON.generate(criteria.request)
69
69
  ]
70
70
  end
@@ -300,8 +300,8 @@ module SearchFlip
300
300
  # @return [Boolean] Returns true or raises SearchFlip::ResponseError
301
301
 
302
302
  def update_mapping(index_name, mapping, type_name: nil)
303
- url = type_name ? type_url(index_name, type_name) : index_url(index_name)
304
- params = type_name && version.to_f >= 6.7 ? { include_type_name: true } : {}
303
+ url = type_name && version.to_i < 8 ? type_url(index_name, type_name) : index_url(index_name)
304
+ params = type_name && version.to_f >= 6.7 && version.to_i < 8 ? { include_type_name: true } : {}
305
305
 
306
306
  http_client.put("#{url}/_mapping", params: params, json: mapping)
307
307
 
@@ -318,8 +318,8 @@ module SearchFlip
318
318
  # @return [Hash] The current type mapping
319
319
 
320
320
  def get_mapping(index_name, type_name: nil)
321
- url = type_name ? type_url(index_name, type_name) : index_url(index_name)
322
- params = type_name && version.to_f >= 6.7 ? { include_type_name: true } : {}
321
+ url = type_name && version.to_i < 8 ? type_url(index_name, type_name) : index_url(index_name)
322
+ params = type_name && version.to_f >= 6.7 && version.to_i < 8 ? { include_type_name: true } : {}
323
323
 
324
324
  response = http_client.headers(accept: "application/json").get("#{url}/_mapping", params: params)
325
325
 
@@ -26,7 +26,8 @@ module SearchFlip
26
26
 
27
27
  attr_accessor :target, :profile_value, :source_value, :suggest_values, :includes_values,
28
28
  :eager_load_values, :preload_values, :failsafe_value, :scroll_args, :terminate_after_value,
29
- :timeout_value, :preference_value, :search_type_value, :routing_value, :track_total_hits_value
29
+ :timeout_value, :preference_value, :search_type_value, :routing_value, :track_total_hits_value,
30
+ :http_timeout_value
30
31
 
31
32
  # Creates a new criteria while merging the attributes (constraints,
32
33
  # settings, etc) of the current criteria with the attributes of another one
@@ -47,7 +48,7 @@ module SearchFlip
47
48
  [
48
49
  :profile_value, :failsafe_value, :terminate_after_value, :timeout_value, :offset_value,
49
50
  :limit_value, :scroll_args, :source_value, :preference_value, :search_type_value,
50
- :routing_value, :track_total_hits_value, :explain_value
51
+ :routing_value, :track_total_hits_value, :explain_value, :http_timeout_value
51
52
  ].each do |name|
52
53
  criteria.send(:"#{name}=", other.send(name)) unless other.send(name).nil?
53
54
  end
@@ -148,6 +149,22 @@ module SearchFlip
148
149
  end
149
150
  end
150
151
 
152
+ # Specifies a http timeout, such that a SearchFlip::TimeoutError will be
153
+ # thrown when the request times out.
154
+ #
155
+ # @example
156
+ # ProductIndex.http_timeout(3).search("hello world")
157
+ #
158
+ # @param value [Fixnum] The timeout value
159
+ #
160
+ # @return [SearchFlip::Criteria] A newly created extended criteria
161
+
162
+ def http_timeout(value)
163
+ fresh.tap do |criteria|
164
+ criteria.http_timeout_value = value
165
+ end
166
+ end
167
+
151
168
  # Specifies early query termination, such that the processing will be
152
169
  # stopped after the specified number of results has been accumulated.
153
170
  #
@@ -330,10 +347,15 @@ module SearchFlip
330
347
  dupped_request.delete(:from)
331
348
  dupped_request.delete(:size)
332
349
 
350
+ http_request = connection.http_client
351
+ http_request = http_request.timeout(http_timeout_value) if http_timeout_value
352
+
333
353
  if connection.version.to_i >= 5
334
- connection.http_client.post("#{target.type_url}/_delete_by_query", params: request_params.merge(params), json: dupped_request)
354
+ url = connection.version.to_i < 8 ? target.type_url : target.index_url
355
+
356
+ http_request.post("#{url}/_delete_by_query", params: request_params.merge(params), json: dupped_request)
335
357
  else
336
- connection.http_client.delete("#{target.type_url}/_query", params: request_params.merge(params), json: dupped_request)
358
+ http_request.delete("#{target.type_url}/_query", params: request_params.merge(params), json: dupped_request)
337
359
  end
338
360
 
339
361
  target.refresh if SearchFlip::Config[:auto_refresh]
@@ -501,8 +523,8 @@ module SearchFlip
501
523
  end
502
524
 
503
525
  # Executes the search request for the current criteria, ie sends the
504
- # request to Elasticsearch and returns the response. Connection and
505
- # response errors will be rescued if you specify the criteria to be
526
+ # request to Elasticsearch and returns the response. Connection, timeout
527
+ # and response errors will be rescued if you specify the criteria to be
506
528
  # #failsafe, such that an empty response is returned instead.
507
529
  #
508
530
  # @example
@@ -590,6 +612,7 @@ module SearchFlip
590
612
 
591
613
  def execute!
592
614
  http_request = connection.http_client.headers(accept: "application/json")
615
+ http_request = http_request.timeout(http_timeout_value) if http_timeout_value
593
616
 
594
617
  http_response =
595
618
  if scroll_args && scroll_args[:id]
@@ -599,17 +622,21 @@ module SearchFlip
599
622
  json: { scroll: scroll_args[:timeout], scroll_id: scroll_args[:id] }
600
623
  )
601
624
  elsif scroll_args
625
+ url = connection.version.to_i < 8 ? target.type_url : target.index_url
626
+
602
627
  http_request.post(
603
- "#{target.type_url}/_search",
628
+ "#{url}/_search",
604
629
  params: request_params.merge(scroll: scroll_args[:timeout]),
605
630
  json: request
606
631
  )
607
632
  else
608
- http_request.post("#{target.type_url}/_search", params: request_params, json: request)
633
+ url = connection.version.to_i < 8 ? target.type_url : target.index_url
634
+
635
+ http_request.post("#{url}/_search", params: request_params, json: request)
609
636
  end
610
637
 
611
638
  SearchFlip::Response.new(self, SearchFlip::JSON.parse(http_response.to_s))
612
- rescue SearchFlip::ConnectionError, SearchFlip::ResponseError => e
639
+ rescue SearchFlip::ConnectionError, SearchFlip::TimeoutError, SearchFlip::ResponseError => e
613
640
  raise e unless failsafe_value
614
641
 
615
642
  SearchFlip::Response.new(self, "took" => 0, "hits" => { "total" => 0, "hits" => [] })
@@ -1,7 +1,28 @@
1
1
  module SearchFlip
2
- # The SearchFlip::HTTPClient class wraps the http gem, is for internal use
3
- # and responsible for the http request/response handling, ie communicating
4
- # with Elasticsearch.
2
+ # The SearchFlip::HTTPClient class wraps the http gem and responsible for the
3
+ # http request/response handling, ie communicating with Elasticsearch. You
4
+ # only need to use it directly if you need authentication to communicate with
5
+ # Elasticsearch or if you want to set some custom http settings.
6
+ #
7
+ # @example
8
+ # http_client = SearchFlip::HTTPClient.new
9
+ #
10
+ # # Basic Auth
11
+ # http_client = http_client.basic_auth(user: "username", pass: "password")
12
+ #
13
+ # # Raw Auth Header
14
+ # http_client = http_client.auth("Bearer VGhlIEhUVFAgR2VtLCBST0NLUw")
15
+ #
16
+ # # Proxy Settings
17
+ # http_client = http_client.via("proxy.host", 8080)
18
+ #
19
+ # # Custom headers
20
+ # http_client = http_client.headers(key: "value")
21
+ #
22
+ # # Timeouts
23
+ # http_client = http_client.timeout(20)
24
+ #
25
+ # SearchFlip::Connection.new(base_url: "...", http_client: http_client)
5
26
 
6
27
  class HTTPClient
7
28
  attr_accessor :request, :plugins
@@ -14,11 +35,11 @@ module SearchFlip
14
35
  class << self
15
36
  extend Forwardable
16
37
 
17
- def_delegators :new, :headers, :via, :basic_auth, :auth
38
+ def_delegators :new, :headers, :via, :basic_auth, :auth, :timeout
18
39
  def_delegators :new, :get, :post, :put, :delete, :head
19
40
  end
20
41
 
21
- [:headers, :via, :basic_auth, :auth].each do |method|
42
+ [:headers, :via, :basic_auth, :auth, :timeout].each do |method|
22
43
  define_method method do |*args|
23
44
  dup.tap do |client|
24
45
  client.request = request.send(method, *args)
@@ -45,6 +66,10 @@ module SearchFlip
45
66
  response
46
67
  rescue HTTP::ConnectionError => e
47
68
  raise SearchFlip::ConnectionError, e.message
69
+ rescue HTTP::TimeoutError => e
70
+ raise SearchFlip::TimeoutError, e.message
71
+ rescue HTTP::Error => e
72
+ raise SearchFlip::HttpError, e.message
48
73
  end
49
74
  end
50
75
  end
@@ -254,7 +254,7 @@ module SearchFlip
254
254
  :page, :per, :search, :highlight, :suggest, :custom, :find_in_batches, :find_results_in_batches,
255
255
  :find_each, :find_each_result, :failsafe, :total_entries, :total_count, :timeout, :terminate_after,
256
256
  :records, :results, :must, :must_not, :should, :preference, :search_type, :routing,
257
- :track_total_hits, :explain
257
+ :track_total_hits, :explain, :http_timeout
258
258
 
259
259
  # Override to specify the type name used within Elasticsearch. Recap,
260
260
  # this gem uses an individual index for each index class, because
@@ -455,7 +455,8 @@ module SearchFlip
455
455
  # @return [Hash] The specified document
456
456
 
457
457
  def get(id, params = {})
458
- response = connection.http_client.headers(accept: "application/json").get("#{type_url}/#{id}", params: params)
458
+ url = connection.version.to_i < 8 ? type_url : "#{index_url}/_doc"
459
+ response = connection.http_client.headers(accept: "application/json").get("#{url}/#{id}", params: params)
459
460
 
460
461
  SearchFlip::JSON.parse(response.to_s)
461
462
  end
@@ -473,7 +474,8 @@ module SearchFlip
473
474
  # @return [Hash] The raw response
474
475
 
475
476
  def mget(request, params = {})
476
- response = connection.http_client.headers(accept: "application/json").post("#{type_url}/_mget", json: request, params: params)
477
+ url = connection.version.to_i < 8 ? type_url : index_url
478
+ response = connection.http_client.headers(accept: "application/json").post("#{url}/_mget", json: request, params: params)
477
479
 
478
480
  SearchFlip::JSON.parse(response.to_s)
479
481
  end
@@ -631,7 +633,9 @@ module SearchFlip
631
633
  bulk_max_mb: connection.bulk_max_mb
632
634
  }
633
635
 
634
- SearchFlip::Bulk.new("#{type_url}/_bulk", default_options.merge(options)) do |indexer|
636
+ url = connection.version.to_i < 8 ? type_url : index_url
637
+
638
+ SearchFlip::Bulk.new("#{url}/_bulk", default_options.merge(options)) do |indexer|
635
639
  yield indexer
636
640
  end
637
641
 
@@ -1,3 +1,3 @@
1
1
  module SearchFlip
2
- VERSION = "3.3.0"
2
+ VERSION = "3.6.0"
3
3
  end
data/lib/search_flip.rb CHANGED
@@ -33,10 +33,15 @@ require "search_flip/index"
33
33
  require "search_flip/model"
34
34
 
35
35
  module SearchFlip
36
- class NotSupportedError < StandardError; end
37
- class ConnectionError < StandardError; end
36
+ class Error < StandardError; end
38
37
 
39
- class ResponseError < StandardError
38
+ class NotSupportedError < Error; end
39
+
40
+ class HttpError < Error; end
41
+ class ConnectionError < HttpError; end
42
+ class TimeoutError < HttpError; end
43
+
44
+ class ResponseError < Error
40
45
  attr_reader :code, :body
41
46
 
42
47
  def initialize(code:, body:)
@@ -16,10 +16,12 @@ RSpec.describe SearchFlip::AwsSigv4Plugin do
16
16
  it "adds the signed headers to the request" do
17
17
  Timecop.freeze Time.parse("2020-01-01 12:00:00 UTC") do
18
18
  expect(client).to receive(:headers).with(
19
- "host" => "localhost",
20
- "authorization" => /.*/,
21
- "x-amz-content-sha256" => /.*/,
22
- "x-amz-date" => /20200101T120000Z/
19
+ an_object_matching(
20
+ "host" => "localhost",
21
+ "authorization" => /.*/,
22
+ "x-amz-content-sha256" => /.*/,
23
+ "x-amz-date" => /20200101T120000Z/
24
+ )
23
25
  )
24
26
 
25
27
  plugin.call(client, :get, "http://localhost/index")
@@ -60,18 +60,15 @@ RSpec.describe SearchFlip::Bulk do
60
60
 
61
61
  it "uses the specified http_client" do
62
62
  product = create(:product)
63
+ url = ProductIndex.connection.version.to_i < 8 ? ProductIndex.type_url : ProductIndex.index_url
63
64
 
64
- stub_request(:put, "#{ProductIndex.type_url}/_bulk")
65
- .with(headers: { "X-Header" => "Value" })
66
- .to_return(status: 500)
65
+ stub_request(:put, "#{url}/_bulk").with(headers: { "X-Header" => "Value" }).to_return(status: 200, body: "{}")
67
66
 
68
- block = lambda do
69
- ProductIndex.bulk http_client: ProductIndex.connection.http_client.headers("X-Header" => "Value") do |bulk|
70
- bulk.index product.id, ProductIndex.serialize(product)
71
- end
67
+ ProductIndex.bulk http_client: ProductIndex.connection.http_client.headers("X-Header" => "Value") do |bulk|
68
+ bulk.index product.id, ProductIndex.serialize(product)
72
69
  end
73
70
 
74
- expect(&block).to raise_error(SearchFlip::ResponseError)
71
+ expect(WebMock).to have_requested(:put, "#{url}/_bulk").with(headers: { "X-Header" => "Value" })
75
72
  end
76
73
 
77
74
  it "transmits up to bulk_max_mb only" do
@@ -170,7 +170,7 @@ RSpec.describe SearchFlip::Connection do
170
170
  it "freezes the specified index" do
171
171
  connection = SearchFlip::Connection.new
172
172
 
173
- if connection.version.to_f >= 6.6
173
+ if connection.version.to_f >= 6.6 && connection.version.to_i < 8
174
174
  begin
175
175
  connection.create_index("index_name")
176
176
  connection.freeze_index("index_name")
@@ -187,7 +187,7 @@ RSpec.describe SearchFlip::Connection do
187
187
  it "unfreezes the specified index" do
188
188
  connection = SearchFlip::Connection.new
189
189
 
190
- if connection.version.to_f >= 6.6
190
+ if connection.version.to_f >= 6.6 && connection.version.to_i < 8
191
191
  begin
192
192
  connection.create_index("index_name")
193
193
  connection.freeze_index("index_name")
@@ -262,12 +262,19 @@ RSpec.describe SearchFlip::Connection do
262
262
  begin
263
263
  connection = SearchFlip::Connection.new
264
264
 
265
- mapping = { "type_name" => { "properties" => { "id" => { "type" => "long" } } } }
265
+ mapping = { "properties" => { "id" => { "type" => "long" } } }
266
266
 
267
267
  connection.create_index("index_name")
268
- connection.update_mapping("index_name", mapping, type_name: "type_name")
269
268
 
270
- expect(connection.get_mapping("index_name", type_name: "type_name")).to eq("index_name" => { "mappings" => mapping })
269
+ if connection.version.to_i < 8
270
+ connection.update_mapping("index_name", { "type_name" => mapping }, type_name: "type_name")
271
+
272
+ expect(connection.get_mapping("index_name", type_name: "type_name")).to eq("index_name" => { "mappings" => { "type_name" => mapping } })
273
+ else
274
+ connection.update_mapping("index_name", mapping)
275
+
276
+ expect(connection.get_mapping("index_name")).to eq("index_name" => { "mappings" => mapping })
277
+ end
271
278
  ensure
272
279
  connection.delete_index("index_name") if connection.index_exists?("index_name")
273
280
  end
@@ -97,7 +97,8 @@ RSpec.describe SearchFlip::Criteria do
97
97
  methods = [
98
98
  :profile_value, :failsafe_value, :terminate_after_value, :timeout_value,
99
99
  :offset_value, :limit_value, :scroll_args, :source_value, :preference_value,
100
- :search_type_value, :routing_value, :track_total_hits_value, :explain_value
100
+ :search_type_value, :routing_value, :track_total_hits_value, :explain_value,
101
+ :http_timeout_value
101
102
  ]
102
103
 
103
104
  methods.each do |method|
@@ -191,6 +192,22 @@ RSpec.describe SearchFlip::Criteria do
191
192
  end
192
193
  end
193
194
 
195
+ describe "#http_timeout" do
196
+ it "sets the query timeout" do
197
+ http_client = double("client").as_null_object
198
+ allow(http_client).to receive(:timeout).and_return(http_client)
199
+ allow(http_client).to receive(:post).and_raise(SearchFlip::TimeoutError)
200
+ allow(ProductIndex.connection).to receive(:http_client).and_return(http_client)
201
+
202
+ expect { ProductIndex.http_timeout(1).execute }.to raise_error(SearchFlip::TimeoutError)
203
+ expect(http_client).to have_received(:timeout).with(1)
204
+ end
205
+
206
+ it "executes without errors" do
207
+ expect { ProductIndex.http_timeout(1).execute }.not_to raise_error
208
+ end
209
+ end
210
+
194
211
  describe "#terminate_after" do
195
212
  it "sets the terminate after value" do
196
213
  query = ProductIndex.terminate_after(1)
@@ -1204,13 +1221,19 @@ RSpec.describe SearchFlip::Criteria do
1204
1221
  end
1205
1222
 
1206
1223
  describe "#failsafe" do
1207
- it "prevents query syntax exceptions" do
1208
- expect { ProductIndex.search("syntax/error").records }.to raise_error(SearchFlip::ResponseError)
1224
+ [SearchFlip::ConnectionError, SearchFlip::TimeoutError, SearchFlip::ResponseError.new(code: "code", body: "body")].each do |error|
1225
+ it "prevents #{error}" do
1226
+ http_client = double("client").as_null_object
1227
+ allow(http_client).to receive(:post).and_raise(error)
1228
+ allow(ProductIndex.connection).to receive(:http_client).and_return(http_client)
1229
+
1230
+ expect { ProductIndex.all.execute }.to raise_error(error)
1209
1231
 
1210
- query = ProductIndex.failsafe(true).search("syntax/error")
1232
+ query = ProductIndex.failsafe(true)
1211
1233
 
1212
- expect(query.records).to eq([])
1213
- expect(query.total_entries).to eq(0)
1234
+ expect(query.records).to eq([])
1235
+ expect(query.total_entries).to eq(0)
1236
+ end
1214
1237
  end
1215
1238
  end
1216
1239
 
@@ -1327,28 +1350,40 @@ RSpec.describe SearchFlip::Criteria do
1327
1350
 
1328
1351
  describe "#preference" do
1329
1352
  it "sets the preference" do
1330
- stub_request(:post, "http://127.0.0.1:9200/products/products/_search?preference=value")
1353
+ url = ProductIndex.connection.version.to_i < 8 ? "products/products" : "products"
1354
+
1355
+ stub_request(:post, "http://127.0.0.1:9200/#{url}/_search?preference=value")
1331
1356
  .to_return(status: 200, headers: { content_type: "application/json" }, body: "{}")
1332
1357
 
1333
1358
  ProductIndex.preference("value").execute
1359
+
1360
+ expect(WebMock).to have_requested(:post, "http://127.0.0.1:9200/#{url}/_search?preference=value")
1334
1361
  end
1335
1362
  end
1336
1363
 
1337
1364
  describe "#search_type" do
1338
1365
  it "sets the search_type" do
1339
- stub_request(:post, "http://127.0.0.1:9200/products/products/_search?search_type=value")
1366
+ url = ProductIndex.connection.version.to_i < 8 ? "products/products" : "products"
1367
+
1368
+ stub_request(:post, "http://127.0.0.1:9200/#{url}/_search?search_type=value")
1340
1369
  .to_return(status: 200, headers: { content_type: "application/json" }, body: "{}")
1341
1370
 
1342
1371
  ProductIndex.search_type("value").execute
1372
+
1373
+ expect(WebMock).to have_requested(:post, "http://127.0.0.1:9200/#{url}/_search?search_type=value")
1343
1374
  end
1344
1375
  end
1345
1376
 
1346
1377
  describe "#routing" do
1347
1378
  it "sets the search_type" do
1348
- stub_request(:post, "http://127.0.0.1:9200/products/products/_search?routing=value")
1379
+ url = ProductIndex.connection.version.to_i < 8 ? "products/products" : "products"
1380
+
1381
+ stub_request(:post, "http://127.0.0.1:9200/#{url}/_search?routing=value")
1349
1382
  .to_return(status: 200, headers: { content_type: "application/json" }, body: "{}")
1350
1383
 
1351
1384
  ProductIndex.routing("value").execute
1385
+
1386
+ expect(WebMock).to have_requested(:post, "http://127.0.0.1:9200/#{url}/_search?routing=value")
1352
1387
  end
1353
1388
  end
1354
1389
  end
@@ -7,7 +7,7 @@ class HttpTestRequest
7
7
  self.calls = []
8
8
  end
9
9
 
10
- [:via, :basic_auth, :auth].each do |method|
10
+ [:headers, :via, :basic_auth, :auth, :timeout].each do |method|
11
11
  define_method method do |*args|
12
12
  dup.tap do |request|
13
13
  request.calls = calls + [[method, args]]
@@ -20,7 +20,7 @@ RSpec.describe SearchFlip::HTTPClient do
20
20
  describe "delegation" do
21
21
  subject { SearchFlip::HTTPClient }
22
22
 
23
- [:headers, :via, :basic_auth, :auth].each do |method|
23
+ [:headers, :via, :basic_auth, :auth, :timeout].each do |method|
24
24
  it { should delegate(method).to(:new) }
25
25
  end
26
26
 
@@ -56,8 +56,12 @@ RSpec.describe SearchFlip::HTTPClient do
56
56
  end
57
57
  end
58
58
 
59
- [:via, :basic_auth, :auth].each do |method|
59
+ [:headers, :via, :basic_auth, :auth, :timeout].each do |method|
60
60
  describe "##{method}" do
61
+ it "is understood by HTTP" do
62
+ expect(HTTP.respond_to?(method)).to eq(true)
63
+ end
64
+
61
65
  it "creates a dupped instance" do
62
66
  client = SearchFlip::HTTPClient.new
63
67
  client.request = HttpTestRequest.new
@@ -14,7 +14,7 @@ RSpec.describe SearchFlip::Index do
14
14
  :total_entries, :total_count, :terminate_after, :timeout, :records, :results,
15
15
  :must, :must_not, :should, :find_each_result,
16
16
  :find_results_in_batches, :preference, :search_type, :routing,
17
- :track_total_hits, :explain
17
+ :track_total_hits, :explain, :http_timeout
18
18
  ]
19
19
 
20
20
  methods.each do |method|
@@ -215,7 +215,11 @@ RSpec.describe SearchFlip::Index do
215
215
 
216
216
  TestIndex.update_mapping
217
217
 
218
- expect(TestIndex.connection).to have_received(:update_mapping).with("test", { "test" => mapping }, type_name: "test")
218
+ if TestIndex.connection.version.to_i < 8
219
+ expect(TestIndex.connection).to have_received(:update_mapping).with("test", { "test" => mapping }, type_name: "test")
220
+ else
221
+ expect(TestIndex.connection).to have_received(:update_mapping).with("test", mapping)
222
+ end
219
223
  end
220
224
 
221
225
  it "updates the mapping" do
@@ -268,7 +272,11 @@ RSpec.describe SearchFlip::Index do
268
272
 
269
273
  TestIndex.get_mapping
270
274
 
271
- expect(TestIndex.connection).to have_received(:get_mapping).with("test", type_name: "test")
275
+ if TestIndex.connection.version.to_i < 8
276
+ expect(TestIndex.connection).to have_received(:get_mapping).with("test", type_name: "test")
277
+ else
278
+ expect(TestIndex.connection).to have_received(:get_mapping).with("test")
279
+ end
272
280
  end
273
281
 
274
282
  it "returns the mapping" do
@@ -332,7 +340,7 @@ RSpec.describe SearchFlip::Index do
332
340
 
333
341
  TestIndex.type_url
334
342
 
335
- expect(TestIndex.connection).to have_received(:type_url).with("test", "test")
343
+ expect(TestIndex.connection).to have_received(:type_url).with("test", TestIndex.connection.version.to_i < 8 ? "test" : "_doc")
336
344
  end
337
345
  end
338
346
 
data/spec/spec_helper.rb CHANGED
@@ -84,7 +84,7 @@ class CommentIndex
84
84
  include SearchFlip::Index
85
85
 
86
86
  def self.type_name
87
- "comments"
87
+ connection.version.to_i < 8 ? "comments" : "_doc"
88
88
  end
89
89
 
90
90
  def self.index_name
@@ -134,7 +134,7 @@ class ProductIndex
134
134
  end
135
135
 
136
136
  def self.type_name
137
- "products"
137
+ connection.version.to_i < 8 ? "products" : "_doc"
138
138
  end
139
139
 
140
140
  def self.index_name
@@ -175,7 +175,7 @@ class TestIndex
175
175
  end
176
176
 
177
177
  def self.type_name
178
- "test"
178
+ connection.version.to_i < 8 ? "test" : "_doc"
179
179
  end
180
180
 
181
181
  def self.index_name
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: search_flip
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.3.0
4
+ version: 3.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Benjamin Vetter
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-05-26 00:00:00.000000000 Z
11
+ date: 2022-03-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -302,7 +302,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
302
302
  version: '0'
303
303
  requirements: []
304
304
  rubygems_version: 3.2.3
305
- signing_key:
305
+ signing_key:
306
306
  specification_version: 4
307
307
  summary: Full-Featured Elasticsearch Ruby Client with a Chainable DSL
308
308
  test_files: