4me-sdk 1.1.6 → 2.0.0.pre.rc.2

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.
@@ -1,8 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe 'ca-bundle.crt' do
4
-
5
- it 'should be able to connect to the 4me API' do
4
+ it 'should be able to connect to the 4me REST API' do
6
5
  WebMock.allow_net_connect!
7
6
  client = Sdk4me::Client.new(api_token: 'invalid', max_retry_time: -1)
8
7
  result = {}
@@ -13,7 +12,21 @@ describe 'ca-bundle.crt' do
13
12
  expect(response.valid?).to be_falsey
14
13
 
15
14
  # expecting 401 error
16
- expect(response.message).to eq('401: Access credentials required')
15
+ expect(response.message).to eq('401: Bad credentials')
16
+ end
17
+
18
+ it 'should be able to connect to the 4me REST API (access token)' do
19
+ WebMock.allow_net_connect!
20
+ client = Sdk4me::Client.new(access_token: 'invalid', max_retry_time: -1)
21
+ result = {}
22
+
23
+ # no exception concerning the certificate
24
+ expect { result[:response] = client.get('me') }.not_to raise_error
25
+ response = result[:response]
26
+ expect(response.valid?).to be_falsey
27
+
28
+ # expecting 401 error
29
+ expect(response.message).to eq('401: Bad credentials')
17
30
  end
18
31
 
19
32
  it 'should be able to connect to S3' do
@@ -23,6 +36,6 @@ describe 'ca-bundle.crt' do
23
36
  http.use_ssl = true
24
37
 
25
38
  # no SSL error please
26
- expect{ http.start{ |_http| _http.request(Net::HTTP::Get.new('/exports/20141107/')) } }.to never_raise(OpenSSL::SSL::SSLError)
39
+ expect { http.start { |transport| transport.request(Net::HTTP::Get.new('/exports/20141107/')) } }.to never_raise(OpenSSL::SSL::SSLError)
27
40
  end
28
41
  end
@@ -1,583 +1,598 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Sdk4me::Client do
4
-
5
- context 'Sdk4me.config' do
6
- before(:each) do
7
- Sdk4me.configure do |config|
8
- config.max_retry_time = 120 # override default value (5400)
9
- config.api_token = 'secret' # set value
10
- end
11
- end
12
-
13
- it 'should define the MAX_PAGE_SIZE' do
14
- expect(Sdk4me::Client::MAX_PAGE_SIZE).to eq(100)
15
- end
16
-
17
- it 'should use the Sdk4me configuration' do
18
- client = Sdk4me::Client.new
19
- expect(client.option(:host)).to eq('https://api.4me.com') # default value
20
- expect(client.option(:api_token)).to eq('secret') # value set using Sdk4me.config
21
- expect(client.option(:max_retry_time)).to eq(120) # value overridden in Sdk4me.config
4
+ def client(authentication, options = {})
5
+ (@client ||= {})["#{authentication}-#{options}"] ||= begin
6
+ options = { max_retry_time: -1 }.merge(options)
7
+ options = if authentication == :api_token
8
+ { api_token: 'secret' }.merge(options)
9
+ else
10
+ { access_token: 'secret' }.merge(options)
11
+ end
12
+ Sdk4me::Client.new(options)
22
13
  end
14
+ end
23
15
 
24
- it 'should override the Sdk4me configuration' do
25
- client = Sdk4me::Client.new(host: 'https://demo.4me.com', api_token: 'unknown', block_at_rate_limit: true)
26
- expect(client.option(:read_timeout)).to eq(25) # default value
27
- expect(client.option(:host)).to eq('https://demo.4me.com') # default value overridden in Client.new
28
- expect(client.option(:api_token)).to eq('unknown') # value set using Sdk4me.config and overridden in Client.new
29
- expect(client.option(:max_retry_time)).to eq(120) # value overridden in Sdk4me.config
30
- expect(client.option(:block_at_rate_limit)).to eq(true) # value overridden in Client.new
16
+ def credentials(authentication)
17
+ if authentication == :api_token
18
+ { basic_auth: %w[secret x] }
19
+ else
20
+ { headers: { 'Authorization' => 'Bearer secret' } }
31
21
  end
22
+ end
32
23
 
33
- [:host, :api_version, :api_token].each do |required_option|
34
- it "should require option #{required_option}" do
35
- expect { Sdk4me::Client.new(required_option => '') }.to raise_error("Missing required configuration option #{required_option}")
24
+ %i[api_token access_token].each do |authentication|
25
+ context 'Sdk4me.config' do
26
+ before(:each) do
27
+ Sdk4me.configure do |config|
28
+ config.max_retry_time = 120 # override default value (5400)
29
+ if authentication == :api_token
30
+ config.api_token = 'secret' # set value
31
+ else
32
+ config.access_token = 'secret'
33
+ end
34
+ end
36
35
  end
37
- end
38
36
 
39
- [ ['https://api.4me.com', true, 'api.4me.com', 443],
40
- ['https://api.example.com:777', true, 'api.example.com', 777],
41
- ['http://sdk4me.example.com', false, 'sdk4me.example.com', 80],
42
- ['http://sdk4me.example.com:777', false, 'sdk4me.example.com', 777]
43
- ].each do |host, ssl, domain, port|
44
- it 'should parse ssl, host and port' do
45
- client = Sdk4me::Client.new(host: host)
46
- expect(client.instance_variable_get(:@ssl)).to eq(ssl)
47
- expect(client.instance_variable_get(:@domain)).to eq(domain)
48
- expect(client.instance_variable_get(:@port)).to eq(port)
37
+ it 'should define the MAX_PAGE_SIZE' do
38
+ expect(Sdk4me::Client::MAX_PAGE_SIZE).to eq(100)
49
39
  end
50
- end
51
- end
52
40
 
53
- it 'should set the ca-bundle.crt file' do
54
- http = Net::HTTP.new('https://api.4me.com')
55
- http.use_ssl = true
56
-
57
- on_disk = `ls #{http.ca_file}`
58
- expect(on_disk).not_to match(/cannot access/)
59
- expect(on_disk).to match(/\/ca-bundle.crt$/)
60
- end
41
+ it 'should use the Sdk4me configuration' do
42
+ client = Sdk4me::Client.new
43
+ expect(client.option(:host)).to eq('https://api.4me.com') # default value
44
+ if authentication == :api_token
45
+ expect(client.option(:api_token)).to eq('secret') # value set using Sdk4me.config
46
+ else
47
+ expect(client.option(:access_token)).to eq('secret') # value set using Sdk4me.config
48
+ end
49
+ expect(client.option(:max_retry_time)).to eq(120) # value overridden in Sdk4me.config
50
+ end
61
51
 
62
- describe 'headers' do
63
- before(:each) do
64
- @client = Sdk4me::Client.new(api_token: 'secret', max_retry_time: -1)
65
- end
52
+ it 'should override the Sdk4me configuration' do
53
+ client = Sdk4me::Client.new(host: 'https://demo.4me.com', api_token: 'unknown', block_at_rate_limit: true)
54
+ expect(client.option(:read_timeout)).to eq(25) # default value
55
+ expect(client.option(:host)).to eq('https://demo.4me.com') # default value overridden in Client.new
56
+ expect(client.option(:api_token)).to eq('unknown') # value set using Sdk4me.config and overridden in Client.new
57
+ expect(client.option(:max_retry_time)).to eq(120) # value overridden in Sdk4me.config
58
+ expect(client.option(:block_at_rate_limit)).to eq(true) # value overridden in Client.new
59
+ end
66
60
 
67
- it 'should set the content type header' do
68
- stub = stub_request(:get, 'https://api.4me.com/v1/me').with(basic_auth: ['secret', 'x']).with(headers: {'Content-Type' => 'application/json'}).to_return(body: {name: 'my name'}.to_json)
69
- @client.get('me')
70
- expect(stub).to have_been_requested
71
- end
61
+ %i[host api_version].each do |required_option|
62
+ it "should require option #{required_option}" do
63
+ expect { Sdk4me::Client.new(required_option => '') }.to raise_error("Missing required configuration option #{required_option}")
64
+ end
65
+ end
72
66
 
73
- it 'should add the X-4me-Account header' do
74
- client = Sdk4me::Client.new(api_token: 'secret', max_retry_time: -1, account: 'test')
75
- stub = stub_request(:get, 'https://api.4me.com/v1/me').with(basic_auth: ['secret', 'x']).with(headers: {'X-4me-Account' => 'test'}).to_return(body: {name: 'my name'}.to_json)
76
- client.get('me')
77
- expect(stub).to have_been_requested
78
- end
67
+ it 'should require access_token' do
68
+ expect { Sdk4me::Client.new(access_token: '', api_token: '') }.to raise_error('Missing required configuration option access_token')
69
+ end
79
70
 
80
- it 'should add the X-4me-Source header' do
81
- client = Sdk4me::Client.new(api_token: 'secret', max_retry_time: -1, source: 'myapp')
82
- stub = stub_request(:get, 'https://api.4me.com/v1/me').with(basic_auth: ['secret', 'x']).with(headers: {'X-4me-Source' => 'myapp'}).to_return(body: {name: 'my name'}.to_json)
83
- client.get('me')
84
- expect(stub).to have_been_requested
71
+ [['https://api.4me.com', true, 'api.4me.com', 443],
72
+ ['https://api.example.com:777', true, 'api.example.com', 777],
73
+ ['http://sdk4me.example.com', false, 'sdk4me.example.com', 80],
74
+ ['http://sdk4me.example.com:777', false, 'sdk4me.example.com', 777]].each do |host, ssl, domain, port|
75
+ it 'should parse ssl, host and port' do
76
+ client = Sdk4me::Client.new(host: host)
77
+ expect(client.instance_variable_get(:@ssl)).to eq(ssl)
78
+ expect(client.instance_variable_get(:@domain)).to eq(domain)
79
+ expect(client.instance_variable_get(:@port)).to eq(port)
80
+ end
81
+ end
85
82
  end
86
83
 
87
- it 'should be able to override headers' do
88
- stub = stub_request(:get, 'https://api.4me.com/v1/me').with(basic_auth: ['secret', 'x']).with(headers: {'Content-Type' => 'application/x-www-form-urlencoded'}).to_return(body: {name: 'my name'}.to_json)
89
- @client.get('me', {}, {'Content-Type' => 'application/x-www-form-urlencoded'})
90
- expect(stub).to have_been_requested
91
- end
84
+ it 'should set the ca-bundle.crt file' do
85
+ http = Net::HTTP.new('https://api.4me.com')
86
+ http.use_ssl = true
92
87
 
