quiz_broker_client 0.1.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 839a7e79c6b2ebb264aebe79fd12efb3329a6ef020b4bb88b7e9d27b01b93a4d
4
+ data.tar.gz: 420b141b32c8f99e5ea7dd0807e4810cc9d8ab947007ab72b95d52e3c4026b04
5
+ SHA512:
6
+ metadata.gz: 7512454ccb3ce64059c645b222853a91347fb7fe837719f0c9f134d8749bb0a9fd748908d2f0edc54b0584f0561dec5bdfc73f820973b8c51bbb8a154efe3053
7
+ data.tar.gz: 2a365d373b825038e6a1b1d62f1c92cd7fcacf88d90a3ad5d5a992a17e081f35f1dc50575e9570690a07d4fda09f3a6b585d8ee0c147a9a01ed9078a9e5246ed
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/.rubocop.yml ADDED
@@ -0,0 +1,72 @@
1
+ AllCops:
2
+ TargetRubyVersion: 2.7
3
+
4
+ Metrics/ClassLength:
5
+ Max: 200 # Default: 100
6
+
7
+ Metrics/LineLength:
8
+ Max: 120 # Default: 80
9
+
10
+ Metrics/MethodLength:
11
+ Max: 20 # Default: 10
12
+
13
+ Metrics/BlockLength:
14
+ Max: 30
15
+ Exclude:
16
+ - quiz_broker_client.gemspec
17
+ - spec/**/*.rb
18
+
19
+ Naming/MemoizedInstanceVariableName:
20
+ EnforcedStyleForLeadingUnderscores: required
21
+
22
+ Layout/ParameterAlignment:
23
+ # Alignment of parameters in multi-line method calls.
24
+ #
25
+ # The `with_fixed_indentation` style aligns the following lines with one
26
+ # level of indentation relative to the start of the line with the method call.
27
+ #
28
+ # method_call(a,
29
+ # b)
30
+ EnforcedStyle: with_fixed_indentation
31
+
32
+ Layout/CaseIndentation:
33
+ EnforcedStyle: end
34
+
35
+ Layout/EndAlignment:
36
+ EnforcedStyleAlignWith: variable
37
+
38
+ Style/ClassAndModuleChildren:
39
+ # Checks the style of children definitions at classes and modules.
40
+ #
41
+ # Basically there are two different styles:
42
+ #
43
+ # `nested` - have each child on a separate line
44
+ # class Foo
45
+ # class Bar
46
+ # end
47
+ # end
48
+ #
49
+ # `compact` - combine definitions as much as possible
50
+ # class Foo::Bar
51
+ # end
52
+ #
53
+ # The compact style is only forced, for classes / modules with one child.
54
+ EnforcedStyle: nested
55
+ Enabled: false
56
+
57
+ Style/Documentation:
58
+ # This cop checks for missing top-level documentation of classes and modules.
59
+ # Classes with no body and namespace modules are exempt from the check.
60
+ # Namespace modules are modules that have nothing in their bodies except
61
+ # classes or other modules.
62
+ Enabled: false
63
+
64
+ Style/FrozenStringLiteralComment:
65
+ # `always` will always add the frozen string literal comment to a file
66
+ # regardless of the Ruby version or if `freeze` or `<<` are called on a
67
+ # string literal. If you run code against multiple versions of Ruby, it is
68
+ # possible that this will create errors in Ruby 2.3.0+.
69
+ #
70
+ # See: https://wyeworks.com/blog/2015/12/1/immutable-strings-in-ruby-2-dot-3
71
+ EnforcedStyle: always
72
+ Enabled: false
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.7.5
data/CHANGELOG.md ADDED
@@ -0,0 +1,5 @@
1
+ ## [Unreleased]
2
+
3
+ ## [0.1.0] - 2024-03-15
4
+
5
+ - Initial release
data/Dockerfile ADDED
@@ -0,0 +1,16 @@
1
+ # Build stage
2
+ FROM instructure/ruby-passenger:2.7
3
+
4
+ RUN mkdir -p coverage log
5
+
6
+ USER root
7
+
8
+ RUN apt-get update && apt-get install -y git
9
+
10
+ USER docker
11
+
12
+ COPY --chown=docker:docker . .
13
+
14
+ RUN ./bin/setup
15
+
16
+ CMD ["tail", "-f", "/dev/null"]
data/Jenkinsfile ADDED
@@ -0,0 +1,75 @@
1
+ pipeline {
2
+ agent {
3
+ label 'docker'
4
+ }
5
+
6
+ options {
7
+ parallelsAlwaysFailFast()
8
+ }
9
+
10
+ stages {
11
+ stage('Build') {
12
+ steps {
13
+ sh 'docker compose build --pull'
14
+ }
15
+ }
16
+
17
+ stage('Lint') {
18
+ stages {
19
+ stage('Rubocop') {
20
+ steps {
21
+ sh '''#!/usr/bin/env bash
22
+ set -o pipefail
23
+ docker compose run --rm quiz_broker_client bundle exec rubocop --fail-level autocorrect
24
+ '''
25
+ }
26
+ }
27
+ }
28
+ }
29
+
30
+ stage('Spec') {
31
+ steps {
32
+ sh 'docker compose run quiz_broker_client bundle exec rspec --format doc'
33
+ sh '''
34
+ image=$(docker ps --all --no-trunc | grep spec | cut -f 1 -d " " | head -n 1)
35
+ docker cp "$image:/usr/src/app/coverage" .
36
+ '''
37
+ sh 'ls -als coverage'
38
+ }
39
+
40
+ post {
41
+ always {
42
+ publishHTML target: [
43
+ allowMissing: false,
44
+ alwaysLinkToLastBuild: false,
45
+ keepAll: true,
46
+ reportDir: 'coverage',
47
+ reportFiles: 'index.html',
48
+ reportName: 'Coverage Report'
49
+ ]
50
+ }
51
+ }
52
+ }
53
+
54
+ stage('Publish') {
55
+ when {
56
+ allOf {
57
+ expression { GERRIT_BRANCH == "master" }
58
+ environment name: "GERRIT_EVENT_TYPE", value: "change-merged"
59
+ }
60
+ }
61
+ steps {
62
+ withCredentials([string(credentialsId: 'rubygems-rw', variable: 'GEM_HOST_API_KEY')]) {
63
+ sh 'docker run -e GEM_HOST_API_KEY --rm quiz_broker_client /bin/bash -lc "./bin/publish.sh"'
64
+ }
65
+ }
66
+ }
67
+ }
68
+
69
+ post {
70
+ cleanup {
71
+ sh 'docker compose down --rmi=all --volumes --remove-orphans'
72
+ }
73
+ }
74
+ }
75
+
data/README.md ADDED
@@ -0,0 +1,24 @@
1
+ # QuizBrokerClient
2
+ Ruby client for New Quizzes broker interactions
3
+
4
+ ## Development
5
+ First copy the compose override example file:
6
+ ```
7
+ cp docker-compose.override.yml.example docker-compose.override.yml
8
+ ```
9
+
10
+ This project uses [Compose watch](https://docs.docker.com/compose/file-watch/) to sync files between host and container.
11
+
12
+ Compose watch will also rebuild the container (and install gems)
13
+ if new dependencies are added to the gemspec.
14
+
15
+ To build the container and start file watching, run the following
16
+ ```
17
+ docker compose watch
18
+ ```
19
+
20
+ ## Testing
21
+ Run the following command to execute the test suite:
22
+ ```
23
+ docker compose run quiz_broker_client rake spec
24
+ ```
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
4
+ require 'rspec/core/rake_task'
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ require 'rubocop/rake_task'
9
+
10
+ RuboCop::RakeTask.new
11
+
12
+ task default: %i[spec rubocop]
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ module QuizBrokerClient::AuthorizedContexts
4
+ extend QuizBrokerClient::DynamoDB
5
+
6
+ AUTHORIZED_CONTEXTS_ATTRIBUTE = 'contexts'
7
+
8
+ class << self
9
+ def for(subject:)
10
+ response = get_item(
11
+ common_params.merge(
12
+ key: {
13
+ subject: subject
14
+ }
15
+ )
16
+ )
17
+
18
+ return Set.new if response.item.nil?
19
+
20
+ response.item[AUTHORIZED_CONTEXTS_ATTRIBUTE]
21
+ end
22
+
23
+ def set(subject:, contexts:)
24
+ put_item(
25
+ common_params.merge(
26
+ item: {
27
+ subject: subject,
28
+ created_at: Time.now.to_i,
29
+ delete_at: Time.now.to_i + QuizBrokerClient.configuration.ttl.to_i,
30
+ AUTHORIZED_CONTEXTS_ATTRIBUTE => Set.new(contexts)
31
+ }
32
+ )
33
+ )
34
+
35
+ true
36
+ end
37
+
38
+ private
39
+
40
+ def common_params
41
+ {
42
+ table_name: QuizBrokerClient.configuration.authorized_contexts_table_name
43
+ }
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,9 @@
1
+ module QuizBrokerClient
2
+ class Configuration
3
+ attr_accessor :authorized_contexts_table_name, :ttl
4
+
5
+ def initialize
6
+ @ttl = 43_200 # 12 hours
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,23 @@
1
+ module QuizBrokerClient::DynamoDB
2
+ methods = %i[get_item put_item]
3
+
4
+ methods.each do |method|
5
+ define_method(method) do |*args|
6
+ client.send(method, *args)
7
+ rescue Aws::DynamoDB::Errors::ServiceError,
8
+ Aws::Errors::MissingCredentialsError => e
9
+ clear_client!
10
+ raise e
11
+ end
12
+ end
13
+
14
+ private
15
+
16
+ def clear_client!
17
+ @_client = nil
18
+ end
19
+
20
+ def client
21
+ @_client ||= Aws::DynamoDB::Client.new
22
+ end
23
+ end
@@ -0,0 +1,4 @@
1
+ require 'aws-sdk-dynamodb'
2
+ require_relative 'dynamodb/client'
3
+
4
+ module QuizBrokerClient::DynamoDB; end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module QuizBrokerClient
4
+ VERSION = '0.1.0'
5
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'quiz_broker_client/version'
4
+ require_relative 'quiz_broker_client/configuration'
5
+ require_relative 'quiz_broker_client/dynamodb'
6
+ require_relative 'quiz_broker_client/authorized_contexts'
7
+
8
+ module QuizBrokerClient
9
+ class Error < StandardError; end
10
+
11
+ class << self
12
+ def configuration
13
+ @_configuration ||= Configuration.new
14
+ end
15
+
16
+ def configure
17
+ yield(configuration)
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'lib/quiz_broker_client/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'quiz_broker_client'
7
+ spec.version = QuizBrokerClient::VERSION
8
+ spec.authors = ['Weston Dransfield']
9
+ spec.email = ['wdransfield@instructure.com']
10
+
11
+ spec.summary = 'Ruby client for New Quizzes broker interactions'
12
+ spec.description = 'Serves as the client for reading and writing to brokered data in Canvas New Quizzes'
13
+ spec.required_ruby_version = '>= 2.7.0'
14
+
15
+ spec.files = Dir.chdir(__dir__) do
16
+ `git ls-files -z`.split("\x0").reject do |f|
17
+ (File.expand_path(f) == __FILE__) ||
18
+ f.start_with?(*%w[bin/ test/ spec/ features/ .git appveyor Gemfile docker-compose])
19
+ end
20
+ end
21
+
22
+ spec.bindir = 'exe'
23
+ spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
24
+ spec.require_paths = ['lib']
25
+
26
+ spec.add_dependency 'aws-sdk-dynamodb', '~> 1', '>= 1.85.0'
27
+
28
+ spec.add_development_dependency 'byebug', '~> 9.0', '>= 9.0.5'
29
+ spec.add_development_dependency 'simplecov'
30
+ end
metadata ADDED
@@ -0,0 +1,112 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: quiz_broker_client
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Weston Dransfield
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2024-03-21 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: aws-sdk-dynamodb
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 1.85.0
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '1'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 1.85.0
33
+ - !ruby/object:Gem::Dependency
34
+ name: byebug
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '9.0'
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: 9.0.5
43
+ type: :development
44
+ prerelease: false
45
+ version_requirements: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - "~>"
48
+ - !ruby/object:Gem::Version
49
+ version: '9.0'
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: 9.0.5
53
+ - !ruby/object:Gem::Dependency
54
+ name: simplecov
55
+ requirement: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: '0'
60
+ type: :development
61
+ prerelease: false
62
+ version_requirements: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: '0'
67
+ description: Serves as the client for reading and writing to brokered data in Canvas
68
+ New Quizzes
69
+ email:
70
+ - wdransfield@instructure.com
71
+ executables: []
72
+ extensions: []
73
+ extra_rdoc_files: []
74
+ files:
75
+ - ".rspec"
76
+ - ".rubocop.yml"
77
+ - ".ruby-version"
78
+ - CHANGELOG.md
79
+ - Dockerfile
80
+ - Jenkinsfile
81
+ - README.md
82
+ - Rakefile
83
+ - lib/quiz_broker_client.rb
84
+ - lib/quiz_broker_client/authorized_contexts.rb
85
+ - lib/quiz_broker_client/configuration.rb
86
+ - lib/quiz_broker_client/dynamodb.rb
87
+ - lib/quiz_broker_client/dynamodb/client.rb
88
+ - lib/quiz_broker_client/version.rb
89
+ - quiz_broker_client.gemspec
90
+ homepage:
91
+ licenses: []
92
+ metadata: {}
93
+ post_install_message:
94
+ rdoc_options: []
95
+ require_paths:
96
+ - lib
97
+ required_ruby_version: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - ">="
100
+ - !ruby/object:Gem::Version
101
+ version: 2.7.0
102
+ required_rubygems_version: !ruby/object:Gem::Requirement
103
+ requirements:
104
+ - - ">="
105
+ - !ruby/object:Gem::Version
106
+ version: '0'
107
+ requirements: []
108
+ rubygems_version: 3.2.6
109
+ signing_key:
110
+ specification_version: 4
111
+ summary: Ruby client for New Quizzes broker interactions
112
+ test_files: []