canvas_sync 0.12.0 → 0.16.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.
- 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
|