93
- it 'should set the other headers' do
94
- stub = stub_request(:get, 'https://api.4me.com/v1/me').with(basic_auth: ['secret', 'x']).with(headers: {'X-4me-Other' => 'value'}).to_return(body: {name: 'my name'}.to_json)
95
- @client.get('me', {}, {'X-4me-Other' => 'value'})
96
- expect(stub).to have_been_requested
88
+ on_disk = `ls #{http.ca_file}`
89
+ expect(on_disk).not_to match(/cannot access/)
90
+ expect(on_disk).to match(%r{/ca-bundle.crt$})
97
91
  end
98
92
 
99
- it 'should accept headers in the each call' do
100
- stub = stub_request(:get, 'https://api.4me.com/v1/requests?fields=subject&page=1&per_page=100').with(basic_auth: ['secret', 'x']).with(headers: {'X-4me-Secret' => 'special'}).to_return(body: [{id: 1, subject: 'Subject 1'}, {id: 2, subject: 'Subject 2'}, {id: 3, subject: 'Subject 3'}].to_json)
101
- @client.each('requests', {fields: 'subject'}, {'X-4me-Secret' => 'special'}) do |request|
102
- expect(request[:subject]).to eq("Subject #{request[:id]}")
93
+ describe 'headers' do
94
+ it 'should set the content type header' do
95
+ stub = stub_request(:get, 'https://api.4me.com/v1/me').with(credentials(authentication)).with(headers: { 'Content-Type' => 'application/json' }).to_return(body: { name: 'my name' }.to_json)
96
+ client(authentication).get('me')
97
+ expect(stub).to have_been_requested
103
98
  end
104
- expect(stub).to have_been_requested
105
- end
106
- end
107
99
 
108
- context 'each' do
109
- before(:each) do
110
- @client = Sdk4me::Client.new(api_token: 'secret', max_retry_time: -1)
111
- end
112
-
113
- it 'should yield each result' do
114
- stub_request(:get, 'https://api.4me.com/v1/requests?fields=subject&page=1&per_page=100').with(basic_auth: ['secret', 'x']).to_return(body: [{id: 1, subject: 'Subject 1'}, {id: 2, subject: 'Subject 2'}, {id: 3, subject: 'Subject 3'}].to_json)
115
- nr_of_requests = @client.each('requests', {fields: 'subject'}) do |request|
116
- expect(request[:subject]).to eq("Subject #{request[:id]}")
100
+ it 'should add the X-4me-Account header' do
101
+ client = client(authentication, account: 'test')
102
+ stub = stub_request(:get, 'https://api.4me.com/v1/me').with(credentials(authentication)).with(headers: { 'X-4me-Account' => 'test' }).to_return(body: { name: 'my name' }.to_json)
103
+ client.get('me')
104
+ expect(stub).to have_been_requested
117
105
  end
118
- expect(nr_of_requests).to eq(3)
119
- end
120
106
 
121
- it 'should retrieve multiple pages' do
122
- stub_page1 = stub_request(:get, 'https://api.4me.com/v1/requests?page=1&per_page=2').with(basic_auth: ['secret', 'x']).to_return(body: [{id: 1, subject: 'Subject 1'}, {id: 2, subject: 'Subject 2'}].to_json, headers: {'Link' => '<https://api.4me.com/v1/requests?page=1&per_page=2>; rel="first",<https://api.4me.com/v1/requests?page=2&per_page=2>; rel="next",<https://api.4me.com/v1/requests?page=2&per_page=2>; rel="last"'})
123
- stub_page2 = stub_request(:get, 'https://api.4me.com/v1/requests?page=2&per_page=2').with(basic_auth: ['secret', 'x']).to_return(body: [{id: 3, subject: 'Subject 3'}].to_json, headers: {'Link' => '<https://api.4me.com/v1/requests?page=1&per_page=2>; rel="first",<https://api.4me.com/v1/requests?page=1&per_page=2>; rel="prev",<https://api.4me.com/v1/requests?page=2&per_page=2>; rel="last"'})
124
- nr_of_requests = @client.each('requests', {per_page: 2}) do |request|
125
- expect(request[:subject]).to eq("Subject #{request[:id]}")
107
+ it 'should add the X-4me-Source header' do
108
+ client = client(authentication, source: 'myapp')
109
+ stub = stub_request(:get, 'https://api.4me.com/v1/me').with(credentials(authentication)).with(headers: { 'X-4me-Source' => 'myapp' }).to_return(body: { name: 'my name' }.to_json)
110
+ client.get('me')
111
+ expect(stub).to have_been_requested
126
112
  end
127
- expect(nr_of_requests).to eq(3)
128
- expect(stub_page2).to have_been_requested
129
- end
130
- end
131
113
 
132
- context 'get' do
133
- before(:each) do
134
- @client = Sdk4me::Client.new(api_token: 'secret', max_retry_time: -1)
135
- end
136
-
137
- it 'should return a response' do
138
- stub_request(:get, 'https://api.4me.com/v1/me').with(basic_auth: ['secret', 'x']).to_return(body: {name: 'my name'}.to_json)
139
- response = @client.get('me')
140
- expect(response[:name]).to eq('my name')
141
- end
142
-
143
- describe 'parameters' do
144
-
145
- [[nil, ''],
146
- [ 'normal', 'normal'],
147
- [ 'hello;<', 'hello%3B%3C'],
148
- [ true, 'true'],
149
- [ false, 'false'],
150
- [ DateTime.now, DateTime.now.new_offset(0).iso8601.gsub('+', '%2B')],
151
- [ Date.new, Date.new.strftime('%Y-%m-%d')],
152
- [ Time.now, Time.now.strftime('%H:%M')],
153
- [ ['first', 'second;<', true], 'first,second%3B%3C,true']
154
- ].each do |param_value, url_value|
155
- it "should cast #{param_value.class.name}: '#{param_value}' to '#{url_value}'" do
156
- stub = stub_request(:get, "https://api.4me.com/v1/me?value=#{url_value}").with(basic_auth: ['secret', 'x']).to_return(body: {name: 'my name'}.to_json)
157
- @client.get('me', {value: param_value})
158
- expect(stub).to have_been_requested
159
- end
114
+ it 'should add a default User-Agent header' do
115
+ client = client(authentication)
116
+ stub = stub_request(:get, 'https://api.4me.com/v1/me').with(credentials(authentication)).with(headers: { 'User-Agent' => "4me-sdk-ruby/#{Sdk4me::Client::VERSION}" }).to_return(body: { name: 'my name' }.to_json)
117
+ client.get('me')
118
+ expect(stub).to have_been_requested
160
119
  end
161
120
 
162
- it 'should not cast arrays in post and put calls' do
163
- client = Sdk4me::Client.new(api_token: 'secret', max_retry_time: -1)
164
- stub = stub_request(:post, 'https://api.4me.com/v1/people').with(basic_auth: ['secret', 'x']).with(body: {user_ids: [1, 2, 3]}, headers: {'X-4me-Custom' => 'custom'}).to_return(body: {id: 101}.to_json)
165
- client.post('people', {user_ids: [1, 2, 3]}, {'X-4me-Custom' => 'custom'})
121
+ it 'should override the default User-Agent header' do
122
+ client = client(authentication, user_agent: 'Foo/1.0')
123
+ stub = stub_request(:get, 'https://api.4me.com/v1/me').with(credentials(authentication)).with(headers: { 'User-Agent' => 'Foo/1.0' }).to_return(body: { name: 'my name' }.to_json)
124
+ client.get('me')
166
125
  expect(stub).to have_been_requested
167
126
  end
168
127
 
169
- it 'should not cast hashes in post and put calls' do
170
- client = Sdk4me::Client.new(api_token: 'secret', max_retry_time: -1)
171
- stub = stub_request(:patch, 'https://api.4me.com/v1/people/55').with(basic_auth: ['secret', 'x']).with(body: '{"contacts_attributes":{"0":{"protocol":"email","label":"work","uri":"work@example.com"}}}', headers: {'X-4me-Custom' => 'custom'}).to_return(body: {id: 101}.to_json)
172
- client.put('people/55', {contacts_attributes: {0 => {protocol: :email, label: :work, uri: 'work@example.com'}}}, {'X-4me-Custom' => 'custom'})
128
+ it 'should be able to override default headers' do
129
+ stub = stub_request(:get, 'https://api.4me.com/v1/me').with(credentials(authentication)).with(headers: { 'Content-Type' => 'application/x-www-form-urlencoded' }).to_return(body: { name: 'my name' }.to_json)
130
+ client(authentication).get('me', {}, { 'Content-Type' => 'application/x-www-form-urlencoded' })
173
131
  expect(stub).to have_been_requested
174
132
  end
175
133
 
176
- it 'should not double escape symbols' do
177
- client = Sdk4me::Client.new(api_token: 'secret', max_retry_time: -1)
178
- stub = stub_request(:patch, 'https://api.4me.com/v1/people/55').with(basic_auth: ['secret', 'x']).with(body: '{"status":"waiting_for"}').to_return(body: {id: 101}.to_json)
179
- client.put('people/55', {status: :waiting_for})
134
+ it 'should be able to override option headers' do
135
+ stub = stub_request(:get, 'https://api.4me.com/v1/me').with(credentials(authentication)).with(headers: { 'X-4me-Source' => 'foo' }).to_return(body: { name: 'my name' }.to_json)
136
+ client(authentication, source: 'myapp').get('me', {}, { 'X-4me-Source' => 'foo' })
180
137
  expect(stub).to have_been_requested
181
138
  end
182
139
 
183
- it 'should handle fancy filter operations' do
184
- now = DateTime.now
185
- stub = stub_request(:get, "https://api.4me.com/v1/people?created_at=>#{now.new_offset(0).iso8601.gsub('+', '%2B')}&id!=15").with(basic_auth: ['secret', 'x']).to_return(body: {name: 'my name'}.to_json)
186
- @client.get('people', {'created_at=>' => now, 'id!=' => 15})
140
+ it 'should set the other headers' do
141
+ stub = stub_request(:get, 'https://api.4me.com/v1/me').with(credentials(authentication)).with(headers: { 'X-4me-Other' => 'value' }).to_return(body: { name: 'my name' }.to_json)
142
+ client(authentication).get('me', {}, { 'X-4me-Other' => 'value' })
187
143
  expect(stub).to have_been_requested
