algolia 2.0.0.pre.alpha.4 → 2.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.rubocop.yml +3 -0
- data/CHANGELOG.md +12 -0
- data/Gemfile +1 -1
- data/README.md +18 -10
- data/SECURITY.md +3 -0
- data/algolia.gemspec +6 -6
- data/lib/algolia.rb +1 -1
- data/lib/algolia/analytics_client.rb +1 -1
- data/lib/algolia/config/analytics_config.rb +2 -2
- data/lib/algolia/config/base_config.rb +43 -0
- data/lib/algolia/config/insights_config.rb +2 -2
- data/lib/algolia/config/recommendation_config.rb +2 -2
- data/lib/algolia/config/search_config.rb +2 -2
- data/lib/algolia/defaults.rb +2 -2
- data/lib/algolia/error.rb +1 -2
- data/lib/algolia/helpers.rb +5 -3
- data/lib/algolia/insights_client.rb +1 -1
- data/lib/algolia/iterators/object_iterator.rb +5 -4
- data/lib/algolia/iterators/paginator_iterator.rb +5 -3
- data/lib/algolia/recommendation_client.rb +1 -1
- data/lib/algolia/search_client.rb +1 -1
- data/lib/algolia/search_index.rb +37 -37
- data/lib/algolia/transport/request_options.rb +1 -1
- data/lib/algolia/transport/transport.rb +2 -5
- data/lib/algolia/version.rb +1 -1
- data/sig/config/algolia_config.rbs +3 -3
- data/sig/config/analytics_config.rbs +1 -1
- data/sig/config/insights_config.rbs +1 -1
- data/sig/config/recommendation_config.rbs +1 -1
- data/sig/config/search_config.rbs +1 -1
- data/test/algolia/integration/analytics_client_test.rb +6 -6
- data/test/algolia/integration/insights_client_test.rb +11 -11
- data/test/algolia/integration/search_client_test.rb +20 -11
- data/test/algolia/unit/algolia_config_test.rb +16 -0
- data/test/algolia/unit/helpers_test.rb +20 -1
- data/test/algolia/unit/retry_strategy_test.rb +3 -3
- data/test/test_helper.rb +1 -1
- data/upgrade_guide.md +30 -22
- metadata +26 -17
- data/lib/algolia/config/algolia_config.rb +0 -40
@@ -127,15 +127,12 @@ module Algolia
|
|
127
127
|
|
128
128
|
# Generates headers from config headers and optional parameters
|
129
129
|
#
|
130
|
-
# @
|
130
|
+
# @param request_options [RequestOptions]
|
131
131
|
#
|
132
132
|
# @return [Hash] merged headers
|
133
133
|
#
|
134
134
|
def generate_headers(request_options = {})
|
135
|
-
headers
|
136
|
-
extra_headers = request_options.headers || {}
|
137
|
-
@config.default_headers.each { |key, val| headers[key.to_s] = val }
|
138
|
-
extra_headers.each { |key, val| headers[key.to_s] = val }
|
135
|
+
headers = @config.headers.merge(request_options.headers)
|
139
136
|
if request_options.compression_type == Defaults::GZIP_ENCODING
|
140
137
|
headers['Accept-Encoding'] = Defaults::GZIP_ENCODING
|
141
138
|
end
|
data/lib/algolia/version.rb
CHANGED
@@ -1,11 +1,10 @@
|
|
1
1
|
module Algolia
|
2
|
-
|
3
|
-
class AlgoliaConfig
|
2
|
+
class BaseConfig
|
4
3
|
attr_accessor app_id: String
|
5
4
|
|
6
5
|
attr_accessor api_key: String
|
7
6
|
|
8
|
-
attr_accessor
|
7
|
+
attr_accessor headers: Hash[String, String]
|
9
8
|
|
10
9
|
attr_accessor batch_size: Integer
|
11
10
|
|
@@ -20,5 +19,6 @@ module Algolia
|
|
20
19
|
attr_accessor symbolize_keys: bool
|
21
20
|
|
22
21
|
def initialize: (?::Hash[Symbol, String|[String]] opts) -> void
|
22
|
+
def set_extra_header: (Symbol|String key, String value) -> void
|
23
23
|
end
|
24
24
|
end
|
@@ -11,14 +11,14 @@ class AnalyticsClientTest < BaseTest
|
|
11
11
|
index1.save_object!({ objectID: 'one' })
|
12
12
|
index2.save_object!({ objectID: 'one' })
|
13
13
|
|
14
|
-
ab_test_name = index1.
|
14
|
+
ab_test_name = index1.name
|
15
15
|
tomorrow = Time.now + 24*60*60
|
16
16
|
|
17
17
|
ab_test = {
|
18
18
|
name: ab_test_name,
|
19
19
|
variants: [
|
20
|
-
{ index: index1.
|
21
|
-
{ index: index2.
|
20
|
+
{ index: index1.name, trafficPercentage: 60, description: 'a description' },
|
21
|
+
{ index: index2.name, trafficPercentage: 40 }
|
22
22
|
],
|
23
23
|
endAt: tomorrow.strftime('%Y-%m-%dT%H:%M:%SZ')
|
24
24
|
}
|
@@ -74,14 +74,14 @@ class AnalyticsClientTest < BaseTest
|
|
74
74
|
|
75
75
|
index.save_object!({ objectID: 'one' })
|
76
76
|
|
77
|
-
ab_test_name = index.
|
77
|
+
ab_test_name = index.name
|
78
78
|
tomorrow = Time.now + 24*60*60
|
79
79
|
|
80
80
|
ab_test = {
|
81
81
|
name: ab_test_name,
|
82
82
|
variants: [
|
83
|
-
{ index: index.
|
84
|
-
{ index: index.
|
83
|
+
{ index: index.name, trafficPercentage: 90 },
|
84
|
+
{ index: index.name, trafficPercentage: 10, customSearchParameters: { ignorePlurals: true } }
|
85
85
|
],
|
86
86
|
endAt: tomorrow.strftime('%Y-%m-%dT%H:%M:%SZ')
|
87
87
|
}
|
@@ -17,7 +17,7 @@ class InsightsClientTest < BaseTest
|
|
17
17
|
client.send_event({
|
18
18
|
eventType: 'click',
|
19
19
|
eventName: 'foo',
|
20
|
-
index: index.
|
20
|
+
index: index.name,
|
21
21
|
userToken: 'bar',
|
22
22
|
objectIDs: %w(one two),
|
23
23
|
timestamp: (today - 2).strftime('%Q').to_i
|
@@ -27,14 +27,14 @@ class InsightsClientTest < BaseTest
|
|
27
27
|
{
|
28
28
|
eventType: 'click',
|
29
29
|
eventName: 'foo',
|
30
|
-
index: index.
|
30
|
+
index: index.name,
|
31
31
|
userToken: 'bar',
|
32
32
|
objectIDs: %w(one two),
|
33
33
|
timestamp: (today - 2).strftime('%Q').to_i
|
34
34
|
}, {
|
35
35
|
eventType: 'click',
|
36
36
|
eventName: 'foo',
|
37
|
-
index: index.
|
37
|
+
index: index.name,
|
38
38
|
userToken: 'bar',
|
39
39
|
objectIDs: %w(one two),
|
40
40
|
timestamp: (today - 2).strftime('%Q').to_i
|
@@ -42,37 +42,37 @@ class InsightsClientTest < BaseTest
|
|
42
42
|
])
|
43
43
|
|
44
44
|
user_client = client.user('bar')
|
45
|
-
response = user_client.clicked_object_ids('foo', index.
|
45
|
+
response = user_client.clicked_object_ids('foo', index.name, %w(one two))
|
46
46
|
assert_equal 200, response[:status]
|
47
47
|
assert_equal 'OK', response[:message]
|
48
48
|
|
49
49
|
query_id = index.search('', { clickAnalytics: true })[:queryID]
|
50
50
|
|
51
|
-
response = user_client.clicked_object_ids_after_search('foo', index.
|
51
|
+
response = user_client.clicked_object_ids_after_search('foo', index.name, %w(one two), [1, 2], query_id)
|
52
52
|
assert_equal 200, response[:status]
|
53
53
|
assert_equal 'OK', response[:message]
|
54
54
|
|
55
|
-
response = user_client.clicked_filters('foo', index.
|
55
|
+
response = user_client.clicked_filters('foo', index.name, %w(filter:foo filter:bar))
|
56
56
|
assert_equal 200, response[:status]
|
57
57
|
assert_equal 'OK', response[:message]
|
58
58
|
|
59
|
-
response = user_client.converted_object_ids('foo', index.
|
59
|
+
response = user_client.converted_object_ids('foo', index.name, %w(one two))
|
60
60
|
assert_equal 200, response[:status]
|
61
61
|
assert_equal 'OK', response[:message]
|
62
62
|
|
63
|
-
response = user_client.converted_object_ids_after_search('foo', index.
|
63
|
+
response = user_client.converted_object_ids_after_search('foo', index.name, %w(one two), query_id)
|
64
64
|
assert_equal 200, response[:status]
|
65
65
|
assert_equal 'OK', response[:message]
|
66
66
|
|
67
|
-
response = user_client.converted_filters('foo', index.
|
67
|
+
response = user_client.converted_filters('foo', index.name, %w(filter:foo filter:bar))
|
68
68
|
assert_equal 200, response[:status]
|
69
69
|
assert_equal 'OK', response[:message]
|
70
70
|
|
71
|
-
response = user_client.viewed_object_ids('foo', index.
|
71
|
+
response = user_client.viewed_object_ids('foo', index.name, %w(one two))
|
72
72
|
assert_equal 200, response[:status]
|
73
73
|
assert_equal 'OK', response[:message]
|
74
74
|
|
75
|
-
response = user_client.viewed_filters('foo', index.
|
75
|
+
response = user_client.viewed_filters('foo', index.name, %w(filter:foo filter:bar))
|
76
76
|
assert_equal 200, response[:status]
|
77
77
|
assert_equal 'OK', response[:message]
|
78
78
|
end
|
@@ -80,10 +80,10 @@ class SearchClientTest < BaseTest
|
|
80
80
|
copy_rules_index = @@search_client.init_index(get_test_index_name('copy_index_rules'))
|
81
81
|
copy_synonyms_index = @@search_client.init_index(get_test_index_name('copy_index_synonyms'))
|
82
82
|
copy_full_copy_index = @@search_client.init_index(get_test_index_name('copy_index_full_copy'))
|
83
|
-
@@search_client.copy_settings!(@index_name, copy_settings_index.
|
84
|
-
@@search_client.copy_rules!(@index_name, copy_rules_index.
|
85
|
-
@@search_client.copy_synonyms!(@index_name, copy_synonyms_index.
|
86
|
-
@@search_client.copy_index!(@index_name, copy_full_copy_index.
|
83
|
+
@@search_client.copy_settings!(@index_name, copy_settings_index.name)
|
84
|
+
@@search_client.copy_rules!(@index_name, copy_rules_index.name)
|
85
|
+
@@search_client.copy_synonyms!(@index_name, copy_synonyms_index.name)
|
86
|
+
@@search_client.copy_index!(@index_name, copy_full_copy_index.name)
|
87
87
|
|
88
88
|
assert_equal @index.get_settings, copy_settings_index.get_settings
|
89
89
|
assert_equal @index.get_rule(rule[:objectID]), copy_rules_index.get_rule(rule[:objectID])
|
@@ -93,7 +93,7 @@ class SearchClientTest < BaseTest
|
|
93
93
|
assert_equal @index.get_synonym(synonym[:objectID]), copy_full_copy_index.get_synonym(synonym[:objectID])
|
94
94
|
|
95
95
|
moved_index = @@search_client.init_index(get_test_index_name('move_index'))
|
96
|
-
@@search_client.move_index!(@index_name, moved_index.
|
96
|
+
@@search_client.move_index!(@index_name, moved_index.name)
|
97
97
|
|
98
98
|
moved_index.get_synonym('google_placeholder')
|
99
99
|
moved_index.get_rule('company_auto_faceting')
|
@@ -233,7 +233,16 @@ class SearchClientTest < BaseTest
|
|
233
233
|
|
234
234
|
assert_equal 'Key does not exist', exception.message
|
235
235
|
|
236
|
-
|
236
|
+
loop do
|
237
|
+
begin
|
238
|
+
@@search_client.restore_api_key!(@api_key[:value])
|
239
|
+
break
|
240
|
+
rescue Algolia::AlgoliaHttpError => e
|
241
|
+
if e.code != 404
|
242
|
+
raise StandardError
|
243
|
+
end
|
244
|
+
end
|
245
|
+
end
|
237
246
|
|
238
247
|
restored_key = @@search_client.get_api_key(@api_key[:value])
|
239
248
|
|
@@ -261,8 +270,8 @@ class SearchClientTest < BaseTest
|
|
261
270
|
end
|
262
271
|
|
263
272
|
def test_multiple_operations
|
264
|
-
index_name1 = @index1.
|
265
|
-
index_name2 = @index2.
|
273
|
+
index_name1 = @index1.name
|
274
|
+
index_name2 = @index2.name
|
266
275
|
|
267
276
|
response = @@search_client.multiple_batch!([
|
268
277
|
{ indexName: index_name1, action: 'addObject', body: { firstname: 'Jimmie' } },
|
@@ -317,12 +326,12 @@ class SearchClientTest < BaseTest
|
|
317
326
|
now = Time.now.to_i
|
318
327
|
secured_api_key = Algolia::Search::Client.generate_secured_api_key(SEARCH_KEY_1, {
|
319
328
|
validUntil: now + (10 * 60),
|
320
|
-
restrictIndices: @index1.
|
329
|
+
restrictIndices: @index1.name
|
321
330
|
})
|
322
331
|
|
323
332
|
secured_client = Algolia::Search::Client.create(APPLICATION_ID_1, secured_api_key)
|
324
|
-
secured_index1 = secured_client.init_index(@index1.
|
325
|
-
secured_index2 = secured_client.init_index(@index2.
|
333
|
+
secured_index1 = secured_client.init_index(@index1.name)
|
334
|
+
secured_index2 = secured_client.init_index(@index2.name)
|
326
335
|
|
327
336
|
secured_index1.search('')
|
328
337
|
exception = assert_raises Algolia::AlgoliaHttpError do
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'algolia'
|
2
|
+
require 'test_helper'
|
3
|
+
|
4
|
+
class AlgoliaConfigTest
|
5
|
+
describe 'set an extra header' do
|
6
|
+
def before_all
|
7
|
+
@config = Algolia::BaseConfig.new(application_id: 'app_id', api_key: 'api_key')
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_set_extra_header
|
11
|
+
@config.set_extra_header('foo', 'bar')
|
12
|
+
assert @config.headers['foo']
|
13
|
+
assert_equal @config.headers['foo'], 'bar'
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -18,7 +18,26 @@ class HelpersTest
|
|
18
18
|
replicas: %w(index1 index2)
|
19
19
|
}
|
20
20
|
|
21
|
-
deserialized_settings = deserialize_settings(old_settings)
|
21
|
+
deserialized_settings = deserialize_settings(old_settings, true)
|
22
|
+
assert_equal new_settings, deserialized_settings
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_deserialize_settings_with_string
|
26
|
+
old_settings = {
|
27
|
+
'attributesToIndex' => %w(attr1 attr2),
|
28
|
+
'numericAttributesToIndex' => %w(attr1 attr2),
|
29
|
+
'slaves' => %w(index1 index2),
|
30
|
+
'minWordSizefor1Typo' => 1
|
31
|
+
}
|
32
|
+
|
33
|
+
new_settings = {
|
34
|
+
'searchableAttributes' => %w(attr1 attr2),
|
35
|
+
'numericAttributesForFiltering' => %w(attr1 attr2),
|
36
|
+
'replicas' => %w(index1 index2),
|
37
|
+
'minWordSizefor1Typo' => 1
|
38
|
+
}
|
39
|
+
|
40
|
+
deserialized_settings = deserialize_settings(old_settings, false)
|
22
41
|
assert_equal new_settings, deserialized_settings
|
23
42
|
end
|
24
43
|
end
|
@@ -13,7 +13,7 @@ class RetryStrategyTest
|
|
13
13
|
stateful_hosts << "#{@app_id}-4.algolianet.com"
|
14
14
|
stateful_hosts << "#{@app_id}-5.algolianet.com"
|
15
15
|
stateful_hosts << "#{@app_id}-6.algolianet.com"
|
16
|
-
@config = Algolia::Search::Config.new(
|
16
|
+
@config = Algolia::Search::Config.new(application_id: @app_id, api_key: @api_key, custom_hosts: stateful_hosts)
|
17
17
|
end
|
18
18
|
|
19
19
|
def test_resets_expired_hosts_according_to_read_type
|
@@ -74,7 +74,7 @@ class RetryStrategyTest
|
|
74
74
|
describe 'All hosts are unreachable' do
|
75
75
|
def test_failure_when_all_hosts_are_down
|
76
76
|
stateful_hosts = ['0.0.0.0']
|
77
|
-
@config = Algolia::Search::Config.new(
|
77
|
+
@config = Algolia::Search::Config.new(application_id: 'foo', api_key: 'bar', custom_hosts: stateful_hosts)
|
78
78
|
client = Algolia::Search::Client.create_with_config(@config)
|
79
79
|
index = client.init_index(get_test_index_name('failure'))
|
80
80
|
|
@@ -91,7 +91,7 @@ class RetryStrategyTest
|
|
91
91
|
super
|
92
92
|
@app_id = 'app_id'
|
93
93
|
@api_key = 'api_key'
|
94
|
-
@config = Algolia::Search::Config.new(
|
94
|
+
@config = Algolia::Search::Config.new(application_id: @app_id, api_key: @api_key)
|
95
95
|
@retry_strategy = Algolia::Transport::RetryStrategy.new(@config)
|
96
96
|
@hosts = @retry_strategy.get_tryable_hosts(READ|WRITE)
|
97
97
|
end
|
data/test/test_helper.rb
CHANGED
@@ -24,7 +24,7 @@ class Minitest::Test
|
|
24
24
|
|
25
25
|
include Minitest::Hooks
|
26
26
|
include Helpers
|
27
|
-
@@search_config = Algolia::Search::Config.new(
|
27
|
+
@@search_config = Algolia::Search::Config.new(application_id: APPLICATION_ID_1, api_key: ADMIN_KEY_1, user_agent: USER_AGENT)
|
28
28
|
@@search_client = Algolia::Search::Client.new(@@search_config)
|
29
29
|
end
|
30
30
|
|
data/upgrade_guide.md
CHANGED
@@ -5,7 +5,7 @@ First, you'll have to include the new version in your Gemfile. To do so, change
|
|
5
5
|
|
6
6
|
```diff
|
7
7
|
- gem 'algoliasearch'
|
8
|
-
+ gem 'algolia', git: 'https://github.com/algolia/algoliasearch-client-ruby.git', tag: 'v2.0.0-
|
8
|
+
+ gem 'algolia', git: 'https://github.com/algolia/algoliasearch-client-ruby.git', tag: 'v2.0.0-beta.1'
|
9
9
|
```
|
10
10
|
|
11
11
|
Then, you'll need to change your current `require` statements:
|
@@ -38,11 +38,17 @@ index = client.init_index('index_name')
|
|
38
38
|
client = Algolia::Search::Client.create('APP_ID', 'API_KEY')
|
39
39
|
index = client.init_index('index_name')
|
40
40
|
# or
|
41
|
-
search_config = Algolia::Search::Config.new(
|
41
|
+
search_config = Algolia::Search::Config.new(application_id: app_id, api_key: api_key)
|
42
42
|
client = Algolia::Search::Client.create_with_config(search_config)
|
43
43
|
index = client.init_index('index_name')
|
44
44
|
```
|
45
45
|
|
46
|
+
By default the keys of the response hashes are symbols. If you wish to change that for strings, use the following configuration
|
47
|
+
```ruby
|
48
|
+
search_config = Algolia::Search::Config.new(application_id: app_id, api_key: api_key, symbolize_keys: false)
|
49
|
+
client = Algolia::Search::Client.create_with_config(search_config)
|
50
|
+
```
|
51
|
+
|
46
52
|
## Search parameters and request options
|
47
53
|
The search parameters and request options are still optional, but they are combined into a single hash instead of two.
|
48
54
|
For example:
|
@@ -55,12 +61,8 @@ index.search('query', search_params, request_opts)
|
|
55
61
|
|
56
62
|
# After
|
57
63
|
opts = {
|
58
|
-
:
|
59
|
-
|
60
|
-
},
|
61
|
-
:params => {
|
62
|
-
hitsPerPage: 50
|
63
|
-
}
|
64
|
+
headers: { 'X-Algolia-UserToken': 'user123' },
|
65
|
+
hitsPerPage: 50
|
64
66
|
}
|
65
67
|
index.search('query', opts)
|
66
68
|
```
|
@@ -69,6 +71,20 @@ index.search('query', opts)
|
|
69
71
|
|
70
72
|
### `Client`
|
71
73
|
|
74
|
+
#### `set_extra_header`
|
75
|
+
The `set_extra_header` method has been moved from the Client to the `Algolia::BaseConfig` class. You have to define your extra headers on Client instantiation.
|
76
|
+
```ruby
|
77
|
+
# Before
|
78
|
+
client.set_extra_header('admin', 'admin-key')
|
79
|
+
|
80
|
+
# After
|
81
|
+
# `Algolia::Search::Config` inherits from `Algolia::BaseConfig`
|
82
|
+
config = Algolia::Search::Config.new(app_id: 'APP_ID', api_key: 'API_KEY')
|
83
|
+
config.set_extra_header('admin', 'admin-key')
|
84
|
+
|
85
|
+
client = Algolia::Search::Client.create_with_config(config)
|
86
|
+
```
|
87
|
+
|
72
88
|
#### `multiple_queries`
|
73
89
|
The `strategy` parameter is no longer a string, but a key in the `requestOptions`.
|
74
90
|
```ruby
|
@@ -213,7 +229,7 @@ client.search_user_ids('query', {clusterName: 'my-cluster', hitPerPage: 12, page
|
|
213
229
|
#### `pending_mappings`
|
214
230
|
New method to check the status of your clusters' migration or user creation.
|
215
231
|
```ruby
|
216
|
-
client.
|
232
|
+
client.pending_mappings?({ retrieveMappings: true })
|
217
233
|
```
|
218
234
|
|
219
235
|
#### `get_logs`
|
@@ -244,12 +260,8 @@ index.search('query', search_params, request_opts)
|
|
244
260
|
|
245
261
|
# After
|
246
262
|
opts = {
|
247
|
-
:
|
248
|
-
|
249
|
-
},
|
250
|
-
:params => {
|
251
|
-
hitsPerPage: 50
|
252
|
-
}
|
263
|
+
headers: { 'X-Algolia-UserToken': 'user123' },
|
264
|
+
hitsPerPage: 50
|
253
265
|
}
|
254
266
|
index.search('query', opts)
|
255
267
|
```
|
@@ -265,12 +277,8 @@ index.search_for_facet_values('category', 'phone', search_params, request_opts)
|
|
265
277
|
|
266
278
|
# After
|
267
279
|
opts = {
|
268
|
-
:
|
269
|
-
|
270
|
-
},
|
271
|
-
:params => {
|
272
|
-
hitsPerPage: 50
|
273
|
-
}
|
280
|
+
headers: { 'X-Algolia-UserToken': 'user123' },
|
281
|
+
hitsPerPage: 50
|
274
282
|
}
|
275
283
|
index.search_for_facet_values('category', 'phone', opts)
|
276
284
|
```
|
@@ -590,6 +598,6 @@ client = Algolia::Client.new({
|
|
590
598
|
})
|
591
599
|
|
592
600
|
# After
|
593
|
-
search_config = Algolia::Search::Config.new(
|
601
|
+
search_config = Algolia::Search::Config.new(application_id: 'app_id', api_key: 'api_key', read_timeout: 10, connect_timeout: 2)
|
594
602
|
client = Algolia::Search::Client.create_with_config(search_config)
|
595
603
|
```
|