canvas_sync 0.3.14 → 0.3.15

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 (30) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +5 -3
  3. data/lib/canvas_sync.rb +3 -1
  4. data/lib/canvas_sync/generators/templates/models/assignment.rb +1 -0
  5. data/lib/canvas_sync/generators/templates/models/assignment_group.rb +7 -0
  6. data/lib/canvas_sync/generators/templates/models/course.rb +1 -0
  7. data/lib/canvas_sync/generators/templates/models/create_assignment_groups.rb +24 -0
  8. data/lib/canvas_sync/generators/templates/models/create_assignments.rb +1 -1
  9. data/lib/canvas_sync/jobs/sync_assignment_groups_job.rb +28 -0
  10. data/lib/canvas_sync/processors/assignment_groups_processor.rb +24 -0
  11. data/lib/canvas_sync/processors/model_mappings.yml +38 -1
  12. data/lib/canvas_sync/version.rb +1 -1
  13. data/spec/canvas_sync/canvas_sync_spec.rb +15 -0
  14. data/spec/canvas_sync/jobs/sync_assignment_groups_job_spec.rb +17 -0
  15. data/spec/canvas_sync/models/assignment_group_spec.rb +24 -0
  16. data/spec/canvas_sync/{assignment_spec.rb → models/assignment_spec.rb} +6 -0
  17. data/spec/canvas_sync/models/course_spec.rb +6 -0
  18. data/spec/canvas_sync/{submission_spec.rb → models/submission_spec.rb} +0 -0
  19. data/spec/canvas_sync/processors/assignment_groups_processor_spec.rb +13 -0
  20. data/spec/dummy/app/models/assignment.rb +1 -0
  21. data/spec/dummy/app/models/assignment_group.rb +13 -0
  22. data/spec/dummy/app/models/course.rb +1 -0
  23. data/spec/dummy/db/migrate/{20180212204530_create_assignments.rb → 20180215214227_create_assignments.rb} +1 -1
  24. data/spec/dummy/db/migrate/20180215220605_create_assignment_groups.rb +30 -0
  25. data/spec/dummy/db/schema.rb +20 -2
  26. data/spec/dummy/log/development.log +511 -0
  27. data/spec/dummy/log/test.log +1970 -0
  28. data/spec/factories/assignment_group_factory.rb +9 -0
  29. data/spec/support/fixtures/reports/assignment_groups.csv +3 -0
  30. metadata +26 -8
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ffcf605b5474780a893dd4cb81c60d39568e5198
4
- data.tar.gz: d2e32471b37b95667680a17c4907c42ce6965bdc
3
+ metadata.gz: f691f2ffe7d6115dae15aed67684917d1b0f5716
4
+ data.tar.gz: 2892f5f534919b7cca8245d458081de23e9908be
5
5
  SHA512:
6
- metadata.gz: 36943420c9986863bc1ae0f54b6cdf50ed284115c99d5bae5ba1421ed65dfada0adc4ba9943c4e6481e5e1eacec50407c103ce82d2bbb926535093d2ba5f0d92
7
- data.tar.gz: 468ee9f16f45dd6cffb2779ea45a4f78b552c17ebb0de0cd4534711aec4c4f9f0a5ab5da38ae4f8cdf7eb812623c11e1591091319b55d2cbaafa834440429d8f
6
+ metadata.gz: a183d815dfae6ba9de78085002f22c27de7ebc68d86e17e331bd8cea89bc7dd43ef4262aaf47800b249cf84750b678b8a066f10cf929bd1d67b4eaf51bce213b
7
+ data.tar.gz: a17e849b655aeeda3d2818bdba6f1e0b12b1addff753e8082687c1d94a5a57a77781e0107196b269fdf949ba6a4a71d1d5eb106c3587b8bf0e2cac7a5005f9cf
data/README.md CHANGED
@@ -27,9 +27,11 @@ bundle exec rake db:migrate
27
27
  For a list of currently supported models, see `CanvasSync::SUPPORTED_MODELS`.
28
28
 
29
29
  Additionally, your Canvas instance must have the "Proserv Provisioning Report" enabled.
30
- - If you are syncing assignments the "Assignment Report" report must be enabled.
31
- - If you are syncing submissions the "Student Submissions"
32
- (proserv_student_submissions_csv) report must be enabled.
30
+
31
+ The following custom reports are required for the specified models:
32
+ - assignments = "Assignments Report" (proserv_assignment_export_csv)
33
+ - submissions = "Student Submissions" (proserv_student_submissions_csv)
34
+ - assignment_groups = "Assignment Group Export" (proserv_assignment_group_export_csv)
33
35
 