188
144
  end
189
145
 
190
- it 'should append parameters' do
191
- stub = stub_request(:get, 'https://api.4me.com/v1/people?id!=15&primary_email=me@example.com').with(basic_auth: ['secret', 'x']).to_return(body: {name: 'my name'}.to_json)
192
- @client.get('people?id!=15', {primary_email: 'me@example.com'})
146
+ it 'should accept headers in the each call' do
147
+ stub = stub_request(:get, 'https://api.4me.com/v1/requests?fields=subject&page=1&per_page=100').with(credentials(authentication)).with(headers: { 'X-4me-Secret' => 'special' }).to_return(body: [{ id: 1, subject: 'Subject 1' }, { id: 2, subject: 'Subject 2' }, { id: 3, subject: 'Subject 3' }].to_json)
148
+ client(authentication).each('requests', { fields: 'subject' }, { 'X-4me-Secret' => 'special' }) do |request|
149
+ expect(request[:subject]).to eq("Subject #{request[:id]}")
150
+ end
193
151
  expect(stub).to have_been_requested
194
152
  end
195
153
  end
196
- end
197
154
 
198
- context 'patch' do
199
- [:put, :patch].each do |method|
200
- it 'should send patch requests with parameters and headers for #{method} calls' do
201
- client = Sdk4me::Client.new(api_token: 'secret', max_retry_time: -1)
202
- stub = stub_request(:patch, 'https://api.4me.com/v1/people/1').with(basic_auth: ['secret', 'x']).with(body: {name: 'New Name'}, headers: {'X-4me-Custom' => 'custom'}).to_return(body: {id: 1}.to_json)
203
- client.send(method, 'people/1', {name: 'New Name'}, {'X-4me-Custom' => 'custom'})
204
- expect(stub).to have_been_requested
155
+ context 'each' do
156
+ it 'should yield each result' do
157
+ stub_request(:get, 'https://api.4me.com/v1/requests?fields=subject&page=1&per_page=100').with(credentials(authentication)).to_return(body: [{ id: 1, subject: 'Subject 1' }, { id: 2, subject: 'Subject 2' }, { id: 3, subject: 'Subject 3' }].to_json)
158
+ nr_of_requests = client(authentication).each('requests', { fields: 'subject' }) do |request|
159
+ expect(request[:subject]).to eq("Subject #{request[:id]}")
160
+ end
161
+ expect(nr_of_requests).to eq(3)
205
162
  end
206
- end
207
- end
208
163
 
209
- context 'post' do
210
- it 'should send post requests with parameters and headers' do
211
- client = Sdk4me::Client.new(api_token: 'secret', max_retry_time: -1)
212
- stub = stub_request(:post, 'https://api.4me.com/v1/people').with(basic_auth: ['secret', 'x']).with(body: {name: 'New Name'}, headers: {'X-4me-Custom' => 'custom'}).to_return(body: {id: 101}.to_json)
213
- client.post('people', {name: 'New Name'}, {'X-4me-Custom' => 'custom'})
214
- expect(stub).to have_been_requested
164
+ it 'should retrieve multiple pages' do
165
+ stub_page1 = stub_request(:get, 'https://api.4me.com/v1/requests?page=1&per_page=2').with(credentials(authentication)).to_return(body: [{ id: 1, subject: 'Subject 1' }, { id: 2, subject: 'Subject 2' }].to_json, headers: { 'Link' => '<https://api.4me.com/v1/requests?page=1&per_page=2>; rel="first",<https://api.4me.com/v1/requests?page=2&per_page=2>; rel="next",<https://api.4me.com/v1/requests?page=2&per_page=2>; rel="last"' })
166
+ stub_page2 = stub_request(:get, 'https://api.4me.com/v1/requests?page=2&per_page=2').with(credentials(authentication)).to_return(body: [{ id: 3, subject: 'Subject 3' }].to_json, headers: { 'Link' => '<https://api.4me.com/v1/requests?page=1&per_page=2>; rel="first",<https://api.4me.com/v1/requests?page=1&per_page=2>; rel="prev",<https://api.4me.com/v1/requests?page=2&per_page=2>; rel="last"' })
167
+ nr_of_requests = client(authentication).each('requests', { per_page: 2 }) do |request|
168
+ expect(request[:subject]).to eq("Subject #{request[:id]}")
169
+ end
170
+ expect(nr_of_requests).to eq(3)
171
+ expect(stub_page1).to have_been_requested
172
+ expect(stub_page2).to have_been_requested
173
+ end
215
174
  end
216
- end
217
175
 
218
- context 'delete' do
219
- it 'should send delete requests with parameters and headers' do
220
- client = Sdk4me::Client.new(api_token: 'secret', max_retry_time: -1)
221
- stub = stub_request(:delete, 'https://api.4me.com/v1/people?id=value').with(basic_auth: ['secret', 'x']).with(headers: {'X-4me-Custom' => 'custom'}).to_return(body: '', status: 204)
222
- response = client.delete('people', {id: 'value'}, {'X-4me-Custom' => 'custom'})
223
- expect(stub).to have_been_requested
224
- expect(response.valid?).to be_truthy
225
- expect(response.json).to eq({})
226
- end
227
- end
176
+ context 'get' do
177
+ it 'should return a response' do
178
+ stub_request(:get, 'https://api.4me.com/v1/me').with(credentials(authentication)).to_return(body: { name: 'my name' }.to_json)
179
+ response = client(authentication).get('me')
180
+ expect(response[:name]).to eq('my name')
181
+ end
228
182
 
229
- context 'attachments' do
230
- before(:each) do
231
- @client = Sdk4me::Client.new(api_token: 'secret', max_retry_time: -1)
232
- end
183
+ describe 'parameters' do
184
+ [[nil, ''],
185
+ %w[normal normal],
186
+ ['hello;<', 'hello%3B%3C'],
187
+ [true, 'true'],
188
+ [false, 'false'],
189
+ [DateTime.now, DateTime.now.new_offset(0).iso8601.gsub('+', '%2B')],
190
+ [Date.new, Date.new.strftime('%Y-%m-%d')],
191
+ [Time.now, Time.now.strftime('%H:%M')],
192
+ [['first', 'second;<', true], 'first,second%3B%3C,true']].each do |param_value, url_value|
193
+ it "should cast #{param_value.class.name}: '#{param_value}' to '#{url_value}'" do
194
+ stub = stub_request(:get, "https://api.4me.com/v1/me?value=#{url_value}").with(credentials(authentication)).to_return(body: { name: 'my name' }.to_json)
195
+ client(authentication).get('me', { value: param_value })
196
+ expect(stub).to have_been_requested
197
+ end
198
+ end
233
199
 
234
- it 'should not log an error for XML responses' do
235
- xml = %(<?xml version="1.0" encoding="UTF-8"?>\n<details>some info</details>)
236
- stub_request(:get, 'https://api.4me.com/v1/me').with(basic_auth: ['secret', 'x']).to_return(body: xml)
237
- expect_log('Sending GET request to api.4me.com:443/v1/me', :debug)
238
- expect_log("XML response:\n#{xml}", :debug)
239
- response = @client.get('me')
240
- expect(response.valid?).to be_falsey
241
- expect(response.raw.body).to eq(xml)
242
- end
200
+ it 'should not cast arrays in post and put calls' do
201
+ stub = stub_request(:post, 'https://api.4me.com/v1/people').with(credentials(authentication)).with(body: { user_ids: [1, 2, 3] }, headers: { 'X-4me-Custom' => 'custom' }).to_return(body: { id: 101 }.to_json)
202
+ client(authentication).post('people', { user_ids: [1, 2, 3] }, { 'X-4me-Custom' => 'custom' })
203
+ expect(stub).to have_been_requested
204
+ end
243
205
 
244
- it 'should not log an error for redirects' do
245
- stub_request(:get, 'https://api.4me.com/v1/me').with(basic_auth: ['secret', 'x']).to_return(body: '', status: 303, headers: {'Location' => 'http://redirect.example.com/to/here'})
246
- expect_log('Sending GET request to api.4me.com:443/v1/me', :debug)
247
- expect_log('Redirect: http://redirect.example.com/to/here', :debug)
248
- response = @client.get('me')
249
- expect(response.valid?).to be_falsey
250
- expect(response.raw.body).to be_nil
251
- end
206
+ it 'should not cast hashes in post and put calls' do
207
+ stub = stub_request(:patch, 'https://api.4me.com/v1/people/55').with(credentials(authentication)).with(body: '{"contacts_attributes":{"0":{"protocol":"email","label":"work","uri":"work@example.com"}}}', headers: { 'X-4me-Custom' => 'custom' }).to_return(body: { id: 101 }.to_json)
208
+ client(authentication).put('people/55', { contacts_attributes: { 0 => { protocol: :email, label: :work, uri: 'work@example.com' } } }, { 'X-4me-Custom' => 'custom' })
209
+ expect(stub).to have_been_requested
210
+ end
252
211
 
253
- it "should not parse attachments for get requests" do
254
- expect(Sdk4me::Attachments).not_to receive(:new)
255
- stub_request(:get, 'https://api.4me.com/v1/requests/777?attachments=/tmp/first.png,/tmp/second.zip&note=note').with(basic_auth: ['secret', 'x']).to_return(body: {id: 777, upload_called: false}.to_json)
212
+ it 'should not double escape symbols' do
213
+ stub = stub_request(:patch, 'https://api.4me.com/v1/people/55').with(credentials(authentication)).with(body: '{"status":"waiting_for"}').to_return(body: { id: 101 }.to_json)
214
+ client(authentication).put('people/55', { status: :waiting_for })
215
+ expect(stub).to have_been_requested
216
+ end
256
217
 
257
- response = @client.get('/requests/777', {note: 'note', attachments: ['/tmp/first.png', '/tmp/second.zip'] })
258
- expect(response.valid?).to be_truthy
259
- expect(response[:upload_called]).to be_falsey
260
- end
218
+ it 'should handle fancy filter operations' do
219
+ now = DateTime.now
220
+ stub = stub_request(:get, "https://api.4me.com/v1/people?created_at=>#{now.new_offset(0).iso8601.gsub('+', '%2B')}&id!=15").with(credentials(authentication)).to_return(body: { name: 'my name' }.to_json)
221
+ client(authentication).get('people', { 'created_at=>' => now, 'id!=' => 15 })
222
+ expect(stub).to have_been_requested
223
+ end
261
224
 
