canvas_sync 0.15.1 → 0.16.5

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 (44) hide show
  1. checksums.yaml +5 -5
  2. data/db/migrate/20170915210836_create_canvas_sync_job_log.rb +12 -31
  3. data/db/migrate/20180725155729_add_job_id_to_canvas_sync_job_logs.rb +4 -13
  4. data/db/migrate/20190916154829_add_fork_count_to_canvas_sync_job_logs.rb +3 -11
  5. data/lib/canvas_sync.rb +11 -27
  6. data/lib/canvas_sync/concerns/api_syncable.rb +27 -0
  7. data/lib/canvas_sync/concerns/legacy_columns.rb +5 -4
  8. data/lib/canvas_sync/generators/templates/migrations/create_submissions.rb +1 -0
  9. data/lib/canvas_sync/generators/templates/models/account.rb +3 -0
  10. data/lib/canvas_sync/generators/templates/models/submission.rb +1 -0
  11. data/lib/canvas_sync/importers/bulk_importer.rb +7 -4
  12. data/lib/canvas_sync/job.rb +8 -2
  13. data/lib/canvas_sync/job_chain.rb +46 -1
  14. data/lib/canvas_sync/jobs/fork_gather.rb +27 -12
  15. data/lib/canvas_sync/jobs/report_starter.rb +1 -1
  16. data/lib/canvas_sync/jobs/sync_provisioning_report_job.rb +5 -5
  17. data/lib/canvas_sync/jobs/sync_simple_table_job.rb +4 -4
  18. data/lib/canvas_sync/misc_helper.rb +15 -0
  19. data/lib/canvas_sync/processors/assignment_groups_processor.rb +3 -2
  20. data/lib/canvas_sync/processors/assignments_processor.rb +3 -2
  21. data/lib/canvas_sync/processors/context_module_items_processor.rb +3 -2
  22. data/lib/canvas_sync/processors/context_modules_processor.rb +3 -2
  23. data/lib/canvas_sync/processors/model_mappings.yml +3 -0
  24. data/lib/canvas_sync/processors/normal_processor.rb +2 -1
  25. data/lib/canvas_sync/processors/provisioning_report_processor.rb +10 -2
  26. data/lib/canvas_sync/processors/submissions_processor.rb +3 -2
  27. data/lib/canvas_sync/version.rb +1 -1
  28. data/spec/canvas_sync/jobs/fork_gather_spec.rb +9 -9
  29. data/spec/canvas_sync/jobs/sync_provisioning_report_job_spec.rb +2 -2
  30. data/spec/canvas_sync/jobs/sync_simple_table_job_spec.rb +1 -1
  31. data/spec/dummy/app/models/account.rb +3 -0
  32. data/spec/dummy/app/models/pseudonym.rb +14 -0
  33. data/spec/dummy/app/models/submission.rb +1 -0
  34. data/spec/dummy/app/models/user.rb +1 -0
  35. data/spec/dummy/db/migrate/20190702203627_create_submissions.rb +1 -0
  36. data/spec/dummy/db/migrate/20201016181346_create_pseudonyms.rb +24 -0
  37. data/spec/dummy/db/schema.rb +17 -4
  38. data/spec/dummy/db/test.sqlite3 +0 -0
  39. data/spec/dummy/log/development.log +1248 -0
  40. data/spec/dummy/log/test.log +43258 -0
  41. data/spec/support/fixtures/reports/provisioning_csv_unzipped/courses.csv +3 -0
  42. data/spec/support/fixtures/reports/provisioning_csv_unzipped/users.csv +4 -0
  43. data/spec/support/fixtures/reports/submissions.csv +3 -3
  44. metadata +22 -8
@@ -9,15 +9,15 @@ module CanvasSync
9
9
  # @param options [Hash]
10
10
  def perform(job_chain, options)
11
11
  if options[:term_scope]
12
- sub_reports = CanvasSync.fork(@job_log, job_chain, keys: [:canvas_term_id]) do |job_chain|
12
+ sub_reports = CanvasSync.fork(@job_log, job_chain, keys: [:canvas_term_id]) do |fork_template|
13
13
  Term.send(options[:term_scope]).find_each.map do |term|
14
+ fork = fork_template.duplicate
14
15
  # Deep copy the job_chain so each report gets the correct term id passed into
15
16
  # its options with no side effects
16
17
  term_id = get_term_id(term)
