quiz_api_client 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 8e46fc44771fd9dd6ceeb5aaa6c4e331ac5f500b
4
+ data.tar.gz: 1bf44fddb2e367f4a1271bafcccf3d256f66994d
5
+ SHA512:
6
+ metadata.gz: 6847f2213f8778d0ab0b6e5513f37cea73d6cbb1f4e7d9f27fce94b2053f437c5dfb1b214012d2b1383e592b5094a8575d6333006afdf1183b041d1a86a045e2
7
+ data.tar.gz: b3e2e93799b2796c2b6ff639009c95adb8c00e2ee65f02d5f1a41813757291977eb6b73b805a079d3cde325a058bd3c4c7cb2c7a2deb2fff2548993fca3cc16c
data/.editorconfig ADDED
@@ -0,0 +1,16 @@
1
+ # .editorconfig
2
+ # Please install EditorConfig plugin for your editor or IDE
3
+ # Usage and plugin list can be found here: http://EditorConfig.org
4
+
5
+ # top-most EditorConfig file
6
+ root = true
7
+
8
+ [*]
9
+ end_of_line = lf
10
+ indent_style = space
11
+ indent_size = 2
12
+ insert_final_newline = true
13
+ trim_trailing_whitespace = true
14
+
15
+ [*.md]
16
+ indent_size = 4
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.rubocop.yml ADDED
@@ -0,0 +1,79 @@
1
+ Rails:
2
+ Enabled: true
3
+
4
+ Rails/HttpPositionalArguments:
5
+ # Renable once we are on Rails v5
6
+ Enabled: false
7
+
8
+ AllCops:
9
+ TargetRubyVersion: 2.3
10
+
11
+ Metrics/ClassLength:
12
+ Max: 200 # Default: 100
13
+
14
+ Metrics/LineLength:
15
+ Max: 120 # Default: 80
16
+
17
+ Metrics/MethodLength:
18
+ Max: 20 # Default: 10
19
+
20
+ Metrics/BlockLength:
21
+ Max: 30
22
+ Exclude:
23
+ - 'spec/**/*.rb'
24
+ - 'config/routes.rb'
25
+ - 'app/docs/**/*.rb'
26
+
27
+ Style/AlignParameters:
28
+ # Alignment of parameters in multi-line method calls.
29
+ #
30
+ # The `with_fixed_indentation` style aligns the following lines with one
31
+ # level of indentation relative to the start of the line with the method call.
32
+ #
33
+ # method_call(a,
34
+ # b)
35
+ EnforcedStyle: with_fixed_indentation
36
+
37
+ Style/ClassAndModuleChildren:
38
+ # Checks the style of children definitions at classes and modules.
39
+ #
40
+ # Basically there are two different styles:
41
+ #
42
+ # `nested` - have each child on a separate line
43
+ # class Foo
44
+ # class Bar
45
+ # end
46
+ # end
47
+ #
48
+ # `compact` - combine definitions as much as possible
49
+ # class Foo::Bar
50
+ # end
51
+ #
52
+ # The compact style is only forced, for classes / modules with one child.
53
+ EnforcedStyle: nested
54
+ Enabled: false
55
+
56
+ Style/Documentation:
57
+ # This cop checks for missing top-level documentation of classes and modules.
58
+ # Classes with no body and namespace modules are exempt from the check.
59
+ # Namespace modules are modules that have nothing in their bodies except
60
+ # classes or other modules.
61
+ Enabled: false
62
+
63
+ Lint/EndAlignment:
64
+ AlignWith: variable
65
+
66
+ Style/CaseIndentation:
67
+ IndentWhenRelativeTo: end
68
+
69
+ Style/FrozenStringLiteralComment:
70
+ # `when_needed` will add the frozen string literal comment to files
71
+ # only when the `TargetRubyVersion` is set to 2.3+.
72
+ # `always` will always add the frozen string literal comment to a file
73
+ # regardless of the Ruby version or if `freeze` or `<<` are called on a
74
+ # string literal. If you run code against multiple versions of Ruby, it is
75
+ # possible that this will create errors in Ruby 2.3.0+.
76
+ #
77
+ # See: https://wyeworks.com/blog/2015/12/1/immutable-strings-in-ruby-2-dot-3
78
+ EnforcedStyle: when_needed
79
+ Enabled: false
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
data/README.md ADDED
@@ -0,0 +1,155 @@
1
+ # QuizApiClient
2
+
3
+ Welcome!
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'quiz_api_client'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install quiz_api_client
20
+
21
+ ## Usage
22
+
23
+ This client library is used to access quiz_api through Signed Auth, our implementation of signing a JWT with the appropriate scope and resource_id.
24
+
25
+ Currently, the "services" are organized by resource, following the REST convention of pluralization.
26
+
27
+ ### Instantiate the Client
28
+
29
+ To instantiate a client, you'll need the secret and the host.
30
+
31
+ ```ruby
32
+ client = QuizApiClient::Client.new(
33
+ quiz_api_host: 'your-quiz-api-host-here.com',
34
+ quiz_api_secret_for_jwt: 'the-api-secret normally stored on the quiz_api account'
35
+ )
36
+ ```
37
+
38
+ ### Creation of Tokens
39
+
40
+ 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.
41
+
42
+ Example, generate a token for building:
43
+ ```ruby
44
+ client.quiz_service.token(
45
+ scope: client.quiz_service.scope_build,
46
+ exp: Time.now.utc.to_i + 60, # some reasonable time, obviously longer is more a security risk
47
+ resource_id: 1)
48
+ ```
49
+
50
+ ### Calling the API
51
+
52
+ Example, create a Quiz:
53
+ ```ruby
54
+ client.quiz_service.create(
55
+ params: {
56
+ title: 'My quiz'
57
+ }
58
+ ```
59
+
60
+ ### Currently Supported Functionality
61
+
62
+ #### Quiz Service
63
+
64
+ **Tokens**
65
+ ```ruby
66
+ # Generate Build token
67
+ client.quiz_service.token(
68
+ scope: client.quiz_service.scope_build,
69
+ exp: some_expiration,
70
+ resource_id: quiz_id_here
71
+ )
72
+ ```
73
+
74
+ #### Quizzes Service
75
+
76
+ **Tokens**
77
+ ```ruby
78
+ # Generate token: Create Quiz
79
+ client.quizzes_service.token(
80
+ scope: client.quizzes_service.scope_create,
81
+ exp: some_expiration
82
+ )
83
+
84
+ # List Quizzes
85
+ client.quizzes_service.token(
86
+ scope: client.quizzes_service.scope_list,
87
+ exp: some_expiration
88
+ )
89
+ ```
90
+
91
+ **API Calls**
92
+ ```ruby
93
+ # Create Quiz
94
+ client.quizzes_service.create(params:)
95
+
96
+ # List Quizzes
97
+ client.quizzes_service.list(params:)
98
+ ```
99
+
100
+ #### Quiz Session Service
101
+
102
+ **Tokens**
103
+ ```ruby
104
+ # Generate token: Update Quiz Session
105
+ client.quiz_session_service.token(
106
+ scope: client.quiz_session_service.scope_update,
107
+ exp: some_expiration,
108
+ resource_id: quiz_session_id
109
+ )
110
+
111
+ # Generate token: Take Quiz Session
112
+ client.quiz_session_service.token(
113
+ scope: client.quiz_session_service.scope_take,
114
+ exp: some_expiration,
115
+ resource_id: quiz_session_id
116
+ )
117
+ ```
118
+
119
+ **API Calls**
120
+ ```ruby
121
+ # Update Quiz Session
122
+ client.quiz_session_service.update(
123
+ params: {
124
+ id: quiz_session_id,
125
+ # Other params here
126
+ }
127
+ )
128
+ ```
129
+
130
+ #### Quiz Sessions Service
131
+
132
+ **Tokens**
133
+ ```ruby
134
+ # Generate token: Create Quiz Session
135
+ client.quiz_sessions_service.token(
136
+ scope: client.quiz_sessions_service.scope_create,
137
+ exp: some_expiration
138
+ )
139
+ ```
140
+
141
+ **API Calls**
142
+ ```ruby
143
+ # Create Quiz Session
144
+ client.quiz_sessions_service.create(
145
+ params: {
146
+ quiz_id: quiz_id_to_create_session_under
147
+ }
148
+ )
149
+ ```
150
+
151
+ ## Development
152
+
153
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `rake console` for an interactive prompt that will allow you to experiment.
154
+
155
+ 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).
data/Rakefile ADDED
@@ -0,0 +1,19 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task default: :spec
7
+
8
+ task :console do
9
+ require 'pry'
10
+ require 'quiz_api_client'
11
+
12
+ def reload!
13
+ files = $LOADED_FEATURES.select { |feat| feat =~ %r{/\/quiz_api_client/} }
14
+ files.each { |file| load file }
15
+ end
16
+
17
+ ARGV.clear
18
+ Pry.start
19
+ end
data/bin/console ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+ require 'quiz_api_client'
5
+ require 'irb'
6
+
7
+ IRB.start
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,58 @@
1
+ require 'httparty'
2
+
3
+ module QuizApiClient
4
+ class HttpClient
5
+ include HTTParty
6
+
7
+ class RequestFailed < StandardError; end
8
+
9
+ attr_reader :jwt, :uri
10
+
11
+ def initialize(uri:, jwt:)
12
+ @uri = uri
13
+ @jwt = jwt
14
+ end
15
+
16
+ def get(path, query = {})
17
+ make_request :get, path, options(query: query)
18
+ end
19
+
20
+ def post(path, body = {})
21
+ make_request :post, path, options(body: body)
22
+ end
23
+
24
+ def patch(path, body = {})
25
+ make_request :patch, path, options(body: body)
26
+ end
27
+
28
+ def put(path, body = {})
29
+ make_request :put, path, options(body: body)
30
+ end
31
+
32
+ def delete(path)
33
+ make_request :delete, path, options
34
+ end
35
+
36
+ private
37
+
38
+ def make_request(method, path, options)
39
+ self.class.send(
40
+ method,
41
+ "#{uri}#{path}",
42
+ options
43
+ )
44
+ rescue HTTParty::Error, Errno::ECONNREFUSED, Net::ReadTimeout => e
45
+ raise RequestFailed, e.message
46
+ end
47
+
48
+ def options(opts = {})
49
+ { headers: headers }.merge(opts)
50
+ end
51
+
52
+ def headers
53
+ { 'Authorization' => jwt,
54
+ 'AuthType' => 'Signature',
55
+ 'Accept' => 'application/json' }
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,43 @@
1
+ require 'quiz_api_client/http_client'
2
+ require 'quiz_api_client/services/jwt_service'
3
+
4
+ module QuizApiClient::Services
5
+ class BaseApiService
6
+ attr_reader :quiz_api_host, :quiz_api_secret_for_jwt, :errors
7
+
8
+ def initialize(quiz_api_host:, quiz_api_secret_for_jwt:)
9
+ @quiz_api_host = quiz_api_host
10
+ @quiz_api_secret_for_jwt = quiz_api_secret_for_jwt
11
+ @errors = []
12
+ end
13
+
14
+ private
15
+
16
+ def token_for_api(default_token = nil, scope = nil, resource_id = nil)
17
+ return default_token unless default_token.nil?
18
+ generate_token(scope: scope, resource_id: resource_id)
19
+ end
20
+
21
+ def quiz_api_url
22
+ "http://#{quiz_api_host}"
23
+ end
24
+
25
+ def generate_token(scope:, exp: nil, resource_id: nil)
26
+ jwt_service.grant_permission(scope: scope, exp: exp, resource_id: resource_id)
27
+ end
28
+
29
+ def jwt_service
30
+ QuizApiClient::Services::JwtService.new(
31
+ url: quiz_api_url,
32
+ jwt_secret: quiz_api_secret_for_jwt
33
+ )
34
+ end
35
+
36
+ def quiz_api_client(token:)
37
+ QuizApiClient::HttpClient.new(
38
+ uri: quiz_api_url,
39
+ jwt: token
40
+ )
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,32 @@
1
+ require 'jwt'
2
+
3
+ module QuizApiClient::Services
4
+ HASHING_ALGORITHM = 'HS512'.freeze
5
+ class JwtService
6
+ attr_reader :url, :jwt_secret, :user_id
7
+
8
+ def initialize(jwt_secret:, url:)
9
+ @url = url
10
+ @jwt_secret = jwt_secret
11
+ end
12
+
13
+ def grant_permission(scope:, exp: nil, resource_id: nil)
14
+ payload = {
15
+ host: url,
16
+ scope: scope,
17
+ exp: exp || Time.now.utc.to_i + 60,
18
+
19
+ # FIXME: This is currently required on quiz_web
20
+ user: {
21
+ full_name: 'Fake Full Name',
22
+ given_name: 'Fake',
23
+ email: 'quizzes+fake@instructure.com',
24
+ id: 1
25
+ }
26
+ }
27
+ payload[:resource_id] = resource_id if resource_id
28
+
29
+ JWT.encode(payload, jwt_secret, HASHING_ALGORITHM)
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,15 @@
1
+ require 'quiz_api_client/services/base_api_service'
2
+
3
+ module QuizApiClient::Services
4
+ class QuizService < BaseApiService
5
+ def token(scope:, exp: nil, resource_id: nil)
6
+ return unless scope == scope_build
7
+ generate_token(scope: scope, exp: exp, resource_id: resource_id)
8
+ end
9
+
10
+ # Allowed scopes
11
+ def scope_build
12
+ 'quiz.build'
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,31 @@
1
+ require 'quiz_api_client/services/base_api_service'
2
+
3
+ module QuizApiClient::Services
4
+ class QuizSessionService < BaseApiService
5
+ def token(scope:, exp: nil, resource_id: nil)
6
+ return unless (scope == scope_update) || (scope == scope_take)
7
+ generate_token(scope: scope, exp: exp, resource_id: resource_id)
8
+ end
9
+
10
+ def update(params:, default_token: nil)
11
+ patch_to_quiz_api(params: params, token: token_for_api(default_token, scope_update, params[:id]))
12
+ end
13
+
14
+ # Allowed scopes
15
+ def scope_update
16
+ 'quiz_session.update'
17
+ end
18
+ def scope_take
19
+ 'quiz_session.take'
20
+ end
21
+
22
+ private
23
+
24
+ def patch_to_quiz_api(params:, token:)
25
+ quiz_api_client(token: token).patch(
26
+ "/api/quiz_sessions/#{params[:id]}",
27
+ quiz_session: params
28
+ )
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,33 @@
1
+ require 'quiz_api_client/services/base_api_service'
2
+
3
+ module QuizApiClient::Services
4
+ class QuizSessionsService < BaseApiService
5
+ def token(scope:, exp: nil, resource_id: nil)
6
+ return unless (scope == scope_create) || (scope == scope_list)
7
+ generate_token(scope: scope, exp: exp, resource_id: resource_id)
8
+ end
9
+
10
+ def create(params:, default_token: nil)
11
+ raise 'Quiz Id Required' unless params && params[:quiz_id]
12
+ post_to_quiz_api(params: params, token: token_for_api(default_token, scope_create, params[:quiz_id]))
13
+ end
14
+
15
+ # Allowed scopes
16
+ def scope_create
17
+ 'quiz_session.create'
18
+ end
19
+
20
+ def scope_list
21
+ 'quiz_session.list'
22
+ end
23
+
24
+ private
25
+
26
+ def post_to_quiz_api(params:, token:)
27
+ quiz_api_client(token: token).post(
28
+ "/api/quizzes/#{params[:quiz_id]}/quiz_sessions",
29
+ quiz_session: params
30
+ )
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,43 @@
1
+ require 'quiz_api_client/services/base_api_service'
2
+
3
+ module QuizApiClient::Services
4
+ class QuizzesService < BaseApiService
5
+ def token(scope:, exp: nil, resource_id: nil)
6
+ return unless (scope == scope_create) || (scope == scope_list)
7
+ generate_token(scope: scope, exp: exp, resource_id: resource_id)
8
+ end
9
+
10
+ def create(params:, default_token: nil)
11
+ post_to_quiz_api(params: params, token: token_for_api(default_token, scope_create))
12
+ end
13
+
14
+ def list(params:, default_token: nil)
15
+ get_from_quiz_api(params: params, token: token_for_api(default_token, scope_list))
16
+ end
17
+
18
+ ## Allowed scopes
19
+ def scope_create
20
+ 'quiz.create'
21
+ end
22
+
23
+ def scope_list
24
+ 'quiz.list'
25
+ end
26
+
27
+ private
28
+
29
+ def post_to_quiz_api(params:, token:)
30
+ quiz_api_client(token: token).post(
31
+ '/api/quizzes',
32
+ quiz: params
33
+ )
34
+ end
35
+
36
+ def get_from_quiz_api(params:, token:)
37
+ quiz_api_client(token: token).get(
38
+ '/api/quizzes',
39
+ params
40
+ )
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,3 @@
1
+ module QuizApiClient
2
+ VERSION = '0.1.0'.freeze
3
+ end
@@ -0,0 +1,45 @@
1
+ require 'quiz_api_client/version'
2
+ require 'quiz_api_client/services/quiz_service'
3
+ require 'quiz_api_client/services/quizzes_service'
4
+ require 'quiz_api_client/services/quiz_sessions_service'
5
+ require 'quiz_api_client/services/quiz_session_service'
6
+ require 'quiz_api_client/services/quiz_sessions_service'
7
+
8
+ module QuizApiClient
9
+ class Client
10
+ attr_reader :quiz_api_host, :quiz_api_secret_for_jwt
11
+
12
+ def initialize(quiz_api_host:, quiz_api_secret_for_jwt:)
13
+ @quiz_api_host = quiz_api_host
14
+ @quiz_api_secret_for_jwt = quiz_api_secret_for_jwt
15
+ end
16
+
17
+ def quiz_service
18
+ @_quiz_service ||= Services::QuizService.new(
19
+ quiz_api_host: quiz_api_host,
20
+ quiz_api_secret_for_jwt: quiz_api_secret_for_jwt
21
+ )
22
+ end
23
+
24
+ def quizzes_service
25
+ @_quizzes_service ||= Services::QuizzesService.new(
26
+ quiz_api_host: quiz_api_host,
27
+ quiz_api_secret_for_jwt: quiz_api_secret_for_jwt
28
+ )
29
+ end
30
+
31
+ def quiz_session_service
32
+ @_quiz_service ||= Services::QuizSessionService.new(
33
+ quiz_api_host: quiz_api_host,
34
+ quiz_api_secret_for_jwt: quiz_api_secret_for_jwt
35
+ )
36
+ end
37
+
38
+ def quiz_sessions_service
39
+ @_quiz_sessions_service ||= Services::QuizSessionsService.new(
40
+ quiz_api_host: quiz_api_host,
41
+ quiz_api_secret_for_jwt: quiz_api_secret_for_jwt
42
+ )
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'quiz_api_client/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'quiz_api_client'
8
+ spec.version = QuizApiClient::VERSION
9
+ spec.authors = ['Chris Wang']
10
+ spec.email = ['cwang@instructure.com']
11
+ spec.summary = 'Ruby client for quiz_api'
12
+
13
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
14
+ spec.bindir = 'exe'
15
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
16
+ spec.require_paths = ['lib']
17
+
18
+ spec.add_dependency 'httparty'
19
+ spec.add_dependency 'jwt'
20
+
21
+ spec.add_development_dependency 'bundler', '~> 1.12'
22
+ spec.add_development_dependency 'simplecov'
23
+ spec.add_development_dependency 'webmock'
24
+ spec.add_development_dependency 'rake', '~> 10.0'
25
+ spec.add_development_dependency 'rspec', '~> 3.0'
26
+ end
metadata ADDED
@@ -0,0 +1,160 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: quiz_api_client
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Chris Wang
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2017-02-10 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: httparty
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: jwt
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.12'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.12'
55
+ - !ruby/object:Gem::Dependency
56
+ name: simplecov
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: webmock
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rake
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '10.0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '10.0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rspec
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '3.0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '3.0'
111
+ description:
112
+ email:
113
+ - cwang@instructure.com
114
+ executables: []
115
+ extensions: []
116
+ extra_rdoc_files: []
117
+ files:
118
+ - ".editorconfig"
119
+ - ".gitignore"
120
+ - ".rspec"
121
+ - ".rubocop.yml"
122
+ - Gemfile
123
+ - README.md
124
+ - Rakefile
125
+ - bin/console
126
+ - bin/setup
127
+ - lib/quiz_api_client.rb
128
+ - lib/quiz_api_client/http_client.rb
129
+ - lib/quiz_api_client/services/base_api_service.rb
130
+ - lib/quiz_api_client/services/jwt_service.rb
131
+ - lib/quiz_api_client/services/quiz_service.rb
132
+ - lib/quiz_api_client/services/quiz_session_service.rb
133
+ - lib/quiz_api_client/services/quiz_sessions_service.rb
134
+ - lib/quiz_api_client/services/quizzes_service.rb
135
+ - lib/quiz_api_client/version.rb
136
+ - quiz_api_client.gemspec
137
+ homepage:
138
+ licenses: []
139
+ metadata: {}
140
+ post_install_message:
141
+ rdoc_options: []
142
+ require_paths:
143
+ - lib
144
+ required_ruby_version: !ruby/object:Gem::Requirement
145
+ requirements:
146
+ - - ">="
147
+ - !ruby/object:Gem::Version
148
+ version: '0'
149
+ required_rubygems_version: !ruby/object:Gem::Requirement
150
+ requirements:
151
+ - - ">="
152
+ - !ruby/object:Gem::Version
153
+ version: '0'
154
+ requirements: []
155
+ rubyforge_project:
156
+ rubygems_version: 2.2.3
157
+ signing_key:
158
+ specification_version: 4
159
+ summary: Ruby client for quiz_api
160
+ test_files: []