262
- [:post, :patch].each do |method|
263
- it "should parse attachments for #{method} requests" do
264
- attachments = double('Sdk4me::Attachments')
265
- expect(attachments).to receive(:upload_attachments!) do |path, data|
266
- expect(path).to eq '/requests/777'
267
- expect(data[:attachments]).to eq ['/tmp/first.png', '/tmp/second.zip']
268
- data.delete(:attachments)
269
- data[:note_attachments] = 'processed'
225
+ it 'should append parameters' do
226
+ stub = stub_request(:get, 'https://api.4me.com/v1/people?id!=15&primary_email=me@example.com').with(credentials(authentication)).to_return(body: { name: 'my name' }.to_json)
227
+ client(authentication).get('people?id!=15', { primary_email: 'me@example.com' })
228
+ expect(stub).to have_been_requested
270
229
  end
271
- expect(Sdk4me::Attachments).to receive(:new).with(@client){ attachments }
272
- stub_request(method, 'https://api.4me.com/v1/requests/777').with(basic_auth: ['secret', 'x']).with(body: {note: 'note', note_attachments: 'processed' }).to_return(body: {id: 777, upload_called: true}.to_json)
230
+ end
231
+ end
273
232
 
274
- response = @client.send(method, '/requests/777', {note: 'note', attachments: ['/tmp/first.png', '/tmp/second.zip'] })
275
- expect(response.valid?).to be_truthy
276
- expect(response[:upload_called]).to be_truthy
233
+ context 'patch' do
234
+ %i[put patch].each do |method|
235
+ it "should send patch requests with parameters and headers for #{method} calls" do
236
+ stub = stub_request(:patch, 'https://api.4me.com/v1/people/1').with(credentials(authentication)).with(body: { name: 'New Name' }, headers: { 'X-4me-Custom' => 'custom' }).to_return(body: { id: 1 }.to_json)
237
+ client(authentication).send(method, 'people/1', { name: 'New Name' }, { 'X-4me-Custom' => 'custom' })
238
+ expect(stub).to have_been_requested
239
+ end
277
240
  end
278
241
  end
279
242
 
280
- end
243
+ context 'post' do
244
+ it 'should send post requests with parameters and headers' do
245
+ stub = stub_request(:post, 'https://api.4me.com/v1/people').with(credentials(authentication)).with(body: { name: 'New Name' }, headers: { 'X-4me-Custom' => 'custom' }).to_return(body: { id: 101 }.to_json)
246
+ client(authentication).post('people', { name: 'New Name' }, { 'X-4me-Custom' => 'custom' })
247
+ expect(stub).to have_been_requested
248
+ end
249
+ end
281
250
 
282
- context 'import' do
283
- before(:each) do
284
- @client = Sdk4me::Client.new(api_token: 'secret', max_retry_time: -1)
285
- csv_mime_type = ['text/csv', 'text/comma-separated-values'].detect{|t| MIME::Types[t].any?} # which mime type is used depends on version of mime-types gem
286
- @multi_part_body = "--0123456789ABLEWASIEREISAWELBA9876543210\r\nContent-Disposition: form-data; name=\"type\"\r\n\r\npeople\r\n--0123456789ABLEWASIEREISAWELBA9876543210\r\nContent-Disposition: form-data; name=\"file\"; filename=\"#{@fixture_dir}/people.csv\"\r\nContent-Type: #{csv_mime_type}\r\n\r\nPrimary Email,Name\nchess.cole@example.com,Chess Cole\ned.turner@example.com,Ed Turner\r\n--0123456789ABLEWASIEREISAWELBA9876543210--"
287
- @multi_part_headers = {'Accept'=>'*/*', 'Content-Type'=>'multipart/form-data; boundary=0123456789ABLEWASIEREISAWELBA9876543210', 'User-Agent'=>'Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en-us) AppleWebKit/523.10.6 (KHTML, like Gecko) Version/3.0.4 Safari/523.10.6'}
288
-
289
- @import_queued_response = {body: {state: 'queued'}.to_json}
290
- @import_processing_response = {body: {state: 'processing'}.to_json}
291
- @import_done_response = {body: {state: 'done', results: {errors: 0, updated: 1, created: 1, failures: 0, unchanged: 0, deleted: 0}}.to_json}
292
- @import_failed_response = {body: {state: 'error', message: 'Invalid byte sequence in UTF-8 on line 2', results: {errors: 1, updated: 1, created: 0, failures: 1, unchanged: 0, deleted: 0}}.to_json}
293
- allow(@client).to receive(:sleep)
294
- WebMock.disable_net_connect!
251
+ context 'delete' do
252
+ it 'should send delete requests with parameters and headers' do
253
+ stub = stub_request(:delete, 'https://api.4me.com/v1/people?id=value').with(credentials(authentication)).with(headers: { 'X-4me-Custom' => 'custom' }).to_return(body: '', status: 204)
254
+ response = client(authentication).delete('people', { id: 'value' }, { 'X-4me-Custom' => 'custom' })
255
+ expect(stub).to have_been_requested
256
+ expect(response.valid?).to be_truthy
257
+ expect(response.json).to eq({})
258
+ end
295
259
  end
296
260
 
297
- it 'should import a CSV file' do
298
- stub_request(:post, 'https://api.4me.com/v1/import').with(basic_auth: ['secret', 'x']).with(body: @multi_part_body, headers: @multi_part_headers).to_return(body: {token: '68ef5ef0f64c0'}.to_json)
299
- expect_log("Import file '#{@fixture_dir}/people.csv' successfully uploaded with token '68ef5ef0f64c0'.")
261
+ context 'attachments' do
262
+ it 'should not log an error for XML responses' do
263
+ xml = %(<?xml version="1.0" encoding="UTF-8"?>\n<details>some info</details>)
264
+ stub_request(:get, 'https://api.4me.com/v1/me').with(credentials(authentication)).to_return(body: xml)
265
+ expect_log('Sending GET request to api.4me.com:443/v1/me', :debug)
266
+ expect_log("XML response:\n#{xml}", :debug)
267
+ response = client(authentication).get('me')
268
+ expect(response.valid?).to be_falsey
269
+ expect(response.raw.body).to eq(xml)
270
+ end
300
271
 
301
- response = @client.import(File.new("#{@fixture_dir}/people.csv"), 'people')
302
- expect(response[:token]).to eq('68ef5ef0f64c0')
303
- end
272
+ it 'should not log an error for redirects' do
273
+ stub_request(:get, 'https://api.4me.com/v1/me').with(credentials(authentication)).to_return(body: '', status: 303, headers: { 'Location' => 'http://redirect.example.com/to/here' })
274
+ expect_log('Sending GET request to api.4me.com:443/v1/me', :debug)
275
+ expect_log('Redirect: http://redirect.example.com/to/here', :debug)
276
+ response = client(authentication).get('me')
277
+ expect(response.valid?).to be_falsey
278
+ expect(response.raw.body).to eq('')
279
+ end
304
280
 
305
- it 'should import a CSV file by filename' do
306
- stub_request(:post, 'https://api.4me.com/v1/import').with(basic_auth: ['secret', 'x']).with(body: @multi_part_body, headers: @multi_part_headers).to_return(body: {token: '68ef5ef0f64c0'}.to_json)
307
- response = @client.import("#{@fixture_dir}/people.csv", 'people')
308
- expect(response[:token]).to eq('68ef5ef0f64c0')
309
- end
281
+ it 'should not parse attachments for get requests' do
282
+ expect(Sdk4me::Attachments).not_to receive(:new)
283
+ stub_request(:get, 'https://api.4me.com/v1/requests/777?note_attachments=/tmp/first.png,/tmp/second.zip&note=note%20%5Battachment:/tmp/third.gif%5D').with(credentials(authentication)).to_return(body: { id: 777, upload_called: false }.to_json)
310
284
 
311
- it 'should wait for the import to complete' do
312
- stub_request(:post, 'https://api.4me.com/v1/import').with(basic_auth: ['secret', 'x']).with(body: @multi_part_body, headers: @multi_part_headers).to_return(body: {token: '68ef5ef0f64c0'}.to_json)
313
- progress_stub = stub_request(:get, 'https://api.4me.com/v1/import/68ef5ef0f64c0').with(basic_auth: ['secret', 'x'])
314
- .to_return(@import_queued_response, @import_processing_response)
315
- .then.to_raise(StandardError.new('network error'))
316
- .then.to_return(@import_done_response)
317
-
318
- # verify the correct log statement are made
319
- expect_log('Sending POST request to api.4me.com:443/v1/import', :debug)
320
- expect_log("Response:\n{\n \"token\": \"68ef5ef0f64c0\"\n}", :debug)
321
- expect_log("Import file '#{@fixture_dir}/people.csv' successfully uploaded with token '68ef5ef0f64c0'.")
322
- expect_log('Sending GET request to api.4me.com:443/v1/import/68ef5ef0f64c0', :debug)
323
- expect_log("Response:\n{\n \"state\": \"queued\"\n}", :debug)
324
- expect_log("Import of '#{@fixture_dir}/people.csv' is queued. Checking again in 30 seconds.", :debug)
325
- expect_log('Sending GET request to api.4me.com:443/v1/import/68ef5ef0f64c0', :debug)
326
- expect_log("Response:\n{\n \"state\": \"processing\"\n}", :debug)
327
- expect_log("Import of '#{@fixture_dir}/people.csv' is processing. Checking again in 30 seconds.", :debug)
328
- expect_log('Sending GET request to api.4me.com:443/v1/import/68ef5ef0f64c0', :debug)
329
- expect_log("Request failed: 500: No Response from Server - network error for 'api.4me.com:443/v1/import/68ef5ef0f64c0'", :error)
330
- expect_log('Sending GET request to api.4me.com:443/v1/import/68ef5ef0f64c0', :debug)
331
- expect_log("Response:\n{\n \"state\": \"done\",\n \"results\": {\n \"errors\": 0,\n \"updated\": 1,\n \"created\": 1,\n \"failures\": 0,\n \"unchanged\": 0,\n \"deleted\": 0\n }\n}", :debug)
332
-
333
- response = @client.import("#{@fixture_dir}/people.csv", 'people', true)
334
- expect(response[:state]).to eq('done')
335
- expect(response[:results][:updated]).to eq(1)
336
- expect(progress_stub).to have_been_requested.times(4)
285
+ response = client(authentication).get('/requests/777', { note: 'note [attachment:/tmp/third.gif]', note_attachments: ['/tmp/first.png', '/tmp/second.zip'] })
286
+ expect(response.valid?).to be_truthy
287
+ expect(response[:upload_called]).to be_falsey
288
+ end
289
+
290
+ %i[post patch].each do |method|
291
+ it "should parse attachments for #{method} requests" do
292
+ attachments = double('Sdk4me::Attachments')
293
+ expect(attachments).to receive(:upload_attachments!) do |data|
294
+ expect(data[:note_attachments]).to eq(['/tmp/first.png', '/tmp/second.zip'])
295
+ data[:note_attachments] = 'processed'
296
+ end
297
+ expect(Sdk4me::Attachments).to receive(:new).with(client(authentication), '/requests/777') { attachments }
298
+ stub_request(method, 'https://api.4me.com/v1/requests/777').with(credentials(authentication)).with(body: { note: 'note', note_attachments: 'processed' }).to_return(body: { id: 777, upload_called: true }.to_json)
299
+
300
+ response = client(authentication).send(method, '/requests/777', { note: 'note', note_attachments: ['/tmp/first.png', '/tmp/second.zip'] })
301
+ expect(response.valid?).to be_truthy
302
+ expect(response[:upload_called]).to be_truthy
303
+ end
304
+ end
337
305
  end