34
36
  ## Prerequisites
35
37
 
data/lib/canvas_sync.rb CHANGED
@@ -8,6 +8,7 @@ require "canvas_sync/jobs/report_processor_job"
8
8
  require "canvas_sync/jobs/sync_provisioning_report_job"
9
9
  require "canvas_sync/jobs/sync_assignments_job"
10
10
  require "canvas_sync/jobs/sync_submissions_job"
11
+ require "canvas_sync/jobs/sync_assignment_groups_job"
11
12
  require "canvas_sync/jobs/sync_terms_job"
12
13
  require "canvas_sync/jobs/sync_users_job"
13
14
  require "canvas_sync/jobs/sync_roles_job"
@@ -17,7 +18,7 @@ Dir[File.dirname(__FILE__) + "/canvas_sync/importers/*.rb"].each { |file| requi
17
18
  Dir[File.dirname(__FILE__) + "/canvas_sync/generators/*.rb"].each { |file| require file }
18
19
 
19
20
  module CanvasSync
20
- SUPPORTED_MODELS = %w[users courses terms enrollments sections assignments submissions roles admins xlist].freeze
21
+ SUPPORTED_MODELS = %w[users courses terms enrollments sections assignments submissions roles admins assignment_groups xlist].freeze
21
22
  SUPPORTED_LIVE_EVENTS = %w[course enrollment submission assignment user syllabus grade].freeze
22
23
 
23
24
  # Runs a standard provisioning sync job with no extra report types.
@@ -105,6 +106,7 @@ module CanvasSync
105
106
 
106
107
  jobs.push(job: CanvasSync::Jobs::SyncAssignmentsJob.to_s, options: {}) if models.include?("assignments")
107
108
  jobs.push(job: CanvasSync::Jobs::SyncSubmissionsJob.to_s, options: {}) if models.include?("submissions")
109
+ jobs.push(job: CanvasSync::Jobs::SyncAssignmentGroupsJob.to_s, options: {}) if models.include?("assignment_groups")
108
110
 
109
111
  global_options = { legacy_support: legacy_support }
110
112
  global_options[:account_id] = account_id if account_id.present?
@@ -3,5 +3,6 @@
3
3
  class Assignment < ApplicationRecord
4
4
  validates :canvas_assignment_id, uniqueness: true, presence: true
5
5
  belongs_to :context, polymorphic: true, optional: true, primary_key: :canvas_course_id
6
+ belongs_to :assignment_group, optional: true, primary_key: :canvas_assignment_group_id, foreign_key: :canvas_assignment_group_id
6
7
  has_many :submissions, primary_key: :canvas_assignment_id, foreign_key: :canvas_assignment_id
7
8
  end
@@ -0,0 +1,7 @@
1
+ <%= autogenerated_model_warning %>
2
+
3
+ class AssignmentGroup < ApplicationRecord
4
+ validates :canvas_assignment_group_id, uniqueness: true, presence: true
5
+ belongs_to :course, primary_key: :canvas_course_id, foreign_key: :canvas_course_id, optional: true
6
+ has_many :assignments, primary_key: :canvas_assignment_group_id, foreign_key: :canvas_assignment_group_id
7
+ end
@@ -7,4 +7,5 @@ class Course < ApplicationRecord
7
7
  has_many :sections, primary_key: :canvas_course_id, foreign_key: :canvas_course_id
8
8
  has_many :assignments, as: :context, primary_key: :canvas_course_id
9
9
  has_many :submissions, primary_key: :canvas_course_id, foreign_key: :canvas_course_id
10
+ has_many :assignment_groups, primary_key: :canvas_course_id, foreign_key: :canvas_course_id
10
11
  end
@@ -0,0 +1,24 @@
1
+ <%= autogenerated_migration_warning %>
2
+
3
+ class CreateAssignmentGroups < ActiveRecord::Migration[5.1]
4
+ def change
5
+ create_table :assignment_groups do |t|
6
+ t.bigint :canvas_assignment_group_id, null: false
7
+ t.bigint :canvas_course_id
8
+ t.string :name
9
+ t.text :rules
10
+ t.string :default_assignment_name
11
+ t.integer :position
12
+ t.text :assignment_weighting_scheme
13
+ t.float :group_weight
14
+ t.string :workflow_state
15
+ t.datetime :canvas_created_at
16
+ t.datetime :canvas_updated_at
17
+
18
+ t.timestamps
19
+ end
20
+
21
+ add_index :assignment_groups, :canvas_assignment_group_id, unique: true
22
+ add_index :assignment_groups, :canvas_course_id
23
+ end
24
+ end
@@ -18,7 +18,7 @@ class CreateAssignments < ActiveRecord::Migration[5.1]
18
18
  t.string :workflow_state
19
19
  t.integer :context_id
20
20
  t.string :context_type
21
- t.integer :assignment_group_id
21
+ t.integer :canvas_assignment_group_id
22
22
  t.integer :grading_scheme_id
23
23
  t.integer :grading_standard_id
24
24
 
@@ -0,0 +1,28 @@
1
+ module CanvasSync
2
+ module Jobs
3
+ class SyncAssignmentGroupsJob < ReportStarter
4
+ # Syncs AssignmentGroups
5
+ #
6
+ # Starts a report processor for the assignment_groups report
7
+ # (the proserv_assignment_group_export_csv report must be enabled)
8
+ #
9
+ # @param job_chain [Hash]
10
+ # @param options [Hash]
11
+ def perform(job_chain, _options)
12
+ report_params = if job_chain[:global_options][:term_id].present?
13
+ { enrollment_term_id: job_chain[:global_options][:term_id] }
14
+ else
15
+ {}
16
+ end
17
+
18
+ super(
19
+ job_chain,
20
+ "proserv_assignment_group_export_csv",
21
+ report_params,
22
+ CanvasSync::Processors::AssignmentGroupsProcessor.to_s,
23
+ {},
24
+ )
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,24 @@
1
+ require_relative "./report_processor"
2
+
3
+ module CanvasSync
4
+ module Processors
5
+ # Processes a assignment_groups report using the bulk importer.
6
+ #
7
+ # @param report_file_path [String]
8
+ # @param options [Hash]
9
+ class AssignmentGroupsProcessor < ReportProcessor
10
+ def self.process(report_file_path, _options)
11
+ new(report_file_path)
12
+ end
13
+
14
+ def initialize(report_file_path)
15
+ CanvasSync::Importers::BulkImporter.import(
16
+ report_file_path,
17
+ mapping[:assignment_groups][:report_columns],
18
+ AssignmentGroup,
19
+ mapping[:assignment_groups][:conflict_target].to_sym,
20
+ )
21
+ end
22
+ end
23
+ end
24
+ end
@@ -178,7 +178,7 @@ assignments:
178
178
  database_column_name: context_type
179
179
  type: string
180
180
  assignment_group_id:
181
- database_column_name: assignment_group_id
181
+ database_column_name: canvas_assignment_group_id
182
182
  type: integer
183
183
  grading_scheme_id:
184
184
  database_column_name: grading_scheme_id
@@ -214,3 +214,40 @@ submissions:
214
214
  points_possible:
215
215
  database_column_name: points_possible
216
216
  type: integer
217
+
218
+ assignment_groups:
219
+ conflict_target: id
220
+ report_columns:
221
+ id:
222
+ database_column_name: :canvas_assignment_group_id
223
+ type: integer
224
+ canvas_course_id:
225
+ database_column_name: :canvas_course_id
226
+ type: integer
227
+ name:
228
+ database_column_name: :name
229
+ type: string
230
+ rules:
231
+ database_column_name: :rules
232
+ type: string
233
+ default_assignment_name:
234
+ database_column_name: :default_assignment_name
235
+ type: string
236
+ position:
237
+ database_column_name: :position
238
+ type: integer
239
+ assignment_weighting_scheme:
240
+ database_column_name: :assignment_weighting_scheme
241
+ type: string
242
+ group_weight:
243
+ database_column_name: :group_weight
244
+ type: string
245
+ workflow_state:
246
+ database_column_name: :workflow_state
247
+ type: string
248
+ created_at:
249
+ database_column_name: canvas_created_at
250
+ type: datetime
251
+ updated_at:
252
+ database_column_name: canvas_updated_at
253
+ type: datetime
@@ -1,3 +1,3 @@
1
1
  module CanvasSync
2
- VERSION = "0.3.14".freeze
2
+ VERSION = "0.3.15".freeze
3
3
  end
@@ -136,6 +136,21 @@ RSpec.describe CanvasSync do
136
136
  )