17
- duped_job_chain = Marshal.load(Marshal.dump(job_chain))
18
- duped_job_chain[:global_options][:canvas_term_id] = term_id
18
+ fork[:global_options][:canvas_term_id] = term_id
19
19
  {
20
- job_chain: duped_job_chain,
20
+ job_chain: fork.serialize,
21
21
  params: report_params(options, term_id),
22
22
  options: options,
23
23
  }
@@ -0,0 +1,15 @@
1
+ require 'active_record'
2
+
3
+ module CanvasSync
4
+ module MiscHelper
5
+ MigrationClass = Rails.version < '5.0' ? ActiveRecord::Migration : ActiveRecord::Migration[4.2]
6
+
7
+ def self.to_boolean(v)
8
+ if Rails.version < '5.0'
9
+ ActiveRecord::Type::Boolean.new.type_cast_from_user(v)
10
+ else
11
+ ActiveRecord::Type::Boolean.new.deserialize(v)
12
+ end
13
+ end
14
+ end
15
+ end
@@ -8,15 +8,16 @@ module CanvasSync
8
8
  # @param options [Hash]
9
9
  class AssignmentGroupsProcessor < ReportProcessor
10
10
  def self.process(report_file_path, _options, report_id)
11
- new(report_file_path)
11
+ new(report_file_path, _options)
12
12
  end
13
13
 
14
- def initialize(report_file_path)
14
+ def initialize(report_file_path, options)
15
15
  CanvasSync::Importers::BulkImporter.import(
16
16
  report_file_path,
17
17
  mapping[:assignment_groups][:report_columns],
18
18
  AssignmentGroup,
19
19
  mapping[:assignment_groups][:conflict_target].to_sym,
20
+ import_args: options
20
21
  )
21
22
  end
22
23
  end
@@ -8,15 +8,16 @@ module CanvasSync
8
8
  # @param options [Hash]
9
9
  class AssignmentsProcessor < ReportProcessor
10
10
  def self.process(report_file_path, _options, report_id)
11
- new(report_file_path)
11
+ new(report_file_path, _options)
12
12
  end
13
13
 
14
- def initialize(report_file_path)
14
+ def initialize(report_file_path, options)
15
15
  CanvasSync::Importers::BulkImporter.import(
16
16
  report_file_path,
17
17
  mapping[:assignments][:report_columns],
18
18
  Assignment,
19
19
  mapping[:assignments][:conflict_target].to_sym,
20
+ import_args: options
20
21
  )
21
22
  end
22
23
  end
@@ -8,15 +8,16 @@ module CanvasSync
8
8
  # @param options [Hash]
9
9
  class ContextModuleItemsProcessor < ReportProcessor
10
10
  def self.process(report_file_path, _options, report_id)
11
- new(report_file_path)
11
+ new(report_file_path, _options)
12
12
  end
13
13
 
14
- def initialize(report_file_path)
14
+ def initialize(report_file_path, options)
15
15
  CanvasSync::Importers::BulkImporter.import(
16
16
  report_file_path,
17
17
  mapping[:context_module_items][:report_columns],
18
18
  ContextModuleItem,
19
19
  mapping[:context_module_items][:conflict_target].to_sym,
20
+ import_args: options
20
21
  )
21
22
  end
22
23
  end
@@ -8,15 +8,16 @@ module CanvasSync
8
8
  # @param options [Hash]
9
9
  class ContextModulesProcessor < ReportProcessor
10
10
  def self.process(report_file_path, _options, report_id)
11
- new(report_file_path)
11
+ new(report_file_path, _options)
12
12
  end
13
13
 
14
- def initialize(report_file_path)
14
+ def initialize(report_file_path, options)
15
15
  CanvasSync::Importers::BulkImporter.import(
16
16
  report_file_path,
17
17
  mapping[:context_modules][:report_columns],
18
18
  ContextModule,
19
19
  mapping[:context_modules][:conflict_target].to_sym,
20
+ import_args: options
20
21
  )
21
22
  end
22
23
  end
@@ -249,6 +249,9 @@ submissions:
249
249
  submission_date:
250
250
  database_column_name: submitted_at
251
251
  type: datetime
252
+ due_at:
253
+ database_column_name: due_at
254
+ type: datetime
252
255
  graded_date:
253
256
  database_column_name: graded_at
254
257
  type: datetime
@@ -18,7 +18,8 @@ module CanvasSync
18
18
  report_file_path,
19
19
  mapping[options[:mapping].to_sym][:report_columns],
20
20
  options[:klass].constantize,
21
- conflict_target ? conflict_target.to_sym : conflict_target
21
+ conflict_target ? conflict_target.to_sym : conflict_target,
22
+ import_args: options
22
23
  )
23
24
  end