338
306
 
339
- it 'should wait for the import to fail' do
340
- stub_request(:post, 'https://api.4me.com/v1/import').with(basic_auth: ['secret', 'x']).with(body: @multi_part_body, headers: @multi_part_headers).to_return(body: {token: '68ef5ef0f64c0'}.to_json)
341
- progress_stub = stub_request(:get, 'https://api.4me.com/v1/import/68ef5ef0f64c0').with(basic_auth: ['secret', 'x']).to_return(@import_queued_response, @import_processing_response, @import_failed_response)
307
+ context 'import' do
308
+ before(:each) do
309
+ csv_mime_type = ['text/csv', 'text/comma-separated-values'].detect { |t| MIME::Types[t].any? } # which mime type is used depends on version of mime-types gem
310
+ @multi_part_body = "--0123456789ABLEWASIEREISAWELBA9876543210\r\nContent-Disposition: form-data; name=\"type\"\r\n\r\npeople\r\n--0123456789ABLEWASIEREISAWELBA9876543210\r\nContent-Disposition: form-data; name=\"file\"; filename=\"#{@fixture_dir}/people.csv\"\r\nContent-Type: #{csv_mime_type}\r\n\r\nPrimary Email,Name\nchess.cole@example.com,Chess Cole\ned.turner@example.com,Ed Turner\r\n--0123456789ABLEWASIEREISAWELBA9876543210--"
311
+ @multi_part_headers = { 'Accept' => '*/*', 'Content-Type' => 'multipart/form-data; boundary=0123456789ABLEWASIEREISAWELBA9876543210', 'User-Agent' => "Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en-us) AppleWebKit/523.10.6 (KHTML, like Gecko) Version/3.0.4 Safari/523.10.6 4me/#{Sdk4me::Client::VERSION}" }
342
312
 
343
- expect{ @client.import("#{@fixture_dir}/people.csv", 'people', true) }.to raise_error(Sdk4me::Exception, "Unable to monitor progress for people import. Invalid byte sequence in UTF-8 on line 2")
344
- expect(progress_stub).to have_been_requested.times(4)
345
- end
313
+ @import_queued_response = { body: { state: 'queued' }.to_json }
314
+ @import_processing_response = { body: { state: 'processing' }.to_json }
315
+ @import_done_response = { body: { state: 'done', results: { errors: 0, updated: 1, created: 1, failures: 0, unchanged: 0, deleted: 0 } }.to_json }
316
+ @import_failed_response = { body: { state: 'error', message: 'Invalid byte sequence in UTF-8 on line 2', results: { errors: 1, updated: 1, created: 0, failures: 1, unchanged: 0, deleted: 0 } }.to_json }
317
+ allow(client(authentication)).to receive(:sleep)
318
+ WebMock.disable_net_connect!
319
+ end
346
320
 
347
- it 'should not continue when there is an error connecting to 4me' do
348
- stub_request(:post, 'https://api.4me.com/v1/import').with(basic_auth: ['secret', 'x']).with(body: @multi_part_body, headers: @multi_part_headers).to_return(body: {token: '68ef5ef0f64c0'}.to_json)
349
- progress_stub = stub_request(:get, 'https://api.4me.com/v1/import/68ef5ef0f64c0').with(basic_auth: ['secret', 'x'])
350
- .to_return(@import_queued_response, @import_processing_response)
351
- .then.to_raise(StandardError.new('network error')) # twice
321
+ it 'should import a CSV file' do
322
+ stub_request(:post, 'https://api.4me.com/v1/import').with(credentials(authentication)).with(body: @multi_part_body, headers: @multi_part_headers).to_return(body: { token: '68ef5ef0f64c0' }.to_json)
323
+ expect_log("Import file '#{@fixture_dir}/people.csv' successfully uploaded with token '68ef5ef0f64c0'.")
352
324
 
353
- expect{ @client.import("#{@fixture_dir}/people.csv", 'people', true) }.to raise_error(Sdk4me::Exception, "Unable to monitor progress for people import. 500: No Response from Server - network error for 'api.4me.com:443/v1/import/68ef5ef0f64c0'")
354
- expect(progress_stub).to have_been_requested.times(4)
355
- end
325
+ response = client(authentication).import(File.new("#{@fixture_dir}/people.csv"), 'people')
326
+ expect(response[:token]).to eq('68ef5ef0f64c0')
327
+ end
356
328
 
357
- it 'should return an invalid response in case waiting for progress is false' do
358
- stub_request(:post, 'https://api.4me.com/v1/import').with(basic_auth: ['secret', 'x']).with(body: @multi_part_body, headers: @multi_part_headers).to_return(body: {message: 'oops!'}.to_json)
359
- response = @client.import("#{@fixture_dir}/people.csv", 'people', false)
360
- expect(response.valid?).to be_falsey
361
- expect(response.message).to eq('oops!')
362
- end
329
+ it 'should import a CSV file by filename' do
330
+ stub_request(:post, 'https://api.4me.com/v1/import').with(credentials(authentication)).with(body: @multi_part_body, headers: @multi_part_headers).to_return(body: { token: '68ef5ef0f64c0' }.to_json)
331
+ response = client(authentication).import("#{@fixture_dir}/people.csv", 'people')
332
+ expect(response[:token]).to eq('68ef5ef0f64c0')
333
+ end
363
334
 
364
- it 'should raise an UploadFailed exception in case waiting for progress is true' do
365
- stub_request(:post, 'https://api.4me.com/v1/import').with(basic_auth: ['secret', 'x']).with(body: @multi_part_body, headers: @multi_part_headers).to_return(body: {message: 'oops!'}.to_json)
366
- expect{ @client.import("#{@fixture_dir}/people.csv", 'people', true) }.to raise_error(Sdk4me::UploadFailed, 'Failed to queue people import. oops!')
367
- end
335
+ it 'should wait for the import to complete' do
336
+ stub_request(:post, 'https://api.4me.com/v1/import').with(credentials(authentication)).with(body: @multi_part_body, headers: @multi_part_headers).to_return(body: { token: '68ef5ef0f64c0' }.to_json)
337
+ progress_stub = stub_request(:get, 'https://api.4me.com/v1/import/68ef5ef0f64c0').with(credentials(authentication))
338
+ .to_return(@import_queued_response, @import_processing_response)
339
+ .then.to_raise(StandardError.new('network error'))
340
+ .then.to_return(@import_done_response)
341
+
342
+ # verify the correct log statement are made
343
+ expect_log('Sending POST request to api.4me.com:443/v1/import', :debug)
344
+ expect_log("Response:\n{\n \"token\": \"68ef5ef0f64c0\"\n}", :debug)
345
+ expect_log("Import file '#{@fixture_dir}/people.csv' successfully uploaded with token '68ef5ef0f64c0'.")
346
+ expect_log('Sending GET request to api.4me.com:443/v1/import/68ef5ef0f64c0', :debug)
347
+ expect_log("Response:\n{\n \"state\": \"queued\"\n}", :debug)
348
+ expect_log("Import of '#{@fixture_dir}/people.csv' is queued. Checking again in 30 seconds.", :debug)
349
+ expect_log('Sending GET request to api.4me.com:443/v1/import/68ef5ef0f64c0', :debug)
350
+ expect_log("Response:\n{\n \"state\": \"processing\"\n}", :debug)
351
+ expect_log("Import of '#{@fixture_dir}/people.csv' is processing. Checking again in 30 seconds.", :debug)
352
+ expect_log('Sending GET request to api.4me.com:443/v1/import/68ef5ef0f64c0', :debug)
353
+ expect_log("GET request to api.4me.com:443/v1/import/68ef5ef0f64c0 failed: 500: No Response from Server - network error for 'api.4me.com:443/v1/import/68ef5ef0f64c0'", :error)
354
+ expect_log('Sending GET request to api.4me.com:443/v1/import/68ef5ef0f64c0', :debug)
355
+ expect_log("Response:\n{\n \"state\": \"done\",\n \"results\": {\n \"errors\": 0,\n \"updated\": 1,\n \"created\": 1,\n \"failures\": 0,\n \"unchanged\": 0,\n \"deleted\": 0\n }\n}", :debug)
356
+
357
+ response = client(authentication).import("#{@fixture_dir}/people.csv", 'people', true)
358
+ expect(response[:state]).to eq('done')
359
+ expect(response[:results][:updated]).to eq(1)
360
+ expect(progress_stub).to have_been_requested.times(4)
361
+ end
368
362
 
369
- end
363
+ it 'should wait for the import to fail' do
364
+ stub_request(:post, 'https://api.4me.com/v1/import').with(credentials(authentication)).with(body: @multi_part_body, headers: @multi_part_headers).to_return(body: { token: '68ef5ef0f64c0' }.to_json)
365
+ progress_stub = stub_request(:get, 'https://api.4me.com/v1/import/68ef5ef0f64c0').with(credentials(authentication)).to_return(@import_queued_response, @import_processing_response, @import_failed_response)
370
366
 
