quiz_api_client 4.2.0 → 4.4.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.
Files changed (78) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/lib/quiz_api_client/services/courses_service.rb +26 -0
  4. data/lib/quiz_api_client/services/items_service.rb +11 -0
  5. data/lib/quiz_api_client/services/quiz_clone_jobs_service.rb +11 -0
  6. data/lib/quiz_api_client/services/quiz_sync_job_service.rb +17 -0
  7. data/lib/quiz_api_client/services/quiz_sync_jobs_service.rb +16 -0
  8. data/lib/quiz_api_client/version.rb +1 -1
  9. data/lib/quiz_api_client.rb +15 -0
  10. data/spec/config_spec.rb +66 -0
  11. data/spec/contracts/interaction_types_service_spec.rb +22 -0
  12. data/spec/contracts/item_analyses_service_spec.rb +59 -0
  13. data/spec/contracts/items_service_spec.rb +59 -0
  14. data/spec/contracts/qti_imports_service_spec.rb +34 -0
  15. data/spec/contracts/quiz_clone_job_service_spec.rb +20 -0
  16. data/spec/contracts/quiz_clone_jobs_service_spec.rb +21 -0
  17. data/spec/contracts/quiz_entries_service_spec.rb +125 -0
  18. data/spec/contracts/quiz_service_spec.rb +68 -0
  19. data/spec/contracts/quiz_session_events_service_spec.rb +30 -0
  20. data/spec/contracts/quiz_session_result_service_spec.rb +42 -0
  21. data/spec/contracts/quiz_session_service_spec.rb +56 -0
  22. data/spec/contracts/quiz_sessions_service_spec.rb +28 -0
  23. data/spec/contracts/quiz_sync_job_service_spec.rb +21 -0
  24. data/spec/contracts/quiz_sync_jobs_service_spec.rb +21 -0
  25. data/spec/contracts/quizzes_service_spec.rb +80 -0
  26. data/spec/contracts/session_item_results_service_spec.rb +60 -0
  27. data/spec/contracts/session_items_service_spec.rb +21 -0
  28. data/spec/contracts/shared_banks_spec.rb +366 -0
  29. data/spec/contracts/shared_examples/http_delete_example.rb +56 -0
  30. data/spec/contracts/shared_examples/http_get_example.rb +139 -0
  31. data/spec/contracts/shared_examples/http_patch_example.rb +60 -0
  32. data/spec/contracts/shared_examples/http_post_example.rb +68 -0
  33. data/spec/contracts/shared_examples/http_put_example.rb +60 -0
  34. data/spec/http_client_spec.rb +347 -0
  35. data/spec/json_formatter_spec.rb +32 -0
  36. data/spec/quiz_api_client/http_request/failure_spec.rb +100 -0
  37. data/spec/quiz_api_client/http_request/metrics_spec.rb +75 -0
  38. data/spec/quiz_api_client_spec.rb +124 -0
  39. data/spec/services/base_api_service_spec.rb +50 -0
  40. data/spec/services/courses_service_spec.rb +59 -0
  41. data/spec/services/interaction_types_service_spec.rb +25 -0
  42. data/spec/services/item_analyses_service_spec.rb +76 -0
  43. data/spec/services/items_service_spec.rb +56 -0
  44. data/spec/services/jwt_service_spec.rb +66 -0
  45. data/spec/services/qti_imports_service_spec.rb +114 -0
  46. data/spec/services/quiz_analyses_service_spec.rb +44 -0
  47. data/spec/services/quiz_clone_job_service_spec.rb +41 -0
  48. data/spec/services/quiz_clone_jobs_service_spec.rb +77 -0
  49. data/spec/services/quiz_entries_service_spec.rb +71 -0
  50. data/spec/services/quiz_service_spec.rb +49 -0
  51. data/spec/services/quiz_session_events_service_spec.rb +42 -0
  52. data/spec/services/quiz_session_result_service_spec.rb +26 -0
  53. data/spec/services/quiz_session_service_spec.rb +49 -0
  54. data/spec/services/quiz_sessions_service_spec.rb +42 -0
  55. data/spec/services/quiz_sync_job_service_spec.rb +41 -0
  56. data/spec/services/quiz_sync_jobs_service_spec.rb +77 -0
  57. data/spec/services/quizzes_service_spec.rb +71 -0
  58. data/spec/services/session_item_results_service_spec.rb +33 -0
  59. data/spec/services/session_items_service_spec.rb +26 -0
  60. data/spec/spec_helper.rb +42 -0
  61. data/spec/support/pact_config.rb +64 -0
  62. data/spec/support/pact_helper.rb +19 -0
  63. metadata +121 -39
  64. data/.dockerignore +0 -7
  65. data/.editorconfig +0 -16
  66. data/.gitignore +0 -13
  67. data/.rspec +0 -3
  68. data/.rubocop.yml +0 -72
  69. data/CHANGELOG.md +0 -35
  70. data/Dockerfile +0 -12
  71. data/Gemfile +0 -5
  72. data/Jenkinsfile +0 -86
  73. data/bin/console +0 -7
  74. data/bin/contracts-generate +0 -26
  75. data/bin/setup +0 -65
  76. data/docker-compose.dev.override.yml +0 -11
  77. data/docker-compose.yml +0 -10
  78. data/quiz_api_client.gemspec +0 -60
