quiz_api_client 3.2.0 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d21ef77c677faced1f5decda500ca2e4e32dbd5e163e3a313c3d68f699de6f38
4
- data.tar.gz: 1614220681706baad9693a638ff0bb9d27622708af4e82ff7a570a47617a1fe5
3
+ metadata.gz: 48279a4ca7eeb3d7fc50e493733f5718c2960b2267d70db68b2956b0b11c99c1
4
+ data.tar.gz: cbd66f799b72273b23b2e7a208fc10336bee5cf2cb93656987d0fdc5d1c173a7
5
5
  SHA512:
6
- metadata.gz: 2e618dca3ed741dddf0d325d7ab77c418fcd9c0a7088b3c4613d137f873efc5b5829f9a1011d57de42dea88edfefe5203debf4c512b5f84e7699b1d5b5594271
7
- data.tar.gz: b20220626d0cc582a0a72fb4bdab8d12a81da5884438357b98695a493e1b4c6c1ef225413430a5b2a7a4ac67cd9b9b1956ff47c7ecdfede673ef4feb1d6c61cd
6
+ metadata.gz: d448acbf4ac471f2c8f55cda52191d35ade2d0e107546946e9cee8f6712556ac402160150555d8e3f978034843240deeeb4cec0a658a5fdf8ce2b2b8d3e1a452
7
+ data.tar.gz: c73951b3bc89f5ff17b08ac1199aff03f3fd2a7e9cf701d5b2d9fffcc31d4bc76ddd2cc4384622584479ab32f2abf85abc3993554fb8a872a4b961eb8b23b4a3
data/.rubocop.yml CHANGED
@@ -1,5 +1,5 @@
1
1
  AllCops:
2
- TargetRubyVersion: 2.4
2
+ TargetRubyVersion: 2.6
3
3
 
4
4
  Metrics/ClassLength:
5
5
  Max: 200 # Default: 100
data/Dockerfile CHANGED
@@ -4,8 +4,9 @@ RUN mkdir -p coverage log pacts
4
4
 
5
5
  COPY --chown=docker:docker quiz_api_client.gemspec Gemfile ./
6
6
  COPY --chown=docker:docker lib/quiz_api_client/version.rb lib/quiz_api_client/version.rb
7
- RUN /bin/bash -l -c "rvm-exec 2.4 bundle install --jobs 5"
7
+ RUN /bin/bash -l -c "rvm-exec 2.6 gem install bundler -v 2.1.4"
8
+ RUN /bin/bash -l -c "rvm-exec 2.6 bundle install --jobs 5"
8
9
 
9
10
  COPY --chown=docker:docker . .
10
11
 
