quiz_api_client 3.2.0 → 4.0.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 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: []