canvas_sync 0.1.1

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 (85) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +178 -0
  3. data/Rakefile +23 -0
  4. data/lib/canvas_sync.rb +96 -0
  5. data/lib/canvas_sync/generators/install_generator.rb +54 -0
  6. data/lib/canvas_sync/generators/templates/course.rb +8 -0
  7. data/lib/canvas_sync/generators/templates/create_courses.rb +21 -0
  8. data/lib/canvas_sync/generators/templates/create_enrollments.rb +26 -0
  9. data/lib/canvas_sync/generators/templates/create_sections.rb +20 -0
  10. data/lib/canvas_sync/generators/templates/create_terms.rb +18 -0
  11. data/lib/canvas_sync/generators/templates/create_users.rb +18 -0
  12. data/lib/canvas_sync/generators/templates/enrollment.rb +8 -0
  13. data/lib/canvas_sync/generators/templates/section.rb +7 -0
  14. data/lib/canvas_sync/generators/templates/term.rb +28 -0
  15. data/lib/canvas_sync/generators/templates/user.rb +6 -0
  16. data/lib/canvas_sync/importers/bulk_importer.rb +54 -0
  17. data/lib/canvas_sync/jobs/application_job.rb +25 -0
  18. data/lib/canvas_sync/jobs/report_checker.rb +48 -0
  19. data/lib/canvas_sync/jobs/report_processor_job.rb +36 -0
  20. data/lib/canvas_sync/jobs/report_starter.rb +29 -0
  21. data/lib/canvas_sync/jobs/sync_provisioning_report_job.rb +58 -0
  22. data/lib/canvas_sync/jobs/sync_terms_job.rb +23 -0
  23. data/lib/canvas_sync/jobs/sync_users_job.rb +32 -0
  24. data/lib/canvas_sync/processors/provisioning_report_processor.rb +118 -0
  25. data/lib/canvas_sync/version.rb +3 -0
  26. data/spec/canvas_sync/canvas_sync_spec.rb +60 -0
  27. data/spec/canvas_sync/jobs/report_checker_spec.rb +62 -0
  28. data/spec/canvas_sync/jobs/report_processor_job_spec.rb +30 -0
  29. data/spec/canvas_sync/jobs/report_starter_spec.rb +27 -0
  30. data/spec/canvas_sync/jobs/sync_provisioning_report_job_spec.rb +81 -0
  31. data/spec/canvas_sync/jobs/sync_terms_job_spec.rb +18 -0
  32. data/spec/canvas_sync/jobs/sync_users_job_spec.rb +18 -0
  33. data/spec/canvas_sync/models/course_spec.rb +30 -0
  34. data/spec/canvas_sync/models/enrollment_spec.rb +30 -0
  35. data/spec/canvas_sync/models/section_spec.rb +24 -0
  36. data/spec/canvas_sync/models/term_spec.rb +71 -0
  37. data/spec/canvas_sync/models/user_spec.rb +18 -0
  38. data/spec/canvas_sync/processors/provisioning_report_processor_spec.rb +41 -0
  39. data/spec/dummy/README.rdoc +1 -0
  40. data/spec/dummy/Rakefile +6 -0
  41. data/spec/dummy/app/models/application_record.rb +3 -0
  42. data/spec/dummy/app/models/course.rb +14 -0
  43. data/spec/dummy/app/models/enrollment.rb +14 -0
  44. data/spec/dummy/app/models/section.rb +13 -0
  45. data/spec/dummy/app/models/term.rb +34 -0
  46. data/spec/dummy/app/models/user.rb +12 -0
  47. data/spec/dummy/bin/rails +4 -0
  48. data/spec/dummy/config.ru +4 -0
  49. data/spec/dummy/config/application.rb +26 -0
  50. data/spec/dummy/config/boot.rb +5 -0
  51. data/spec/dummy/config/database.yml +25 -0
  52. data/spec/dummy/config/environment.rb +5 -0
  53. data/spec/dummy/config/environments/development.rb +41 -0
  54. data/spec/dummy/config/environments/test.rb +42 -0
  55. data/spec/dummy/config/initializers/assets.rb +11 -0
  56. data/spec/dummy/config/initializers/session_store.rb +3 -0
  57. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  58. data/spec/dummy/config/routes.rb +2 -0
  59. data/spec/dummy/config/secrets.yml +22 -0
  60. data/spec/dummy/db/development.sqlite3 +0 -0
  61. data/spec/dummy/db/migrate/20170831220702_create_courses.rb +27 -0
  62. data/spec/dummy/db/migrate/20170831221129_create_users.rb +24 -0
  63. data/spec/dummy/db/migrate/20170905192509_create_enrollments.rb +32 -0
  64. data/spec/dummy/db/migrate/20170906193506_create_terms.rb +24 -0
  65. data/spec/dummy/db/migrate/20170906203438_create_sections.rb +26 -0
  66. data/spec/dummy/db/schema.rb +88 -0
  67. data/spec/dummy/db/test.sqlite3 +0 -0
  68. data/spec/dummy/log/development.log +828 -0
  69. data/spec/dummy/log/test.log +14582 -0
  70. data/spec/factories/course_factory.rb +10 -0
  71. data/spec/factories/enrollment_factory.rb +5 -0
  72. data/spec/factories/section_factory.rb +5 -0
  73. data/spec/factories/term_factory.rb +10 -0
  74. data/spec/factories/user_factory.rb +9 -0
  75. data/spec/spec_helper.rb +46 -0
  76. data/spec/support/fake_canvas.rb +22 -0
  77. data/spec/support/fixtures/canvas_responses/terms.json +64 -0
  78. data/spec/support/fixtures/reports/courses.csv +3 -0
  79. data/spec/support/fixtures/reports/enrollments.csv +3 -0
  80. data/spec/support/fixtures/reports/provisioning_csv +0 -0
  81. data/spec/support/fixtures/reports/provisioning_csv_unzipped/courses.csv +3 -0
  82. data/spec/support/fixtures/reports/provisioning_csv_unzipped/users.csv +4 -0
  83. data/spec/support/fixtures/reports/sections.csv +3 -0
  84. data/spec/support/fixtures/reports/users.csv +4 -0
  85. metadata +423 -0
