itrp-client 1.1.3 → 1.1.4

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.
@@ -0,0 +1,271 @@
1
+ require 'spec_helper'
2
+
3
+ describe Itrp::Response do
4
+ before(:each) do
5
+ @client = Itrp::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: 'ITRP 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.itrp.com/v1/me').with(basic_auth: ['secret', 'x']).to_return(body: @person_hash.to_json)
23
+ @response_hash = @client.get('me')
24
+
25
+ @client = Itrp::Client.new(api_token: 'secret', max_retry_time: -1)
26
+ @people_array = [
27
+ {id: 562, name: 'John', organization: { id: 20, name: 'ITRP Institute'}, site: {id: 14, name: 'IT Training Facility'} },
28
+ {id: 560, name: 'Lucas', organization: { id: 20, name: 'ITRP Institute', office: { name: 'The Office'}}, site: {id: 14, name: 'IT Training Facility'} },
29
+ {id: 561, name: 'Sheryl', organization: { id: 20, name: 'ITRP Institute'}, site: {id: 14, name: 'IT Training Facility'} }
30
+ ]
31
+ stub_request(:get, 'https://api.itrp.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('ITRP Institute')
60
+ expect(@response_hash.json[:organization][:name]).to eq('ITRP Institute')
61
+ expect(@response_hash.json[:organization]['name']).to eq('ITRP Institute')
62
+ expect(@response_hash.json['organization'][:name]).to eq('ITRP 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.itrp.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.itrp.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.itrp.com/v1/organizations').with(basic_auth: ['secret', 'x']).to_return(body: '==$$!invalid')
94
+ response = @client.get('organizations')
95
+
96
+ message = "Invalid JSON - 757: 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.itrp.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('ITRP 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(['ITRP Institute', 'ITRP Institute', 'ITRP 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.itrp.com/v1/people?page=1&per_page=3>; rel="first",<https://api.itrp.com/v1/people?page=2&per_page=3>; rel="next", <https://api.itrp.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.itrp.com/v1/people?page=1&per_page=3',
222
+ next: 'https://api.itrp.com/v1/people?page=2&per_page=3',
223
+ last: 'https://api.itrp.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.itrp.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.itrp.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.itrp.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 Itrp do
4
+ it "should define a default configuration" do
5
+ conf = Itrp.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.itrp.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(Itrp.logger.class).to eq(::Logger)
28
+ end
29
+
30
+ it "should define an exception class" do
31
+ expect { raise ::Itrp::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 'itrp/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
+ Itrp.configuration.logger = Logger.new("#{log_dir}/test.log")
36
+ @spec_dir = dir
37
+ @fixture_dir = "#{dir}/support/fixtures"
38
+ end
39
+ config.after(:each) { Itrp.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 = Itrp.configuration.logger)
2
+ expect(logger).to receive(level).ordered { |&args| expect(args.call).to eq(text) }
3
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: itrp-client
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.3
4
+ version: 1.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - ITRP
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-02-19 00:00:00.000000000 Z
11
+ date: 2018-11-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: gem_config
@@ -140,6 +140,16 @@ files:
140
140
  - lib/itrp/client/multipart.rb
141
141
  - lib/itrp/client/response.rb
142
142
  - lib/itrp/client/version.rb
143
+ - spec/lib/itrp/attachments_spec.rb
144
+ - spec/lib/itrp/certificate_spec.rb
145
+ - spec/lib/itrp/client_spec.rb
146
+ - spec/lib/itrp/response_spec.rb
147
+ - spec/lib/itrp_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: http://github.com/itrp/itrp-client
144
154
  licenses:
145
155
  - MIT
@@ -161,9 +171,18 @@ required_rubygems_version: !ruby/object:Gem::Requirement
161
171
  version: '0'
162
172
  requirements: []
163
173
  rubyforge_project:
164
- rubygems_version: 2.5.2.1
174
+ rubygems_version: 2.4.6
165
175
  signing_key:
166
176
  specification_version: 4
167
177
  summary: Client for accessing the ITRP REST API
168
- test_files: []
169
- has_rdoc:
178
+ test_files:
179
+ - spec/lib/itrp/attachments_spec.rb
180
+ - spec/lib/itrp/certificate_spec.rb
181
+ - spec/lib/itrp/client_spec.rb
182
+ - spec/lib/itrp/response_spec.rb
183
+ - spec/lib/itrp_spec.rb
184
+ - spec/spec_helper.rb
185
+ - spec/support/fixtures/people.csv
186
+ - spec/support/fixtures/upload.txt
187
+ - spec/support/matchers/never_raise.rb
188
+ - spec/support/util.rb