137
137
  end
138
138
  end
139
+
140
+ context "we are syncing assignment groups" do
141
+ it "appends the SyncAssignmentGroupsJob" do
142
+ chain = CanvasSync.default_provisioning_report_chain(%w[users enrollments assignment_groups])
143
+
144
+ expect(chain).to eq(
145
+ jobs: [
146
+ { job: CanvasSync::Jobs::SyncTermsJob.to_s, options: {} },
147
+ { job: CanvasSync::Jobs::SyncProvisioningReportJob.to_s, options: { term_scope: nil, models: %w[users enrollments assignment_groups] } },
148
+ { job: CanvasSync::Jobs::SyncAssignmentGroupsJob.to_s, options: {} },
149
+ ],
150
+ global_options: { legacy_support: false },
151
+ )
152
+ end
153
+ end
139
154
  end
140
155
  end
141
156
  end
@@ -0,0 +1,17 @@
1
+ require "spec_helper"
2
+
3
+ RSpec.describe CanvasSync::Jobs::SyncAssignmentGroupsJob do
4
+ describe "#perform" do
5
+ context "a term id is in the global_options" do
6
+ it "enqueues a ReportStarter for the proserv_assignment_group_export_csv for the given term" do
7
+ expect_any_instance_of(Bearcat::Client).to receive(:start_report)
8
+ .with("self", "proserv_assignment_group_export_csv", enrollment_term_id: 1)
9
+ .and_return("id" => 1)
10
+
11
+ expect(CanvasSync::Jobs::ReportChecker).to receive(:set).and_call_original
12
+
13
+ CanvasSync::Jobs::SyncAssignmentGroupsJob.perform_now({ jobs: [], global_options: { term_id: 1 } }, {})
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe AssignmentGroup, type: :model do
4
+ let(:subject) { FactoryGirl.create(:assignment_group) }
5
+
6
+ describe 'validations' do
7
+ it { should validate_presence_of(:canvas_assignment_group_id) }
8
+ it { should validate_uniqueness_of(:canvas_assignment_group_id) }
9
+ end
10
+
11
+ describe 'associations' do
12
+ it do
13
+ should belong_to(:course)
14
+ .with_primary_key(:canvas_course_id)
15
+ .with_foreign_key(:canvas_course_id)
16
+ end
17
+
18
+ it do
19
+ should have_many(:assignments)
20
+ .with_primary_key(:canvas_assignment_group_id)
21
+ .with_foreign_key(:canvas_assignment_group_id)
22
+ end
23
+ end
24
+ end
@@ -15,6 +15,12 @@ RSpec.describe Assignment, type: :model do
15
15
  .with_foreign_key(:canvas_assignment_id)
16
16
  end
17
17
 
18
+ it do
19
+ should belong_to(:assignment_group)
20
+ .with_primary_key(:canvas_assignment_group_id)
21
+ .with_foreign_key(:canvas_assignment_group_id)
22
+ end
23
+
18
24
  describe "context" do
19
25
  let!(:other_course) { FactoryGirl.create(:course) }
20
26
  let!(:matching_course) { FactoryGirl.create(:course) }
@@ -27,6 +27,12 @@ RSpec.describe Course, type: :model do
27
27
  .with_foreign_key(:canvas_course_id)
28
28
  end
29
29
 
30
+ it do
31
+ should have_many(:assignment_groups)
32
+ .with_primary_key(:canvas_course_id)
33
+ .with_foreign_key(:canvas_course_id)
34
+ end
35
+
30
36
  it do
31
37
  should have_many(:assignments)
32
38
  .with_primary_key(:canvas_course_id)
@@ -0,0 +1,13 @@
1
+ require "spec_helper"
2
+
3
+ RSpec.describe CanvasSync::Processors::AssignmentGroupsProcessor do
4
+ let(:subject) { CanvasSync::Processors::AssignmentGroupsProcessor }
5
+
6
+ describe "#process" do
7
+ it "inserts assignment_groups" do
8
+ expect {
9
+ subject.process("spec/support/fixtures/reports/assignment_groups.csv", {})
10
+ }.to change { AssignmentGroup.count }.by(2)
11
+ end
12
+ end
13
+ end
@@ -9,5 +9,6 @@
9
9
  class Assignment < ApplicationRecord
10
10
  validates :canvas_assignment_id, uniqueness: true, presence: true
11
11
  belongs_to :context, polymorphic: true, optional: true, primary_key: :canvas_course_id