367
+ expect { client(authentication).import("#{@fixture_dir}/people.csv", 'people', true) }.to raise_error(Sdk4me::Exception, 'Unable to monitor progress for people import. Invalid byte sequence in UTF-8 on line 2')
368
+ expect(progress_stub).to have_been_requested.times(4)
369
+ end
371
370
 
372
- context 'export' do
373
- before(:each) do
374
- @client = Sdk4me::Client.new(api_token: 'secret', max_retry_time: -1)
371
+ it 'should not continue when there is an error connecting to 4me' do
372
+ stub_request(:post, 'https://api.4me.com/v1/import').with(credentials(authentication)).with(body: @multi_part_body, headers: @multi_part_headers).to_return(body: { token: '68ef5ef0f64c0' }.to_json)
373
+ progress_stub = stub_request(:get, 'https://api.4me.com/v1/import/68ef5ef0f64c0').with(credentials(authentication))
374
+ .to_return(@import_queued_response, @import_processing_response)
375
+ .then.to_raise(StandardError.new('network error')) # twice
375
376
 
376
- @export_queued_response = {body: {state: 'queued'}.to_json}
377
- @export_processing_response = {body: {state: 'processing'}.to_json}
378
- @export_done_response = {body: {state: 'done', url: 'https://download.example.com/export.zip?AWSAccessKeyId=12345'}.to_json}
379
- allow(@client).to receive(:sleep)
380
- end
377
+ expect { client(authentication).import("#{@fixture_dir}/people.csv", 'people', true) }.to raise_error(Sdk4me::Exception, "Unable to monitor progress for people import. 500: No Response from Server - network error for 'api.4me.com:443/v1/import/68ef5ef0f64c0'")
378
+ expect(progress_stub).to have_been_requested.times(4)
379
+ end
381
380
 
382
- it 'should export multiple types' do
383
- stub_request(:post, 'https://api.4me.com/v1/export').with(basic_auth: ['secret', 'x']).with(body: {type: 'people,people_contact_details'}).to_return(body: {token: '68ef5ef0f64c0'}.to_json)
384
- expect_log("Export for 'people,people_contact_details' successfully queued with token '68ef5ef0f64c0'.")
381
+ it 'should return an invalid response in case waiting for progress is false' do
382
+ stub_request(:post, 'https://api.4me.com/v1/import').with(credentials(authentication)).with(body: @multi_part_body, headers: @multi_part_headers).to_return(body: { message: 'oops!' }.to_json)
383
+ response = client(authentication).import("#{@fixture_dir}/people.csv", 'people', false)
384
+ expect(response.valid?).to be_falsey
385
+ expect(response.message).to eq('oops!')
386
+ end
385
387
 
386
- response = @client.export(['people', 'people_contact_details'])
387
- expect(response[:token]).to eq('68ef5ef0f64c0')
388
+ it 'should raise an UploadFailed exception in case waiting for progress is true' do
389
+ stub_request(:post, 'https://api.4me.com/v1/import').with(credentials(authentication)).with(body: @multi_part_body, headers: @multi_part_headers).to_return(body: { message: 'oops!' }.to_json)
390
+ expect { client(authentication).import("#{@fixture_dir}/people.csv", 'people', true) }.to raise_error(Sdk4me::UploadFailed, 'Failed to queue people import. oops!')
391
+ end
388
392
  end
389
393
 
390
- it 'should indicate when nothing is exported' do
391
- stub_request(:post, 'https://api.4me.com/v1/export').with(basic_auth: ['secret', 'x']).with(body: {type: 'people', from: '2012-03-30T23:00:00+00:00'}).to_return(status: 204)
392
- expect_log("No changed records for 'people' since 2012-03-30T23:00:00+00:00.")
394
+ context 'export' do
395
+ before(:each) do
396
+ @export_queued_response = { body: { state: 'queued' }.to_json }
397
+ @export_processing_response = { body: { state: 'processing' }.to_json }
398
+ @export_done_response = { body: { state: 'done', url: 'https://download.example.com/export.zip?AWSAccessKeyId=12345' }.to_json }
399
+ allow(client(authentication)).to receive(:sleep)
400
+ end
393
401
 
394
- response = @client.export('people', DateTime.new(2012,03,30,23,00,00))
395
- expect(response[:token]).to be_nil
396
- end
402
+ it 'should export multiple types' do
403
+ stub_request(:post, 'https://api.4me.com/v1/export').with(credentials(authentication)).with(body: { type: 'people,people_contact_details' }).to_return(body: { token: '68ef5ef0f64c0' }.to_json)
404
+ expect_log("Export for 'people,people_contact_details' successfully queued with token '68ef5ef0f64c0'.")
397
405
 
398
- it 'should export since a certain time' do
399
- stub_request(:post, 'https://api.4me.com/v1/export').with(basic_auth: ['secret', 'x']).with(body: {type: 'people', from: '2012-03-30T23:00:00+00:00'}).to_return(body: {token: '68ef5ef0f64c0'}.to_json)
400
- expect_log("Export for 'people' successfully queued with token '68ef5ef0f64c0'.")
406
+ response = client(authentication).export(%w[people people_contact_details])
407
+ expect(response[:token]).to eq('68ef5ef0f64c0')
408
+ end
401
409
 
402
- response = @client.export('people', DateTime.new(2012,03,30,23,00,00))
403
- expect(response[:token]).to eq('68ef5ef0f64c0')
404
- end
410
+ it 'should indicate when nothing is exported' do
411
+ stub_request(:post, 'https://api.4me.com/v1/export').with(credentials(authentication)).with(body: { type: 'people', from: '2012-03-30T23:00:00+00:00' }).to_return(status: 204)
412
+ expect_log("No changed records for 'people' since 2012-03-30T23:00:00+00:00.")
405
413
 
406
- it 'should export with locale' do
407
- stub_request(:post, 'https://api.4me.com/v1/export').with(basic_auth: ['secret', 'x']).with(body: {type: 'translations', locale: 'nl'}).to_return(body: {token: '68ef5ef0f64c0'}.to_json)
408
- expect_log("Export for 'translations' successfully queued with token '68ef5ef0f64c0'.")
414
+ response = client(authentication).export('people', DateTime.new(2012, 0o3, 30, 23, 0o0, 0o0))
415
+ expect(response[:token]).to be_nil
416
+ end
409
417
 
410
- response = @client.export('translations', nil, nil, 'nl')
411
- expect(response[:token]).to eq('68ef5ef0f64c0')
412
- end
418
+ it 'should export since a certain time' do
419
+ stub_request(:post, 'https://api.4me.com/v1/export').with(credentials(authentication)).with(body: { type: 'people', from: '2012-03-30T23:00:00+00:00' }).to_return(body: { token: '68ef5ef0f64c0' }.to_json)
420
+ expect_log("Export for 'people' successfully queued with token '68ef5ef0f64c0'.")
413
421
 
414
- it 'should wait for the export to complete' do
415
- stub_request(:post, 'https://api.4me.com/v1/export').with(basic_auth: ['secret', 'x']).with(body: {type: 'people'}).to_return(body: {token: '68ef5ef0f64c0'}.to_json)
416
- progress_stub = stub_request(:get, 'https://api.4me.com/v1/export/68ef5ef0f64c0').with(basic_auth: ['secret', 'x'])
417
- .to_return(@export_queued_response, @export_processing_response)
418
- .then.to_raise(StandardError.new('network error'))
419
- .then.to_return(@export_done_response)
420
-
421
- # verify the correct log statement are made
422
- expect_log('Sending POST request to api.4me.com:443/v1/export', :debug)
423
- expect_log(%(Response:\n{\n "token": "68ef5ef0f64c0"\n}), :debug)
424
- expect_log("Export for 'people' successfully queued with token '68ef5ef0f64c0'.")
425
- expect_log('Sending GET request to api.4me.com:443/v1/export/68ef5ef0f64c0', :debug)
426
- expect_log(%(Response:\n{\n "state": "queued"\n}), :debug)
427
- expect_log("Export of 'people' is queued. Checking again in 30 seconds.", :debug)
428
- expect_log('Sending GET request to api.4me.com:443/v1/export/68ef5ef0f64c0', :debug)
429
- expect_log(%(Response:\n{\n "state": "processing"\n}), :debug)
430
- expect_log("Export of 'people' is processing. Checking again in 30 seconds.", :debug)
431
- expect_log('Sending GET request to api.4me.com:443/v1/export/68ef5ef0f64c0', :debug)
432
- expect_log("Request failed: 500: No Response from Server - network error for 'api.4me.com:443/v1/export/68ef5ef0f64c0'", :error)
433
- expect_log('Sending GET request to api.4me.com:443/v1/export/68ef5ef0f64c0', :debug)
434
- expect_log(%(Response:\n{\n "state": "done",\n "url": "https://download.example.com/export.zip?AWSAccessKeyId=12345"\n}), :debug)
435
-
436
- response = @client.export('people', nil, true)
437
- expect(response[:state]).to eq('done')
438
- expect(response[:url]).to eq('https://download.example.com/export.zip?AWSAccessKeyId=12345')
439
- expect(progress_stub).to have_been_requested.times(4)
440
- end
422
+ response = client(authentication).export('people', DateTime.new(2012, 0o3, 30, 23, 0o0, 0o0))
423
+ expect(response[:token]).to eq('68ef5ef0f64c0')
424
+ end
441
425
 
442
- it 'should not continue when there is an error connecting to 4me' do
443
- stub_request(:post, 'https://api.4me.com/v1/export').with(basic_auth: ['secret', 'x']).with(body: {type: 'people'}).to_return(body: {token: '68ef5ef0f64c0'}.to_json)
444
- progress_stub = stub_request(:get, 'https://api.4me.com/v1/export/68ef5ef0f64c0').with(basic_auth: ['secret', 'x'])
445
- .to_return(@export_queued_response, @export_processing_response)
446
- .then.to_raise(StandardError.new('network error')) # twice
426
+ it 'should export with locale' do
427
+ stub_request(:post, 'https://api.4me.com/v1/export').with(credentials(authentication)).with(body: { type: 'translations', locale: 'nl' }).to_return(body: { token: '68ef5ef0f64c0' }.to_json)
428
+ expect_log("Export for 'translations' successfully queued with token '68ef5ef0f64c0'.")
447
429
 
