4me-sdk 2.0.3 → 2.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/4me-sdk.gemspec +2 -8
- data/Gemfile +8 -0
- data/README.md +12 -4
- data/lib/sdk4me/client/response.rb +3 -3
- data/lib/sdk4me/client/version.rb +1 -1
- data/lib/sdk4me/client.rb +10 -2
- data/lib/sdk4me.rb +1 -1
- metadata +5 -108
- data/spec/lib/sdk4me/attachments_spec.rb +0 -342
- data/spec/lib/sdk4me/certificate_spec.rb +0 -41
- data/spec/lib/sdk4me/client_spec.rb +0 -598
- data/spec/lib/sdk4me/response_spec.rb +0 -287
- data/spec/lib/sdk4me_spec.rb +0 -33
- data/spec/spec_helper.rb +0 -45
- data/spec/support/fixtures/people.csv +0 -3
- data/spec/support/fixtures/upload.txt +0 -1
- data/spec/support/matchers/never_raise.rb +0 -41
- data/spec/support/util.rb +0 -3
@@ -1,287 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Sdk4me::Response do
|
4
|
-
def client(authentication)
|
5
|
-
(@client ||= {})[authentication] ||= begin
|
6
|
-
if authentication == :api_token
|
7
|
-
Sdk4me::Client.new(api_token: 'secret', max_retry_time: -1, block_at_rate_limit: false)
|
8
|
-
else
|
9
|
-
Sdk4me::Client.new(access_token: 'secret', max_retry_time: -1, block_at_rate_limit: false)
|
10
|
-
end
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
def credentials(authentication)
|
15
|
-
if authentication == :api_token
|
16
|
-
{ basic_auth: %w[secret x] }
|
17
|
-
else
|
18
|
-
{ headers: { 'Authorization' => 'Bearer secret' } }
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
%i[api_token access_token].each do |authentication|
|
23
|
-
context "#{authentication} - " do
|
24
|
-
before(:each) do
|
25
|
-
@person_hash = {
|
26
|
-
addresses: [],
|
27
|
-
contacts: [{ id: 1365, label: 'work', telephone: '7139872946' }],
|
28
|
-
id: 562,
|
29
|
-
information: 'Info about John.',
|
30
|
-
job_title: 'rolling stone',
|
31
|
-
locale: 'en-US',
|
32
|
-
location: 'Top of John Hill',
|
33
|
-
name: 'John',
|
34
|
-
organization: { id: 20, name: 'SDK4ME Institute' },
|
35
|
-
picture_uri: nil,
|
36
|
-
primary_email: 'john@example.com',
|
37
|
-
site: { id: 14, name: 'IT Training Facility' },
|
38
|
-
time_format_24h: false,
|
39
|
-
time_zone: 'Central Time (US & Canada)'
|
40
|
-
}
|
41
|
-
stub_request(:get, 'https://api.4me.com/v1/me').with(credentials(authentication)).to_return(body: @person_hash.to_json)
|
42
|
-
@response_hash = client(authentication).get('me')
|
43
|
-
|
44
|
-
@people_array = [
|
45
|
-
{ id: 562, name: 'John', organization: { id: 20, name: 'SDK4ME Institute' }, site: { id: 14, name: 'IT Training Facility' } },
|
46
|
-
{ id: 560, name: 'Lucas', organization: { id: 20, name: 'SDK4ME Institute', office: { name: 'The Office' } }, site: { id: 14, name: 'IT Training Facility' } },
|
47
|
-
{ id: 561, name: 'Sheryl', organization: { id: 20, name: 'SDK4ME Institute' }, site: { id: 14, name: 'IT Training Facility' } }
|
48
|
-
]
|
49
|
-
stub_request(:get, 'https://api.4me.com/v1/people').to_return(body: @people_array.to_json).with(credentials(authentication))
|
50
|
-
@response_array = client(authentication).get('people')
|
51
|
-
end
|
52
|
-
|
53
|
-
it 'should contain the request' do
|
54
|
-
expect(@response_hash.request.class.name).to eq('Net::HTTP::Get')
|
55
|
-
expect(@response_hash.request.path).to eq('/v1/me')
|
56
|
-
end
|
57
|
-
|
58
|
-
it 'should contain the full request' do
|
59
|
-
expect(@response_hash.response.class.name).to eq('Net::HTTPOK')
|
60
|
-
expect(@response_hash.response).to respond_to(:body)
|
61
|
-
end
|
62
|
-
|
63
|
-
it 'should provide easy access to the body' do
|
64
|
-
expect(@response_hash.body).to include(%("primary_email":"john@example.com"))
|
65
|
-
end
|
66
|
-
|
67
|
-
context 'json/message' do
|
68
|
-
it 'should provide the JSON value for single records' do
|
69
|
-
be_json_eql(@response_hash.json, @person_hash)
|
70
|
-
end
|
71
|
-
|
72
|
-
it 'should provide the JSON value for lists' do
|
73
|
-
be_json_eql(@response_array.json, @people_array)
|
74
|
-
end
|
75
|
-
|
76
|
-
it 'should provide indifferent access for single records' do
|
77
|
-
expect(@response_hash.json['organization']['name']).to eq('SDK4ME Institute')
|
78
|
-
expect(@response_hash.json[:organization][:name]).to eq('SDK4ME Institute')
|
79
|
-
expect(@response_hash.json[:organization]['name']).to eq('SDK4ME Institute')
|
80
|
-
expect(@response_hash.json['organization'][:name]).to eq('SDK4ME Institute')
|
81
|
-
end
|
82
|
-
|
83
|
-
it 'should provide indifferent access for lists' do
|
84
|
-
expect(@response_array.json.first['site']['name']).to eq('IT Training Facility')
|
85
|
-
expect(@response_array.json.first[:site][:name]).to eq('IT Training Facility')
|
86
|
-
expect(@response_array.json.last[:site]['name']).to eq('IT Training Facility')
|
87
|
-
expect(@response_array.json.last['site'][:name]).to eq('IT Training Facility')
|
88
|
-
end
|
89
|
-
|
90
|
-
it 'should add a message if the body is empty' do
|
91
|
-
stub_request(:get, 'https://api.4me.com/v1/organizations').with(credentials(authentication)).to_return(status: 429, body: nil)
|
92
|
-
response = client(authentication).get('organizations')
|
93
|
-
|
94
|
-
message = '429: empty body'
|
95
|
-
expect(response.json[:message]).to eq(message)
|
96
|
-
expect(response.json['message']).to eq(message)
|
97
|
-
expect(response.message).to eq(message)
|
98
|
-
end
|
99
|
-
|
100
|
-
it 'should add a message if the HTTP response is not OK' do
|
101
|
-
stub_request(:get, 'https://api.4me.com/v1/organizations').with(credentials(authentication)).to_return(status: 429, body: { message: 'Too Many Requests' }.to_json)
|
102
|
-
response = client(authentication).get('organizations')
|
103
|
-
|
104
|
-
message = '429: Too Many Requests'
|
105
|
-
expect(response.json[:message]).to eq(message)
|
106
|
-
expect(response.json['message']).to eq(message)
|
107
|
-
expect(response.message).to eq(message)
|
108
|
-
end
|
109
|
-
|
110
|
-
it 'should add a message if the JSON body cannot be parsed' do
|
111
|
-
stub_request(:get, 'https://api.4me.com/v1/organizations').with(credentials(authentication)).to_return(body: '==$$!invalid')
|
112
|
-
response = client(authentication).get('organizations')
|
113
|
-
|
114
|
-
message = "unexpected token at '==$$!invalid' for:\n#{response.body}"
|
115
|
-
expect(response.json[:message]).to include(message)
|
116
|
-
expect(response.json['message']).to include(message)
|
117
|
-
expect(response.message).to include(message)
|
118
|
-
end
|
119
|
-
|
120
|
-
it 'should have a blank message when single record is succesfully retrieved' do
|
121
|
-
expect(@response_hash.message).to be_nil
|
122
|
-
end
|
123
|
-
|
124
|
-
it 'should have a blank message when single record is succesfully retrieved' do
|
125
|
-
expect(@response_array.message).to be_nil
|
126
|
-
end
|
127
|
-
end
|
128
|
-
|
129
|
-
it 'should define empty' do
|
130
|
-
stub_request(:get, 'https://api.4me.com/v1/organizations').with(credentials(authentication)).to_return(status: 429, body: nil)
|
131
|
-
response = client(authentication).get('organizations')
|
132
|
-
|
133
|
-
expect(response.empty?).to be_truthy
|
134
|
-
expect(@person_hash.empty?).to be_falsey
|
135
|
-
expect(@people_array.empty?).to be_falsey
|
136
|
-
end
|
137
|
-
|
138
|
-
context 'valid' do
|
139
|
-
it 'should be valid when the message is nil' do
|
140
|
-
expect(@response_hash).to receive(:message) { nil }
|
141
|
-
expect(@response_hash.valid?).to be_truthy
|
142
|
-
end
|
143
|
-
|
144
|
-
it 'should not be valid when the message is not nil' do
|
145
|
-
expect(@response_array).to receive(:message) { 'invalid' }
|
146
|
-
expect(@response_array.valid?).to be_falsey
|
147
|
-
end
|
148
|
-
end
|
149
|
-
|
150
|
-
context '[] access' do
|
151
|
-
context 'single records' do
|
152
|
-
it 'should delegate [] to the json' do
|
153
|
-
expect(@response_hash[:name]).to eq('John')
|
154
|
-
end
|
155
|
-
|
156
|
-
it 'should allow multiple keys' do
|
157
|
-
expect(@response_hash[:organization, 'name']).to eq('SDK4ME Institute')
|
158
|
-
end
|
159
|
-
|
160
|
-
it 'should allow nils when using multiple keys' do
|
161
|
-
expect(@response_hash[:organization, :missing, 'name']).to be_nil
|
162
|
-
end
|
163
|
-
end
|
164
|
-
|
165
|
-
context 'list of records' do
|
166
|
-
it 'should delegate [] to the json of each record' do
|
167
|
-
expect(@response_array['name']).to eq(%w[John Lucas Sheryl])
|
168
|
-
end
|
169
|
-
|
170
|
-
it 'should allow multiple keys' do
|
171
|
-
expect(@response_array[:organization, 'name']).to eq(['SDK4ME Institute', 'SDK4ME Institute', 'SDK4ME Institute'])
|
172
|
-
end
|
173
|
-
|
174
|
-
it 'should allow nils when using multiple keys' do
|
175
|
-
expect(@response_array[:organization, :office, 'name']).to eq([nil, 'The Office', nil])
|
176
|
-
end
|
177
|
-
end
|
178
|
-
end
|
179
|
-
|
180
|
-
context 'size' do
|
181
|
-
it 'should return 1 for single records' do
|
182
|
-
expect(@response_hash.size).to eq(1)
|
183
|
-
end
|
184
|
-
|
185
|
-
it 'should return the array size for list records' do
|
186
|
-
expect(@response_array.size).to eq(3)
|
187
|
-
end
|
188
|
-
|
189
|
-
it 'should return nil if an error message is present' do
|
190
|
-
expect(@response_hash).to receive(:message) { 'error message' }
|
191
|
-
expect(@response_hash.size).to eq(0)
|
192
|
-
end
|
193
|
-
end
|
194
|
-
|
195
|
-
context 'count' do
|
196
|
-
it 'should return 1 for single records' do
|
197
|
-
expect(@response_hash.count).to eq(1)
|
198
|
-
end
|
199
|
-
|
200
|
-
it 'should return the array size for list records' do
|
201
|
-
expect(@response_array.count).to eq(3)
|
202
|
-
end
|
203
|
-
|
204
|
-
it 'should return nil if an error message is present' do
|
205
|
-
expect(@response_hash).to receive(:message) { 'error message' }
|
206
|
-
expect(@response_hash.count).to eq(0)
|
207
|
-
end
|
208
|
-
end
|
209
|
-
|
210
|
-
context 'pagination' do
|
211
|
-
before(:each) do
|
212
|
-
@pagination_header = {
|
213
|
-
'X-Pagination-Per-Page' => 3,
|
214
|
-
'X-Pagination-Current-Page' => 1,
|
215
|
-
'X-Pagination-Total-Pages' => 2,
|
216
|
-
'X-Pagination-Total-Entries' => 5,
|
217
|
-
'Link' => '<https://api.4me.com/v1/people?page=1&per_page=3&fields=id,name>; rel="first",<https://api.4me.com/v1/people?fields=id%2Cname&page=2&per_page=3>; rel="next", <https://api.4me.com/v1/people?page=2&per_page=3>; rel="last"'
|
218
|
-
}
|
219
|
-
allow(@response_array.response).to receive('header') { @pagination_header }
|
220
|
-
end
|
221
|
-
|
222
|
-
it "should retrieve per_page from the 'X-Pagination-Per-Page' header" do
|
223
|
-
expect(@response_array.per_page).to eq(3)
|
224
|
-
end
|
225
|
-
|
226
|
-
it "should retrieve current_page from the 'X-Pagination-Current-Page' header" do
|
227
|
-
expect(@response_array.current_page).to eq(1)
|
228
|
-
end
|
229
|
-
|
230
|
-
it "should retrieve total_pages from the 'X-Pagination-Total-Pages' header" do
|
231
|
-
expect(@response_array.total_pages).to eq(2)
|
232
|
-
end
|
233
|
-
|
234
|
-
it "should retrieve total_entries from the 'X-Pagination-Total-Entries' header" do
|
235
|
-
expect(@response_array.total_entries).to eq(5)
|
236
|
-
end
|
237
|
-
|
238
|
-
{ first: 'https://api.4me.com/v1/people?page=1&per_page=3&fields=id,name',
|
239
|
-
next: 'https://api.4me.com/v1/people?fields=id%2Cname&page=2&per_page=3',
|
240
|
-
last: 'https://api.4me.com/v1/people?page=2&per_page=3' }.each do |relation, link|
|
241
|
-
it "should define pagination link for :#{relation}" do
|
242
|
-
expect(@response_array.pagination_link(relation)).to eq(link)
|
243
|
-
end
|
244
|
-
end
|
245
|
-
|
246
|
-
{ first: '/v1/people?page=1&per_page=3&fields=id,name',
|
247
|
-
next: '/v1/people?fields=id%2Cname&page=2&per_page=3',
|
248
|
-
last: '/v1/people?page=2&per_page=3' }.each do |relation, link|
|
249
|
-
it "should define pagination relative link for :#{relation}" do
|
250
|
-
expect(@response_array.pagination_relative_link(relation)).to eq(link)
|
251
|
-
end
|
252
|
-
end
|
253
|
-
end
|
254
|
-
|
255
|
-
context 'throttled?' do
|
256
|
-
it 'should not be trhottled by default' do
|
257
|
-
expect(@response_hash.throttled?).to be_falsey
|
258
|
-
expect(@response_array.throttled?).to be_falsey
|
259
|
-
end
|
260
|
-
|
261
|
-
it 'should check the return code' do
|
262
|
-
stub_request(:get, 'https://api.4me.com/v1/organizations').with(credentials(authentication)).to_return(status: 429, body: nil)
|
263
|
-
response = client(authentication).get('organizations')
|
264
|
-
expect(response.throttled?).to be_truthy
|
265
|
-
end
|
266
|
-
|
267
|
-
it 'should check the return message' do
|
268
|
-
stub_request(:get, 'https://api.4me.com/v1/organizations').with(credentials(authentication)).to_return(status: 500, body: { message: 'Too Many Requests' }.to_json)
|
269
|
-
response = client(authentication).get('organizations')
|
270
|
-
expect(response.throttled?).to be_truthy
|
271
|
-
end
|
272
|
-
end
|
273
|
-
|
274
|
-
context 'to_s' do
|
275
|
-
it 'should return the JSON as a string' do
|
276
|
-
expect(@response_hash.to_s).to eq(JSON.parse(@person_hash.to_json).to_s)
|
277
|
-
end
|
278
|
-
|
279
|
-
it 'should return the message in case the response is not valid' do
|
280
|
-
stub_request(:get, 'https://api.4me.com/v1/organizations').with(credentials(authentication)).to_return(status: 429, body: nil)
|
281
|
-
response = client(authentication).get('organizations')
|
282
|
-
expect(response.to_s).to eq('429: empty body')
|
283
|
-
end
|
284
|
-
end
|
285
|
-
end
|
286
|
-
end
|
287
|
-
end
|
data/spec/lib/sdk4me_spec.rb
DELETED
@@ -1,33 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Sdk4me do
|
4
|
-
it 'should define a default configuration' do
|
5
|
-
conf = Sdk4me.configuration.current
|
6
|
-
|
7
|
-
expect(conf.keys.sort).to eq(%i[access_token account api_token api_version block_at_rate_limit ca_file host logger max_retry_time max_throttle_time proxy_host proxy_password proxy_port proxy_user read_timeout source])
|
8
|
-
|
9
|
-
expect(conf[:logger].class).to eq(::Logger)
|
10
|
-
expect(conf[:host]).to eq('https://api.4me.com')
|
11
|
-
expect(conf[:api_version]).to eq('v1')
|
12
|
-
|
13
|
-
expect(conf[:max_retry_time]).to eq(300)
|
14
|
-
expect(conf[:read_timeout]).to eq(25)
|
15
|
-
expect(conf[:block_at_rate_limit]).to be_truthy
|
16
|
-
|
17
|
-
expect(conf[:proxy_port]).to eq(8080)
|
18
|
-
|
19
|
-
%i[access_token api_token account source proxy_host proxy_user proxy_password].each do |no_default|
|
20
|
-
expect(conf[no_default]).to be_nil
|
21
|
-
end
|
22
|
-
|
23
|
-
expect(conf[:ca_file]).to eq('../ca-bundle.crt')
|
24
|
-
end
|
25
|
-
|
26
|
-
it 'should define a logger' do
|
27
|
-
expect(Sdk4me.logger.class).to eq(::Logger)
|
28
|
-
end
|
29
|
-
|
30
|
-
it 'should define an exception class' do
|
31
|
-
expect { raise ::Sdk4me::Exception, 'test' }.to raise_error('test')
|
32
|
-
end
|
33
|
-
end
|
data/spec/spec_helper.rb
DELETED
@@ -1,45 +0,0 @@
|
|
1
|
-
dir = File.dirname(__FILE__)
|
2
|
-
$LOAD_PATH.unshift "#{dir}/../lib"
|
3
|
-
$LOAD_PATH.unshift dir
|
4
|
-
|
5
|
-
warn("Running specs using ruby version #{RUBY_VERSION}")
|
6
|
-
|
7
|
-
require 'simplecov'
|
8
|
-
SimpleCov.start
|
9
|
-
|
10
|
-
require 'rspec'
|
11
|
-
require 'webmock/rspec'
|
12
|
-
|
13
|
-
# Patch for https://github.com/bblimke/webmock/issues/623
|
14
|
-
module WebMock
|
15
|
-
class BodyPattern
|
16
|
-
def assert_non_multipart_body(content_type)
|
17
|
-
# if content_type =~ %r{^multipart/form-data}
|
18
|
-
# raise ArgumentError.new("WebMock does not support matching body for multipart/form-data requests yet :(")
|
19
|
-
# end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
require 'sdk4me/client'
|
25
|
-
|
26
|
-
# Requires supporting ruby files with custom matchers and macros, etc,
|
27
|
-
# in spec/support/ and its subdirectories.
|
28
|
-
Dir["#{dir}/support/**/*.rb"].sort.each { |f| require f }
|
29
|
-
|
30
|
-
RSpec.configure do |config|
|
31
|
-
config.before(:each) do
|
32
|
-
log_dir = "#{File.dirname(__FILE__)}/log"
|
33
|
-
Dir.mkdir(log_dir) unless File.exist?(log_dir)
|
34
|
-
Sdk4me.configuration.logger = Logger.new("#{log_dir}/test.log")
|
35
|
-
@spec_dir = dir
|
36
|
-
@fixture_dir = "#{dir}/support/fixtures"
|
37
|
-
end
|
38
|
-
config.after(:each) { Sdk4me.configuration.reset }
|
39
|
-
|
40
|
-
# Run specs in random order to surface order dependencies. If you find an
|
41
|
-
# order dependency and want to debug it, you can fix the order by providing
|
42
|
-
# the seed, which is printed after each run.
|
43
|
-
# --seed 1234
|
44
|
-
config.order = 'random'
|
45
|
-
end
|
@@ -1 +0,0 @@
|
|
1
|
-
content
|
@@ -1,41 +0,0 @@
|
|
1
|
-
# This matcher will return:
|
2
|
-
# 1. TRUE if the code was run without exceptions
|
3
|
-
# 2. FALSE if the code was run but raised (only) the specified exception
|
4
|
-
#
|
5
|
-
# It *will* raise an exception if the block of code raises an exception other than
|
6
|
-
# (the exception specified)
|
7
|
-
#
|
8
|
-
# To use it
|
9
|
-
#
|
10
|
-
# expect {
|
11
|
-
# code
|
12
|
-
# }.to never_raise(MySpecificException)
|
13
|
-
#
|
14
|
-
RSpec::Matchers.define :never_raise do |exception_class|
|
15
|
-
global_result = nil
|
16
|
-
|
17
|
-
def supports_block_expectations?
|
18
|
-
true # or some logic
|
19
|
-
end
|
20
|
-
|
21
|
-
match do |block|
|
22
|
-
block.call
|
23
|
-
rescue exception_class => e
|
24
|
-
global_result = "expected #{block.source_location[0]}:#{block.source_location[1]} to never raise #{exception_class.name}, but did: #{e.message}"
|
25
|
-
false # we did NOT never raise this exception
|
26
|
-
rescue RSpec::Expectations::ExpectationNotMetError => e
|
27
|
-
global_result = "expectation failed inside block at #{block.source_location[0]}:#{block.source_location[1]}: #{e}"
|
28
|
-
# give us a pretty error message in addition to the error message from the exception
|
29
|
-
raise e
|
30
|
-
rescue StandardError
|
31
|
-
# handle other exceptions by reraising them. They are exceptional!!!
|
32
|
-
# (also, no pretty error messages here)
|
33
|
-
raise
|
34
|
-
else
|
35
|
-
true # everything ran, nothing raised at all, thus code did in fact not raise anything
|
36
|
-
end
|
37
|
-
|
38
|
-
failure_message do |_player|
|
39
|
-
global_result
|
40
|
-
end
|
41
|
-
end
|
data/spec/support/util.rb
DELETED