12
+ belongs_to :assignment_group, optional: true, primary_key: :canvas_assignment_group_id, foreign_key: :canvas_assignment_group_id
12
13
  has_many :submissions, primary_key: :canvas_assignment_id, foreign_key: :canvas_assignment_id
13
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 AssignmentGroup < ApplicationRecord
10
+ validates :canvas_assignment_group_id, uniqueness: true, presence: true
11
+ belongs_to :course, primary_key: :canvas_course_id, foreign_key: :canvas_course_id, optional: true
12
+ has_many :assignments, primary_key: :canvas_assignment_group_id, foreign_key: :canvas_assignment_group_id
13
+ end
@@ -13,4 +13,5 @@ class Course < ApplicationRecord
13
13
  has_many :sections, primary_key: :canvas_course_id, foreign_key: :canvas_course_id
14
14
  has_many :assignments, as: :context, primary_key: :canvas_course_id
15
15
  has_many :submissions, primary_key: :canvas_course_id, foreign_key: :canvas_course_id
16
+ has_many :assignment_groups, primary_key: :canvas_course_id, foreign_key: :canvas_course_id
16
17
  end
@@ -24,7 +24,7 @@ class CreateAssignments < ActiveRecord::Migration[5.1]
24
24
  t.string :workflow_state
25
25
  t.integer :context_id
26
26
  t.string :context_type
27
- t.integer :assignment_group_id
27
+ t.integer :canvas_assignment_group_id
28
28
  t.integer :grading_scheme_id
29
29
  t.integer :grading_standard_id
30
30
 
@@ -0,0 +1,30 @@
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 CreateAssignmentGroups < ActiveRecord::Migration[5.1]
10
+ def change
11
+ create_table :assignment_groups do |t|
12
+ t.bigint :canvas_assignment_group_id, null: false
13
+ t.bigint :canvas_course_id
14
+ t.string :name
15
+ t.text :rules
16
+ t.string :default_assignment_name
17
+ t.integer :position
18
+ t.text :assignment_weighting_scheme
19
+ t.float :group_weight
20
+ t.string :workflow_state
21
+ t.datetime :canvas_created_at
22
+ t.datetime :canvas_updated_at
23
+
24
+ t.timestamps
25
+ end
26
+
27
+ add_index :assignment_groups, :canvas_assignment_group_id, unique: true
28
+ add_index :assignment_groups, :canvas_course_id
29
+ end
30
+ end
@@ -10,7 +10,7 @@
10
10
  #
11
11
  # It's strongly recommended that you check this file into your version control system.
12
12
 
13
- ActiveRecord::Schema.define(version: 20180213235544) do
13
+ ActiveRecord::Schema.define(version: 20180215220605) do
14
14
 
15
15
  # These are extensions that must be enabled in order to support this database
16
16
  enable_extension "plpgsql"
@@ -27,6 +27,24 @@ ActiveRecord::Schema.define(version: 20180213235544) do
27
27
  t.index ["canvas_admin_id"], name: "index_admins_on_canvas_admin_id", unique: true
28
28
  end
29
29
 
30
+ create_table "assignment_groups", force: :cascade do |t|
31
+ t.bigint "canvas_assignment_group_id", null: false
32
+ t.bigint "canvas_course_id"
33
+ t.string "name"
34
+ t.text "rules"
35
+ t.string "default_assignment_name"
36
+ t.integer "position"
37
+ t.text "assignment_weighting_scheme"
38
+ t.float "group_weight"
39
+ t.string "workflow_state"
40
+ t.datetime "canvas_created_at"
41
+ t.datetime "canvas_updated_at"
42
+ t.datetime "created_at", null: false
43
+ t.datetime "updated_at", null: false
44
+ t.index ["canvas_assignment_group_id"], name: "index_assignment_groups_on_canvas_assignment_group_id", unique: true
45
+ t.index ["canvas_course_id"], name: "index_assignment_groups_on_canvas_course_id"
46
+ end
47
+
30
48
  create_table "assignments", force: :cascade do |t|
31
49
  t.bigint "canvas_assignment_id", null: false
32
50
  t.string "title"
@@ -43,7 +61,7 @@ ActiveRecord::Schema.define(version: 20180213235544) do
43
61
  t.string "workflow_state"
44
62
  t.integer "context_id"
45
63
  t.string "context_type"
46
- t.integer "assignment_group_id"
64
+ t.integer "canvas_assignment_group_id"
47
65
  t.integer "grading_scheme_id"
48
66
  t.integer "grading_standard_id"
49
67
  t.datetime "created_at", null: false