448
- expect{ @client.export('people', nil, true) }.to raise_error(Sdk4me::Exception, "Unable to monitor progress for 'people' export. 500: No Response from Server - network error for 'api.4me.com:443/v1/export/68ef5ef0f64c0'")
449
- expect(progress_stub).to have_been_requested.times(4)
450
- end
430
+ response = client(authentication).export('translations', nil, nil, 'nl')
431
+ expect(response[:token]).to eq('68ef5ef0f64c0')
432
+ end
451
433
 
452
- it 'should return an invalid response in case waiting for progress is false' do
453
- stub_request(:post, 'https://api.4me.com/v1/export').with(basic_auth: ['secret', 'x']).with(body: {type: 'people'}).to_return(body: {message: 'oops!'}.to_json)
454
- response = @client.export('people')
455
- expect(response.valid?).to be_falsey
456
- expect(response.message).to eq('oops!')
457
- end
434
+ it 'should wait for the export to complete' do
435
+ stub_request(:post, 'https://api.4me.com/v1/export').with(credentials(authentication)).with(body: { type: 'people' }).to_return(body: { token: '68ef5ef0f64c0' }.to_json)
436
+ progress_stub = stub_request(:get, 'https://api.4me.com/v1/export/68ef5ef0f64c0').with(credentials(authentication))
437
+ .to_return(@export_queued_response, @export_processing_response)
438
+ .then.to_raise(StandardError.new('network error'))
439
+ .then.to_return(@export_done_response)
440
+
441
+ # verify the correct log statement are made
442
+ expect_log('Sending POST request to api.4me.com:443/v1/export', :debug)
443
+ expect_log(%(Response:\n{\n "token": "68ef5ef0f64c0"\n}), :debug)
444
+ expect_log("Export for 'people' successfully queued with token '68ef5ef0f64c0'.")
445
+ expect_log('Sending GET request to api.4me.com:443/v1/export/68ef5ef0f64c0', :debug)
446
+ expect_log(%(Response:\n{\n "state": "queued"\n}), :debug)
447
+ expect_log("Export of 'people' is queued. Checking again in 30 seconds.", :debug)
448
+ expect_log('Sending GET request to api.4me.com:443/v1/export/68ef5ef0f64c0', :debug)
449
+ expect_log(%(Response:\n{\n "state": "processing"\n}), :debug)
450
+ expect_log("Export of 'people' is processing. Checking again in 30 seconds.", :debug)
451
+ expect_log('Sending GET request to api.4me.com:443/v1/export/68ef5ef0f64c0', :debug)
452
+ expect_log("GET request to api.4me.com:443/v1/export/68ef5ef0f64c0 failed: 500: No Response from Server - network error for 'api.4me.com:443/v1/export/68ef5ef0f64c0'", :error)
453
+ expect_log('Sending GET request to api.4me.com:443/v1/export/68ef5ef0f64c0', :debug)
454
+ expect_log(%(Response:\n{\n "state": "done",\n "url": "https://download.example.com/export.zip?AWSAccessKeyId=12345"\n}), :debug)
455
+
456
+ response = client(authentication).export('people', nil, true)
457
+ expect(response[:state]).to eq('done')
458
+ expect(response[:url]).to eq('https://download.example.com/export.zip?AWSAccessKeyId=12345')
459
+ expect(progress_stub).to have_been_requested.times(4)
460
+ end
458
461
 
459
- it 'should raise an UploadFailed exception in case waiting for progress is true' do
460
- stub_request(:post, 'https://api.4me.com/v1/export').with(basic_auth: ['secret', 'x']).with(body: {type: 'people'}).to_return(body: {message: 'oops!'}.to_json)
461
- expect{ @client.export('people', nil, true) }.to raise_error(Sdk4me::UploadFailed, "Failed to queue 'people' export. oops!")
462
- end
462
+ it 'should not continue when there is an error connecting to 4me' do
463
+ stub_request(:post, 'https://api.4me.com/v1/export').with(credentials(authentication)).with(body: { type: 'people' }).to_return(body: { token: '68ef5ef0f64c0' }.to_json)
464
+ progress_stub = stub_request(:get, 'https://api.4me.com/v1/export/68ef5ef0f64c0').with(credentials(authentication))
465
+ .to_return(@export_queued_response, @export_processing_response)
466
+ .then.to_raise(StandardError.new('network error')) # twice
463
467
 
464
- end
468
+ expect { client(authentication).export('people', nil, true) }.to raise_error(Sdk4me::Exception, "Unable to monitor progress for 'people' export. 500: No Response from Server - network error for 'api.4me.com:443/v1/export/68ef5ef0f64c0'")
469
+ expect(progress_stub).to have_been_requested.times(4)
470
+ end
471
+
472
+ it 'should return an invalid response in case waiting for progress is false' do
473
+ stub_request(:post, 'https://api.4me.com/v1/export').with(credentials(authentication)).with(body: { type: 'people' }).to_return(body: { message: 'oops!' }.to_json)
474
+ response = client(authentication).export('people')
475
+ expect(response.valid?).to be_falsey
476
+ expect(response.message).to eq('oops!')
477
+ end
465
478
 
466
- context 'retry' do
467
- it 'should not retry when max_retry_time = -1' do
468
- stub = stub_request(:get, 'https://api.4me.com/v1/me').with(basic_auth: ['secret', 'x']).to_raise(StandardError.new('network error'))
469
- expect_log('Sending GET request to api.4me.com:443/v1/me', :debug )
470
- expect_log("Request failed: 500: No Response from Server - network error for 'api.4me.com:443/v1/me'", :error)
471
-
472
- client = Sdk4me::Client.new(api_token: 'secret', max_retry_time: -1)
473
- response = client.get('me')
474
- expect(stub).to have_been_requested.times(1)
475
- expect(response.valid?).to be_falsey
476
- expect(response.message).to eq("500: No Response from Server - network error for 'api.4me.com:443/v1/me'")
479
+ it 'should raise an UploadFailed exception in case waiting for progress is true' do
480
+ stub_request(:post, 'https://api.4me.com/v1/export').with(credentials(authentication)).with(body: { type: 'people' }).to_return(body: { message: 'oops!' }.to_json)
481
+ expect { client(authentication).export('people', nil, true) }.to raise_error(Sdk4me::UploadFailed, "Failed to queue 'people' export. oops!")
482
+ end
477
483
  end
478
484
 
479
- it 'should not retry 4 times when max_retry_time = 16' do
480
- stub = stub_request(:get, 'https://api.4me.com/v1/me').with(basic_auth: ['secret', 'x']).to_raise(StandardError.new('network error'))
481
- [2,4,8].each_with_index do |secs, i|
482
- expect_log('Sending GET request to api.4me.com:443/v1/me', :debug )
483
- expect_log("Request failed, retry ##{i+1} in #{secs} seconds: 500: No Response from Server - network error for 'api.4me.com:443/v1/me'", :warn)
485
+ context 'retry' do
486
+ it 'should not retry when max_retry_time = -1' do
487
+ stub = stub_request(:get, 'https://api.4me.com/v1/me').with(credentials(authentication)).to_raise(StandardError.new('network error'))
488
+ expect_log('Sending GET request to api.4me.com:443/v1/me', :debug)
489
+ expect_log("GET request to api.4me.com:443/v1/me failed: 500: No Response from Server - network error for 'api.4me.com:443/v1/me'", :error)
490
+
491
+ response = client(authentication).get('me')
492
+ expect(stub).to have_been_requested.times(1)
493
+ expect(response.valid?).to be_falsey
494
+ expect(response.message).to eq("500: No Response from Server - network error for 'api.4me.com:443/v1/me'")
484
495
  end
485
- expect_log('Sending GET request to api.4me.com:443/v1/me', :debug )
486
496
 
487
- client = Sdk4me::Client.new(api_token: 'secret', max_retry_time: 16)
488
- allow(client).to receive(:sleep)
489
- response = client.get('me')
490
- expect(stub).to have_been_requested.times(4)
491
- expect(response.valid?).to be_falsey
492
- expect(response.message).to eq("500: No Response from Server - network error for 'api.4me.com:443/v1/me'")
493
- end
497
+ it 'should not retry 4 times when max_retry_time = 16' do
498
+ stub = stub_request(:get, 'https://api.4me.com/v1/me').with(credentials(authentication)).to_raise(StandardError.new('network error'))
499
+ [2, 4, 8].each_with_index do |secs, i|
500
+ expect_log('Sending GET request to api.4me.com:443/v1/me', :debug)
501
+ expect_log("Request failed, retry ##{i + 1} in #{secs} seconds: 500: No Response from Server - network error for 'api.4me.com:443/v1/me'", :warn)
502
+ end
503
+ expect_log('Sending GET request to api.4me.com:443/v1/me', :debug)
504
+
505
+ retry_client = client(authentication, max_retry_time: 16)
506
+ allow(retry_client).to receive(:sleep)
507
+ response = retry_client.get('me')
508
+ expect(stub).to have_been_requested.times(4)
509
+ expect(response.valid?).to be_falsey
510
+ expect(response.message).to eq("500: No Response from Server - network error for 'api.4me.com:443/v1/me'")
511
+ end
494
512
 
