canvas_sync 0.12.0 → 0.16.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/lib/canvas_sync.rb +85 -30
- data/lib/canvas_sync/api_syncable.rb +4 -162
- data/lib/canvas_sync/class_callback_executor.rb +35 -0
- data/lib/canvas_sync/concerns/account/ancestry.rb +60 -0
- data/lib/canvas_sync/concerns/api_syncable.rb +189 -0
- data/lib/canvas_sync/concerns/legacy_columns.rb +34 -0
- data/lib/canvas_sync/generators/templates/migrations/create_group_memberships.rb +18 -0
- data/lib/canvas_sync/generators/templates/migrations/create_groups.rb +23 -0
- data/lib/canvas_sync/generators/templates/migrations/create_pseudonyms.rb +18 -0
- data/lib/canvas_sync/generators/templates/migrations/create_submissions.rb +1 -0
- data/lib/canvas_sync/generators/templates/models/account.rb +11 -1
- data/lib/canvas_sync/generators/templates/models/admin.rb +2 -1
- data/lib/canvas_sync/generators/templates/models/assignment.rb +2 -1
- data/lib/canvas_sync/generators/templates/models/assignment_group.rb +2 -1
- data/lib/canvas_sync/generators/templates/models/context_module.rb +2 -1
- data/lib/canvas_sync/generators/templates/models/context_module_item.rb +2 -1
- data/lib/canvas_sync/generators/templates/models/course.rb +4 -2
- data/lib/canvas_sync/generators/templates/models/enrollment.rb +2 -1
- data/lib/canvas_sync/generators/templates/models/group.rb +19 -0
- data/lib/canvas_sync/generators/templates/models/group_membership.rb +17 -0
- data/lib/canvas_sync/generators/templates/models/pseudonym.rb +8 -0
- data/lib/canvas_sync/generators/templates/models/role.rb +2 -1
- data/lib/canvas_sync/generators/templates/models/section.rb +2 -1
- data/lib/canvas_sync/generators/templates/models/submission.rb +3 -1
- data/lib/canvas_sync/generators/templates/models/term.rb +2 -1
- data/lib/canvas_sync/generators/templates/models/user.rb +4 -1
- data/lib/canvas_sync/importers/bulk_importer.rb +7 -1
- data/lib/canvas_sync/importers/legacy_importer.rb +4 -2
- data/lib/canvas_sync/job.rb +3 -1
- data/lib/canvas_sync/job_chain.rb +57 -0
- data/lib/canvas_sync/jobs/{sync_users_job.rb → sync_accounts_job.rb} +11 -6
- data/lib/canvas_sync/jobs/sync_provisioning_report_job.rb +2 -0
- data/lib/canvas_sync/processors/model_mappings.yml +81 -0
- data/lib/canvas_sync/processors/provisioning_report_processor.rb +28 -0
- data/lib/canvas_sync/record.rb +9 -0
- data/lib/canvas_sync/version.rb +1 -1
- data/spec/canvas_sync/canvas_sync_spec.rb +19 -16
- data/spec/canvas_sync/models/accounts_spec.rb +3 -0
- data/spec/canvas_sync/models/course_spec.rb +4 -0
- data/spec/canvas_sync/models/group_membership_spec.rb +26 -0
- data/spec/canvas_sync/models/group_spec.rb +26 -0
- data/spec/canvas_sync/models/user_spec.rb +2 -0
- data/spec/canvas_sync/processors/provisioning_report_processor_spec.rb +20 -0
- data/spec/dummy/app/models/account.rb +8 -1
- data/spec/dummy/app/models/admin.rb +2 -1
- data/spec/dummy/app/models/assignment.rb +2 -1
- data/spec/dummy/app/models/assignment_group.rb +2 -1
- data/spec/dummy/app/models/context_module.rb +2 -1
- data/spec/dummy/app/models/context_module_item.rb +2 -1
- data/spec/dummy/app/models/course.rb +4 -2
- data/spec/dummy/app/models/enrollment.rb +2 -1
- data/spec/dummy/app/models/group.rb +25 -0
- data/spec/dummy/app/models/group_membership.rb +23 -0
- data/spec/dummy/app/models/role.rb +2 -1
- data/spec/dummy/app/models/section.rb +2 -1
- data/spec/dummy/app/models/submission.rb +2 -1
- data/spec/dummy/app/models/term.rb +2 -1
- data/spec/dummy/app/models/user.rb +3 -1
- data/spec/dummy/config/application.rb +12 -1
- data/spec/dummy/config/database.yml +11 -11
- data/spec/dummy/config/environments/development.rb +3 -3
- data/spec/dummy/config/initializers/assets.rb +1 -1
- data/spec/dummy/db/migrate/20190702203627_create_submissions.rb +1 -0
- data/spec/dummy/db/migrate/20200415171620_create_groups.rb +29 -0
- data/spec/dummy/db/migrate/20200416214248_create_group_memberships.rb +24 -0
- data/spec/dummy/db/schema.rb +31 -1
- data/spec/factories/group_factory.rb +8 -0
- data/spec/factories/group_membership_factory.rb +6 -0
- data/spec/support/fixtures/reports/group_memberships.csv +3 -0
- data/spec/support/fixtures/reports/groups.csv +3 -0
- data/spec/support/fixtures/reports/submissions.csv +3 -3
- metadata +36 -6
- data/spec/canvas_sync/jobs/sync_users_job_spec.rb +0 -15
@@ -1,7 +1,8 @@
|
|
1
1
|
# <%= autogenerated_model_warning %>
|
2
2
|
|
3
3
|
class Role < ApplicationRecord
|
4
|
-
include CanvasSync::
|
4
|
+
include CanvasSync::Record
|
5
|
+
include CanvasSync::Concerns::ApiSyncable
|
5
6
|
|
6
7
|
validates :canvas_id, uniqueness: true, presence: true
|
7
8
|
has_many :admins, foreign_key: :canvas_role_id, primary_key: :canvas_id
|
@@ -1,7 +1,8 @@
|
|
1
1
|
# <%= autogenerated_model_warning %>
|
2
2
|
|
3
3
|
class Section < ApplicationRecord
|
4
|
-
include CanvasSync::
|
4
|
+
include CanvasSync::Record
|
5
|
+
include CanvasSync::Concerns::ApiSyncable
|
5
6
|
|
6
7
|
validates :canvas_id, uniqueness: true, presence: true
|
7
8
|
belongs_to :course, primary_key: :canvas_id, foreign_key: :canvas_course_id, optional: true
|
@@ -1,7 +1,8 @@
|
|
1
1
|
# <%= autogenerated_model_warning %>
|
2
2
|
|
3
3
|
class Submission < ApplicationRecord
|
4
|
-
include CanvasSync::
|
4
|
+
include CanvasSync::Record
|
5
|
+
include CanvasSync::Concerns::ApiSyncable
|
5
6
|
|
6
7
|
validates :canvas_id, uniqueness: true, presence: true
|
7
8
|
belongs_to :assignment, primary_key: :canvas_id, foreign_key: :canvas_assignment_id, optional: true
|
@@ -13,6 +14,7 @@ class Submission < ApplicationRecord
|
|
13
14
|
canvas_user_id: :user_id,
|
14
15
|
submitted_at: :submitted_at,
|
15
16
|
graded_at: :graded_at,
|
17
|
+
cached_due_date: :due_at,
|
16
18
|
score: :score,
|
17
19
|
excused: :excused,
|
18
20
|
workflow_state: :workflow_state,
|
@@ -1,7 +1,8 @@
|
|
1
1
|
# <%= autogenerated_model_warning %>
|
2
2
|
|
3
3
|
class Term < ApplicationRecord
|
4
|
-
include CanvasSync::
|
4
|
+
include CanvasSync::Record
|
5
|
+
include CanvasSync::Concerns::ApiSyncable
|
5
6
|
|
6
7
|
validates :canvas_id, uniqueness: true, presence: true
|
7
8
|
has_many :courses, foreign_key: :canvas_term_id, primary_key: :canvas_id
|
@@ -1,13 +1,16 @@
|
|
1
1
|
# <%= autogenerated_model_warning %>
|
2
2
|
|
3
3
|
class User < ApplicationRecord
|
4
|
-
include CanvasSync::
|
4
|
+
include CanvasSync::Record
|
5
|
+
include CanvasSync::Concerns::ApiSyncable
|
5
6
|
|
6
7
|
validates :canvas_id, uniqueness: true, presence: true
|
8
|
+
has_many :pseudonyms, primary_key: :canvas_id, foreign_key: :canvas_user_id
|
7
9
|
has_many :enrollments, primary_key: :canvas_id, foreign_key: :canvas_user_id
|
8
10
|
has_many :admins, primary_key: :canvas_id, foreign_key: :canvas_user_id
|
9
11
|
has_many :admin_roles, through: :admins, source: :role
|
10
12
|
has_many :submissions, primary_key: :canvas_id, foreign_key: :canvas_user_id
|
13
|
+
has_many :group_memberships, primary_key: :canvas_id, foreign_key: :canvas_user_id
|
11
14
|
|
12
15
|
api_syncable({
|
13
16
|
sis_id: :sis_user_id,
|
@@ -17,7 +17,13 @@ module CanvasSync
|
|
17
17
|
# Note: passing the key [:on_duplicate_key_ignore] will override the default behavior of [:on_duplicate_key_update]
|
18
18
|
# @yieldparam [Array] row if a block is passed in it will yield the current row from the CSV.
|
19
19
|
# This can be used if you need to filter or massage the data in any way.
|
20
|
-
def self.import(report_file_path, mapping, klass, conflict_target, import_args: {}) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/LineLength
|
20
|
+
def self.import(report_file_path, mapping, klass, conflict_target, import_args: {}, &blk) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/LineLength
|
21
|
+
ClassCallbackExecutor.run_if_defined(klass, :sync_import) do
|
22
|
+
perform_in_batches(report_file_path, mapping, klass, conflict_target, import_args: import_args, &blk)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.perform_in_batches(report_file_path, mapping, klass, conflict_target, import_args: {})
|
21
27
|
csv_column_names = mapping.keys
|
22
28
|
database_column_names = mapping.values.map { |value| value[:database_column_name] }
|
23
29
|
rows = []
|
@@ -8,8 +8,10 @@ module CanvasSync
|
|
8
8
|
# @param report_file_path [String]
|
9
9
|
# @param klass [Object]
|
10
10
|
def self.import(report_file_path, klass, account_id, options)
|
11
|
-
|
12
|
-
|
11
|
+
ClassCallbackExecutor.run_if_defined(klass, :sync_import) do
|
12
|
+
CSV.foreach(report_file_path, headers: true, header_converters: :symbol) do |row|
|
13
|
+
klass.create_or_update_from_csv(row, account_id, options)
|
14
|
+
end
|
13
15
|
end
|
14
16
|
end
|
15
17
|
end
|
data/lib/canvas_sync/job.rb
CHANGED
@@ -61,7 +61,9 @@ module CanvasSync
|
|
61
61
|
if model.respond_to? :create_or_update
|
62
62
|
model.create_or_update(params)
|
63
63
|
elsif model.method_defined? :update_from_api_params!
|
64
|
-
model.find_or_initialize_by(canvas_id: params['id'])
|
64
|
+
instance = model.find_or_initialize_by(canvas_id: params['id'])
|
65
|
+
instance.update_from_api_params!(params)
|
66
|
+
instance
|
65
67
|
else
|
66
68
|
raise "Could not create/update #{model.name}. It must have a create_or_update(params) ClassMethod or implement ApiSyncable."
|
67
69
|
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module CanvasSync
|
2
|
+
class JobChain
|
3
|
+
attr_reader :chain_data
|
4
|
+
|
5
|
+
delegate_missing_to :chain_data
|
6
|
+
|
7
|
+
VALID_PLACEMENT_PARAMETERS = %i[before after].freeze
|
8
|
+
|
9
|
+
def initialize(chain_data)
|
10
|
+
@chain_data = chain_data
|
11
|
+
end
|
12
|
+
|
13
|
+
def jobs
|
14
|
+
chain_data[:jobs]
|
15
|
+
end
|
16
|
+
|
17
|
+
def global_options
|
18
|
+
chain_data[:global_options]
|
19
|
+
end
|
20
|
+
|
21
|
+
def merge_options(job, options)
|
22
|
+
jobs.each do |j|
|
23
|
+
j[:options].deep_merge!(options) if job_matches_pattern(j, job)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def insert(new_job, **kwargs)
|
28
|
+
invalid_params = kwargs.keys - VALID_PLACEMENT_PARAMETERS
|
29
|
+
raise "Invalid placement parameters: #{invalid_params.map(&:to_s).join(', ')}" if invalid_params.present?
|
30
|
+
raise "Exactly one placement parameter may be provided" if kwargs.values.compact!.length > 1
|
31
|
+
|
32
|
+
if !kwargs.present?
|
33
|
+
jobs << new_job
|
34
|
+
else
|
35
|
+
placement = kwargs.keys[0]
|
36
|
+
relative_to = kwargs.values[0]
|
37
|
+
|
38
|
+
index = jobs.index { |job| job_matches_pattern(job, relative_to) }
|
39
|
+
raise "Could not find a \"#{relative_to}\" job in the chain" if index.nil?
|
40
|
+
|
41
|
+
index += 1 if placement == :after
|
42
|
+
new_job[:job] = new_job[:job].to_s
|
43
|
+
jobs.insert(index, new_job)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def process!(extra_options: {})
|
48
|
+
CanvasSync::invoke_next(self, extra_options: extra_options)
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def job_matches_pattern(job_entry, pattern)
|
54
|
+
job_entry[:job].to_s == pattern.to_s
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -1,24 +1,29 @@
|
|
1
1
|
module CanvasSync
|
2
2
|
module Jobs
|
3
|
-
class
|
4
|
-
# Starts a provisioning report for just
|
3
|
+
class SyncAccountsJob < ReportStarter
|
4
|
+
# Starts a provisioning report for just accounts.
|
5
5
|
#
|
6
|
-
# Provisioning reports do not scope
|
6
|
+
# Provisioning reports do not scope accounts by term, so when we are
|
7
7
|
# running provisioning by term we sync users first so we don't duplicate
|
8
|
-
# the work of syncing all
|
8
|
+
# the work of syncing all accounts for each term.
|
9
9
|
#
|
10
10
|
# @param job_chain [Hash]
|
11
11
|
# @param options [Hash]
|
12
12
|
def perform(job_chain, options)
|
13
|
+
unless options[:root_account] == false
|
14
|
+
acc_params = CanvasSync.get_canvas_sync_client(job_chain[:global_options]).account("self")
|
15
|
+
update_or_create_model(Account, acc_params)
|
16
|
+
end
|
17
|
+
|
13
18
|
super(
|
14
19
|
job_chain,
|
15
20
|
"proservices_provisioning_csv",
|
16
21
|
merge_report_params(job_chain, options, {
|
17
|
-
|
22
|
+
accounts: true,
|
18
23
|
include_deleted: true,
|
19
24
|
}, term_scope: false),
|
20
25
|
CanvasSync::Processors::ProvisioningReportProcessor.to_s,
|
21
|
-
{ models: ["
|
26
|
+
{ models: ["accounts"] },
|
22
27
|
)
|
23
28
|
end
|
24
29
|
end
|
@@ -29,6 +29,25 @@ users:
|
|
29
29
|
database_column_name: login_id
|
30
30
|
type: string
|
31
31
|
|
32
|
+
pseudonyms:
|
33
|
+
conflict_target: pseudonym_id
|
34
|
+
report_columns:
|
35
|
+
pseudonym_id:
|
36
|
+
database_column_name: canvas_id
|
37
|
+
type: integer
|
38
|
+
canvas_user_id:
|
39
|
+
database_column_name: canvas_user_id
|
40
|
+
type: integer
|
41
|
+
sis_user_id:
|
42
|
+
database_column_name: sis_id
|
43
|
+
type: string
|
44
|
+
unique_id:
|
45
|
+
database_column_name: unique_id
|
46
|
+
type: string
|
47
|
+
status:
|
48
|
+
database_column_name: workflow_state
|
49
|
+
type: string
|
50
|
+
|
32
51
|
accounts:
|
33
52
|
conflict_target: canvas_account_id
|
34
53
|
report_columns:
|
@@ -230,6 +249,9 @@ submissions:
|
|
230
249
|
submission_date:
|
231
250
|
database_column_name: submitted_at
|
232
251
|
type: datetime
|
252
|
+
due_at:
|
253
|
+
database_column_name: due_at
|
254
|
+
type: datetime
|
233
255
|
graded_date:
|
234
256
|
database_column_name: graded_at
|
235
257
|
type: datetime
|
@@ -326,3 +348,62 @@ context_module_items:
|
|
326
348
|
assignment_id:
|
327
349
|
database_column_name: canvas_assignment_id
|
328
350
|
type: integer
|
351
|
+
|
352
|
+
groups:
|
353
|
+
conflict_target: canvas_group_id
|
354
|
+
report_columns:
|
355
|
+
canvas_group_id:
|
356
|
+
database_column_name: canvas_id
|
357
|
+
type: integer
|
358
|
+
group_id:
|
359
|
+
database_column_name: sis_id
|
360
|
+
type: string
|
361
|
+
canvas_group_category_id:
|
362
|
+
database_column_name: canvas_group_category_id
|
363
|
+
type: integer
|
364
|
+
group_category_id:
|
365
|
+
database_column_name: group_category_sis_id
|
366
|
+
type: integer
|
367
|
+
canvas_account_id:
|
368
|
+
database_column_name: canvas_account_id
|
369
|
+
type: integer
|
370
|
+
canvas_course_id:
|
371
|
+
database_column_name: canvas_course_id
|
372
|
+
type: integer
|
373
|
+
name:
|
374
|
+
database_column_name: name
|
375
|
+
type: string
|
376
|
+
status:
|
377
|
+
database_column_name: workflow_state
|
378
|
+
type: string
|
379
|
+
context_id:
|
380
|
+
database_column_name: context_id
|
381
|
+
type: integer
|
382
|
+
context_type:
|
383
|
+
database_column_name: context_type
|
384
|
+
type: string
|
385
|
+
max_membership:
|
386
|
+
database_column_name: max_membership
|
387
|
+
type: integer
|
388
|
+
|
389
|
+
group_memberships:
|
390
|
+
conflict_target: canvas_group_membership_id
|
391
|
+
report_columns:
|
392
|
+
canvas_group_membership_id:
|
393
|
+
database_column_name: canvas_id
|
394
|
+
type: integer
|
395
|
+
canvas_group_id:
|
396
|
+
database_column_name: canvas_group_id
|
397
|
+
type: integer
|
398
|
+
group_id:
|
399
|
+
database_column_name: group_sis_id
|
400
|
+
type: string
|
401
|
+
canvas_user_id:
|
402
|
+
database_column_name: canvas_user_id
|
403
|
+
type: integer
|
404
|
+
user_id:
|
405
|
+
database_column_name: user_sis_id
|
406
|
+
type: string
|
407
|
+
status:
|
408
|
+
database_column_name: workflow_state
|
409
|
+
type: string
|
@@ -78,6 +78,15 @@ module CanvasSync
|
|
78
78
|
)
|
79
79
|
end
|
80
80
|
|
81
|
+
def bulk_process_pseudonyms(report_file_path)
|
82
|
+
CanvasSync::Importers::BulkImporter.import(
|
83
|
+
report_file_path,
|
84
|
+
mapping[:pseudonyms][:report_columns],
|
85
|
+
Pseudonym,
|
86
|
+
mapping[:pseudonyms][:conflict_target].to_sym,
|
87
|
+
)
|
88
|
+
end
|
89
|
+
|
81
90
|
def bulk_process_accounts(report_file_path)
|
82
91
|
CanvasSync::Importers::BulkImporter.import(
|
83
92
|
report_file_path,
|
@@ -122,6 +131,25 @@ module CanvasSync
|
|
122
131
|
mapping[:xlist][:conflict_target].to_sym,
|
123
132
|
)
|
124
133
|
end
|
134
|
+
|
135
|
+
def bulk_process_groups(report_file_path)
|
136
|
+
CanvasSync::Importers::BulkImporter.import(
|
137
|
+
report_file_path,
|
138
|
+
mapping[:groups][:report_columns],
|
139
|
+
Group,
|
140
|
+
mapping[:groups][:conflict_target].to_sym,
|
141
|
+
)
|
142
|
+
end
|
143
|
+
|
144
|
+
# Note that group membership is singular because we override the model name param in sync_provisioning_report_job
|
145
|
+
def bulk_process_group_membership(report_file_path)
|
146
|
+
CanvasSync::Importers::BulkImporter.import(
|
147
|
+
report_file_path,
|
148
|
+
mapping[:group_memberships][:report_columns],
|
149
|
+
GroupMembership,
|
150
|
+
mapping[:group_memberships][:conflict_target].to_sym,
|
151
|
+
)
|
152
|
+
end
|
125
153
|
end
|
126
154
|
end
|
127
155
|
end
|
data/lib/canvas_sync/version.rb
CHANGED
@@ -3,7 +3,7 @@ require 'spec_helper'
|
|
3
3
|
RSpec.describe CanvasSync do
|
4
4
|
describe '.provisioning_sync' do
|
5
5
|
it 'invokes the first job in the queue and passes on the rest of the job chain' do
|
6
|
-
expected_job_chain = CanvasSync.default_provisioning_report_chain(['courses'], nil)
|
6
|
+
expected_job_chain = CanvasSync.default_provisioning_report_chain(['courses'], nil).chain_data
|
7
7
|
first_job = expected_job_chain[:jobs].shift
|
8
8
|
|
9
9
|
expect(CanvasSync::Jobs::SyncTermsJob).to receive(:perform_later)
|
@@ -31,10 +31,10 @@ RSpec.describe CanvasSync do
|
|
31
31
|
provisioning: { c: 3 },
|
32
32
|
global: { d: 4 },
|
33
33
|
})
|
34
|
-
expect(chain).to eq({
|
34
|
+
expect(chain.chain_data).to eq({
|
35
35
|
jobs: [
|
36
36
|
{ job: CanvasSync::Jobs::SyncTermsJob.to_s, options: { a: 1 } },
|
37
|
-
{ job: CanvasSync::Jobs::
|
37
|
+
{ job: CanvasSync::Jobs::SyncProvisioningReportJob.to_s, options: { models: ['users'], b: 2 } },
|
38
38
|
{ job: CanvasSync::Jobs::SyncProvisioningReportJob.to_s, options: { term_scope: 'active', models: ['courses'], c: 3 } }
|
39
39
|
],
|
40
40
|
global_options: { legacy_support: false, d: 4 }
|
@@ -44,10 +44,10 @@ RSpec.describe CanvasSync do
|
|
44
44
|
context 'we are syncing users with a term scope' do
|
45
45
|
it 'syncs the users in a separate job that runs first' do
|
46
46
|
chain = CanvasSync.default_provisioning_report_chain(['users', 'courses'], :active)
|
47
|
-
expect(chain).to eq({
|
47
|
+
expect(chain.chain_data).to eq({
|
48
48
|
jobs: [
|
49
49
|
{ job: CanvasSync::Jobs::SyncTermsJob.to_s, options: {} },
|
50
|
-
{ job: CanvasSync::Jobs::
|
50
|
+
{ job: CanvasSync::Jobs::SyncProvisioningReportJob.to_s, options: { models: ['users'] } },
|
51
51
|
{ job: CanvasSync::Jobs::SyncProvisioningReportJob.to_s, options: { term_scope: 'active', models: ['courses'] } }
|
52
52
|
],
|
53
53
|
global_options: { legacy_support: false }
|
@@ -58,7 +58,7 @@ RSpec.describe CanvasSync do
|
|
58
58
|
context 'we are syncing users without a term scope' do
|
59
59
|
it 'syncs users along with the rest of the provisioning report' do
|
60
60
|
chain = CanvasSync.default_provisioning_report_chain(['users', 'courses'])
|
61
|
-
expect(chain).to eq({
|
61
|
+
expect(chain.chain_data).to eq({
|
62
62
|
jobs: [
|
63
63
|
{ job: CanvasSync::Jobs::SyncTermsJob.to_s, options: {} },
|
64
64
|
{ job: CanvasSync::Jobs::SyncProvisioningReportJob.to_s, options: { term_scope: nil, models: ['users', 'courses'] } }
|
@@ -71,7 +71,7 @@ RSpec.describe CanvasSync do
|
|
71
71
|
context 'we are syncing roles with a term scope' do
|
72
72
|
it 'syncs the roles in a separate job that runs first' do
|
73
73
|
chain = CanvasSync.default_provisioning_report_chain(['roles', 'courses'], :active)
|
74
|
-
expect(chain).to eq({
|
74
|
+
expect(chain.chain_data).to eq({
|
75
75
|
jobs: [
|
76
76
|
{ job: CanvasSync::Jobs::SyncTermsJob.to_s, options: {} },
|
77
77
|
{ job: CanvasSync::Jobs::SyncRolesJob.to_s, options: {} },
|
@@ -85,7 +85,7 @@ RSpec.describe CanvasSync do
|
|
85
85
|
context 'we are syncing roles without a term scope' do
|
86
86
|
it 'syncs roles separately even with no term scope' do
|
87
87
|
chain = CanvasSync.default_provisioning_report_chain(['roles', 'courses'])
|
88
|
-
expect(chain).to eq({
|
88
|
+
expect(chain.chain_data).to eq({
|
89
89
|
jobs: [
|
90
90
|
{ job: CanvasSync::Jobs::SyncTermsJob.to_s, options: {} },
|
91
91
|
{ job: CanvasSync::Jobs::SyncRolesJob.to_s, options: {} },
|
@@ -99,7 +99,7 @@ RSpec.describe CanvasSync do
|
|
99
99
|
context 'we are syncing admins with a term scope' do
|
100
100
|
it 'syncs the admins in a separate job that runs first' do
|
101
101
|
chain = CanvasSync.default_provisioning_report_chain(['admins', 'courses'], :active)
|
102
|
-
expect(chain).to eq({
|
102
|
+
expect(chain.chain_data).to eq({
|
103
103
|
jobs: [
|
104
104
|
{ job: CanvasSync::Jobs::SyncTermsJob.to_s, options: {} },
|
105
105
|
{ job: CanvasSync::Jobs::SyncAdminsJob.to_s, options: {} },
|
@@ -113,7 +113,7 @@ RSpec.describe CanvasSync do
|
|
113
113
|
context 'we are syncing admins without a term scope' do
|
114
114
|
it 'syncs admins separately even with no term scope' do
|
115
115
|
chain = CanvasSync.default_provisioning_report_chain(['admins', 'courses'])
|
116
|
-
expect(chain).to eq({
|
116
|
+
expect(chain.chain_data).to eq({
|
117
117
|
jobs: [
|
118
118
|
{ job: CanvasSync::Jobs::SyncTermsJob.to_s, options: {} },
|
119
119
|
{ job: CanvasSync::Jobs::SyncAdminsJob.to_s, options: {} },
|
@@ -128,7 +128,7 @@ RSpec.describe CanvasSync do
|
|
128
128
|
it "appends the SyncAssignmentsJob" do
|
129
129
|
chain = CanvasSync.default_provisioning_report_chain(%w[users enrollments assignments])
|
130
130
|
|
131
|
-
expect(chain).to eq(
|
131
|
+
expect(chain.chain_data).to eq(
|
132
132
|
jobs: [
|
133
133
|
{ job: CanvasSync::Jobs::SyncTermsJob.to_s, options: {} },
|
134
134
|
{ job: CanvasSync::Jobs::SyncProvisioningReportJob.to_s, options: { term_scope: nil, models: %w[users enrollments] } },
|
@@ -143,7 +143,7 @@ RSpec.describe CanvasSync do
|
|
143
143
|
it "appends the SyncSubmissionsJob" do
|
144
144
|
chain = CanvasSync.default_provisioning_report_chain(%w[users enrollments submissions])
|
145
145
|
|
146
|
-
expect(chain).to eq(
|
146
|
+
expect(chain.chain_data).to eq(
|
147
147
|
jobs: [
|
148
148
|
{ job: CanvasSync::Jobs::SyncTermsJob.to_s, options: {} },
|
149
149
|
{ job: CanvasSync::Jobs::SyncProvisioningReportJob.to_s, options: { term_scope: nil, models: %w[users enrollments] } },
|
@@ -158,7 +158,7 @@ RSpec.describe CanvasSync do
|
|
158
158
|
it "appends the SyncAssignmentGroupsJob" do
|
159
159
|
chain = CanvasSync.default_provisioning_report_chain(%w[users enrollments assignment_groups])
|
160
160
|
|
161
|
-
expect(chain).to eq(
|
161
|
+
expect(chain.chain_data).to eq(
|
162
162
|
jobs: [
|
163
163
|
{ job: CanvasSync::Jobs::SyncTermsJob.to_s, options: {} },
|
164
164
|
{ job: CanvasSync::Jobs::SyncProvisioningReportJob.to_s, options: { term_scope: nil, models: %w[users enrollments] } },
|
@@ -185,7 +185,7 @@ RSpec.describe CanvasSync do
|
|
185
185
|
}
|
186
186
|
}
|
187
187
|
]
|
188
|
-
)
|
188
|
+
).chain_data
|
189
189
|
first_job = expected_job_chain[:jobs].shift
|
190
190
|
|
191
191
|
expect(CanvasSync::Jobs::SyncSimpleTableJob).to receive(:perform_later)
|
@@ -242,9 +242,12 @@ RSpec.describe CanvasSync do
|
|
242
242
|
global_options: {}
|
243
243
|
}
|
244
244
|
|
245
|
-
expect(chain).to eq(expected_job_chain)
|
245
|
+
expect(chain.chain_data).to eq(expected_job_chain)
|
246
246
|
|
247
247
|
end
|
248
248
|
end
|
249
|
-
|
249
|
+
|
250
|
+
describe ".sync_scope" do
|
251
|
+
|
252
|
+
end
|
250
253
|
end
|