@@ -0,0 +1,18 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe User, type: :model do
4
+ let(:subject) { FactoryGirl.create(:user) }
5
+
6
+ describe 'validations' do
7
+ it { should validate_presence_of(:canvas_user_id) }
8
+ it { should validate_uniqueness_of(:canvas_user_id) }
9
+ end
10
+
11
+ describe 'associations' do
12
+ it do
13
+ should have_many(:enrollments)
14
+ .with_primary_key(:canvas_user_id)
15
+ .with_foreign_key(:canvas_user_id)
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,41 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe CanvasSync::Processors::ProvisioningReportProcessor do
4
+ let(:subject) { CanvasSync::Processors::ProvisioningReportProcessor }
5
+
6
+ describe '#process' do
7
+ it 'process users' do
8
+ expect {
9
+ subject.process('spec/support/fixtures/reports/users.csv', { models: ['users'] })
10
+ }.to change { User.count }.by(2)
11
+ end
12
+
13
+ it 'processes courses' do
14
+ expect {
15
+ subject.process('spec/support/fixtures/reports/courses.csv', { models: ['courses'] })
16
+ }.to change { Course.count }.by(2)
17
+ end
18
+
19
+ it 'processes enrollments' do
20
+ expect {
21
+ subject.process('spec/support/fixtures/reports/enrollments.csv', { models: ['enrollments'] })
22
+ }.to change { Enrollment.count }.by(2)
23
+ end
24
+
25
+ it 'processes sections' do
26
+ expect {
27
+ subject.process('spec/support/fixtures/reports/sections.csv', { models: ['sections'] })
28
+ }.to change { Section.count }.by(2)
29
+ end
30
+
31
+ context 'options[:models] is multiple models' do
32
+ it 'extracts the ZIP and processes each model' do
33
+ user_count = User.count
34
+ course_count = Course.count
35
+ subject.process('spec/support/fixtures/reports/provisioning_csv', { models: ['courses', 'users'] })
36
+ expect(User.count).to eq(user_count + 2)
37
+ expect(Course.count).to eq(course_count + 2)
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1 @@
1
+ Dummy Rails App for gem testing
@@ -0,0 +1,6 @@
1
+ # Add your own tasks in files placed in lib/tasks ending in .rake,
2
+ # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
3
+
4
+ require File.expand_path('../config/application', __FILE__)
5
+
6
+ Rails.application.load_tasks
@@ -0,0 +1,3 @@
1
+ class ApplicationRecord < ActiveRecord::Base
2
+ self.abstract_class = true
3
+ end
@@ -0,0 +1,14 @@
1
+ #
2
+ # AUTO GENERATED MODEL
3
+ # This model was auto generated by the CanvasSync Gem.
4
+ # You can customize it as needed, but make sure you test
5
+ # any changes you make to the auto generated methods.
6
+ #
7
+
8
+
9
+ class Course < ApplicationRecord
10
+ validates :canvas_course_id, uniqueness: true, presence: true
11
+ belongs_to :term, foreign_key: :canvas_term_id, primary_key: :canvas_term_id, optional: true
12
+ has_many :enrollments, primary_key: :canvas_course_id, foreign_key: :canvas_course_id
13
+ has_many :sections, primary_key: :canvas_course_id, foreign_key: :canvas_course_id
14
+ end
@@ -0,0 +1,14 @@
1
+ #
2
+ # AUTO GENERATED MODEL
3
+ # This model was auto generated by the CanvasSync Gem.
4
+ # You can customize it as needed, but make sure you test
5
+ # any changes you make to the auto generated methods.
6
+ #
7
+
8
+
9
+ class Enrollment < ApplicationRecord
10
+ validates :canvas_enrollment_id, uniqueness: true, presence: true
11
+ belongs_to :user, primary_key: :canvas_user_id, foreign_key: :canvas_user_id, optional: true
12
+ belongs_to :course, primary_key: :canvas_course_id, foreign_key: :canvas_course_id, optional: true
13
+ belongs_to :section, primary_key: :canvas_section_id, foreign_key: :canvas_section_id, optional: true
14
+ end
@@ -0,0 +1,13 @@
1
+ #
2
+ # AUTO GENERATED MODEL
3
+ # This model was auto generated by the CanvasSync Gem.
4
+ # You can customize it as needed, but make sure you test
5
+ # any changes you make to the auto generated methods.
6
+ #
7
+
8
+
9
+ class Section < ApplicationRecord
10
+ validates :canvas_section_id, uniqueness: true, presence: true
11
+ belongs_to :course, primary_key: :canvas_course_id, foreign_key: :canvas_course_id, optional: true
12
+ has_many :enrollments, primary_key: :canvas_section_id, foreign_key: :canvas_section_id
13
+ end
@@ -0,0 +1,34 @@
1
+ #
2
+ # AUTO GENERATED MODEL
3
+ # This model was auto generated by the CanvasSync Gem.
4
+ # You can customize it as needed, but make sure you test
5
+ # any changes you make to the auto generated methods.
6
+ #
7
+
8
+
9
+ class Term < ApplicationRecord
10
+ validates :canvas_term_id, uniqueness: true, presence: true
11
+ has_many :courses, foreign_key: :canvas_term_id, primary_key: :canvas_term_id
12
+
13
+ # This is a sample scope created by the CanvasSync gem; feel
14
+ # free to customize it for your tool's requirements.
15
+ scope :active, -> {
16
+ where(workflow_state: 'active')
17
+ .where("start_at <= ? OR start_at IS NULL", 15.days.from_now)
18
+ .where("end_at >= ? OR end_at IS NULL", 15.days.ago)
19
+ }
20
+
21
+ def self.create_or_update(term_params)
22
+ term = Term.find_or_initialize_by(canvas_term_id: term_params['id'])
23
+
24
+ term.assign_attributes(name: term_params['name'],
25
+ start_at: term_params['start_at'],
26
+ end_at: term_params['end_at'],
27
+ workflow_state: term_params['workflow_state'],
28
+ grading_period_group_id: term_params['grading_period_group_id'],
29
+ sis_id: term_params['sis_term_id'])
30
+
31
+ term.save! if term.changed?
32
+ term
33
+ end
34
+ end
@@ -0,0 +1,12 @@
1
+ #
2
+ # AUTO GENERATED MODEL
3
+ # This model was auto generated by the CanvasSync Gem.
4
+ # You can customize it as needed, but make sure you test
5
+ # any changes you make to the auto generated methods.
6
+ #
7
+
8
+
9
+ class User < ApplicationRecord
10
+ validates :canvas_user_id, uniqueness: true, presence: true
11
+ has_many :enrollments, primary_key: :canvas_user_id, foreign_key: :canvas_user_id
12
+ end
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ APP_PATH = File.expand_path('../../config/application', __FILE__)
3
+ require_relative '../config/boot'
4
+ require 'rails/commands'
@@ -0,0 +1,4 @@
1
+ # This file is used by Rack-based servers to start the application.
2
+
3
+ require ::File.expand_path('../config/environment', __FILE__)
4
+ run Rails.application
@@ -0,0 +1,26 @@
1
+ require File.expand_path('../boot', __FILE__)
2
+
3
+ require 'rails/all'
4
+
5
+ Bundler.require(*Rails.groups)
6
+ require "canvas_sync"
7
+
8
+ module Dummy
9
+ class Application < Rails::Application
10
+ # Settings in config/environments/* take precedence over those specified here.
11
+ # Application configuration should go into files in config/initializers
12
+ # -- all .rb files in that directory are automatically loaded.
13
+
14
+ # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
15
+ # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
16
+ # config.time_zone = 'Central Time (US & Canada)'
17
+
18
+ # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
19
+ # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
20
+ # config.i18n.default_locale = :de
21
+
22
+ # Do not swallow errors in after_commit/after_rollback callbacks.
23
+ # config.active_record.raise_in_transactional_callbacks = true
24
+ end
25
+ end
26
+
@@ -0,0 +1,5 @@
1
+ # Set up gems listed in the Gemfile.
2
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../../../Gemfile', __FILE__)
3
+
4
+ require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])
5
+ $LOAD_PATH.unshift File.expand_path('../../../../lib', __FILE__)
@@ -0,0 +1,25 @@
1
+ # SQLite version 3.x
2
+ # gem install sqlite3
3
+ #
4
+ # Ensure the SQLite 3 gem is defined in your Gemfile
5
+ # gem 'sqlite3'
6
+ #
7
+ default: &default
8
+ adapter: sqlite3
9
+ pool: 5
10
+ timeout: 5000
11
+
12
+ development:
13
+ <<: *default
14
+ database: db/development.sqlite3
15
+
16
+ # Warning: The database defined as "test" will be erased and
17
+ # re-generated from your development database when you run "rake".
18
+ # Do not set this db to the same as development or production.
19
+ test:
20
+ <<: *default
21
+ database: db/test.sqlite3
22
+
23
+ production:
24
+ <<: *default
25
+ database: db/production.sqlite3
@@ -0,0 +1,5 @@
1
+ # Load the Rails application.
2
+ require File.expand_path('../application', __FILE__)
3
+
4
+ # Initialize the Rails application.
5
+ Rails.application.initialize!
@@ -0,0 +1,41 @@
1
+ Rails.application.configure do
2
+ # Settings specified here will take precedence over those in config/application.rb.
3
+
4
+ # In the development environment your application's code is reloaded on
5
+ # every request. This slows down response time but is perfect for development
6
+ # since you don't have to restart the web server when you make code changes.
7
+ config.cache_classes = false
8
+
9
+ # Do not eager load code on boot.
10
+ config.eager_load = false
11
+
12
+ # Show full error reports and disable caching.
13
+ config.consider_all_requests_local = true
14
+ config.action_controller.perform_caching = false
15
+
16
+ # Don't care if the mailer can't send.
17
+ config.action_mailer.raise_delivery_errors = false
18
+
19
+ # Print deprecation notices to the Rails logger.
20
+ config.active_support.deprecation = :log
21
+
22
+ # Raise an error on page load if there are pending migrations.
23
+ config.active_record.migration_error = :page_load
24
+
25
+ # Debug mode disables concatenation and preprocessing of assets.
26
+ # This option may cause significant delays in view rendering with a large
27
+ # number of complex assets.
28
+ config.assets.debug = true
29
+
30
+ # Asset digests allow you to set far-future HTTP expiration dates on all assets,
31
+ # yet still be able to expire them through the digest params.
32
+ config.assets.digest = true
33
+
34
+ # Adds additional error checking when serving assets at runtime.
35
+ # Checks for improperly declared sprockets dependencies.
36
+ # Raises helpful error messages.
37
+ config.assets.raise_runtime_errors = true
38
+
39
+ # Raises error for missing translations
40
+ # config.action_view.raise_on_missing_translations = true
41
+ end
@@ -0,0 +1,42 @@
1
+ Rails.application.configure do
2
+ # Settings specified here will take precedence over those in config/application.rb.
3
+
4
+ # The test environment is used exclusively to run your application's
5
+ # test suite. You never need to work with it otherwise. Remember that
6
+ # your test database is "scratch space" for the test suite and is wiped
7
+ # and recreated between test runs. Don't rely on the data there!
8
+ config.cache_classes = true
9
+
10
+ # Do not eager load code on boot. This avoids loading your whole application
11
+ # just for the purpose of running a single test. If you are using a tool that
12
+ # preloads Rails for running tests, you may have to set it to true.
13
+ config.eager_load = false
14
+
15
+ # Configure static file server for tests with Cache-Control for performance.
16
+ config.serve_static_files = true
17
+ config.static_cache_control = 'public, max-age=3600'
18
+
19
+ # Show full error reports and disable caching.
20
+ config.consider_all_requests_local = true
21
+ config.action_controller.perform_caching = false
22
+
23
+ # Raise exceptions instead of rendering exception templates.
24
+ config.action_dispatch.show_exceptions = false
25
+
26
+ # Disable request forgery protection in test environment.
27
+ config.action_controller.allow_forgery_protection = false
28
+
29
+ # Tell Action Mailer not to deliver emails to the real world.
30
+ # The :test delivery method accumulates sent emails in the
31
+ # ActionMailer::Base.deliveries array.
32
+ config.action_mailer.delivery_method = :test
33
+
34
+ # Randomize the order test cases are executed.
35
+ config.active_support.test_order = :random
36
+
37
+ # Print deprecation notices to the stderr.
38
+ config.active_support.deprecation = :stderr
39
+
40
+ # Raises error for missing translations
41
+ # config.action_view.raise_on_missing_translations = true
42
+ end
@@ -0,0 +1,11 @@
1
+ # Be sure to restart your server when you modify this file.
2
+
3
+ # Version of your assets, change this if you want to expire all your assets.
4
+ Rails.application.config.assets.version = '1.0'
5
+
6
+ # Add additional assets to the asset load path
7
+ # Rails.application.config.assets.paths << Emoji.images_path
8
+
9
+ # Precompile additional assets.
10
+ # application.js, application.css, and all non-JS/CSS in app/assets folder are already added.
11
+ # Rails.application.config.assets.precompile += %w( search.js )
@@ -0,0 +1,3 @@
1
+ # Be sure to restart your server when you modify this file.
2
+
3
+ Rails.application.config.session_store :cookie_store, key: '_dummy_session'
@@ -0,0 +1,14 @@
1
+ # Be sure to restart your server when you modify this file.
2
+
3
+ # This file contains settings for ActionController::ParamsWrapper which
4
+ # is enabled by default.
5
+
6
+ # Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array.
7
+ ActiveSupport.on_load(:action_controller) do
8
+ wrap_parameters format: [:json] if respond_to?(:wrap_parameters)
9
+ end
10
+
11
+ # To enable root element in JSON for ActiveRecord objects.
12
+ # ActiveSupport.on_load(:active_record) do
13
+ # self.include_root_in_json = true
14
+ # end
@@ -0,0 +1,2 @@
1
+ Rails.application.routes.draw do
2
+ end
@@ -0,0 +1,22 @@
1
+ # Be sure to restart your server when you modify this file.
2
+
3
+ # Your secret key is used for verifying the integrity of signed cookies.
4
+ # If you change this key, all old signed cookies will become invalid!
5
+
6
+ # Make sure the secret is at least 30 characters and all random,
7
+ # no regular words or you'll be exposed to dictionary attacks.
8
+ # You can use `rake secret` to generate a secure secret key.
9
+
10
+ # Make sure the secrets in this file are kept private
11
+ # if you're sharing your code publicly.
12
+
13
+ development:
14
+ secret_key_base: 4fc03e27b5bfc390d7beaf99e739c1a9ad4264d58cd2a1db40fbb83b6ed320e1fa77fb4e0dd7c24816811170a59d65b623bc887b4ca1e0bd0c57348e9e304f73
15
+
16
+ test:
17
+ secret_key_base: 7700238de042256ef63c58a57c6bf431b6ebca79f95f66ccd04b5ad8b89761db15a9b89a85b08ace8a69ae3867462cb9514eb21d0e591d8f3881de79d7b72675
18
+
19
+ # Do not keep production secrets in the repository,
20
+ # instead read values from the environment.
21
+ production:
22
+ secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
@@ -0,0 +1,27 @@
1
+ #
2
+ # AUTO GENERATED MIGRATION
3
+ # This migration was auto generated by the CanvasSync Gem.
4
+ # You can add new columns to this table, but removing or
5
+ # re-naming ones created here may break Canvas Syncing.
6
+ #
7
+
8
+
9
+ class CreateCourses < ActiveRecord::Migration[5.1]
10
+ def change
11
+ create_table :courses do |t|
12
+ t.bigint :canvas_course_id, null: false
13
+ t.string :sis_id
14
+ t.string :short_name
15
+ t.string :long_name
16
+ t.integer :canvas_account_id
17
+ t.integer :canvas_term_id
18
+ t.integer :term_sis_id
19
+ t.datetime :start_date
20
+ t.datetime :end_date
21
+
22
+ t.timestamps
23
+ end
24
+
25
+ add_index :courses, :canvas_course_id, unique: true
26
+ end
27
+ end
@@ -0,0 +1,24 @@
1
+ #
2
+ # AUTO GENERATED MIGRATION
3
+ # This migration was auto generated by the CanvasSync Gem.
4
+ # You can add new columns to this table, but removing or
5
+ # re-naming ones created here may break Canvas Syncing.
6
+ #
7
+
8
+
9
+ class CreateUsers < ActiveRecord::Migration[5.1]
10
+ def change
11
+ create_table :users do |t|
12
+ t.bigint :canvas_user_id, null: false
13
+ t.string :sis_id
14
+ t.string :email
15
+ t.string :first_name
16
+ t.string :last_name
17
+ t.string :status
18
+
19
+ t.timestamps
20
+ end
21
+
22
+ add_index :users, :canvas_user_id, unique: true
23
+ end
24
+ end