11
- CMD /bin/bash -l -c "rvm-exec 2.4 bundle exec rspec"
12
+ CMD /bin/bash -l -c "rvm-exec 2.6 bundle exec rspec"
data/Jenkinsfile CHANGED
@@ -1,4 +1,4 @@
1
- def buildMatrix = ['2.4', '2.5', '2.6'].collectEntries { ruby ->
1
+ def buildMatrix = ['2.6', '2.7'].collectEntries { ruby ->
2
2
  ["Ruby ${ruby}": {
3
3
  sh """
4
4
  docker-compose run --name "${env.BUILD_ID}-ruby-${ruby}" \
@@ -25,7 +25,7 @@ pipeline {
25
25
  steps {
26
26
  sh '''
27
27
  docker-compose run --rm app /bin/bash -lc \
28
- "rvm-exec 2.4 bundle exec rubocop --fail-level autocorrect"
28
+ "rvm-exec 2.6 bundle exec rubocop --fail-level autocorrect"
29
29
  '''
30
30
  }
31
31
  }
@@ -34,7 +34,7 @@ pipeline {
34
34
  }
35
35
  stage('Contract Tests') {
36
36
  steps {
37
- sh 'docker-compose run app /bin/bash -l -c "rvm-exec 2.4 bundle exec rspec -t pact"'
37
+ sh 'docker-compose run app /bin/bash -l -c "rvm-exec 2.6 bundle exec rspec -t pact"'
38
38
  }
39
39
  }
40
40
  stage ('Publish') {
@@ -58,7 +58,7 @@ pipeline {
58
58
  -e PACT_BROKER_PASSWORD="${PACT_BROKER_PASSWORD}" \
59
59
  -e PACT_CONSUMER_TAG="${PACT_CONSUMER_TAG}" \
60
60
  -e SHA="${sha}" \
61
- app /bin/bash -l -c "rvm-exec 2.4 bundle exec rake broker:pact:publish:jenkins_post_merge"
61
+ app /bin/bash -l -c "rvm-exec 2.6 bundle exec rake broker:pact:publish:jenkins_post_merge"
62
62
  '''
63
63
  }
64
64
  }
@@ -67,7 +67,7 @@ pipeline {
67
67
 
68
68
  post {
69
69
  success {
70
- sh "docker cp \"${env.BUILD_ID}-ruby-2.4:/usr/src/app/coverage\" ."
70
+ sh "docker cp \"${env.BUILD_ID}-ruby-2.6:/usr/src/app/coverage\" ."
71
71
  publishHTML target: [
72
72
  allowMissing: false,
73
73
  alwaysLinkToLastBuild: false,
data/README.md CHANGED
@@ -37,6 +37,10 @@ client = QuizApiClient::Client.new(
37
37
  )
38
38
  ```
39
39
 
40
+ ### Error Handler
41
+
42
+ In order to set addition error information in your error handling system, you can set the `error_hander` property of the config. The list of valid values can be found in the `QuizApiClient::Config::ERROR_HANDLERS` constant.
43
+
40
44
  ### Creation of Tokens
41
45
 
42
46
  JWTs are created without hitting quiz_api and and they are validated on quiz_api. Tokens are created for a given scope, expiration, and an optional resource_id.
@@ -0,0 +1,38 @@
1
+ module QuizApiClient
2
+ class Config
3
+ DEFAULT_PROTOCOL = 'https'.freeze
4
+ ERROR_HANDLERS = %i[sentry_raven].freeze
5
+
6
+ class InvalidErrorHandler < StandardError; end
7
+
8
+ attr_reader :error_handler
9
+ attr_writer :protocol
10
+ attr_accessor :consumer_key, :consumer_request_id, :host, :shared_secret
11
+
12
+ def initialize
13
+ yield(self) if block_given?
14
+ end
15
+
16
+ def protocol
17
+ @protocol || DEFAULT_PROTOCOL
18
+ end
19
+
20
+ def error_handler=(handler)
21
+ validate_error_hander!(handler)
22
+
23
+ @error_handler = handler
24
+ end
25
+
26
+ private
27
+
28
+ def validate_error_hander!(handler)
29
+ return unless handler
30
+
31
+ unless ERROR_HANDLERS.include?(handler)
32
+ raise InvalidErrorHandler, "It must be one of the following: #{ERROR_HANDLERS.inspect}"
33
+ end
34
+
35
+ @error_handler = handler.to_sym
36
+ end
37
+ end
38
+ end
@@ -6,12 +6,12 @@ module QuizApiClient
6
6
 
7
7
  class RequestFailed < StandardError; end
8
8
 
9
- attr_reader :jwt, :uri
9
+ attr_reader :jwt, :uri, :config
10
10
 
11
- def initialize(uri:, jwt:, consumer_request_id: nil, logging: true, log_level: :info)
11
+ def initialize(uri:, jwt:, config:, logging: true, log_level: :info)
12
12
  @uri = uri
13
13
  @jwt = jwt
14
- @consumer_request_id = consumer_request_id
14
+ @config = config
15
15
  initialize_logger(log_level) if logging
16
16
  end
17
17
 
@@ -49,7 +49,7 @@ module QuizApiClient
49
49
  HTTParty::Logger.add_formatter('quiz_api_client_json_formatter', QuizApiClient::JSONFormatter)
50
50
  @logger = ::Logger.new(
51
51
  STDOUT,
52
- formatter: proc { |_, _, _, msg| msg.merge(consumer_request_id: @consumer_request_id).to_json },
52
+ formatter: proc { |_, _, _, msg| msg.merge(consumer_request_id: config.consumer_request_id).to_json },
53
53
  level: unfriendly_logger_level(log_level)
54
54
  )
55
55
  @logger_config = {
@@ -81,7 +81,7 @@ module QuizApiClient
81
81
  default_request_data.merge(request_options)
82
82
  )
83
83
  rescue HTTParty::Error, Errno::ECONNREFUSED, Net::ReadTimeout => e
84
- raise RequestFailed, e.message
84
+ raise_error(method, url, current_error: e)
85
85
  end
86
86
 
87
87
  def make_paginated_request(method, url, options)
@@ -91,7 +91,7 @@ module QuizApiClient
91
91
 
92
92
  until request_url.nil?
93
93
  resp = make_request(method, request_url, request_options)
94
- raise RequestFailed, "#{url} responded #{resp.body} (#{resp.code})" unless resp.code == 200
94
+ raise_error(method, url, response: resp) unless resp.code == 200
95
95
 
96
96
  entities.concat(resp.parsed_response)
97
97
  request_url, request_options = next_page(resp, url, options)
@@ -109,7 +109,7 @@ module QuizApiClient
109
109
  }
110
110
  }
111
111
 
112
- initial_hash[:headers]['X-Consumer-Request-Id'] = @consumer_request_id if @consumer_request_id
112
+ initial_hash[:headers]['X-Consumer-Request-Id'] = config.consumer_request_id if config.consumer_request_id
113
113
 
114
114
  initial_hash.merge!(@logger_config) if @logger_config
115
115
  initial_hash
@@ -138,5 +138,51 @@ module QuizApiClient
138
138
  )
139
139
  [url, options.merge(query: query)]
140
140
  end
141
+
142
+ def generate_error_context(method, url, response = nil)
143
+ context = {
144
+ quiz_api_client: {
145
+ request: {
146
+ method: method,
147
+ url: url
148
+ }
149
+ }
150
+ }
151
+
152
+ if response
153
+ context[:quiz_api_client][:response] = {
154
+ body: response.body,
155
+ code: response.code
156
+ }
157
+ end
158
+
159
+ context
160
+ end
161
+
162
+ def record_error_context(context)
163
+ case config.error_handler
164
+ when :sentry_raven
165
+ require 'sentry-raven'
166
+ Raven.extra_context(context)
167
+ end
168
+ end
169
+
170
+ def error_message(current_error, url, response)
171
+ if current_error && response
172
+ "#{current_error.message}: #{url} responded #{response.body} (#{response.code})"
173
+ elsif current_error
174
+ current_error.message
175
+ elsif response
176
+ "#{url} responded #{response.body} (#{response.code})"
177
+ end
178
+ end
179
+
180
+ def raise_error(method, url, response: nil, current_error: nil, error_class: RequestFailed)
181
+ context = generate_error_context(method, url, response)
182
+
183
+ record_error_context(context)
184
+
185
+ raise error_class, error_message(current_error, url, response)
186
+ end
141
187
  end
142
188
  end
@@ -1,29 +1,23 @@
1
1
  module QuizApiClient::Services
2
2
  class BaseApiService
3
- attr_reader :consumer_key, :errors, :host, :protocol, :shared_secret
3
+ attr_reader :config
4
4
 
5
- def initialize(
6
- consumer_key:, consumer_request_id: nil, host:, protocol: 'https', shared_secret:
7
- )
8
- @consumer_key = consumer_key
9
- @consumer_request_id = consumer_request_id
10
- @host = host
11
- @protocol = protocol
12
- @shared_secret = shared_secret
5
+ def initialize(config)
6
+ @config = config
13
7
  @errors = []
14
8
  end
15
9
 
16
10
  private
17
11
 
18
12
  def uri
19
- URI.parse("#{protocol}://#{host}").to_s
13
+ URI.parse("#{config.protocol}://#{config.host}").to_s
20
14
  end
21
15
 
22
16
  def client(token:)
23
17
  QuizApiClient::HttpClient.new(
24
18
  uri: uri,
25
19
  jwt: token,
26
- consumer_request_id: @consumer_request_id
20
+ config: config
27
21
  )
28
22
  end
29
23
  end
@@ -1,15 +1,14 @@
1
1
  module QuizApiClient::Services
2
2
  class JwtService
3
+ extend Forwardable
4
+
3
5
  HASHING_ALGORITHM = 'HS512'.freeze
4
6
 
5
- attr_reader :consumer_key, :host, :shared_secret, :protocol
7
+ attr_reader :config
8
+ def_delegators :config, :host, :protocol, :consumer_key
6
9
 
7
- def initialize(consumer_key: nil, consumer_request_id: nil, shared_secret:, host:, protocol: 'https')
8
- @consumer_key = consumer_key
9
- @host = host
10
- @shared_secret = shared_secret
11
- @protocol = protocol
12
- @consumer_request_id = consumer_request_id
10
+ def initialize(config)
11
+ @config = config
13
12
  end
14
13
 
15
14
  def grant_permission(scope:, exp: nil, uuid: nil, **additional_fields)
@@ -26,7 +25,7 @@ module QuizApiClient::Services
26
25
  payload[:user][:uuid] = uuid
27
26
  end
28
27
 
29
- JWT.encode(payload, shared_secret, HASHING_ALGORITHM)
28
+ JWT.encode(payload, config.shared_secret, HASHING_ALGORITHM)
30
29
  end
31
30
  end
32
31
  end
@@ -1,3 +1,3 @@
1
1
  module QuizApiClient
2
- VERSION = '3.2.0'.freeze
2
+ VERSION = '4.0.0'.freeze
3
3
  end
@@ -4,104 +4,101 @@ require 'link_header'
4
4
 
5
5
  module QuizApiClient
6
6
  class Client
7
- attr_reader :consumer_key, :consumer_request_id, :host, :protocol, :shared_secret
7
+ extend Forwardable
8
+
9
+ def_delegators :config, :consumer_key, :consumer_request_id, :host, :protocol, :shared_secret
8
10
 
9
11
  def initialize(consumer_key:, host:, shared_secret:, protocol: 'https', consumer_request_id: nil)
10
- @consumer_key = consumer_key
11
- @host = host
12
- @shared_secret = shared_secret
13
- @protocol = protocol
14
- @consumer_request_id = consumer_request_id
12
+ config.consumer_key = consumer_key
13
+ config.host = host
14
+ config.shared_secret = shared_secret
15
+ config.protocol = protocol
16
+ config.consumer_request_id = consumer_request_id
17
+
18
+ yield(config) if block_given?
19
+ end
20
+
21
+ def config
22
+ @_config ||= QuizApiClient::Config.new
15
23
  end
16
24
 
17
25
  def jwt_service
18
- @_jwt_service ||= QuizApiClient::Services::JwtService.new(service_params)
26
+ @_jwt_service ||= QuizApiClient::Services::JwtService.new(config)
19
27
  end
20
28
 
21
29
  def quiz_service
22
- @_quiz_service ||= Services::QuizService.new(service_params)
30
+ @_quiz_service ||= Services::QuizService.new(config)
23
31
  end
24
32
 
25
33
  def quizzes_service
26
- @_quizzes_service ||= Services::QuizzesService.new(service_params)
34
+ @_quizzes_service ||= Services::QuizzesService.new(config)
27
35
  end
28
36
 
29
37
  def quiz_session_service
30
- @_quiz_session_service ||= Services::QuizSessionService.new(service_params)
38
+ @_quiz_session_service ||= Services::QuizSessionService.new(config)
31
39
  end
32
40
 
33
41
  def quiz_sessions_service
34
- @_quiz_sessions_service ||= Services::QuizSessionsService.new(service_params)
42
+ @_quiz_sessions_service ||= Services::QuizSessionsService.new(config)
35
43
  end
36
44
 
37
45
  def quiz_clone_job_service
38
- @_quiz_clone_job_service ||= Services::QuizCloneJobService.new(service_params)
46
+ @_quiz_clone_job_service ||= Services::QuizCloneJobService.new(config)
39
47
  end
40
48
 
41
49
  def quiz_clone_jobs_service
42
- @_quiz_clone_jobs_service ||= Services::QuizCloneJobsService.new(service_params)
50
+ @_quiz_clone_jobs_service ||= Services::QuizCloneJobsService.new(config)
43
51
  end
44
52
 
45
53
  def qti_imports_service
46
- @_qti_imports_service ||= Services::QtiImportsService.new(service_params)
54
+ @_qti_imports_service ||= Services::QtiImportsService.new(config)
47
55
  end
48
56
 
49
57
  def item_analyses_service
50
- @_item_analyses_service ||= Services::ItemAnalysesService.new(service_params)
58
+ @_item_analyses_service ||= Services::ItemAnalysesService.new(config)
51
59
  end
52
60
 
53
61
  def quiz_analyses_service
54
- @_quiz_analyses_service ||= Services::QuizAnalysesService.new(service_params)
62
+ @_quiz_analyses_service ||= Services::QuizAnalysesService.new(config)
55
63
  end
56
64
 
57
65
  def quiz_session_events_service
58
- @_quiz_session_events_service ||= Services::QuizSessionEventsService.new(service_params)
66
+ @_quiz_session_events_service ||= Services::QuizSessionEventsService.new(config)
59
67
  end
60
68
 
61
69
  def quiz_session_result_service
62
- @_quiz_session_result_service ||= Services::QuizSessionResultService.new(service_params)
70
+ @_quiz_session_result_service ||= Services::QuizSessionResultService.new(config)
63
71
  end
64
72
 
65
73
  def quiz_entries_service
66
- @_quiz_entries_service ||= Services::QuizEntriesService.new(service_params)
74
+ @_quiz_entries_service ||= Services::QuizEntriesService.new(config)
67
75
  end
68
76
 
69
77
  def session_items_service
70
- @_session_items_service ||= Services::SessionItemsService.new(service_params)
78
+ @_session_items_service ||= Services::SessionItemsService.new(config)
71
79
  end
72
80
 
73
81
  def session_item_results_service
74
- @_session_item_results_service ||= Services::SessionItemResultsService.new(service_params)
82
+ @_session_item_results_service ||= Services::SessionItemResultsService.new(config)
75
83
  end
76
84
 
77
85
  def items_service
78
- @_items_service ||= QuizApiClient::Services::ItemsService.new(service_params)
86
+ @_items_service ||= QuizApiClient::Services::ItemsService.new(config)
79
87
  end
80
88
 
81
89
  def interaction_types_service
82
- @_interaction_types_service ||= QuizApiClient::Services::InteractionTypesService.new(service_params)
90
+ @_interaction_types_service ||= QuizApiClient::Services::InteractionTypesService.new(config)
83
91
  end
84
92
 
85
93
  def shared_banks
86
- @_shared_banks ||= QuizApiClient::Services::SharedBanks.new(service_params)
87
- end
88
-
89
- private
90
-
91
- def service_params
92
- {
93
- consumer_key: consumer_key,
94
- consumer_request_id: consumer_request_id,
95
- host: host,
96
- protocol: protocol,
97
- shared_secret: shared_secret
98
- }
94
+ @_shared_banks ||= QuizApiClient::Services::SharedBanks.new(config)
99
95
  end
100
96
  end
101
97
  end
102
98
 
103
99
  require 'quiz_api_client/version'
104
100
 
101
+ require 'quiz_api_client/config'
105
102
  require 'quiz_api_client/http_client'
106
103
  require 'quiz_api_client/json_formatter'
107
104
  require 'quiz_api_client/services/jwt_service'
@@ -13,6 +13,7 @@ Gem::Specification.new do |spec|
13
13
  'Han Yan',
14
14
  'Jayce Higgins',
15
15
  'Marc Alan Phillips',
16
+ 'Mark Starkman',
16
17
  'Michael Brewer-Davis',
17
18
  'Michael Hargiss',
18
19
  'Omar Khan',
@@ -26,6 +27,7 @@ Gem::Specification.new do |spec|
26
27
  'hyan@instructure.com',
27
28
  'jhiggins@instructure.com',
28
29
  'mphillips@instructure.com',
30
+ 'mark.starkman@instructure.com',
29
31
  'mbd@instructure.com',
30
32
  'mhargiss@instructure.com',
31
33
  'okhan@instructure.com',
@@ -40,7 +42,7 @@ Gem::Specification.new do |spec|
40
42
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
41
43
  spec.require_paths = ['lib']
42
44
 
43
- spec.required_ruby_version = '>= 2.4'
45
+ spec.required_ruby_version = '>= 2.6'
44
46
 
45
47
  spec.add_dependency 'httparty', '~> 0.17'
46
48
  spec.add_dependency 'jwt', '~> 2.2'
@@ -51,6 +53,7 @@ Gem::Specification.new do |spec|
51
53
  spec.add_development_dependency 'rake', '~> 12.3'
52
54
  spec.add_development_dependency 'rspec', '~> 3.8'
53
55
  spec.add_development_dependency 'rubocop', '~> 0.74.0'
56
+ spec.add_development_dependency 'sentry-raven', '~> 3.1'
54
57
  spec.add_development_dependency 'simplecov'
55
58
  spec.add_development_dependency 'webmock'
56
59
  end
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: 3.2.0
4
+ version: 4.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Wang
@@ -11,15 +11,16 @@ authors:
11
11
  - Han Yan
12
12
  - Jayce Higgins
13
13
  - Marc Alan Phillips
14
+ - Mark Starkman
14
15
  - Michael Brewer-Davis
15
16
  - Michael Hargiss
16
17
  - Omar Khan
17
18
  - Robin Kuss
18
19
  - Ryan Taylor
19
- autorequire:
20
+ autorequire:
20
21
  bindir: exe
21
22
  cert_chain: []
22
- date: 2021-04-19 00:00:00.000000000 Z
23
+ date: 2021-10-18 00:00:00.000000000 Z
23
24
  dependencies:
24
25
  - !ruby/object:Gem::Dependency
25
26
  name: httparty
@@ -133,6 +134,20 @@ dependencies:
133
134
  - - "~>"
134
135
  - !ruby/object:Gem::Version
135
136
  version: 0.74.0
137
+ - !ruby/object:Gem::Dependency
138
+ name: sentry-raven
139
+ requirement: !ruby/object:Gem::Requirement
140
+ requirements:
141
+ - - "~>"
142
+ - !ruby/object:Gem::Version
143
+ version: '3.1'
144
+ type: :development
145
+ prerelease: false
146
+ version_requirements: !ruby/object:Gem::Requirement
147
+ requirements:
148
+ - - "~>"
149
+ - !ruby/object:Gem::Version
150
+ version: '3.1'
136
151
  - !ruby/object:Gem::Dependency
137
152
  name: simplecov
138
153
  requirement: !ruby/object:Gem::Requirement
@@ -161,7 +176,7 @@ dependencies:
161
176
  - - ">="
162
177
  - !ruby/object:Gem::Version
163
178
  version: '0'
164
- description:
179
+ description:
165
180
  email:
166
181
  - acallejas@instructure.com
167
182
  - bpetty@instructure.com
@@ -169,6 +184,7 @@ email:
169
184
  - hyan@instructure.com
170
185
  - jhiggins@instructure.com
171
186
  - mphillips@instructure.com
187
+ - mark.starkman@instructure.com
172
188
  - mbd@instructure.com
173
189
  - mhargiss@instructure.com
174
190
  - okhan@instructure.com
@@ -195,6 +211,7 @@ files:
195
211
  - docker-compose.dev.override.yml
196
212
  - docker-compose.yml
197
213
  - lib/quiz_api_client.rb
214
+ - lib/quiz_api_client/config.rb
198
215
  - lib/quiz_api_client/http_client.rb
199
216
  - lib/quiz_api_client/json_formatter.rb
200
217
  - lib/quiz_api_client/services/base_api_service.rb
@@ -218,10 +235,10 @@ files:
218
235
  - lib/quiz_api_client/services/shared_banks.rb
219
236
  - lib/quiz_api_client/version.rb
220
237
  - quiz_api_client.gemspec
221
- homepage:
238
+ homepage:
222
239
  licenses: []
223
240
  metadata: {}
224
- post_install_message:
241
+ post_install_message:
225
242
  rdoc_options: []
226
243
  require_paths:
227
244
  - lib
@@ -229,15 +246,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
229
246
  requirements:
230
247
  - - ">="
231
248
  - !ruby/object:Gem::Version
232
- version: '2.4'
249
+ version: '2.6'
233
250
  required_rubygems_version: !ruby/object:Gem::Requirement
234
251
  requirements:
235
252
  - - ">="
236
253
  - !ruby/object:Gem::Version
237
254
  version: '0'
238
255
  requirements: []
239
- rubygems_version: 3.0.6
240
- signing_key:
256
+ rubygems_version: 3.1.6
257
+ signing_key:
241
258
  specification_version: 4
242
259
  summary: Ruby client for quiz_api
243
260
  test_files: []