@@ -0,0 +1,124 @@
1
+ describe QuizApiClient do
2
+ it 'has a version number' do
3
+ expect(QuizApiClient::VERSION).not_to be nil
4
+ end
5
+
6
+ context 'service helper methods' do
7
+ let(:host) { 'api.host' }
8
+ let(:shared_secret) { 'secret' }
9
+ let(:protocol) { 'http' }
10
+ let(:consumer_key) { 'some consumer_key' }
11
+ let(:consumer_request_id) { 'guid_value' }
12
+ let(:subject) do
13
+ QuizApiClient::Client.new(
14
+ consumer_key: consumer_key,
15
+ consumer_request_id: consumer_request_id,
16
+ host: host,
17
+ shared_secret: shared_secret,
18
+ protocol: protocol
19
+ )
20
+ end
21
+
22
+ describe '#config' do
23
+ it 'should populate the values' do
24
+ config = subject.config
25
+ expect(config.consumer_key).to eq consumer_key
26
+ expect(config.consumer_request_id).to eq consumer_request_id
27
+ expect(config.host).to eq host
28
+ expect(config.shared_secret).to eq shared_secret
29
+ expect(config.protocol).to eq protocol
30
+ end
31
+
32
+ it 'should yield the config on instantiation' do
33
+ client = QuizApiClient::Client.new(
34
+ consumer_key: consumer_key,
35
+ consumer_request_id: consumer_request_id,
36
+ host: host,
37
+ shared_secret: shared_secret,
38
+ protocol: protocol
39
+ ) do |config|
40
+ config.host = 'my.hosting'
41
+ end
42
+
43
+ expect(client.config.host).to eq 'my.hosting'
44
+ end
45
+ end
46
+
47
+ describe '#jwt_service' do
48
+ it 'should create the service' do
49
+ expect(QuizApiClient::Services::JwtService).to receive(:new).with(subject.config)
50
+ subject.jwt_service
51
+ end
52
+ end
53
+
54
+ describe '#courses_service' do
55
+ it 'creates the service' do
56
+ expect(QuizApiClient::Services::CoursesService).to receive(:new).with(subject.config)
57
+ subject.courses_service
58
+ end
59
+ end
60
+
61
+ describe '#quizzes_service' do
62
+ it 'should create the service' do
63
+ expect(QuizApiClient::Services::QuizzesService).to receive(:new).with(subject.config)
64
+ subject.quizzes_service
65
+ end
66
+ end
67
+
68
+ describe '#quiz_session_service' do
69
+ it 'should create the service' do
70
+ expect(QuizApiClient::Services::QuizSessionService).to receive(:new).with(subject.config)
71
+ subject.quiz_session_service
72
+ end
73
+ end
74
+
75
+ describe '#quiz_sessions_service' do
76
+ it 'should create the service' do
77
+ expect(QuizApiClient::Services::QuizSessionsService).to receive(:new).with(subject.config)
78
+ subject.quiz_sessions_service
79
+ end
80
+ end
81
+
82
+ describe '#qti_imports_service' do
83
+ it 'should create the service' do
84
+ expect(QuizApiClient::Services::QtiImportsService).to receive(:new).with(subject.config)
85
+ subject.qti_imports_service
86
+ end
87
+ end
88
+
89
+ describe '#item_analyses_service' do
90
+ it 'should create the service' do
91
+ expect(QuizApiClient::Services::ItemAnalysesService).to receive(:new).with(subject.config)
92
+ subject.item_analyses_service
93
+ end
94
+ end
95
+
96
+ describe '#quiz_analyses_service' do
97
+ it 'should create the service' do
98
+ expect(QuizApiClient::Services::QuizAnalysesService).to receive(:new).with(subject.config)
99
+ subject.quiz_analyses_service
100
+ end
101
+ end
102
+
103
+ describe '#quiz_session_events_service' do
104
+ it 'should create the service' do
105
+ expect(QuizApiClient::Services::QuizSessionEventsService).to receive(:new).with(subject.config)
106
+ subject.quiz_session_events_service
107
+ end
108
+ end
109
+
110
+ describe '#items_service' do
111
+ it 'should create the service' do
112
+ expect(QuizApiClient::Services::ItemsService).to receive(:new).with(subject.config)
113
+ subject.items_service
114
+ end
115
+ end
116
+
117
+ describe '#interaction_types_service' do
118
+ it 'should create the service' do
119
+ expect(QuizApiClient::Services::InteractionTypesService).to receive(:new).with(subject.config)
120
+ subject.interaction_types_service
121
+ end
122
+ end
123
+ end
124
+ end
@@ -0,0 +1,50 @@
1
+ describe QuizApiClient::Services::BaseApiService do
2
+ let(:consumer_key) { 'consumer key' }
3
+ let(:host) { 'api.host' }
4
+ let(:shared_secret) { 'secret' }
5
+ let(:protocol) { 'http' }
6
+ let(:service_class) do
7
+ Class.new(QuizApiClient::Services::BaseApiService) do
8
+ def test_uri
9
+ uri
10
+ end
11
+ end
12
+ end
13
+ let(:service) do
14
+ service_class.new(QuizApiClient::Config.new do |c|
15
+ c.consumer_key = consumer_key
16
+ c.host = host
17
+ c.shared_secret = shared_secret
18
+ c.protocol = protocol
19
+ end)
20
+ end
21
+
22
+ def decode_token(token, secret)
23
+ JWT.decode(
24
+ token, secret, true,
25
+ algorithm: QuizApiClient::Services::JwtService::HASHING_ALGORITHM
26
+ )
27
+ end
28
+
29
+ describe '#uri' do
30
+ it 'returns full URI' do
31
+ expect(service.test_uri).to eq 'http://api.host'
32
+ end
33
+
34
+ context 'with https protocol' do
35
+ let(:protocol) { 'https' }
36
+
37
+ it 'uses specified protocol' do
38
+ expect(service.test_uri).to eq 'https://api.host'
39
+ end
40
+ end
41
+
42
+ context 'with port specified in host' do
43
+ let(:host) { 'api.host:8443' }
44
+
45
+ it 'includes port in URI' do
46
+ expect(service.test_uri).to eq 'http://api.host:8443'
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,59 @@
1
+ describe QuizApiClient::Services::CoursesService do
2
+ let(:host) { 'api.host' }
3
+ let(:config) { QuizApiClient::Config.new { |c| c.host = host } }
4
+ let(:subject) { described_class.new(config) }
5
+
6
+ describe '#create' do
7
+ let(:params) do
8
+ {
9
+ title: 'foo',
10
+ canvas_id: 2,
11
+ is_blueprint: true
12
+ }
13
+ end
14
+
15
+ let(:response) do
16
+ {
17
+ 'id' => '4',
18
+ 'title' => 'foo',
19
+ 'canvas_id' => '2',
20
+ 'is_blueprint' => true,
21
+ 'created_at' => '2022-06-22T18:59:27.577Z',
22
+ 'updated_at' => '2022-06-22T18:59:27.577Z'
23
+ }
24
+ end
25
+
26
+ let(:expected_url) { "https://#{host}/api/courses" }
27
+
28
+ before do
29
+ stub_request(:post, expected_url)
30
+ .with(body: { course: params }.to_json)
31
+ .to_return(
32
+ status: 201,
33
+ body: response.to_json,
34
+ headers: { 'Content-Type' => 'application/json' }
35
+ )
36
+ end
37
+
38
+ it 'posts to the correct endpoint and returns the response' do
39
+ expect(
40
+ subject.create(params: params, token: 'token').parsed_response
41
+ ).to eq(response)
42
+ end
43
+ end
44
+
45
+ describe '#destroy' do
46
+ let(:params) { { canvas_id: 1 } }
47
+ let(:expected_url) { "https://#{host}/api/courses/1" }
48
+
49
+ before do
50
+ stub_request(:delete, expected_url).to_return(status: 204)
51
+ end
52
+
53
+ it 'deletes to the correct endpoint and returns the response' do
54
+ response = subject.destroy(params: params, token: 'token')
55
+ expect(response.code).to eq 204
56
+ expect(response.body).to be_nil
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,25 @@
1
+ describe QuizApiClient::Services::InteractionTypesService do
2
+ let(:host) { 'api.host' }
3
+ let(:config) { QuizApiClient::Config.new { |c| c.host = host } }
4
+ let(:subject) { described_class.new(config) }
5
+
6
+ describe '#list' do
7
+ let(:status_code) { 200 }
8
+ let(:expected_url) { "https://#{host}/api/interaction_types" }
9
+ let(:stubbed_response) { [{ 'name' => 'Type One', 'id' => 1 }] }
10
+
11
+ before do
12
+ stub_request(:get, expected_url)
13
+ .to_return(
14
+ status: status_code,
15
+ body: stubbed_response.to_json,
16
+ headers: { 'Content-Type' => 'application/json' }
17
+ )
18
+ end
19
+
20
+ it 'gets from quiz_api/api/interaction_types and returns the response' do
21
+ result = subject.list(token: 'token')
22
+ expect(result.parsed_response).to eql(stubbed_response)
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,76 @@
1
+ describe QuizApiClient::Services::ItemAnalysesService do
2
+ let(:host) { 'api.host' }
3
+ let(:config) { QuizApiClient::Config.new { |c| c.host = host } }
4
+ let(:subject) { described_class.new(config) }
5
+
6
+ describe '#list' do
7
+ let(:params) { { quiz_id: 1, id: 7 } }
8
+ let(:stubbed_response) { { 'id' => '1' } }
9
+ let(:expected_url) do
10
+ "https://#{host}/api/quizzes/#{params[:quiz_id]}/stats/item_analyses"
11
+ end
12
+ let(:expected_body) { '' }
13
+ let(:status_code) { 200 }
14
+
15
+ before do
16
+ stub_request(:get, expected_url)
17
+ .with(body: expected_body)
18
+ .to_return(
19
+ status: status_code,
20
+ body: stubbed_response.to_json,
21
+ headers: { 'Content-Type' => 'application/json' }
22
+ )
23
+ end
24
+
25
+ it 'posts to /api/quizzes/1/stats/item_analyses and returns the response' do
26
+ result = subject.list(params: params, token: 'token')
27
+ expect(result.parsed_response).to eql(stubbed_response)
28
+ end
29
+
30
+ it 'raises an error when no quiz_id is specified' do
31
+ params = {}
32
+ expect do
33
+ subject.list(params: params, token: 'token')
34
+ end.to raise_error 'Quiz Id Required'
35
+ end
36
+ end
37
+
38
+ describe '#get' do
39
+ let(:params) { { quiz_id: 1, id: 7 } }
40
+ let(:stubbed_response) { { 'id' => '1' } }
41
+ let(:expected_url) do
42
+ "https://#{host}/api/quizzes/#{params[:quiz_id]}/stats/item_analyses/#{params[:id]}"
43
+ end
44
+ let(:expected_body) { '' }
45
+ let(:status_code) { 200 }
46
+
47
+ before do
48
+ stub_request(:get, expected_url)
49
+ .with(body: expected_body)
50
+ .to_return(
51
+ status: status_code,
52
+ body: stubbed_response.to_json,
53
+ headers: { 'Content-Type' => 'application/json' }
54
+ )
55
+ end
56
+
57
+ it 'posts to /api/quizzes/1/stats/item_analyses/7 and returns the response' do
58
+ result = subject.get(params: params, token: 'token')
59
+ expect(result.parsed_response).to eql(stubbed_response)
60
+ end
61
+
62
+ it 'raises an error when no quiz_id is specified' do
63
+ params = {}
64
+ expect do
65
+ subject.list(params: params, token: 'token')
66
+ end.to raise_error 'Quiz Id Required'
67
+ end
68
+
69
+ context 'response' do
70
+ it 'returns the response with the correct status code' do
71
+ response = subject.get(params: params, token: 'token')
72
+ expect(response.code).to eq(status_code)
73
+ end
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,56 @@
1
+ describe QuizApiClient::Services::ItemsService do
2
+ let(:host) { 'api.host' }
3
+ let(:config) { QuizApiClient::Config.new { |c| c.host = host } }
4
+ let(:subject) { described_class.new(config) }
5
+
6
+ describe '#list' do
7
+ let(:params) { { quiz_id: 1 } }
8
+ let(:stubbed_response) { { 'id' => 1, 'item' => { 'id' => 1 } } }
9
+ let(:expected_url) { "https://#{host}/api/quizzes/#{params[:quiz_id]}/items" }
10
+ let(:status_code) { 200 }
11
+
12
+ before do
13
+ stub_request(:get, expected_url)
14
+ .to_return(
15
+ status: status_code,
16
+ body: stubbed_response.to_json,
17
+ headers: { 'Content-Type' => 'application/json' }
18
+ )
19
+ end
20
+
21
+ it 'list from quiz_api/api/quizzes/{id}/items and returns the response' do
22
+ result = subject.list(params: params, token: 'token')
23
+ expect(result.parsed_response).to eql(stubbed_response)
24
+ end
25
+ end
26
+
27
+ describe '#create' do
28
+ let(:params) do
29
+ {
30
+ quiz_id: 1,
31
+ item_body: 'item body',
32
+ scoring_data: { value: 'value' },
33
+ scoring_algorithm: 'Equivalence',
34
+ interaction_type_id: 'choice',
35
+ user_response_type: 'response type'
36
+ }
37
+ end
38
+ let(:stubbed_response) { { 'id' => 1, 'item' => { 'id' => 1 } } }
39
+ let(:expected_url) { "https://#{host}/api/quizzes/#{params[:quiz_id]}/items" }
40
+ let(:status_code) { 201 }
41
+
42
+ before do
43
+ stub_request(:post, expected_url)
44
+ .to_return(
45
+ status: status_code,
46
+ body: stubbed_response.to_json,
47
+ headers: { 'Content-Type' => 'application/json' }
48
+ )
49
+ end
50
+
51
+ it 'posts to quiz_api/api/quizzes/{id}/items and returns the response' do
52
+ result = subject.create(params: params, token: 'token')
53
+ expect(result.parsed_response).to eql(stubbed_response)
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,66 @@
1
+ describe QuizApiClient::Services::JwtService do
2
+ let(:host) { 'test.host' }
3
+ let(:shared_secret) { 'secret' }
4
+ let(:consumer_key) { 'some consumer_key' }
5
+
6
+ let(:config) do
7
+ QuizApiClient::Config.new do |c|
8
+ c.shared_secret = shared_secret
9
+ c.host = host
10
+ c.consumer_key = consumer_key
11
+ end
12
+ end
13
+
14
+ subject do
15
+ QuizApiClient::Services::JwtService.new(config)
16
+ end
17
+
18
+ describe 'grant_permission' do
19
+ it 'generates a JWT using the shared_secret' do
20
+ jwt = subject.grant_permission(scope: 'quiz.create')
21
+
22
+ payload, header = JWT.decode(jwt, shared_secret, true, algorithm: 'HS512')
23
+
24
+ expect(payload['host']).to eq(host)
25
+ expect(payload['scope']).to eq('quiz.create')
26
+ expect(payload['consumer_key']).to eq(consumer_key)
27
+ expect(payload).not_to have_key('resource_id')
28
+ expect(payload).not_to have_key('user')
29
+ expect(payload).to have_key('exp')
30
+ expect(header['alg']).to eq('HS512')
31
+ end
32
+
33
+ it 'includes user uuid in payload when provided' do
34
+ jwt = subject.grant_permission(scope: 'quiz.create', uuid: '123')
35
+
36
+ payload = JWT.decode(jwt, shared_secret, true, algorithm: 'HS512').first
37
+
38
+ expect(payload['user']).to eq('uuid' => '123')
39
+ end
40
+
41
+ it 'merges in other provided user context' do
42
+ jwt = subject.grant_permission(scope: 'quiz.create', uuid: '123', user: { email: 'test@example.com' })
43
+
44
+ payload = JWT.decode(jwt, shared_secret, true, algorithm: 'HS512').first
45
+
46
+ expect(payload['user']).to eq('uuid' => '123', 'email' => 'test@example.com')
47
+ end
48
+
49
+ it 'allows arbitrary additional params' do
50
+ jwt = subject.grant_permission(scope: 'quiz.create', foo: 'bar', monkey: 'do')
51
+ payload = JWT.decode(jwt, shared_secret, true, algorithm: 'HS512').first
52
+ expect(payload['foo']).to eq 'bar'
53
+ expect(payload['monkey']).to eq 'do'
54
+ end
55
+
56
+ context 'with port in host' do
57
+ let(:host) { 'test.host:8443' }
58
+
59
+ it 'leaves port out of payload host' do
60
+ jwt = subject.grant_permission scope: 'quiz.build'
61
+ payload, _header = JWT.decode(jwt, shared_secret, true, algorithm: 'HS512')
62
+ expect(payload['host']).to eq 'test.host'
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,114 @@
1
+ describe QuizApiClient::Services::QtiImportsService do
2
+ let(:host) { 'api.host' }
3
+ let(:config) { QuizApiClient::Config.new { |c| c.host = host } }
4
+ let(:subject) { described_class.new(config) }
5
+
6
+ describe '#create' do
7
+ let(:params) { { url: 'https://fake-s3-url.com', quiz_id: 1 } }
8
+ let(:stubbed_response) { { 'id' => '1', 'status' => 'created' } }
9
+ let(:expected_url) { "https://#{host}/api/quizzes/1/qti_imports" }
10
+ let(:expected_body) { {} }
11
+ let(:status_code) { 200 }
12
+
13
+ before do
14
+ stub_request(:post, expected_url)
15
+ .with(body: expected_body)
16
+ .to_return(
17
+ status: 200,
18
+ body: stubbed_response.to_json,
19
+ headers: { 'Content-Type' => 'application/json' }
20
+ )
21
+ end
22
+
23
+ it 'posts to quiz_api/api/qti_imports and returns the response' do
24
+ result = subject.create(params: params, token: 'token')
25
+ expect(result.parsed_response).to eql(stubbed_response)
26
+ end
27
+
28
+ context 'response' do
29
+ it 'returns the response with the correct code' do
30
+ response = subject.create(params: params, token: 'token')
31
+ expect(response.code).to eq(status_code)
32
+ end
33
+ end
34
+
35
+ context 'no quiz id provided' do
36
+ let(:params) {}
37
+ it 'raises Quiz Id Required' do
38
+ expect do
39
+ subject.create(params: params, token: 'token')
40
+ end.to raise_error('Quiz Id Required')
41
+ end
42
+ end
43
+ end
44
+
45
+ describe '#banks' do
46
+ let(:params) { { everything: false, overwrite: false, assessment_question_banks: ['abc123'] } }
47
+ let(:stubbed_response) { { 'id' => '1', 'status' => 'created' } }
48
+ let(:expected_url) { "https://#{host}/api/qti_imports/banks" }
49
+ let(:expected_body) { {} }
50
+ let(:status_code) { 200 }
51
+
52
+ before do
53
+ stub_request(:post, expected_url)
54
+ .with(body: expected_body)
55
+ .to_return(
56
+ status: 200,
57
+ body: stubbed_response.to_json,
58
+ headers: { 'Content-Type' => 'application/json' }
59
+ )
60
+ end
61
+
62
+ it 'posts to quiz_api/api/qti_imports and returns the response' do
63
+ result = subject.banks(params: params, token: 'token')
64
+ expect(result.parsed_response).to eql(stubbed_response)
65
+ end
66
+
67
+ context 'response' do
68
+ it 'returns the response with the correct code' do
69
+ response = subject.banks(params: params, token: 'token')
70
+ expect(response.code).to eq(status_code)
71
+ end
72
+ end
73
+ end
74
+
75
+ describe '#get_imported_consumer_settings' do
76
+ let(:params) { { quiz_id: 1 } }
77
+ let(:stubbed_response) { { 'score_to_keep' => 'highest', 'max_attempts' => '10' } }
78
+ let(:expected_url) { "https://#{host}/api/quizzes/1/qti_imports/imported_consumer_settings" }
79
+
80
+ let(:expected_body) { {} }
81
+ let(:status_code) { 200 }
82
+
83
+ before do
84
+ stub_request(:get, expected_url)
85
+ .with(body: expected_body)
86
+ .to_return(
87
+ status: 200,
88
+ body: stubbed_response.to_json,
89
+ headers: { 'Content-Type' => 'application/json' }
90
+ )
91
+ end
92
+
93
+ it 'posts to quiz_api/api/qti_imports and returns the response' do
94
+ result = subject.get_imported_consumer_settings(params: params, token: 'token')
95
+ expect(result.parsed_response).to eql(stubbed_response)
96
+ end
97
+
98
+ context 'response' do
99
+ it 'returns the response with the correct code' do
100
+ response = subject.get_imported_consumer_settings(params: params, token: 'token')
101
+ expect(response.code).to eq(status_code)
102
+ end
103
+ end
104
+
105
+ context 'no quiz id provided' do
106
+ let(:params) {}
107
+ it 'raises Quiz Id Required' do
108
+ expect do
109
+ subject.create(params: params, token: 'token')
110
+ end.to raise_error('Quiz Id Required')
111
+ end
112
+ end
113
+ end
114
+ end
@@ -0,0 +1,44 @@
1
+ describe QuizApiClient::Services::QuizAnalysesService do
2
+ let(:host) { 'api.host' }
3
+ let(:config) { QuizApiClient::Config.new { |c| c.host = host } }
4
+ let(:subject) { described_class.new(config) }
5
+
6
+ describe '#list' do
7
+ let(:params) { { quiz_id: 1 } }
8
+ let(:stubbed_response) { { 'id' => '1' } }
9
+ let(:expected_url) do
10
+ "https://#{host}/api/quizzes/#{params[:quiz_id]}/stats/quiz_analysis"
11
+ end
12
+ let(:expected_body) { '' }
13
+ let(:status_code) { 200 }
14
+
15
+ before do
16
+ stub_request(:get, expected_url)
17
+ .with(body: expected_body)
18
+ .to_return(
19
+ status: status_code,
20
+ body: stubbed_response.to_json,
21
+ headers: { 'Content-Type' => 'application/json' }
22
+ )
23
+ end
24
+
25
+ it 'posts to quiz_api/api/quizzes and returns the response' do
26
+ result = subject.get(params: params, token: 'token')
27
+ expect(result.parsed_response).to eql(stubbed_response)
28
+ end
29
+
30
+ it 'raises an error when no quiz_id is specified' do
31
+ params = {}
32
+ expect do
33
+ subject.get(params: params, token: 'token')
34
+ end.to raise_error 'Quiz Id Required'
35
+ end
36
+
37
+ context 'response' do
38
+ it 'returns the response with the correct status code' do
39
+ response = subject.get(params: params, token: 'token')
40
+ expect(response.code).to eq(status_code)
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,41 @@
1
+ describe QuizApiClient::Services::QuizCloneJobService do
2
+ let(:host) { 'api.host' }
3
+ let(:config) { QuizApiClient::Config.new { |c| c.host = host } }
4
+ let(:subject) { described_class.new(config) }
5
+
6
+ describe '#show' do
7
+ let(:expected_url) { "https://#{host}/api/quiz_clone_jobs/#{params[:id]}" }
8
+ let(:params) { { id: 1 } }
9
+ let(:stubbed_response) { { 'id' => 1, 'original_quiz_id' => 666, 'status' => 'completed' } }
10
+
11
+ context 'on success' do
12
+ before do
13
+ stub_request(:get, expected_url)
14
+ .to_return(
15
+ status: 200,
16
+ body: stubbed_response.to_json,
17
+ headers: { 'Content-Type' => 'application/json' }
18
+ )
19
+ end
20
+
21
+ it 'gets from /api/quiz_clone_jobs/:id' do
22
+ result = subject.show(params: params, token: 'token')
23
+ expect(result.parsed_response).to eql(stubbed_response)
24
+ end
25
+ end
26
+
27
+ context 'on failure' do
28
+ let(:status_code) { 401 }
29
+
30
+ before do
31
+ stub_request(:get, expected_url)
32
+ .to_return(status: status_code)
33
+ end
34
+
35
+ it 'returns a response with the correct code' do
36
+ response = subject.show(params: params, token: 'token')
37
+ expect(response.code).to eq(status_code)
38
+ end
39
+ end
40
+ end
41
+ end