24
25
  end
@@ -21,7 +21,6 @@ module CanvasSync
21
21
 
22
22
  def initialize(report_file_path, options) # rubocop:disable Metrics/AbcSize
23
23
  @options = options
24
-
25
24
  if options[:models].length == 1
26
25
  run_import(options[:models][0], report_file_path)
27
26
  else
@@ -75,6 +74,7 @@ module CanvasSync
75
74
  mapping[:users][:report_columns],
76
75
  User,
77
76
  mapping[:users][:conflict_target].to_sym,
77
+ import_args: @options
78
78
  )
79
79
  end
80
80
 
@@ -84,6 +84,7 @@ module CanvasSync
84
84
  mapping[:pseudonyms][:report_columns],
85
85
  Pseudonym,
86
86
  mapping[:pseudonyms][:conflict_target].to_sym,
87
+ import_args: @options
87
88
  )
88
89
  end
89
90
 
@@ -92,7 +93,8 @@ module CanvasSync
92
93
  report_file_path,
93
94
  mapping[:accounts][:report_columns],
94
95
  Account,
95
- mapping[:accounts][:conflict_target].to_sym
96
+ mapping[:accounts][:conflict_target].to_sym,
97
+ import_args: @options
96
98
  )
97
99
  end
98
100
 
@@ -102,6 +104,7 @@ module CanvasSync
102
104
  mapping[:courses][:report_columns],
103
105
  Course,
104
106
  mapping[:courses][:conflict_target].to_sym,
107
+ import_args: @options
105
108
  )
106
109
  end
107
110
 
@@ -111,6 +114,7 @@ module CanvasSync
111
114
  mapping[:enrollments][:report_columns],
112
115
  Enrollment,
113
116
  mapping[:enrollments][:conflict_target].to_sym,
117
+ import_args: @options
114
118
  )
115
119
  end
116
120
 
@@ -120,6 +124,7 @@ module CanvasSync
120
124
  mapping[:sections][:report_columns],
121
125
  Section,
122
126
  mapping[:sections][:conflict_target].to_sym,
127
+ import_args: @options
123
128
  )
124
129
  end
125
130
 
@@ -129,6 +134,7 @@ module CanvasSync
129
134
  mapping[:xlist][:report_columns],
130
135
  Section,
131
136
  mapping[:xlist][:conflict_target].to_sym,
137
+ import_args: @options
132
138
  )
133
139
  end
134
140
 
@@ -138,6 +144,7 @@ module CanvasSync
138
144
  mapping[:groups][:report_columns],
139
145
  Group,
140
146
  mapping[:groups][:conflict_target].to_sym,
147
+ import_args: @options
141
148
  )
142
149
  end
143
150
 
@@ -148,6 +155,7 @@ module CanvasSync
148
155
  mapping[:group_memberships][:report_columns],
149
156
  GroupMembership,
150
157
  mapping[:group_memberships][:conflict_target].to_sym,
158
+ import_args: @options
151
159
  )
152
160
  end
153
161
  end
@@ -8,15 +8,16 @@ module CanvasSync
8
8
  # @param options [Hash]
9
9
  class SubmissionsProcessor < ReportProcessor
10
10
  def self.process(report_file_path, _options, report_id)
11
- new(report_file_path)
11
+ new(report_file_path, _options)
12
12
  end
13
13
 
14
- def initialize(report_file_path)
14
+ def initialize(report_file_path, options)
15
15
  CanvasSync::Importers::BulkImporter.import(
16
16
  report_file_path,
17
17
  mapping[:submissions][:report_columns],
18
18
  Submission,
19
19
  mapping[:submissions][:conflict_target].to_sym,
20
+ import_args: options
20
21
  )
21
22
  end
22
23
  end
@@ -1,3 +1,3 @@
1
1
  module CanvasSync
2
- VERSION = "0.15.1".freeze
2
+ VERSION = "0.16.5".freeze
3
3
  end
@@ -3,7 +3,7 @@ require 'spec_helper'
3
3
  RSpec.describe CanvasSync::Jobs::ForkGather do
4
4
  describe '#perform' do
5
5
  let!(:job_log) { CanvasSync::JobLog.create!(job_id: 'BLAH', fork_count: 3) }
6
- let(:job_chain) { {jobs: [], global_options: { fork_path: ['BLAH'] }} }
6
+ let(:job_chain) { {jobs: [], fork_state: { forking_path: ['BLAH'], pre_fork_globals: [{}] }} }
7
7
 
8
8
  it 'decrements fork_count' do
9
9
  CanvasSync::Jobs::ForkGather.perform_now(job_chain, {})
@@ -21,16 +21,16 @@ RSpec.describe CanvasSync::Jobs::ForkGather do
21
21
  CanvasSync::Jobs::ForkGather.perform_now(job_chain, {})
22
22
  end
23
23
 
24
- it 'continues if no fork_path is specified' do
25
- job_chain[:global_options].delete(:fork_path)
24
+ it 'continues if no forking_path is specified' do
25
+ job_chain[:fork_state].delete(:forking_path)
26
26
  expect(CanvasSync).to receive(:invoke_next)
27
27
  CanvasSync::Jobs::ForkGather.perform_now(job_chain, {})
28
28
  end
29
29
 
30
- it 'pops the most-recent fork_path enrty' do
30
+ it 'pops the most-recent forking_path enrty' do
31
31
  job_log.update!(fork_count: 1)
32
32
  expect(CanvasSync).to receive(:invoke_next) do |*args|
33
- expect(args[0][:global_options][:fork_path]).to eq []
33
+ expect(args[0][:fork_state][:forking_path]).to eq []
34
34
  end
35
35
  CanvasSync::Jobs::ForkGather.perform_now(job_chain, {})
36
36
  end
@@ -47,8 +47,8 @@ RSpec.describe CanvasSync::Jobs::ForkGather do
47
47
  { job: 'CanvasSync::Jobs::ForkGather' },
48
48
  { job: 'CanvasSync::Jobs::ReportChecker' },
49
49
  ],
50
- global_options: {
51
- fork_path: ['BLAH'],
50
+ fork_state: {
51
+ forking_path: ['BLAH'],
52
52
  }
53
53
  }
54
54
  }
@@ -65,8 +65,8 @@ RSpec.describe CanvasSync::Jobs::ForkGather do
65
65
  expect(CanvasSync::Jobs::ForkGather.handle_branch_error(error, job_chain: job_chain)).to be nil
66
66
  end
67
67
 
68
- it 'does nothing if no fork_path is present' do
69
- job_chain[:global_options][:fork_path] = []
68
+ it 'does nothing if no forking_path is present' do
69
+ job_chain[:fork_state][:forking_path] = []
70
70
  expect(CanvasSync::Jobs::ForkGather.handle_branch_error(error, job_chain: job_chain)).to be nil
71
71
  end
72
72
  end
@@ -16,7 +16,7 @@ RSpec.describe CanvasSync::Jobs::SyncProvisioningReportJob do
16
16
 
17
17
  expect(CanvasSync::Jobs::ReportStarter).to receive(:perform_later)
18
18
  .with(
19
- expected_job_chain,
19
+ hash_including(expected_job_chain),
20
20
  'proservices_provisioning_csv',
21
21
  {
22
22
  parameters: {
@@ -36,7 +36,7 @@ RSpec.describe CanvasSync::Jobs::SyncProvisioningReportJob do
36
36
 
37
37
  expect(CanvasSync::Jobs::ReportStarter).to receive(:perform_later)
38
38
  .with(
39
- expected_job_chain_2,
39
+ hash_including(expected_job_chain_2),
40
40
  'proservices_provisioning_csv',
41
41
  {
42
42
  parameters: {
@@ -15,7 +15,7 @@ RSpec.describe CanvasSync::Jobs::SyncSimpleTableJob do
15
15
 
16
16
  expect(CanvasSync::Jobs::ReportStarter).to receive(:perform_later)
17
17
  .with(
18
- expected_job_chain,
18
+ hash_including(expected_job_chain),
19
19
  'proservices_provisioning_csv',
20
20
  {
21
21
  "parameters[include_deleted]" => true,
@@ -20,6 +20,9 @@ class Account < ApplicationRecord
20
20
  primary_key: :canvas_id, foreign_key: :canvas_parent_account_id
21
21
  has_many :groups, primary_key: :canvas_id, foreign_key: :canvas_account_id
22
22
 
23
+ scope :active, -> { where.not(workflow_state: 'deleted') }
24
+ # scope :should_canvas_sync, -> { active } # Optional - uses .active if not given
25
+
23
26
  api_syncable({
24
27
  name: :name,
25
28
  workflow_state: :workflow_state,
@@ -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 Pseudonym < ApplicationRecord
10
+ include CanvasSync::Record
11
+
12
+ validates :canvas_id, uniqueness: true, presence: true
13
+ belongs_to :user, primary_key: :canvas_id, foreign_key: :canvas_user_id
14
+ end
@@ -20,6 +20,7 @@ class Submission < ApplicationRecord
20
20
  canvas_user_id: :user_id,
21
21
  submitted_at: :submitted_at,
22
22
  graded_at: :graded_at,
23
+ cached_due_date: :due_at,
23
24
  score: :score,
24
25
  excused: :excused,
25
26
  workflow_state: :workflow_state,
@@ -11,6 +11,7 @@ class User < ApplicationRecord
11
11
  include CanvasSync::Concerns::ApiSyncable
12
12
 
13
13
  validates :canvas_id, uniqueness: true, presence: true
14
+ has_many :pseudonyms, primary_key: :canvas_id, foreign_key: :canvas_user_id
14
15
  has_many :enrollments, primary_key: :canvas_id, foreign_key: :canvas_user_id
15
16
  has_many :admins, primary_key: :canvas_id, foreign_key: :canvas_user_id
16
17
  has_many :admin_roles, through: :admins, source: :role
@@ -14,6 +14,7 @@ class CreateSubmissions < ActiveRecord::Migration[5.1]
14
14
  t.bigint :canvas_assignment_id
15
15
  t.bigint :canvas_user_id
16
16
  t.datetime :submitted_at
17
+ t.datetime :due_at
17
18
  t.datetime :graded_at
18
19
  t.float :score
19
20
  t.float :points_possible
@@ -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 CreatePseudonyms < ActiveRecord::Migration[5.1]
10
+ def change
11
+ create_table :pseudonyms do |t|
12
+ t.bigint :canvas_id, null: false
13
+ t.bigint :canvas_user_id
14
+ t.string :sis_id
15
+ t.string :unique_id
16
+ t.string :workflow_state
17
+
18
+ t.timestamps
19
+ end
20
+
21
+ add_index :pseudonyms, :canvas_id, unique: true
22
+ add_index :pseudonyms, :canvas_user_id
23
+ end
24
+ 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: 2020_04_16_214248) do
13
+ ActiveRecord::Schema.define(version: 2020_10_16_181346) do
14
14
 
15
15
  # These are extensions that must be enabled in order to support this database
16
16
  enable_extension "plpgsql"
@@ -83,7 +83,7 @@ ActiveRecord::Schema.define(version: 2020_04_16_214248) do
83
83
  t.index ["canvas_id"], name: "index_assignments_on_canvas_id", unique: true
84
84
  end
85
85
 
86
- create_table "canvas_sync_job_logs", force: :cascade do |t|
86
+ create_table "canvas_sync_job_logs", id: :serial, force: :cascade do |t|
87
87
  t.datetime "started_at"
88
88
  t.datetime "completed_at"
89
89
  t.string "exception"
@@ -92,8 +92,8 @@ ActiveRecord::Schema.define(version: 2020_04_16_214248) do
92
92
  t.string "status"
93
93
  t.text "metadata"
94
94
  t.text "job_arguments"
95
- t.datetime "created_at", null: false
96
- t.datetime "updated_at", null: false
95
+ t.datetime "created_at"
96
+ t.datetime "updated_at"
97
97
  t.string "job_id"
98
98
  t.integer "fork_count"
99
99
  t.index ["job_id"], name: "index_canvas_sync_job_logs_on_job_id"
@@ -191,6 +191,18 @@ ActiveRecord::Schema.define(version: 2020_04_16_214248) do
191
191
  t.index ["canvas_id"], name: "index_groups_on_canvas_id", unique: true
192
192
  end
193
193
 
194
+ create_table "pseudonyms", force: :cascade do |t|
195
+ t.bigint "canvas_id", null: false
196
+ t.bigint "canvas_user_id"
197
+ t.string "sis_id"
198
+ t.string "unique_id"
199
+ t.string "workflow_state"
200
+ t.datetime "created_at", null: false
201
+ t.datetime "updated_at", null: false
202
+ t.index ["canvas_id"], name: "index_pseudonyms_on_canvas_id", unique: true
203
+ t.index ["canvas_user_id"], name: "index_pseudonyms_on_canvas_user_id"
204
+ end
205
+
194
206
  create_table "roles", force: :cascade do |t|
195
207
  t.integer "canvas_id", null: false
196
208
  t.string "label"
@@ -225,6 +237,7 @@ ActiveRecord::Schema.define(version: 2020_04_16_214248) do
225
237
  t.bigint "canvas_assignment_id"
226
238
  t.bigint "canvas_user_id"
227
239
  t.datetime "submitted_at"
240
+ t.datetime "due_at"
228
241
  t.datetime "graded_at"
229
242
  t.float "score"
230
243
  t.float "points_possible"