4me-sdk 1.1.2 → 1.1.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,271 @@
1
+ require 'spec_helper'
2
+
3
+ describe Sdk4me::Response do
4
+ before(:each) do
5
+ @client = Sdk4me::Client.new(api_token: 'secret', max_retry_time: -1)
6
+ @person_hash = {
7
+ addresses:[],
8
+ contacts:[ {id: 1365, label: 'work', telephone: '7139872946'} ],
9
+ id: 562,
10
+ information: 'Info about John.',
11
+ job_title: 'rolling stone',
12
+ locale: 'en-US',
13
+ location: 'Top of John Hill',
14
+ name: 'John',
15
+ organization: {id: 20, name: 'SDK4ME Institute'},
16
+ picture_uri: nil,
17
+ primary_email: 'john@example.com',
18
+ site: {id:14, name: 'IT Training Facility'},
19
+ time_format_24h: false,
20
+ time_zone: 'Central Time (US & Canada)'
21
+ }
22
+ stub_request(:get, 'https://api.4me.com/v1/me').with(basic_auth: ['secret', 'x']).to_return(body: @person_hash.to_json)
23
+ @response_hash = @client.get('me')
24
+
25
+ @client = Sdk4me::Client.new(api_token: 'secret', max_retry_time: -1)
26
+ @people_array = [
27
+ {id: 562, name: 'John', organization: { id: 20, name: 'SDK4ME Institute'}, site: {id: 14, name: 'IT Training Facility'} },
28
+ {id: 560, name: 'Lucas', organization: { id: 20, name: 'SDK4ME Institute', office: { name: 'The Office'}}, site: {id: 14, name: 'IT Training Facility'} },
29
+ {id: 561, name: 'Sheryl', organization: { id: 20, name: 'SDK4ME Institute'}, site: {id: 14, name: 'IT Training Facility'} }
30
+ ]
31
+ stub_request(:get, 'https://api.4me.com/v1/people').to_return(body: @people_array.to_json).with(basic_auth: ['secret', 'x'])
32
+ @response_array = @client.get('people')
33
+ end
34
+
35
+ it 'should contain the request' do
36
+ expect(@response_hash.request.class.name).to eq('Net::HTTP::Get')
37
+ expect(@response_hash.request.path).to eq('/v1/me')
38
+ end
39
+
40
+ it 'should contain the full request' do
41
+ expect(@response_hash.response.class.name).to eq('Net::HTTPOK')
42
+ expect(@response_hash.response).to respond_to(:body)
43
+ end
44
+
45
+ it 'should provide easy access to the body' do
46
+ expect(@response_hash.body).to include(%("primary_email":"john@example.com"))
47
+ end
48
+
49
+ context 'json/message' do
50
+ it 'should provide the JSON value for single records' do
51
+ be_json_eql(@response_hash.json, @person_hash)
52
+ end
53
+
54
+ it 'should provide the JSON value for lists' do
55
+ be_json_eql(@response_array.json, @people_array)
56
+ end
57
+
58
+ it 'should provide indifferent access for single records' do
59
+ expect(@response_hash.json['organization']['name']).to eq('SDK4ME Institute')
60
+ expect(@response_hash.json[:organization][:name]).to eq('SDK4ME Institute')
61
+ expect(@response_hash.json[:organization]['name']).to eq('SDK4ME Institute')
62
+ expect(@response_hash.json['organization'][:name]).to eq('SDK4ME Institute')
63
+ end
64
+
65
+ it 'should provide indifferent access for lists' do
66
+ expect(@response_array.json.first['site']['name']).to eq('IT Training Facility')
67
+ expect(@response_array.json.first[:site][:name]).to eq('IT Training Facility')
68
+ expect(@response_array.json.last[:site]['name']).to eq('IT Training Facility')
69
+ expect(@response_array.json.last['site'][:name]).to eq('IT Training Facility')
70
+ end
71
+
72
+ it 'should add a message if the body is empty' do
73
+ stub_request(:get, 'https://api.4me.com/v1/organizations').with(basic_auth: ['secret', 'x']).to_return(status: 429, body: nil)
74
+ response = @client.get('organizations')
75
+
76
+ message = '429: empty body'
77
+ expect(response.json[:message]).to eq(message)
78
+ expect(response.json['message']).to eq(message)
79
+ expect(response.message).to eq(message)
80
+ end
81
+
82
+ it 'should add a message if the HTTP response is not OK' do
83
+ stub_request(:get, 'https://api.4me.com/v1/organizations').with(basic_auth: ['secret', 'x']).to_return(status: 429, body: {message: 'Too Many Requests'}.to_json)
84
+ response = @client.get('organizations')
85
+
86
+ message = '429: Too Many Requests'
87
+ expect(response.json[:message]).to eq(message)
88
+ expect(response.json['message']).to eq(message)
89
+ expect(response.message).to eq(message)
90
+ end
91
+
92
+ it 'should add a message if the JSON body cannot be parsed' do
93
+ stub_request(:get, 'https://api.4me.com/v1/organizations').with(basic_auth: ['secret', 'x']).to_return(body: '==$$!invalid')
94
+ response = @client.get('organizations')
95
+
96
+ message = "Invalid JSON - 765: unexpected token at '==$$!invalid' for:\n#{response.body}"
97
+ expect(response.json[:message]).to eq(message)
98
+ expect(response.json['message']).to eq(message)
99
+ expect(response.message).to eq(message)
100
+ end
101
+
102
+ it 'should have a blank message when single record is succesfully retrieved' do
103
+ expect(@response_hash.message).to be_nil
104
+ end
105
+
106
+ it 'should have a blank message when single record is succesfully retrieved' do
107
+ expect(@response_array.message).to be_nil
108
+ end
109
+
110
+ end
111
+
112
+ it 'should define empty' do
113
+ stub_request(:get, 'https://api.4me.com/v1/organizations').with(basic_auth: ['secret', 'x']).to_return(status: 429, body: nil)
114
+ response = @client.get('organizations')
115
+
116
+ expect(response.empty?).to be_truthy
117
+ expect(@person_hash.empty?).to be_falsey
118
+ expect(@people_array.empty?).to be_falsey
119
+ end
120
+
121
+ context 'valid' do
122
+ it 'should be valid when the message is nil' do
123
+ expect(@response_hash).to receive(:message){ nil }
124
+ expect(@response_hash.valid?).to be_truthy
125
+ end
126
+
127
+ it 'should not be valid when the message is not nil' do
128
+ expect(@response_array).to receive(:message){ 'invalid' }
129
+ expect(@response_array.valid?).to be_falsey
130
+ end
131
+ end
132
+
133
+ context '[] access' do
134
+ context 'single records' do
135
+ it 'should delegate [] to the json' do
136
+ expect(@response_hash[:name]).to eq('John')
137
+ end
138
+
139
+ it 'should allow multiple keys' do
140
+ expect(@response_hash[:organization, 'name']).to eq('SDK4ME Institute')
141
+ end
142
+
143
+ it 'should allow nils when using multiple keys' do
144
+ expect(@response_hash[:organization, :missing, 'name']).to be_nil
145
+ end
146
+ end
147
+
148
+ context 'list of records' do
149
+ it 'should delegate [] to the json of each record' do
150
+ expect(@response_array['name']).to eq(['John', 'Lucas', 'Sheryl'])
151
+ end
152
+
153
+ it 'should allow multiple keys' do
154
+ expect(@response_array[:organization, 'name']).to eq(['SDK4ME Institute', 'SDK4ME Institute', 'SDK4ME Institute'])
155
+ end
156
+
157
+ it 'should allow nils when using multiple keys' do
158
+ expect(@response_array[:organization, :office, 'name']).to eq([nil, 'The Office', nil])
159
+ end
160
+ end
161
+ end
162
+
163
+ context 'size' do
164
+ it 'should return 1 for single records' do
165
+ expect(@response_hash.size).to eq(1)
166
+ end
167
+
168
+ it 'should return the array size for list records' do
169
+ expect(@response_array.size).to eq(3)
170
+ end
171
+
172
+ it 'should return nil if an error message is present' do
173
+ expect(@response_hash).to receive(:message){ 'error message' }
174
+ expect(@response_hash.size).to eq(0)
175
+ end
176
+ end
177
+
178
+ context 'count' do
179
+ it 'should return 1 for single records' do
180
+ expect(@response_hash.count).to eq(1)
181
+ end
182
+
183
+ it 'should return the array size for list records' do
184
+ expect(@response_array.count).to eq(3)
185
+ end
186
+
187
+ it 'should return nil if an error message is present' do
188
+ expect(@response_hash).to receive(:message){ 'error message' }
189
+ expect(@response_hash.count).to eq(0)
190
+ end
191
+ end
192
+
193
+ context 'pagination' do
194
+ before(:each) do
195
+ @pagination_header = {
196
+ 'X-Pagination-Per-Page' => 3,
197
+ 'X-Pagination-Current-Page' => 1,
198
+ 'X-Pagination-Total-Pages' => 2,
199
+ 'X-Pagination-Total-Entries' => 5,
200
+ 'Link' => '<https://api.4me.com/v1/people?page=1&per_page=3>; rel="first",<https://api.4me.com/v1/people?page=2&per_page=3>; rel="next", <https://api.4me.com/v1/people?page=2&per_page=3>; rel="last"',
201
+ }
202
+ allow(@response_array.response).to receive('header'){ @pagination_header }
203
+ end
204
+
205
+ it "should retrieve per_page from the 'X-Pagination-Per-Page' header" do
206
+ expect(@response_array.per_page).to eq(3)
207
+ end
208
+
209
+ it "should retrieve current_page from the 'X-Pagination-Current-Page' header" do
210
+ expect(@response_array.current_page).to eq(1)
211
+ end
212
+
213
+ it "should retrieve total_pages from the 'X-Pagination-Total-Pages' header" do
214
+ expect(@response_array.total_pages).to eq(2)
215
+ end
216
+
217
+ it "should retrieve total_entries from the 'X-Pagination-Total-Entries' header" do
218
+ expect(@response_array.total_entries).to eq(5)
219
+ end
220
+
221
+ {first: 'https://api.4me.com/v1/people?page=1&per_page=3',
222
+ next: 'https://api.4me.com/v1/people?page=2&per_page=3',
223
+ last: 'https://api.4me.com/v1/people?page=2&per_page=3'}.each do |relation, link|
224
+
225
+ it "should define pagination link for :#{relation}" do
226
+ expect(@response_array.pagination_link(relation)).to eq(link)
227
+ end
228
+ end
229
+
230
+ {first: '/v1/people?page=1&per_page=3',
231
+ next: '/v1/people?page=2&per_page=3',
232
+ last: '/v1/people?page=2&per_page=3'}.each do |relation, link|
233
+
234
+ it "should define pagination relative link for :#{relation}" do
235
+ expect(@response_array.pagination_relative_link(relation)).to eq(link)
236
+ end
237
+ end
238
+ end
239
+
240
+ context 'throttled?' do
241
+ it 'should not be trhottled by default' do
242
+ expect(@response_hash.throttled?).to be_falsey
243
+ expect(@response_array.throttled?).to be_falsey
244
+ end
245
+
246
+ it 'should check the return code' do
247
+ stub_request(:get, 'https://api.4me.com/v1/organizations').with(basic_auth: ['secret', 'x']).to_return(status: 429, body: nil)
248
+ response = @client.get('organizations')
249
+ expect(response.throttled?).to be_truthy
250
+ end
251
+
252
+ it 'should check the return message' do
253
+ stub_request(:get, 'https://api.4me.com/v1/organizations').with(basic_auth: ['secret', 'x']).to_return(status: 500, body: {message: 'Too Many Requests'}.to_json )
254
+ response = @client.get('organizations')
255
+ expect(response.throttled?).to be_truthy
256
+ end
257
+ end
258
+
259
+ context 'to_s' do
260
+ it 'should return the JSON as a string' do
261
+ expect(@response_hash.to_s).to eq(JSON.parse(@person_hash.to_json).to_s)
262
+ end
263
+
264
+ it 'should return the message in case the response is not valid' do
265
+ stub_request(:get, 'https://api.4me.com/v1/organizations').with(basic_auth: ['secret', 'x']).to_return(status: 429, body: nil)
266
+ response = @client.get('organizations')
267
+ expect(response.to_s).to eq('429: empty body')
268
+ end
269
+ end
270
+
271
+ end
@@ -0,0 +1,33 @@
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([:account, :api_token, :api_version, :block_at_rate_limit, :ca_file, :host, :logger, :max_retry_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(5400)
14
+ expect(conf[:read_timeout]).to eq(25)
15
+ expect(conf[:block_at_rate_limit]).to be_falsey
16
+
17
+ expect(conf[:proxy_port]).to eq(8080)
18
+
19
+ [: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.new('test') }.to raise_error('test')
32
+ end
33
+ end
@@ -0,0 +1,48 @@
1
+ # -*- encoding : utf-8 -*-
2
+ dir = File.dirname(__FILE__)
3
+ $LOAD_PATH.unshift dir + '/../lib'
4
+ $LOAD_PATH.unshift dir
5
+
6
+ STDERR.puts("Running specs using ruby version #{RUBY_VERSION}")
7
+
8
+ require 'simplecov'
9
+ SimpleCov.start
10
+
11
+ require 'rspec'
12
+ require 'webmock/rspec'
13
+
14
+ # Patch for https://github.com/bblimke/webmock/issues/623
15
+ module WebMock
16
+ class BodyPattern
17
+ def assert_non_multipart_body(content_type)
18
+ # if content_type =~ %r{^multipart/form-data}
19
+ # raise ArgumentError.new("WebMock does not support matching body for multipart/form-data requests yet :(")
20
+ # end
21
+ end
22
+ end
23
+ end
24
+
25
+ require 'sdk4me/client'
26
+
27
+ # Requires supporting ruby files with custom matchers and macros, etc,
28
+ # in spec/support/ and its subdirectories.
29
+ Dir["#{dir}/support/**/*.rb"].each { |f| require f }
30
+
31
+ RSpec.configure do |config|
32
+ config.before(:each) do
33
+ log_dir = File.dirname(__FILE__) + '/log'
34
+ Dir.mkdir(log_dir) unless File.exists?(log_dir)
35
+ Sdk4me.configuration.logger = Logger.new("#{log_dir}/test.log")
36
+ @spec_dir = dir
37
+ @fixture_dir = "#{dir}/support/fixtures"
38
+ end
39
+ config.after(:each) { Sdk4me.configuration.reset }
40
+
41
+ # Run specs in random order to surface order dependencies. If you find an
42
+ # order dependency and want to debug it, you can fix the order by providing
43
+ # the seed, which is printed after each run.
44
+ # --seed 1234
45
+ config.order = 'random'
46
+
47
+ end
48
+
@@ -0,0 +1,3 @@
1
+ Primary Email,Name
2
+ chess.cole@example.com,Chess Cole
3
+ ed.turner@example.com,Ed Turner
@@ -0,0 +1 @@
1
+ content
@@ -0,0 +1,46 @@
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
+ begin
23
+ block.call
24
+ rescue exception_class => e
25
+ global_result = "expected #{block.source_location[0]}:#{block.source_location[1]} to never raise #{exception_class.name}, but did: #{e.message}"
26
+ false # we did NOT never raise this exception
27
+
28
+ rescue RSpec::Expectations::ExpectationNotMetError => exception
29
+ global_result = "expectation failed inside block at #{block.source_location[0]}:#{block.source_location[1]}: #{exception}"
30
+ # give us a pretty error message in addition to the error message from the exception
31
+ raise exception
32
+
33
+ rescue
34
+ # handle other exceptions by reraising them. They are exceptional!!!
35
+ # (also, no pretty error messages here)
36
+ raise
37
+
38
+ else
39
+ true # everything ran, nothing raised at all, thus code did in fact not raise anything
40
+ end
41
+ end
42
+
43
+ failure_message do |player|
44
+ global_result
45
+ end
46
+ end
@@ -0,0 +1,3 @@
1
+ def expect_log(text, level = :info, logger = Sdk4me.configuration.logger)
2
+ expect(logger).to receive(level).ordered { |&args| expect(args.call).to eq(text) }
3
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: 4me-sdk
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.2
4
+ version: 1.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - 4me
@@ -122,7 +122,7 @@ dependencies:
122
122
  - - "~>"
123
123
  - !ruby/object:Gem::Version
124
124
  version: '0'
125
- description: SDK for accessing the 4me
125
+ description: SDK for accessing the 4me API
126
126
  email: developers@4me.com
127
127
  executables: []
128
128
  extensions: []
@@ -140,6 +140,16 @@ files:
140
140
  - lib/sdk4me/client/multipart.rb
141
141
  - lib/sdk4me/client/response.rb
142
142
  - lib/sdk4me/client/version.rb
143
+ - spec/lib/sdk4me/attachments_spec.rb
144
+ - spec/lib/sdk4me/certificate_spec.rb
145
+ - spec/lib/sdk4me/client_spec.rb
146
+ - spec/lib/sdk4me/response_spec.rb
147
+ - spec/lib/sdk4me_spec.rb
148
+ - spec/spec_helper.rb
149
+ - spec/support/fixtures/people.csv
150
+ - spec/support/fixtures/upload.txt
151
+ - spec/support/matchers/never_raise.rb
152
+ - spec/support/util.rb
143
153
  homepage: https://github.com/code4me/4me-sdk-ruby
144
154
  licenses:
145
155
  - MIT
@@ -166,4 +176,14 @@ signing_key:
166
176
  specification_version: 4
167
177
  summary: The official 4me SDK for Ruby. Provides easy access to the APIs found at
168
178
  https://developer.4me.com
169
- test_files: []
179
+ test_files:
180
+ - spec/lib/sdk4me/attachments_spec.rb
181
+ - spec/lib/sdk4me/certificate_spec.rb
182
+ - spec/lib/sdk4me/client_spec.rb
183
+ - spec/lib/sdk4me/response_spec.rb
184
+ - spec/lib/sdk4me_spec.rb
185
+ - spec/spec_helper.rb
186
+ - spec/support/fixtures/people.csv
187
+ - spec/support/fixtures/upload.txt
188
+ - spec/support/matchers/never_raise.rb
189
+ - spec/support/util.rb