quiz_api_client 4.24.0 → 4.25.0
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/README.md +34 -0
- data/lib/quiz_api_client/config.rb +1 -1
- data/lib/quiz_api_client/http_request/failure.rb +4 -0
- data/lib/quiz_api_client/version.rb +1 -1
- data/spec/http_client_spec.rb +156 -0
- metadata +30 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 271c4523cdeb2e7861c0292366ce7db0e6f87ab37a1406d5a9bc5fb001ad935e
|
|
4
|
+
data.tar.gz: 3e290ab1b995fbd19c9b00e0b73a8cea69974a15f77859900a4a8d66f1876c85
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 2f125d17891e1fddacaaab43282ac302e88668277e00df91cd184358cca2ee5c0303cf97345eb2a592e53d8237d126e13319b6169db5e091548f3434153624e0
|
|
7
|
+
data.tar.gz: 904d69175eee4889c4c12f17ca57d1306f909fe585171b1d100229e0036c57b9e70686e05a602fb782258dac16d2f1ff8fd041fb8f6f8c8ec8361f0415c1877d
|
data/README.md
CHANGED
|
@@ -187,3 +187,37 @@ Then, run `bundle exec rake spec` to run the tests.
|
|
|
187
187
|
You can also run `bundle exec rake console` for an interactive prompt that will allow you to experiment.
|
|
188
188
|
|
|
189
189
|
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
|
190
|
+
|
|
191
|
+
## Development with Quiz LTI
|
|
192
|
+
|
|
193
|
+
Copy this repo inside the Quiz LTI docker container:
|
|
194
|
+
|
|
195
|
+
```shell
|
|
196
|
+
docker cp . quiz-lti-web:/quiz_api_client_ruby
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
Tell Quiz LTI to use the gem, find the line containing `gem 'quiz_api_client'` in `app.rb`, update it to:
|
|
200
|
+
|
|
201
|
+
```shell
|
|
202
|
+
gem 'quiz_api_client', path: '/quiz_api_client_ruby'
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
Run bundle install the container:
|
|
206
|
+
|
|
207
|
+
```shell
|
|
208
|
+
docker exec quiz-lti-web bundle install
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
Restart the container:
|
|
212
|
+
|
|
213
|
+
```shell
|
|
214
|
+
docker restart quiz-lti-web
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
Your changes should be reflected in the container!
|
|
218
|
+
|
|
219
|
+
If you update the code afterwards you'll need to copy and restart the container:
|
|
220
|
+
|
|
221
|
+
```shell
|
|
222
|
+
docker cp . quiz-lti-web:gems/quiz_api_client_ruby && docker restart quiz-lti-web
|
|
223
|
+
```
|
|
@@ -2,7 +2,7 @@ module QuizApiClient
|
|
|
2
2
|
class Config
|
|
3
3
|
DEFAULT_ALLOWABLE_RESPONSE_CODES = [401, 422].freeze
|
|
4
4
|
DEFAULT_PROTOCOL = 'https'.freeze
|
|
5
|
-
ERROR_HANDLERS = %i[sentry_raven].freeze
|
|
5
|
+
ERROR_HANDLERS = %i[sentry_raven sentry_rails].freeze
|
|
6
6
|
METRICS_HANDLERS = %i[inststatsd].freeze
|
|
7
7
|
|
|
8
8
|
class InvalidErrorHandler < StandardError; end
|
data/spec/http_client_spec.rb
CHANGED
|
@@ -360,6 +360,162 @@ describe QuizApiClient::HttpClient do
|
|
|
360
360
|
expect { client.get('/') }.to raise_error(QuizApiClient::HttpClient::RequestFailed)
|
|
361
361
|
end
|
|
362
362
|
|
|
363
|
+
it 'handles an Net::ReadTimeout error' do
|
|
364
|
+
stub_request(:get, url).to_raise(Net::ReadTimeout)
|
|
365
|
+
expect_metrics_calls(client.config, :get, 0)
|
|
366
|
+
expect_raise_error_call(client.config, :get, url_for_path(path), nil, kind_of(Net::ReadTimeout))
|
|
367
|
+
expect { client.get('/') }.to raise_error(QuizApiClient::HttpClient::RequestFailed)
|
|
368
|
+
end
|
|
369
|
+
end
|
|
370
|
+
context 'with :sentry_rails error handler' do
|
|
371
|
+
let(:error_handler) { :sentry_rails }
|
|
372
|
+
let(:path) { '/' }
|
|
373
|
+
let(:url) { "http://api.quiz.docker#{path}" }
|
|
374
|
+
let(:error_context) do
|
|
375
|
+
{
|
|
376
|
+
quiz_api_client: {
|
|
377
|
+
request: {
|
|
378
|
+
method: :get,
|
|
379
|
+
url: url
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
end
|
|
384
|
+
|
|
385
|
+
before do
|
|
386
|
+
client.config.error_handler = error_handler
|
|
387
|
+
end
|
|
388
|
+
|
|
389
|
+
context 'with non-success responses' do
|
|
390
|
+
let(:body) { '[2]' }
|
|
391
|
+
let(:code) { 404 }
|
|
392
|
+
let(:path) { '/api/quizzes' }
|
|
393
|
+
let(:context_url) { url }
|
|
394
|
+
let(:method) { :get }
|
|
395
|
+
let(:error_context) do
|
|
396
|
+
{
|
|
397
|
+
quiz_api_client: {
|
|
398
|
+
request: {
|
|
399
|
+
method: method,
|
|
400
|
+
url: context_url
|
|
401
|
+
},
|
|
402
|
+
response: {
|
|
403
|
+
body: body,
|
|
404
|
+
code: code
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
end
|
|
409
|
+
let(:mock_response) do
|
|
410
|
+
instance_double(
|
|
411
|
+
'HTTParty::Response',
|
|
412
|
+
success?: false,
|
|
413
|
+
body: body,
|
|
414
|
+
code: code
|
|
415
|
+
)
|
|
416
|
+
end
|
|
417
|
+
let(:success_response) do
|
|
418
|
+
# rubocop:disable Metrics/LineLength
|
|
419
|
+
instance_double(
|
|
420
|
+
'HTTParty::Response',
|
|
421
|
+
body: body,
|
|
422
|
+
code: 200,
|
|
423
|
+
parsed_response: [1],
|
|
424
|
+
headers: {
|
|
425
|
+
'link' => '<http://api.quiz.docker/api/quizzes?page=2>; rel="last", <http://api.quiz.docker/api/quizzes?page=2>; rel="next"',
|
|
426
|
+
'content-type' => ['application/json']
|
|
427
|
+
}
|
|
428
|
+
)
|
|
429
|
+
# rubocop:enable Metrics/LineLength
|
|
430
|
+
end
|
|
431
|
+
|
|
432
|
+
context ':get request' do
|
|
433
|
+
it 'raises error' do
|
|
434
|
+
expect(client).to receive(:successful_response?).with(mock_response).and_return(false)
|
|
435
|
+
expect(client.class).to receive(:get).and_return(mock_response)
|
|
436
|
+
expect_metrics_calls(client.config, method, code)
|
|
437
|
+
expect_raise_error_call(client.config, method, url_for_path(path), mock_response, nil)
|
|
438
|
+
expect { client.get(path, all: false, query: { sort: 'alpha' }) }
|
|
439
|
+
.to raise_error(QuizApiClient::HttpClient::RequestFailed)
|
|
440
|
+
end
|
|
441
|
+
end
|
|
442
|
+
|
|
443
|
+
context ':post request' do
|
|
444
|
+
let(:method) { :post }
|
|
445
|
+
|
|
446
|
+
it 'raises error' do
|
|
447
|
+
expect(client).to receive(:successful_response?).with(mock_response).and_return(false)
|
|
448
|
+
expect(client.class).to receive(:post).and_return(mock_response)
|
|
449
|
+
expect_metrics_calls(client.config, method, code)
|
|
450
|
+
expect_raise_error_call(client.config, method, url_for_path(path), mock_response, nil)
|
|
451
|
+
expect { client.post(path) }.to raise_error(QuizApiClient::HttpClient::RequestFailed)
|
|
452
|
+
end
|
|
453
|
+
end
|
|
454
|
+
|
|
455
|
+
context ':put request' do
|
|
456
|
+
let(:method) { :put }
|
|
457
|
+
|
|
458
|
+
it 'raises error' do
|
|
459
|
+
expect(client).to receive(:successful_response?).with(mock_response).and_return(false)
|
|
460
|
+
expect(client.class).to receive(:put).and_return(mock_response)
|
|
461
|
+
expect_metrics_calls(client.config, method, code)
|
|
462
|
+
expect_raise_error_call(client.config, method, url_for_path(path), mock_response, nil)
|
|
463
|
+
expect { client.put(path) }.to raise_error(QuizApiClient::HttpClient::RequestFailed)
|
|
464
|
+
end
|
|
465
|
+
end
|
|
466
|
+
|
|
467
|
+
context ':patch request' do
|
|
468
|
+
let(:method) { :patch }
|
|
469
|
+
|
|
470
|
+
it 'raises error' do
|
|
471
|
+
expect(client).to receive(:successful_response?).with(mock_response).and_return(false)
|
|
472
|
+
expect(client.class).to receive(:patch).and_return(mock_response)
|
|
473
|
+
expect_metrics_calls(client.config, method, code)
|
|
474
|
+
expect_raise_error_call(client.config, method, url_for_path(path), mock_response, nil)
|
|
475
|
+
expect { client.patch(path) }.to raise_error(QuizApiClient::HttpClient::RequestFailed)
|
|
476
|
+
end
|
|
477
|
+
end
|
|
478
|
+
|
|
479
|
+
context ':delete request' do
|
|
480
|
+
let(:method) { :delete }
|
|
481
|
+
|
|
482
|
+
it 'raises error' do
|
|
483
|
+
expect(client).to receive(:successful_response?).with(mock_response).and_return(false)
|
|
484
|
+
expect(client.class).to receive(:delete).and_return(mock_response)
|
|
485
|
+
expect_metrics_calls(client.config, method, code)
|
|
486
|
+
expect_raise_error_call(client.config, method, url_for_path(path), mock_response, nil)
|
|
487
|
+
expect { client.delete(path) }.to raise_error(QuizApiClient::HttpClient::RequestFailed)
|
|
488
|
+
end
|
|
489
|
+
end
|
|
490
|
+
|
|
491
|
+
context 'with pagination' do
|
|
492
|
+
let(:context_url) { "#{url}?page=2" }
|
|
493
|
+
|
|
494
|
+
it 'raises error if one of the linked pages does not return 200 response' do
|
|
495
|
+
stub_quiz_api path, headers: { link: link_header(path, 1, 2) }
|
|
496
|
+
stub_quiz_api path, item: 2, query: { page: 2 }, headers: { link: link_header(path, 2, 2) }, status: code
|
|
497
|
+
allow(HTTParty::Response).to receive(:new).and_return(success_response, mock_response)
|
|
498
|
+
expect(client).to receive(:successful_response?).and_return(true, false).twice
|
|
499
|
+
expect_raise_error_call(client.config, method, context_url, mock_response, nil)
|
|
500
|
+
expect { client.get('/api/quizzes', all: true) }.to raise_error(QuizApiClient::HttpClient::RequestFailed)
|
|
501
|
+
end
|
|
502
|
+
end
|
|
503
|
+
end
|
|
504
|
+
|
|
505
|
+
it 'handles an HTTParty::Error error' do
|
|
506
|
+
stub_request(:get, url).to_raise(HTTParty::Error)
|
|
507
|
+
expect_metrics_calls(client.config, :get, 0)
|
|
508
|
+
expect_raise_error_call(client.config, :get, url_for_path(path), nil, kind_of(HTTParty::Error))
|
|
509
|
+
expect { client.get('/') }.to raise_error(QuizApiClient::HttpClient::RequestFailed)
|
|
510
|
+
end
|
|
511
|
+
|
|
512
|
+
it 'handles an Errno::ECONNREFUSED error' do
|
|
513
|
+
stub_request(:get, url).to_raise(Errno::ECONNREFUSED)
|
|
514
|
+
expect_metrics_calls(client.config, :get, 0)
|
|
515
|
+
expect_raise_error_call(client.config, :get, url_for_path(path), nil, kind_of(Errno::ECONNREFUSED))
|
|
516
|
+
expect { client.get('/') }.to raise_error(QuizApiClient::HttpClient::RequestFailed)
|
|
517
|
+
end
|
|
518
|
+
|
|
363
519
|
it 'handles an Net::ReadTimeout error' do
|
|
364
520
|
stub_request(:get, url).to_raise(Net::ReadTimeout)
|
|
365
521
|
expect_metrics_calls(client.config, :get, 0)
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: quiz_api_client
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 4.
|
|
4
|
+
version: 4.25.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Alex Slaughter
|
|
@@ -15,7 +15,7 @@ authors:
|
|
|
15
15
|
autorequire:
|
|
16
16
|
bindir: exe
|
|
17
17
|
cert_chain: []
|
|
18
|
-
date:
|
|
18
|
+
date: 2026-04-29 00:00:00.000000000 Z
|
|
19
19
|
dependencies:
|
|
20
20
|
- !ruby/object:Gem::Dependency
|
|
21
21
|
name: httparty
|
|
@@ -115,6 +115,20 @@ dependencies:
|
|
|
115
115
|
- - "~>"
|
|
116
116
|
- !ruby/object:Gem::Version
|
|
117
117
|
version: 0.74.0
|
|
118
|
+
- !ruby/object:Gem::Dependency
|
|
119
|
+
name: sentry-rails
|
|
120
|
+
requirement: !ruby/object:Gem::Requirement
|
|
121
|
+
requirements:
|
|
122
|
+
- - "~>"
|
|
123
|
+
- !ruby/object:Gem::Version
|
|
124
|
+
version: '6.5'
|
|
125
|
+
type: :development
|
|
126
|
+
prerelease: false
|
|
127
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
128
|
+
requirements:
|
|
129
|
+
- - "~>"
|
|
130
|
+
- !ruby/object:Gem::Version
|
|
131
|
+
version: '6.5'
|
|
118
132
|
- !ruby/object:Gem::Dependency
|
|
119
133
|
name: sentry-raven
|
|
120
134
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -129,6 +143,20 @@ dependencies:
|
|
|
129
143
|
- - "~>"
|
|
130
144
|
- !ruby/object:Gem::Version
|
|
131
145
|
version: '3.1'
|
|
146
|
+
- !ruby/object:Gem::Dependency
|
|
147
|
+
name: sentry-ruby
|
|
148
|
+
requirement: !ruby/object:Gem::Requirement
|
|
149
|
+
requirements:
|
|
150
|
+
- - "~>"
|
|
151
|
+
- !ruby/object:Gem::Version
|
|
152
|
+
version: '6.5'
|
|
153
|
+
type: :development
|
|
154
|
+
prerelease: false
|
|
155
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
156
|
+
requirements:
|
|
157
|
+
- - "~>"
|
|
158
|
+
- !ruby/object:Gem::Version
|
|
159
|
+
version: '6.5'
|
|
132
160
|
- !ruby/object:Gem::Dependency
|
|
133
161
|
name: simplecov
|
|
134
162
|
requirement: !ruby/object:Gem::Requirement
|