495
- it 'should return the response after retry succeeds' do
496
- stub = stub_request(:get, 'https://api.4me.com/v1/me').with(basic_auth: ['secret', 'x']).to_raise(StandardError.new('network error')).then.to_return(body: {name: 'my name'}.to_json)
497
- expect_log('Sending GET request to api.4me.com:443/v1/me', :debug )
498
- expect_log("Request failed, retry #1 in 2 seconds: 500: No Response from Server - network error for 'api.4me.com:443/v1/me'", :warn)
499
- expect_log('Sending GET request to api.4me.com:443/v1/me', :debug )
500
- expect_log(%(Response:\n{\n "name": "my name"\n}), :debug )
501
-
502
- client = Sdk4me::Client.new(api_token: 'secret', max_retry_time: 16)
503
- allow(client).to receive(:sleep)
504
- response = client.get('me')
505
- expect(stub).to have_been_requested.times(2)
506
- expect(response.valid?).to be_truthy
507
- expect(response[:name]).to eq('my name')
513
+ it 'should return the response after retry succeeds' do
514
+ stub = stub_request(:get, 'https://api.4me.com/v1/me').with(credentials(authentication)).to_raise(StandardError.new('network error')).then.to_return(body: { name: 'my name' }.to_json)
515
+ expect_log('Sending GET request to api.4me.com:443/v1/me', :debug)
516
+ expect_log("Request failed, retry #1 in 2 seconds: 500: No Response from Server - network error for 'api.4me.com:443/v1/me'", :warn)
517
+ expect_log('Sending GET request to api.4me.com:443/v1/me', :debug)
518
+ expect_log(%(Response:\n{\n "name": "my name"\n}), :debug)
519
+
520
+ retry_client = client(authentication, max_retry_time: 16)
521
+ allow(retry_client).to receive(:sleep)
522
+ response = retry_client.get('me')
523
+ expect(stub).to have_been_requested.times(2)
524
+ expect(response.valid?).to be_truthy
525
+ expect(response[:name]).to eq('my name')
526
+ end
508
527
  end
509
- end
510
528
 
511
- context 'rate limiting' do
512
- it 'should not block on rate limit when block_at_rate_limit is false' do
513
- stub = stub_request(:get, 'https://api.4me.com/v1/me').with(basic_auth: ['secret', 'x']).to_return(status: 429, body: {message: 'Too Many Requests'}.to_json)
514
- expect_log('Sending GET request to api.4me.com:443/v1/me', :debug )
515
- expect_log("Request failed: 429: Too Many Requests", :error)
516
-
517
- client = Sdk4me::Client.new(api_token: 'secret', block_at_rate_limit: false)
518
- response = client.get('me')
519
- expect(stub).to have_been_requested.times(1)
520
- expect(response.valid?).to be_falsey
521
- expect(response.message).to eq('429: Too Many Requests')
522
- end
529
+ context 'rate limiting' do
530
+ it 'should not block on rate limit when block_at_rate_limit is false' do
531
+ stub = stub_request(:get, 'https://api.4me.com/v1/me').with(credentials(authentication)).to_return(status: 429, body: { message: 'Too Many Requests' }.to_json)
532
+ expect_log('Sending GET request to api.4me.com:443/v1/me', :debug)
533
+ expect_log('GET request to api.4me.com:443/v1/me failed: 429: Too Many Requests', :error)
523
534
 
524
- it 'should block on rate limit when block_at_rate_limit is true' do
525
- stub = stub_request(:get, 'https://api.4me.com/v1/me').with(basic_auth: ['secret', 'x']).to_return(status: 429, body: {message: 'Too Many Requests'}.to_json).then.to_return(body: {name: 'my name'}.to_json)
526
- expect_log('Sending GET request to api.4me.com:443/v1/me', :debug )
527
- expect_log('Request throttled, trying again in 300 seconds: 429: Too Many Requests', :warn)
528
- expect_log('Sending GET request to api.4me.com:443/v1/me', :debug )
529
- expect_log(%(Response:\n{\n "name": "my name"\n}), :debug )
530
-
531
- client = Sdk4me::Client.new(api_token: 'secret', block_at_rate_limit: true, max_retry_time: 500)
532
- allow(client).to receive(:sleep)
533
- response = client.get('me')
534
- expect(stub).to have_been_requested.times(2)
535
- expect(response.valid?).to be_truthy
536
- expect(response[:name]).to eq('my name')
537
- end
535
+ response = client(authentication, block_at_rate_limit: false).get('me')
536
+ expect(stub).to have_been_requested.times(1)
537
+ expect(response.valid?).to be_falsey
538
+ expect(response.message).to eq('429: Too Many Requests')
539
+ end
538
540
 
539
- it 'should block on rate limit using Retry-After when block_at_rate_limit is true' do
540
- stub = stub_request(:get, 'https://api.4me.com/v1/me').with(basic_auth: ['secret', 'x']).to_return(status: 429, body: {message: 'Too Many Requests'}.to_json, headers: {'Retry-After' => '20'}).then.to_return(body: {name: 'my name'}.to_json)
541
- expect_log('Sending GET request to api.4me.com:443/v1/me', :debug )
542
- expect_log('Request throttled, trying again in 20 seconds: 429: Too Many Requests', :warn)
543
- expect_log('Sending GET request to api.4me.com:443/v1/me', :debug )
544
- expect_log(%(Response:\n{\n "name": "my name"\n}), :debug )
545
-
546
- client = Sdk4me::Client.new(api_token: 'secret', block_at_rate_limit: true)
547
- allow(client).to receive(:sleep)
548
- response = client.get('me')
549
- expect(stub).to have_been_requested.times(2)
550
- expect(response.valid?).to be_truthy
551
- expect(response[:name]).to eq('my name')
552
- end
541
+ it 'should block on rate limit when block_at_rate_limit is true' do
542
+ stub = stub_request(:get, 'https://api.4me.com/v1/me').with(credentials(authentication)).to_return(status: 429, body: { message: 'Too Many Requests' }.to_json).then.to_return(body: { name: 'my name' }.to_json)
543
+ expect_log('Sending GET request to api.4me.com:443/v1/me', :debug)
544
+ expect_log('Request throttled, trying again in 300 seconds: 429: Too Many Requests', :warn)
545
+ expect_log('Sending GET request to api.4me.com:443/v1/me', :debug)
546
+ expect_log(%(Response:\n{\n "name": "my name"\n}), :debug)
547
+
548
+ block_client = client(authentication, block_at_rate_limit: true, max_retry_time: 500)
549
+ allow(block_client).to receive(:sleep)
550
+ response = block_client.get('me')
551
+ expect(stub).to have_been_requested.times(2)
552
+ expect(response.valid?).to be_truthy
553
+ expect(response[:name]).to eq('my name')
554
+ end
553
555
 
554
- it 'should block on rate limit using Retry-After with minimum of 2 seconds when block_at_rate_limit is true' do
555
- stub = stub_request(:get, 'https://api.4me.com/v1/me').with(basic_auth: ['secret', 'x']).to_return(status: 429, body: {message: 'Too Many Requests'}.to_json, headers: {'Retry-After' => '1'}).then.to_return(body: {name: 'my name'}.to_json)
556
- expect_log('Sending GET request to api.4me.com:443/v1/me', :debug )
557
- expect_log('Request throttled, trying again in 2 seconds: 429: Too Many Requests', :warn)
558
- expect_log('Sending GET request to api.4me.com:443/v1/me', :debug )
559
- expect_log(%(Response:\n{\n "name": "my name"\n}), :debug )
560
-
561
- client = Sdk4me::Client.new(api_token: 'secret', block_at_rate_limit: true)
562
- allow(client).to receive(:sleep)
563
- response = client.get('me')
564
- expect(stub).to have_been_requested.times(2)
565
- expect(response.valid?).to be_truthy
566
- expect(response[:name]).to eq('my name')
567
- end
568
- end
556
+ it 'should block on rate limit using Retry-After when block_at_rate_limit is true' do
557
+ stub = stub_request(:get, 'https://api.4me.com/v1/me').with(credentials(authentication)).to_return(status: 429, body: { message: 'Too Many Requests' }.to_json, headers: { 'Retry-After' => '20' }).then.to_return(body: { name: 'my name' }.to_json)
558
+ expect_log('Sending GET request to api.4me.com:443/v1/me', :debug)
559
+ expect_log('Request throttled, trying again in 20 seconds: 429: Too Many Requests', :warn)
560
+ expect_log('Sending GET request to api.4me.com:443/v1/me', :debug)
561
+ expect_log(%(Response:\n{\n "name": "my name"\n}), :debug)
562
+
563
+ block_client = client(authentication, block_at_rate_limit: true)
564
+ allow(block_client).to receive(:sleep)
565
+ response = block_client.get('me')
566
+ expect(stub).to have_been_requested.times(2)
567
+ expect(response.valid?).to be_truthy
568
+ expect(response[:name]).to eq('my name')
569
+ end
569
570
 
570
- context 'logger' do
571
- before(:each) do
572
- @logger = Logger.new(STDOUT)
573
- @client = Sdk4me::Client.new(api_token: 'secret', max_retry_time: -1, logger: @logger)
571
+ it 'should block on rate limit using Retry-After with minimum of 2 seconds when block_at_rate_limit is true' do
572
+ stub = stub_request(:get, 'https://api.4me.com/v1/me').with(credentials(authentication)).to_return(status: 429, body: { message: 'Too Many Requests' }.to_json, headers: { 'Retry-After' => '1' }).then.to_return(body: { name: 'my name' }.to_json)
573
+ expect_log('Sending GET request to api.4me.com:443/v1/me', :debug)
574
+ expect_log('Request throttled, trying again in 2 seconds: 429: Too Many Requests', :warn)
575
+ expect_log('Sending GET request to api.4me.com:443/v1/me', :debug)
576
+ expect_log(%(Response:\n{\n "name": "my name"\n}), :debug)
577
+
578
+ block_client = client(authentication, block_at_rate_limit: true)
579
+ allow(block_client).to receive(:sleep)
580
+ response = block_client.get('me')
581
+ expect(stub).to have_been_requested.times(2)
582
+ expect(response.valid?).to be_truthy
583
+ expect(response[:name]).to eq('my name')
584
+ end
574
585
  end
575
586
 
576
- it 'should be possible to override the default logger' do
577
- stub_request(:get, 'https://api.4me.com/v1/me').with(basic_auth: ['secret', 'x']).to_return(body: {name: 'my name'}.to_json)
578
- expect_log('Sending GET request to api.4me.com:443/v1/me', :debug, @logger )
579
- expect_log(%(Response:\n{\n "name": "my name"\n}), :debug, @logger )
580
- @client.get('me')
587
+ context 'logger' do
588
+ it 'should be possible to override the default logger' do
589
+ logger = Logger.new($stdout)
590
+ logger_client = client(authentication, max_retry_time: -1, logger: logger)
591
+ stub_request(:get, 'https://api.4me.com/v1/me').with(credentials(authentication)).to_return(body: { name: 'my name' }.to_json)
592
+ expect_log('Sending GET request to api.4me.com:443/v1/me', :debug, logger)
593
+ expect_log(%(Response:\n{\n "name": "my name"\n}), :debug, logger)
594
+ logger_client.get('me')
595
+ end
581
596
  end
582
597
  end
583
598
  end