search_flip 3.3.0 → 3.6.0

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 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: