algolia 2.0.4 → 2.1.1

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: e2ba367e6308158bc455c60a0d0a5c16fbb1ed4565aaa3a6b8d4cca3e16f0c0d
4
- data.tar.gz: af53995633ba454c929265d5d81d311c67a99fcdd76e8eeec51f98aa8e89f778
3
+ metadata.gz: dc743bd03ca6ebc94d2ae61eec22670ccbaa3531d2a9b66c44858280c644a938
4
+ data.tar.gz: 9e5fb85f9d474d266de360c25b7ef3efafa0fe0b78765aa1cae32b402a0865ac
5
5
  SHA512:
6
- metadata.gz: 896b3821ad99f02449f652090c6b4249a932d454bd03e58879c2fad030d6179480b208c36bd07003dd3c58f96cd7630e28aa1afa026cc83f907a3bcf015f2f02
7
- data.tar.gz: bdc286d0c8df062b33fc6d25fd6d3d4348dc82cce74703d26a12d8374a91c5e378e3d7f03ff2d617a76beab88828a8004d3457997394df2a9832277ca308f411
6
+ metadata.gz: b343a5a32c22f73fd18b33235e9dfd4adcc4c6f3236bac881ad37160dce5af9a7b79e836643ba126e3c0f2943d0187ffb804fe1688fdd6f9599966d39950fa48
7
+ data.tar.gz: 98fea72cc28767839cead8d54d75f9d2ac262999bb92b5ba446d81abfb9d43ef7986c99bccc523c892916df6cf605b3e5fcf305935161bf9bdf371ab24e44196
data/.circleci/config.yml CHANGED
@@ -23,6 +23,13 @@ aliases:
23
23
  name: Run linting tool
24
24
  command: bundle exec rake rubocop
25
25
 
26
+ - &credentials
27
+ name: Retrieve temporary Algolia credentials if needed
28
+ command: |
29
+ if [ "$CIRCLE_PR_REPONAME" ]; then
30
+ curl -s https://algoliasearch-client-keygen.herokuapp.com | sh >> $BASH_ENV
31
+ fi
32
+
26
33
  - &run_tests
27
34
  name: Run unit and integration tests
28
35
  command: |
@@ -73,6 +80,7 @@ jobs:
73
80
  - restore_cache: *restore_cache
74
81
  - run: *install_bundler
75
82
  - save_cache: *save_cache
83
+ - run: *credentials
76
84
  - run: *run_tests
77
85
 
78
86
  test_jruby:
@@ -88,6 +96,7 @@ jobs:
88
96
  - restore_cache: *restore_cache
89
97
  - run: *install_bundler
90
98
  - save_cache: *save_cache
99
+ - run: *credentials
91
100
  - run: *run_tests
92
101
 
93
102
  release:
data/CHANGELOG.md CHANGED
@@ -1,6 +1,19 @@
1
1
  # ChangeLog
2
2
 
3
- ## [Unreleased](https://github.com/algolia/algoliasearch-client-ruby/compare/2.0.4...master)
3
+ ## [Unreleased](https://github.com/algolia/algoliasearch-client-ruby/compare/2.1.1..master)
4
+
5
+ ## [2.1.1](https://github.com/algolia/algoliasearch-client-ruby/compare/2.1.0...2.1.1) (2021-05-27)
6
+
7
+ ### Fix
8
+ - Bug with read/write nodes caching ([`#455`](https://github.com/algolia/algoliasearch-client-ruby/pull/455))
9
+
10
+ ## [2.1.0](https://github.com/algolia/algoliasearch-client-ruby/compare/2.0.4...2.1.0) (2021-03-30)
11
+
12
+ ### Feat
13
+ - Custom dictionaries methods
14
+
15
+ ### Fix
16
+ - The parameter `forwardToReplicas` should be handled independently in the `set_settings` method
4
17
 
5
18
  ## [2.0.4](https://github.com/algolia/algoliasearch-client-ruby/compare/2.0.3...2.0.4) (2021-01-05)
6
19
 
data/lib/algolia.rb CHANGED
@@ -20,6 +20,7 @@ require 'algolia/responses/indexing_response'
20
20
  require 'algolia/responses/add_api_key_response'
21
21
  require 'algolia/responses/update_api_key_response'
22
22
  require 'algolia/responses/delete_api_key_response'
23
+ require 'algolia/responses/dictionary_response'
23
24
  require 'algolia/responses/restore_api_key_response'
24
25
  require 'algolia/responses/multiple_batch_indexing_response'
25
26
  require 'algolia/responses/multiple_response'
@@ -82,4 +82,53 @@ module Helpers
82
82
  end
83
83
  res
84
84
  end
85
+
86
+ # Check the passed object to determine if it's an array
87
+ #
88
+ # @param object [Object]
89
+ #
90
+ def check_array(object)
91
+ raise Algolia::AlgoliaError, 'argument must be an array of objects' unless object.is_a?(Array)
92
+ end
93
+
94
+ # Check the passed object
95
+ #
96
+ # @param object [Object]
97
+ # @param in_array [Boolean] whether the object is an array or not
98
+ #
99
+ def check_object(object, in_array = false)
100
+ case object
101
+ when Array
102
+ raise Algolia::AlgoliaError, in_array ? 'argument must be an array of objects' : 'argument must not be an array'
103
+ when String, Integer, Float, TrueClass, FalseClass, NilClass
104
+ raise Algolia::AlgoliaError, "argument must be an #{'array of' if in_array} object, got: #{object.inspect}"
105
+ end
106
+ end
107
+
108
+ # Check if passed object has a objectID
109
+ #
110
+ # @param object [Object]
111
+ # @param object_id [String]
112
+ #
113
+ def get_object_id(object, object_id = nil)
114
+ check_object(object)
115
+ object_id ||= object[:objectID] || object['objectID']
116
+ raise Algolia::AlgoliaError, "Missing 'objectID'" if object_id.nil?
117
+ object_id
118
+ end
119
+
120
+ # Build a batch request
121
+ #
122
+ # @param action [String] action to perform on the engine
123
+ # @param objects [Array] objects on which build the action
124
+ # @param with_object_id [Boolean] if set to true, check if each object has an objectID set
125
+ #
126
+ def chunk(action, objects, with_object_id = false)
127
+ objects.map do |object|
128
+ check_object(object, true)
129
+ request = { action: action, body: object }
130
+ request[:objectID] = get_object_id(object).to_s if with_object_id
131
+ request
132
+ end
133
+ end
85
134
  end
@@ -9,9 +9,9 @@ module Algolia
9
9
  # @param logger [Object] logger used to log requests. Defaults to Algolia::LoggerHelper
10
10
  #
11
11
  def initialize(adapter, logger)
12
- @adapter = adapter
13
- @logger = logger
14
- @connection = nil
12
+ @adapter = adapter
13
+ @logger = logger
14
+ @connections = {}
15
15
  end
16
16
 
17
17
  # Sends request to the engine
@@ -65,7 +65,7 @@ module Algolia
65
65
  # @return [Faraday::Connection]
66
66
  #
67
67
  def connection(host)
68
- @connection ||= Faraday.new(build_url(host)) do |f|
68
+ @connections[host.accept] ||= Faraday.new(build_url(host)) do |f|
69
69
  f.adapter @adapter.to_sym
70
70
  end
71
71
  end
@@ -0,0 +1,33 @@
1
+ module Algolia
2
+ class DictionaryResponse < BaseResponse
3
+ include CallType
4
+
5
+ attr_reader :raw_response
6
+
7
+ # @param client [Search::Client] Algolia Search Client used for verification
8
+ # @param response [Hash] Raw response from the client
9
+ #
10
+ def initialize(client, response)
11
+ @client = client
12
+ @raw_response = response
13
+ @done = false
14
+ end
15
+
16
+ # Wait for the task to complete
17
+ #
18
+ # @param opts [Hash] contains extra parameters to send with your query
19
+ #
20
+ def wait(_opts = {})
21
+ until @done
22
+ res = @client.custom_request({}, path_encode('/1/task/%s', @raw_response[:taskID]), :GET, READ)
23
+ status = get_option(res, 'status')
24
+ if status == 'published'
25
+ @done = true
26
+ end
27
+ sleep(Defaults::WAIT_TASK_DEFAULT_TIME_BEFORE_RETRY / 1000)
28
+ end
29
+
30
+ self
31
+ end
32
+ end
33
+ end
@@ -80,7 +80,7 @@ module Algolia
80
80
  end
81
81
 
82
82
  # # # # # # # # # # # # # # # # # # # # #
83
- # MISC
83
+ # INDEX METHODS
84
84
  # # # # # # # # # # # # # # # # # # # # #
85
85
 
86
86
  # Initialize an index with a given name
@@ -594,12 +594,185 @@ module Algolia
594
594
  @transporter.read(:GET, '/1/clusters/mapping/pending' + handle_params({ getClusters: retrieve_mappings }), {}, request_options)
595
595
  end
596
596
 
597
- #
598
597
  # Aliases the pending_mappings? method
599
598
  #
600
599
  alias_method :has_pending_mappings, :pending_mappings?
601
600
 
601
+ # # # # # # # # # # # # # # # # # # # # #
602
+ # CUSTOM DICTIONARIES METHODS
603
+ # # # # # # # # # # # # # # # # # # # # #
604
+
605
+ # Save entries for a given dictionary
606
+ #
607
+ # @param dictionary [String] dictionary name. Can be either 'stopwords', 'plurals' or 'compounds'
608
+ # @param dictionary_entries [Array<Hash>] array of dictionary entries
609
+ # @param opts [Hash] contains extra parameters to send with your query
610
+ #
611
+ # @return DictionaryResponse
612
+ #
613
+ def save_dictionary_entries(dictionary, dictionary_entries, opts = {})
614
+ response = @transporter.write(
615
+ :POST,
616
+ path_encode('/1/dictionaries/%s/batch', dictionary),
617
+ { clearExistingDictionaryEntries: false, requests: chunk('addEntry', dictionary_entries) },
618
+ opts
619
+ )
620
+
621
+ DictionaryResponse.new(self, response)
622
+ end
623
+
624
+ # Save entries for a given dictionary and wait for the task to finish
625
+ #
626
+ # @param dictionary [String] dictionary name. Can be either 'stopwords', 'plurals' or 'compounds'
627
+ # @param dictionary_entries [Array<Hash>] array of dictionary entries
628
+ # @param opts [Hash] contains extra parameters to send with your query
629
+ #
630
+ def save_dictionary_entries!(dictionary, dictionary_entries, opts = {})
631
+ response = save_dictionary_entries(dictionary, dictionary_entries, opts)
632
+
633
+ response.wait(opts)
634
+ end
635
+
636
+ # Replace entries for a given dictionary
637
+ #
638
+ # @param dictionary [String] dictionary name. Can be either 'stopwords', 'plurals' or 'compounds'
639
+ # @param dictionary_entries [Array<Hash>] array of dictionary entries
640
+ # @param opts [Hash] contains extra parameters to send with your query
641
+ #
642
+ # @return DictionaryResponse
643
+ #
644
+ def replace_dictionary_entries(dictionary, dictionary_entries, opts = {})
645
+ response = @transporter.write(
646
+ :POST,
647
+ path_encode('/1/dictionaries/%s/batch', dictionary),
648
+ { clearExistingDictionaryEntries: true, requests: chunk('addEntry', dictionary_entries) },
649
+ opts
650
+ )
651
+
652
+ DictionaryResponse.new(self, response)
653
+ end
654
+
655
+ # Replace entries for a given dictionary and wait for the task to finish
656
+ #
657
+ # @param dictionary [String] dictionary name. Can be either 'stopwords', 'plurals' or 'compounds'
658
+ # @param dictionary_entries [Array<Hash>] array of dictionary entries
659
+ # @param opts [Hash] contains extra parameters to send with your query
660
+ #
661
+ def replace_dictionary_entries!(dictionary, dictionary_entries, opts = {})
662
+ response = replace_dictionary_entries(dictionary, dictionary_entries, opts)
663
+
664
+ response.wait(opts)
665
+ end
666
+
667
+ # Delete entries for a given dictionary
668
+ #
669
+ # @param dictionary [String] dictionary name. Can be either 'stopwords', 'plurals' or 'compounds'
670
+ # @param object_ids [Array<Hash>] array of object ids
671
+ # @param opts [Hash] contains extra parameters to send with your query
672
+ #
673
+ # @return DictionaryResponse
674
+ #
675
+ def delete_dictionary_entries(dictionary, object_ids, opts = {})
676
+ request = object_ids.map do |object_id|
677
+ { objectID: object_id }
678
+ end
679
+ response = @transporter.write(
680
+ :POST,
681
+ path_encode('/1/dictionaries/%s/batch', dictionary),
682
+ { clearExistingDictionaryEntries: false, requests: chunk('deleteEntry', request) },
683
+ opts
684
+ )
685
+
686
+ DictionaryResponse.new(self, response)
687
+ end
688
+
689
+ # Delete entries for a given dictionary and wait for the task to finish
690
+ #
691
+ # @param dictionary [String] dictionary name. Can be either 'stopwords', 'plurals' or 'compounds'
692
+ # @param object_ids [Array<Hash>] array of object ids
693
+ # @param opts [Hash] contains extra parameters to send with your query
602
694
  #
695
+ def delete_dictionary_entries!(dictionary, object_ids, opts = {})
696
+ response = delete_dictionary_entries(dictionary, object_ids, opts)
697
+
698
+ response.wait(opts)
699
+ end
700
+
701
+ # Clear all entries for a given dictionary
702
+ #
703
+ # @param dictionary [String] dictionary name. Can be either 'stopwords', 'plurals' or 'compounds'
704
+ # @param opts [Hash] contains extra parameters to send with your query
705
+ #
706
+ # @return DictionaryResponse
707
+ #
708
+ def clear_dictionary_entries(dictionary, opts = {})
709
+ replace_dictionary_entries(dictionary, [], opts)
710
+ end
711
+
712
+ # Clear all entries for a given dictionary and wait for the task to finish
713
+ #
714
+ # @param dictionary [String] dictionary name. Can be either 'stopwords', 'plurals' or 'compounds'
715
+ # @param opts [Hash] contains extra parameters to send with your query
716
+ #
717
+ def clear_dictionary_entries!(dictionary, opts = {})
718
+ response = replace_dictionary_entries(dictionary, [], opts)
719
+
720
+ response.wait(opts)
721
+ end
722
+
723
+ # Search entries for a given dictionary
724
+ #
725
+ # @param dictionary [String] dictionary name. Can be either 'stopwords', 'plurals' or 'compounds'
726
+ # @param query [String] query to send
727
+ # @param opts [Hash] contains extra parameters to send with your query
728
+ #
729
+ def search_dictionary_entries(dictionary, query, opts = {})
730
+ @transporter.read(
731
+ :POST,
732
+ path_encode('/1/dictionaries/%s/search', dictionary),
733
+ { query: query },
734
+ opts
735
+ )
736
+ end
737
+
738
+ # Set settings for all the dictionaries
739
+ #
740
+ # @param dictionary_settings [Hash]
741
+ # @param opts [Hash] contains extra parameters to send with your query
742
+ #
743
+ # @return DictionaryResponse
744
+ #
745
+ def set_dictionary_settings(dictionary_settings, opts = {})
746
+ response = @transporter.write(:PUT, '/1/dictionaries/*/settings', dictionary_settings, opts)
747
+
748
+ DictionaryResponse.new(self, response)
749
+ end
750
+
751
+ # Set settings for all the dictionaries and wait for the task to finish
752
+ #
753
+ # @param dictionary_settings [Hash]
754
+ # @param opts [Hash] contains extra parameters to send with your query
755
+ #
756
+ # @return DictionaryResponse
757
+ #
758
+ def set_dictionary_settings!(dictionary_settings, opts = {})
759
+ response = set_dictionary_settings(dictionary_settings, opts)
760
+
761
+ response.wait(opts)
762
+ end
763
+
764
+ # Retrieve settings for all the dictionaries
765
+ #
766
+ # @param opts [Hash] contains extra parameters to send with your query
767
+ #
768
+ def get_dictionary_settings(opts = {})
769
+ @transporter.read(:GET, '/1/dictionaries/*/settings', {}, opts)
770
+ end
771
+
772
+ # # # # # # # # # # # # # # # # # # # # #
773
+ # MISC METHODS
774
+ # # # # # # # # # # # # # # # # # # # # #
775
+
603
776
  # Method available to make custom requests to the API
604
777
  #
605
778
  def custom_request(data, uri, method, call_type, opts = {})
@@ -987,7 +987,15 @@ module Algolia
987
987
  # @return [IndexingResponse]
988
988
  #
989
989
  def set_settings(settings, opts = {})
990
- response = @transporter.write(:PUT, path_encode('/1/indexes/%s/settings', @name), settings, opts)
990
+ request_options = symbolize_hash(opts)
991
+ forward_to_replicas = request_options.delete(:forwardToReplicas) || false
992
+
993
+ response = @transporter.write(
994
+ :PUT,
995
+ path_encode('/1/indexes/%s/settings', @name) + handle_params({ forwardToReplicas: forward_to_replicas }),
996
+ settings,
997
+ request_options
998
+ )
991
999
 
992
1000
  IndexingResponse.new(self, response)
993
1001
  end
@@ -1037,55 +1045,6 @@ module Algolia
1037
1045
 
1038
1046
  private
1039
1047
 
1040
- # Check the passed object to determine if it's an array
1041
- #
1042
- # @param object [Object]
1043
- #
1044
- def check_array(object)
1045
- raise AlgoliaError, 'argument must be an array of objects' unless object.is_a?(Array)
1046
- end
1047
-
1048
- # Check the passed object
1049
- #
1050
- # @param object [Object]
1051
- # @param in_array [Boolean] whether the object is an array or not
1052
- #
1053
- def check_object(object, in_array = false)
1054
- case object
1055
- when Array
1056
- raise AlgoliaError, in_array ? 'argument must be an array of objects' : 'argument must not be an array'
1057
- when String, Integer, Float, TrueClass, FalseClass, NilClass
1058
- raise AlgoliaError, "argument must be an #{'array of' if in_array} object, got: #{object.inspect}"
1059
- end
1060
- end
1061
-
1062
- # Check if passed object has a objectID
1063
- #
1064
- # @param object [Object]
1065
- # @param object_id [String]
1066
- #
1067
- def get_object_id(object, object_id = nil)
1068
- check_object(object)
1069
- object_id ||= object[:objectID] || object['objectID']
1070
- raise AlgoliaError, "Missing 'objectID'" if object_id.nil?
1071
- object_id
1072
- end
1073
-
1074
- # Build a batch request
1075
- #
1076
- # @param action [String] action to perform on the engine
1077
- # @param objects [Array] objects on which build the action
1078
- # @param with_object_id [Boolean] if set to true, check if each object has an objectID set
1079
- #
1080
- def chunk(action, objects, with_object_id = false)
1081
- objects.map do |object|
1082
- check_object(object, true)
1083
- request = { action: action, body: object }
1084
- request[:objectID] = get_object_id(object).to_s if with_object_id
1085
- request
1086
- end
1087
- end
1088
-
1089
1048
  def raw_batch(requests, opts)
1090
1049
  @transporter.write(:POST, path_encode('/1/indexes/%s/batch', @name), { requests: requests }, opts)
1091
1050
  end
@@ -1,3 +1,3 @@
1
1
  module Algolia
2
- VERSION = '2.0.4'.freeze
2
+ VERSION = '2.1.1'.freeze
3
3
  end
@@ -23,7 +23,9 @@ class AnalyticsClientTest < BaseTest
23
23
  endAt: tomorrow.strftime('%Y-%m-%dT%H:%M:%SZ')
24
24
  }
25
25
 
26
- response = client.add_ab_test(ab_test)
26
+ response = retry_test do
27
+ client.add_ab_test(ab_test)
28
+ end
27
29
  ab_test_id = response[:abTestID]
28
30
 
29
31
  index1.wait_task(response[:taskID])
@@ -86,7 +88,9 @@ class AnalyticsClientTest < BaseTest
86
88
  endAt: tomorrow.strftime('%Y-%m-%dT%H:%M:%SZ')
87
89
  }
88
90
 
89
- response = client.add_ab_test(ab_test)
91
+ response = retry_test do
92
+ client.add_ab_test(ab_test)
93
+ end
90
94
  ab_test_id = response[:abTestID]
91
95
 
92
96
  index.wait_task(response[:taskID])
@@ -1,3 +1,4 @@
1
+ require 'securerandom'
1
2
  require_relative 'base_test'
2
3
 
3
4
  class SearchClientTest < BaseTest
@@ -223,7 +224,9 @@ class SearchClientTest < BaseTest
223
224
  assert_includes api_keys, @api_key[:value]
224
225
 
225
226
  @@search_client.update_api_key!(@api_key[:value], { maxHitsPerQuery: 42 })
226
- updated_api_key = @@search_client.get_api_key(@api_key[:value])
227
+ updated_api_key = retry_test do
228
+ @@search_client.get_api_key(@api_key[:value], test: 'test')
229
+ end
227
230
  assert_equal 42, updated_api_key[:maxHitsPerQuery]
228
231
 
229
232
  @@search_client.delete_api_key!(@api_key[:value])
@@ -234,18 +237,13 @@ class SearchClientTest < BaseTest
234
237
 
235
238
  assert_equal 'Key does not exist', exception.message
236
239
 
237
- loop do
238
- begin
239
- @@search_client.restore_api_key!(@api_key[:value])
240
- break
241
- rescue Algolia::AlgoliaHttpError => e
242
- if e.code != 404
243
- raise StandardError
244
- end
245
- end
240
+ retry_test do
241
+ @@search_client.restore_api_key!(@api_key[:value])
246
242
  end
247
243
 
248
- restored_key = @@search_client.get_api_key(@api_key[:value])
244
+ restored_key = retry_test do
245
+ @@search_client.get_api_key(@api_key[:value])
246
+ end
249
247
 
250
248
  refute_nil restored_key
251
249
  end
@@ -334,7 +332,12 @@ class SearchClientTest < BaseTest
334
332
  secured_index1 = secured_client.init_index(@index1.name)
335
333
  secured_index2 = secured_client.init_index(@index2.name)
336
334
 
337
- secured_index1.search('')
335
+ res = retry_test do
336
+ secured_index1.search('')
337
+ end
338
+
339
+ assert_equal 1, res[:hits].length
340
+
338
341
  exception = assert_raises Algolia::AlgoliaHttpError do
339
342
  secured_index2.search('')
340
343
  end
@@ -367,5 +370,96 @@ class SearchClientTest < BaseTest
367
370
  assert_equal 'The SecuredAPIKey doesn\'t have a validUntil parameter.', exception.message
368
371
  end
369
372
  end
373
+
374
+ describe 'Custom Dictionaries' do
375
+ def before_all
376
+ @client = Algolia::Search::Client.create(APPLICATION_ID_2, ADMIN_KEY_2)
377
+ end
378
+
379
+ def test_stopwords_dictionaries
380
+ entry_id = SecureRandom.hex
381
+ assert_equal 0, @client.search_dictionary_entries('stopwords', entry_id)[:nbHits]
382
+
383
+ entry = {
384
+ objectID: entry_id,
385
+ language: 'en',
386
+ word: 'down'
387
+ }
388
+ @client.save_dictionary_entries!('stopwords', [entry])
389
+
390
+ stopwords = @client.search_dictionary_entries('stopwords', entry_id)
391
+ assert_equal 1, stopwords[:nbHits]
392
+ assert_equal stopwords[:hits][0][:objectID], entry[:objectID]
393
+ assert_equal stopwords[:hits][0][:word], entry[:word]
394
+
395
+ @client.delete_dictionary_entries!('stopwords', [entry_id])
396
+ assert_equal 0, @client.search_dictionary_entries('stopwords', entry_id)[:nbHits]
397
+
398
+ old_dictionary_state = @client.search_dictionary_entries('stopwords', '')
399
+ old_dictionary_entries = old_dictionary_state[:hits].map do |hit|
400
+ hit.reject { |key| key == :type }
401
+ end
402
+
403
+ @client.save_dictionary_entries!('stopwords', [entry])
404
+ assert_equal 1, @client.search_dictionary_entries('stopwords', entry_id)[:nbHits]
405
+
406
+ @client.replace_dictionary_entries!('stopwords', old_dictionary_entries)
407
+ assert_equal 0, @client.search_dictionary_entries('stopwords', entry_id)[:nbHits]
408
+
409
+ stopwords_settings = {
410
+ disableStandardEntries: {
411
+ stopwords: {
412
+ en: true
413
+ }
414
+ }
415
+ }
416
+
417
+ @client.set_dictionary_settings!(stopwords_settings)
418
+
419
+ assert_equal @client.get_dictionary_settings, stopwords_settings
420
+ end
421
+
422
+ def test_plurals_dictionaries
423
+ entry_id = SecureRandom.hex
424
+ assert_equal 0, @client.search_dictionary_entries('plurals', entry_id)[:nbHits]
425
+
426
+ entry = {
427
+ objectID: entry_id,
428
+ language: 'fr',
429
+ words: %w(cheval chevaux)
430
+ }
431
+ @client.save_dictionary_entries!('plurals', [entry])
432
+
433
+ plurals = @client.search_dictionary_entries('plurals', entry_id)
434
+ assert_equal 1, plurals[:nbHits]
435
+ assert_equal plurals[:hits][0][:objectID], entry[:objectID]
436
+ assert_equal plurals[:hits][0][:words], entry[:words]
437
+
438
+ @client.delete_dictionary_entries!('plurals', [entry_id])
439
+ assert_equal 0, @client.search_dictionary_entries('plurals', entry_id)[:nbHits]
440
+ end
441
+
442
+ def test_compounds_dictionaries
443
+ entry_id = SecureRandom.hex
444
+ assert_equal 0, @client.search_dictionary_entries('compounds', entry_id)[:nbHits]
445
+
446
+ entry = {
447
+ objectID: entry_id,
448
+ language: 'de',
449
+ word: 'kopfschmerztablette',
450
+ decomposition: %w(kopf schmerz tablette)
451
+ }
452
+ @client.save_dictionary_entries!('compounds', [entry])
453
+
454
+ compounds = @client.search_dictionary_entries('compounds', entry_id)
455
+ assert_equal 1, compounds[:nbHits]
456
+ assert_equal compounds[:hits][0][:objectID], entry[:objectID]
457
+ assert_equal compounds[:hits][0][:word], entry[:word]
458
+ assert_equal compounds[:hits][0][:decomposition], entry[:decomposition]
459
+
460
+ @client.delete_dictionary_entries!('compounds', [entry_id])
461
+ assert_equal 0, @client.search_dictionary_entries('compounds', entry_id)[:nbHits]
462
+ end
463
+ end
370
464
  end
371
465
  end
@@ -274,6 +274,9 @@ class SearchIndexTest < BaseTest
274
274
  @index.set_settings!(settings)
275
275
 
276
276
  assert_equal @index.get_settings, settings
277
+
278
+ # check that the forwardToReplicas parameter is passed correctly
279
+ assert @index.set_settings!(settings, { forwardToReplicas: true })
277
280
  end
278
281
  end
279
282
 
data/test/test_helper.rb CHANGED
@@ -87,3 +87,15 @@ def rule_without_metadata(rule)
87
87
  rule.delete(:_metadata)
88
88
  rule
89
89
  end
90
+
91
+ def retry_test(delay = 0.1, max_retries = 30)
92
+ (1...max_retries).each do |i|
93
+ begin
94
+ return yield
95
+ rescue Algolia::AlgoliaHttpError
96
+ sleep delay * i
97
+ end
98
+ end
99
+
100
+ raise StandardError, 'reached the maximum number of retries'
101
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: algolia
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.4
4
+ version: 2.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Algolia
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-01-05 00:00:00.000000000 Z
11
+ date: 2021-05-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -238,6 +238,7 @@ files:
238
238
  - lib/algolia/responses/add_api_key_response.rb
239
239
  - lib/algolia/responses/base_response.rb
240
240
  - lib/algolia/responses/delete_api_key_response.rb
241
+ - lib/algolia/responses/dictionary_response.rb
241
242
  - lib/algolia/responses/indexing_response.rb
242
243
  - lib/algolia/responses/multiple_batch_indexing_response.rb
243
244
  - lib/algolia/responses/multiple_response.rb
@@ -304,7 +305,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
304
305
  - !ruby/object:Gem::Version
305
306
  version: '0'
306
307
  requirements: []
307
- rubygems_version: 3.1.4
308
+ rubygems_version: 3.0.6
308
309
  signing_key:
309
310
  specification_version: 4
310
311
  summary: A simple Ruby client for the algolia.com REST API