canvas_sync 0.16.2 → 0.17.0.beta3
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 +49 -137
- data/app/models/canvas_sync/sync_batch.rb +5 -0
- data/db/migrate/20170915210836_create_canvas_sync_job_log.rb +12 -31
- data/db/migrate/20180725155729_add_job_id_to_canvas_sync_job_logs.rb +4 -13
- data/db/migrate/20190916154829_add_fork_count_to_canvas_sync_job_logs.rb +3 -11
- data/db/migrate/20201018210836_create_canvas_sync_sync_batches.rb +11 -0
- data/lib/canvas_sync.rb +36 -118
- data/lib/canvas_sync/concerns/api_syncable.rb +27 -0
- data/lib/canvas_sync/job.rb +5 -5
- data/lib/canvas_sync/job_batches/batch.rb +399 -0
- data/lib/canvas_sync/job_batches/batch_aware_job.rb +62 -0
- data/lib/canvas_sync/job_batches/callback.rb +153 -0
- data/lib/canvas_sync/job_batches/chain_builder.rb +210 -0
- data/lib/canvas_sync/job_batches/context_hash.rb +147 -0
- data/lib/canvas_sync/job_batches/jobs/base_job.rb +7 -0
- data/lib/canvas_sync/job_batches/jobs/concurrent_batch_job.rb +18 -0
- data/lib/canvas_sync/job_batches/jobs/serial_batch_job.rb +73 -0
- data/lib/canvas_sync/job_batches/sidekiq.rb +93 -0
- data/lib/canvas_sync/job_batches/status.rb +63 -0
- data/lib/canvas_sync/jobs/begin_sync_chain_job.rb +34 -0
- data/lib/canvas_sync/jobs/report_checker.rb +3 -6
- data/lib/canvas_sync/jobs/report_processor_job.rb +2 -5
- data/lib/canvas_sync/jobs/report_starter.rb +27 -19
- data/lib/canvas_sync/jobs/sync_accounts_job.rb +3 -5
- data/lib/canvas_sync/jobs/sync_admins_job.rb +2 -4
- data/lib/canvas_sync/jobs/sync_assignment_groups_job.rb +2 -4
- data/lib/canvas_sync/jobs/sync_assignments_job.rb +2 -4
- data/lib/canvas_sync/jobs/sync_context_module_items_job.rb +2 -4
- data/lib/canvas_sync/jobs/sync_context_modules_job.rb +2 -4
- data/lib/canvas_sync/jobs/sync_provisioning_report_job.rb +5 -35
- data/lib/canvas_sync/jobs/sync_roles_job.rb +2 -5
- data/lib/canvas_sync/jobs/sync_simple_table_job.rb +11 -32
- data/lib/canvas_sync/jobs/sync_submissions_job.rb +2 -4
- data/lib/canvas_sync/jobs/sync_terms_job.rb +25 -8
- data/lib/canvas_sync/misc_helper.rb +15 -0
- data/lib/canvas_sync/version.rb +1 -1
- data/spec/canvas_sync/canvas_sync_spec.rb +136 -153
- data/spec/canvas_sync/jobs/job_spec.rb +9 -17
- data/spec/canvas_sync/jobs/report_checker_spec.rb +1 -3
- data/spec/canvas_sync/jobs/report_processor_job_spec.rb +0 -3
- data/spec/canvas_sync/jobs/report_starter_spec.rb +19 -28
- data/spec/canvas_sync/jobs/sync_admins_job_spec.rb +1 -4
- data/spec/canvas_sync/jobs/sync_assignment_groups_job_spec.rb +2 -1
- data/spec/canvas_sync/jobs/sync_assignments_job_spec.rb +3 -2
- data/spec/canvas_sync/jobs/sync_context_module_items_job_spec.rb +3 -2
- data/spec/canvas_sync/jobs/sync_context_modules_job_spec.rb +3 -2
- data/spec/canvas_sync/jobs/sync_provisioning_report_job_spec.rb +3 -35
- data/spec/canvas_sync/jobs/sync_roles_job_spec.rb +1 -4
- data/spec/canvas_sync/jobs/sync_simple_table_job_spec.rb +5 -12
- data/spec/canvas_sync/jobs/sync_submissions_job_spec.rb +2 -1
- data/spec/canvas_sync/jobs/sync_terms_job_spec.rb +1 -4
- data/spec/dummy/app/models/account.rb +3 -0
- data/spec/dummy/app/models/pseudonym.rb +14 -0
- data/spec/dummy/app/models/submission.rb +1 -0
- data/spec/dummy/app/models/user.rb +1 -0
- data/spec/dummy/config/environments/test.rb +2 -0
- data/spec/dummy/db/migrate/20201016181346_create_pseudonyms.rb +24 -0
- data/spec/dummy/db/schema.rb +24 -4
- data/spec/job_batching/batch_aware_job_spec.rb +100 -0
- data/spec/job_batching/batch_spec.rb +363 -0
- data/spec/job_batching/callback_spec.rb +38 -0
- data/spec/job_batching/flow_spec.rb +91 -0
- data/spec/job_batching/integration/integration.rb +57 -0
- data/spec/job_batching/integration/nested.rb +88 -0
- data/spec/job_batching/integration/simple.rb +47 -0
- data/spec/job_batching/integration/workflow.rb +134 -0
- data/spec/job_batching/integration_helper.rb +48 -0
- data/spec/job_batching/sidekiq_spec.rb +124 -0
- data/spec/job_batching/status_spec.rb +92 -0
- data/spec/job_batching/support/base_job.rb +14 -0
- data/spec/job_batching/support/sample_callback.rb +2 -0
- data/spec/spec_helper.rb +17 -0
- metadata +90 -8
- data/lib/canvas_sync/job_chain.rb +0 -57
- data/lib/canvas_sync/jobs/fork_gather.rb +0 -59
- data/spec/canvas_sync/jobs/fork_gather_spec.rb +0 -73
@@ -4,11 +4,10 @@ module CanvasSync
|
|
4
4
|
# Syncs Admins using the Canvas API
|
5
5
|
#
|
6
6
|
#
|
7
|
-
# @param job_chain [Hash]
|
8
7
|
# @param options [Hash]
|
9
|
-
def perform(
|
8
|
+
def perform(options)
|
10
9
|
updated_admin_ids = []
|
11
|
-
api_client = CanvasSync.get_canvas_sync_client(
|
10
|
+
api_client = CanvasSync.get_canvas_sync_client(batch_context)
|
12
11
|
CanvasSync.sync_scope(Account).find_each do |acc|
|
13
12
|
api_client.account_admins(acc.canvas_id).all_pages_each do |admin_params|
|
14
13
|
admin_params[:account_id] = acc.canvas_id
|
@@ -17,7 +16,6 @@ module CanvasSync
|
|
17
16
|
end
|
18
17
|
end
|
19
18
|
Admin.where.not(id: updated_admin_ids).update_all(workflow_state: 'inactive')
|
20
|
-
CanvasSync.invoke_next(job_chain)
|
21
19
|
end
|
22
20
|
end
|
23
21
|
end
|
@@ -6,13 +6,11 @@ module CanvasSync
|
|
6
6
|
# Starts a report processor for the assignment_groups report
|
7
7
|
# (the proserv_assignment_group_export_csv report must be enabled)
|
8
8
|
#
|
9
|
-
# @param job_chain [Hash]
|
10
9
|
# @param options [Hash]
|
11
|
-
def perform(
|
10
|
+
def perform(options)
|
12
11
|
super(
|
13
|
-
job_chain,
|
14
12
|
"proserv_assignment_group_export_csv",
|
15
|
-
merge_report_params(
|
13
|
+
merge_report_params(options),
|
16
14
|
CanvasSync::Processors::AssignmentGroupsProcessor.to_s,
|
17
15
|
{},
|
18
16
|
)
|
@@ -6,13 +6,11 @@ module CanvasSync
|
|
6
6
|
# Starts a report processor for the assignment report
|
7
7
|
# (the proserv_assignment_export_csv report must be enabled)
|
8
8
|
#
|
9
|
-
# @param job_chain [Hash]
|
10
9
|
# @param options [Hash]
|
11
|
-
def perform(
|
10
|
+
def perform(options)
|
12
11
|
super(
|
13
|
-
job_chain,
|
14
12
|
"proserv_assignment_export_csv",
|
15
|
-
merge_report_params(
|
13
|
+
merge_report_params(options),
|
16
14
|
CanvasSync::Processors::AssignmentsProcessor.to_s,
|
17
15
|
{},
|
18
16
|
)
|
@@ -6,13 +6,11 @@ module CanvasSync
|
|
6
6
|
# Starts a report processor for the context modules report
|
7
7
|
# (the proserv_context_module_items_csv report must be enabled)
|
8
8
|
#
|
9
|
-
# @param job_chain [Hash]
|
10
9
|
# @param options [Hash]
|
11
|
-
def perform(
|
10
|
+
def perform(options)
|
12
11
|
super(
|
13
|
-
job_chain,
|
14
12
|
"proserv_context_module_items_csv",
|
15
|
-
merge_report_params(
|
13
|
+
merge_report_params(options),
|
16
14
|
CanvasSync::Processors::ContextModuleItemsProcessor.to_s,
|
17
15
|
{},
|
18
16
|
)
|
@@ -6,13 +6,11 @@ module CanvasSync
|
|
6
6
|
# Starts a report processor for the context modules report
|
7
7
|
# (the proserv_context_modules_csv report must be enabled)
|
8
8
|
#
|
9
|
-
# @param job_chain [Hash]
|
10
9
|
# @param options [Hash]
|
11
|
-
def perform(
|
10
|
+
def perform(options)
|
12
11
|
super(
|
13
|
-
job_chain,
|
14
12
|
"proserv_context_modules_csv",
|
15
|
-
merge_report_params(
|
13
|
+
merge_report_params(options),
|
16
14
|
CanvasSync::Processors::ContextModulesProcessor.to_s,
|
17
15
|
{},
|
18
16
|
)
|
@@ -2,40 +2,14 @@ module CanvasSync
|
|
2
2
|
module Jobs
|
3
3
|
# ActiveJob class that starts a Canvas provisioning report
|
4
4
|
class SyncProvisioningReportJob < CanvasSync::Job
|
5
|
-
|
6
|
-
|
7
|
-
# will be started for each term in that scope. :models should be an array of
|
8
|
-
# models to sync.
|
9
|
-
def perform(job_chain, options)
|
10
|
-
if options[:term_scope]
|
11
|
-
sub_reports = CanvasSync.fork(@job_log, job_chain, keys: [:canvas_term_id]) do |job_chain|
|
12
|
-
Term.send(options[:term_scope]).find_each.map do |term|
|
13
|
-
# Deep copy the job_chain so each report gets the correct term id passed into
|
14
|
-
# its options with no side effects
|
15
|
-
term_id = get_term_id(term)
|
16
|
-
duped_job_chain = Marshal.load(Marshal.dump(job_chain))
|
17
|
-
duped_job_chain[:global_options][:canvas_term_id] = term_id
|
18
|
-
{
|
19
|
-
job_chain: duped_job_chain,
|
20
|
-
params: report_params(options, term_id),
|
21
|
-
options: options,
|
22
|
-
}
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
sub_reports.each do |r|
|
27
|
-
start_report(r[:params], r[:job_chain], r[:options])
|
28
|
-
end
|
29
|
-
else
|
30
|
-
start_report(report_params(options), job_chain, options)
|
31
|
-
end
|
5
|
+
def perform(options)
|
6
|
+
start_report(report_params(options), options)
|
32
7
|
end
|
33
8
|
|
34
|
-
|
9
|
+
protected
|
35
10
|
|
36
|
-
def start_report(report_params,
|
11
|
+
def start_report(report_params, options)
|
37
12
|
CanvasSync::Jobs::ReportStarter.perform_later(
|
38
|
-
job_chain,
|
39
13
|
"proservices_provisioning_csv",
|
40
14
|
report_params,
|
41
15
|
CanvasSync::Processors::ProvisioningReportProcessor.to_s,
|
@@ -43,7 +17,7 @@ module CanvasSync
|
|
43
17
|
)
|
44
18
|
end
|
45
19
|
|
46
|
-
def report_params(options, canvas_term_id=
|
20
|
+
def report_params(options, canvas_term_id = options[:canvas_term_id] || batch_context[:canvas_term_id])
|
47
21
|
params = {
|
48
22
|
include_deleted: true,
|
49
23
|
}
|
@@ -60,10 +34,6 @@ module CanvasSync
|
|
60
34
|
|
61
35
|
{ parameters: params }
|
62
36
|
end
|
63
|
-
|
64
|
-
def get_term_id(term)
|
65
|
-
term.try(:canvas_id) || term.canvas_term_id
|
66
|
-
end
|
67
37
|
end
|
68
38
|
end
|
69
39
|
end
|
@@ -3,12 +3,10 @@ module CanvasSync
|
|
3
3
|
class SyncRolesJob < CanvasSync::Job
|
4
4
|
# Syncs Roles using the Canvas API
|
5
5
|
#
|
6
|
-
#
|
7
|
-
# @param job_chain [Hash]
|
8
6
|
# @param options [Hash]
|
9
|
-
def perform(
|
7
|
+
def perform(options)
|
10
8
|
updated_role_ids = []
|
11
|
-
api_client = CanvasSync.get_canvas_sync_client(
|
9
|
+
api_client = CanvasSync.get_canvas_sync_client(batch_context)
|
12
10
|
CanvasSync.sync_scope(Account).find_each do |acc|
|
13
11
|
api_client.list_roles(acc.canvas_id, state: %w[active inactive]).all_pages_each do |role_params|
|
14
12
|
role = update_or_create_model(Role, role_params)
|
@@ -16,7 +14,6 @@ module CanvasSync
|
|
16
14
|
end
|
17
15
|
end
|
18
16
|
Role.where.not(id: updated_role_ids).update_all(workflow_state: 'inactive')
|
19
|
-
CanvasSync.invoke_next(job_chain)
|
20
17
|
end
|
21
18
|
end
|
22
19
|
end
|
@@ -5,36 +5,19 @@ module CanvasSync
|
|
5
5
|
# Starts a report processor for the specified report
|
6
6
|
# (the specified report must be enabled)
|
7
7
|
#
|
8
|
-
# @param
|
9
|
-
#
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
duped_job_chain = Marshal.load(Marshal.dump(job_chain))
|
18
|
-
duped_job_chain[:global_options][:canvas_term_id] = term_id
|
19
|
-
{
|
20
|
-
job_chain: duped_job_chain,
|
21
|
-
params: report_params(options, term_id),
|
22
|
-
options: options,
|
23
|
-
}
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
sub_reports.each do |r|
|
28
|
-
start_report(r[:params], r[:job_chain], r[:options])
|
29
|
-
end
|
30
|
-
else
|
31
|
-
start_report(report_params(options), job_chain, options)
|
32
|
-
end
|
8
|
+
# @param options [Hash] {
|
9
|
+
# report_name: "", # Name of the report in the Canvas API
|
10
|
+
# model: , # Model to map the report results as
|
11
|
+
# mapping: {} # Mapping to describe how to convert the report to the Model,
|
12
|
+
# klass: ,
|
13
|
+
# params: {}, # List of params to pass to the report
|
14
|
+
# }
|
15
|
+
def perform(options)
|
16
|
+
start_report(report_params(options), options)
|
33
17
|
end
|
34
18
|
|
35
|
-
def start_report(params,
|
19
|
+
def start_report(params, options)
|
36
20
|
CanvasSync::Jobs::ReportStarter.perform_later(
|
37
|
-
job_chain,
|
38
21
|
options[:report_name],
|
39
22
|
params,
|
40
23
|
CanvasSync::Processors::NormalProcessor.to_s,
|
@@ -42,15 +25,11 @@ module CanvasSync
|
|
42
25
|
)
|
43
26
|
end
|
44
27
|
|
45
|
-
def report_params(options, canvas_term_id=
|
28
|
+
def report_params(options, canvas_term_id = options[:canvas_term_id] || batch_context[:canvas_term_id])
|
46
29
|
params = options[:params] || {}
|
47
30
|
params["parameters[enrollment_term_id]"] = canvas_term_id if canvas_term_id
|
48
31
|
params
|
49
32
|
end
|
50
|
-
|
51
|
-
def get_term_id(term)
|
52
|
-
term.try(:canvas_id) || term.canvas_term_id
|
53
|
-
end
|
54
33
|
end
|
55
34
|
end
|
56
35
|
end
|
@@ -6,13 +6,11 @@ module CanvasSync
|
|
6
6
|
# Starts a report processor for the submission report
|
7
7
|
# (the proserv_student_submissions_csv report must be enabled)
|
8
8
|
#
|
9
|
-
# @param job_chain [Hash]
|
10
9
|
# @param options [Hash]
|
11
|
-
def perform(
|
10
|
+
def perform(options)
|
12
11
|
super(
|
13
|
-
job_chain,
|
14
12
|
"proserv_student_submissions_csv",
|
15
|
-
merge_report_params(
|
13
|
+
merge_report_params(options, { include_all: options[:include_all] }, {}),
|
16
14
|
CanvasSync::Processors::SubmissionsProcessor.to_s,
|
17
15
|
{},
|
18
16
|
)
|
@@ -5,16 +5,17 @@ module CanvasSync
|
|
5
5
|
#
|
6
6
|
# Terms are pre-synced so that provisioning reports can be scoped to term.
|
7
7
|
#
|
8
|
-
# @param
|
9
|
-
#
|
10
|
-
|
11
|
-
|
12
|
-
|
8
|
+
# @param options [Hash] If options contains a :term_scope a seperate provisioning report
|
9
|
+
# will be started for each term in that scope. :models should be an array of
|
10
|
+
# models to sync.
|
11
|
+
def perform(options)
|
12
|
+
CanvasSync.get_canvas_sync_client(batch_context).terms("self").all_pages!.each do |term_params|
|
13
|
+
if account_id = batch_context[:account_id]
|
13
14
|
# These branches are primarily to support Legacy apps
|
14
15
|
if Term.respond_to?(:create_or_update) && Term.method(:create_or_update).arity.abs == 2
|
15
|
-
Term.create_or_update(term_params,
|
16
|
+
Term.create_or_update(term_params, account_id)
|
16
17
|
else
|
17
|
-
term_params[:account_id] |=
|
18
|
+
term_params[:account_id] |= account_id
|
18
19
|
update_or_create_model(Term, term_params)
|
19
20
|
end
|
20
21
|
else
|
@@ -22,7 +23,23 @@ module CanvasSync
|
|
22
23
|
end
|
23
24
|
end
|
24
25
|
|
25
|
-
|
26
|
+
if (jobs = options[:sub_jobs]).present?
|
27
|
+
context = options[:context] || {}
|
28
|
+
if options[:term_scope]
|
29
|
+
Term.send(options[:term_scope]).find_each.map do |term|
|
30
|
+
local_context = context.merge(canvas_term_id: get_term_id(term))
|
31
|
+
JobBatches::ConcurrentBatchJob.perform_now(jobs, context: local_context)
|
32
|
+
end
|
33
|
+
else
|
34
|
+
JobBatches::ConcurrentBatchJob.perform_now(jobs, context: context)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
protected
|
40
|
+
|
41
|
+
def get_term_id(term)
|
42
|
+
term.try(:canvas_id) || term.canvas_term_id
|
26
43
|
end
|
27
44
|
end
|
28
45
|
end
|
@@ -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
|
data/lib/canvas_sync/version.rb
CHANGED
@@ -3,13 +3,12 @@ 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).
|
7
|
-
first_job = expected_job_chain[:jobs].shift
|
6
|
+
expected_job_chain = CanvasSync.default_provisioning_report_chain(['courses'], term_scope: nil).normalize![:parameters][0]
|
8
7
|
|
9
|
-
expect(CanvasSync::Jobs::
|
8
|
+
expect(CanvasSync::Jobs::BeginSyncChainJob).to receive(:perform_later)
|
10
9
|
.with(
|
11
10
|
expected_job_chain,
|
12
|
-
|
11
|
+
anything
|
13
12
|
)
|
14
13
|
|
15
14
|
CanvasSync.provisioning_sync(['courses'])
|
@@ -25,32 +24,44 @@ RSpec.describe CanvasSync do
|
|
25
24
|
|
26
25
|
describe '.default_provisioning_report_chain' do
|
27
26
|
it 'splits an options: Hash into options for separate models' do
|
28
|
-
chain = CanvasSync.default_provisioning_report_chain(['users', 'courses'], :active, options: {
|
27
|
+
chain = CanvasSync.default_provisioning_report_chain(['users', 'courses'], term_scope: :active, options: {
|
29
28
|
terms: { a: 1 },
|
30
29
|
users: { b: 2 },
|
31
30
|
provisioning: { c: 3 },
|
32
31
|
global: { d: 4 },
|
33
32
|
})
|
34
|
-
expect(chain.
|
35
|
-
|
36
|
-
|
37
|
-
{
|
38
|
-
|
39
|
-
|
40
|
-
|
33
|
+
expect(chain.normalize!).to eq({
|
34
|
+
:job => "CanvasSync::Jobs::BeginSyncChainJob",
|
35
|
+
:parameters => [[
|
36
|
+
{:job=>"CanvasSync::JobBatches::ConcurrentBatchJob", :parameters=>[[
|
37
|
+
{:job=>"CanvasSync::Jobs::SyncProvisioningReportJob", :options=>{:models=>["users"], :b=>2}},
|
38
|
+
{:job=>"CanvasSync::Jobs::SyncTermsJob", :parameters=>[{
|
39
|
+
:term_scope=>"active",
|
40
|
+
:sub_jobs=>[
|
41
|
+
{:job=>"CanvasSync::Jobs::SyncProvisioningReportJob", :options=>{:models=>["courses"], :c=>3}}
|
42
|
+
]
|
43
|
+
}]}
|
44
|
+
]]}
|
45
|
+
], {:legacy_support=>false, :updated_after=>nil, :d=>4}],
|
41
46
|
})
|
42
47
|
end
|
43
48
|
|
44
49
|
context 'we are syncing users with a term scope' do
|
45
50
|
it 'syncs the users in a separate job that runs first' do
|
46
|
-
chain = CanvasSync.default_provisioning_report_chain(['users', 'courses'], :active)
|
47
|
-
expect(chain.
|
48
|
-
|
49
|
-
|
50
|
-
{
|
51
|
-
|
52
|
-
|
53
|
-
|
51
|
+
chain = CanvasSync.default_provisioning_report_chain(['users', 'courses'], term_scope: :active)
|
52
|
+
expect(chain.normalize!).to eq({
|
53
|
+
:job => "CanvasSync::Jobs::BeginSyncChainJob",
|
54
|
+
:parameters => [[
|
55
|
+
{:job=>"CanvasSync::JobBatches::ConcurrentBatchJob", :parameters=>[[
|
56
|
+
{:job=>"CanvasSync::Jobs::SyncProvisioningReportJob", :options=>{:models=>["users"]}},
|
57
|
+
{:job=>"CanvasSync::Jobs::SyncTermsJob", :parameters=>[{
|
58
|
+
:term_scope=>"active",
|
59
|
+
:sub_jobs=>[
|
60
|
+
{:job=>"CanvasSync::Jobs::SyncProvisioningReportJob", :options=>{:models=>["courses"]}}
|
61
|
+
]
|
62
|
+
}]}
|
63
|
+
]]}
|
64
|
+
], {:legacy_support=>false, :updated_after=>nil}]
|
54
65
|
})
|
55
66
|
end
|
56
67
|
end
|
@@ -58,26 +69,38 @@ RSpec.describe CanvasSync do
|
|
58
69
|
context 'we are syncing users without a term scope' do
|
59
70
|
it 'syncs users along with the rest of the provisioning report' do
|
60
71
|
chain = CanvasSync.default_provisioning_report_chain(['users', 'courses'])
|
61
|
-
expect(chain.
|
62
|
-
|
63
|
-
|
64
|
-
{
|
65
|
-
|
66
|
-
|
72
|
+
expect(chain.normalize!).to eq({
|
73
|
+
:job => "CanvasSync::Jobs::BeginSyncChainJob",
|
74
|
+
:parameters => [[
|
75
|
+
{:job=>"CanvasSync::JobBatches::ConcurrentBatchJob", :parameters=>[[
|
76
|
+
{:job=>"CanvasSync::Jobs::SyncTermsJob", :parameters=>[{
|
77
|
+
:term_scope=>nil,
|
78
|
+
:sub_jobs=>[
|
79
|
+
{:job=>"CanvasSync::Jobs::SyncProvisioningReportJob", :options=>{:models=>["users", "courses"]}}
|
80
|
+
]
|
81
|
+
}]}
|
82
|
+
]]}
|
83
|
+
], {:legacy_support=>false, :updated_after=>nil}],
|
67
84
|
})
|
68
85
|
end
|
69
86
|
end
|
70
87
|
|
71
88
|
context 'we are syncing roles with a term scope' do
|
72
89
|
it 'syncs the roles in a separate job that runs first' do
|
73
|
-
chain = CanvasSync.default_provisioning_report_chain(['roles', 'courses'], :active)
|
74
|
-
expect(chain.
|
75
|
-
|
76
|
-
|
77
|
-
{
|
78
|
-
|
79
|
-
|
80
|
-
|
90
|
+
chain = CanvasSync.default_provisioning_report_chain(['roles', 'courses'], term_scope: :active)
|
91
|
+
expect(chain.normalize!).to eq({
|
92
|
+
:job => "CanvasSync::Jobs::BeginSyncChainJob",
|
93
|
+
:parameters => [[
|
94
|
+
{:job=>"CanvasSync::JobBatches::ConcurrentBatchJob", :parameters=>[[
|
95
|
+
{:job=>"CanvasSync::Jobs::SyncRolesJob", :options=>{}},
|
96
|
+
{:job=>"CanvasSync::Jobs::SyncTermsJob", :parameters=>[{
|
97
|
+
:term_scope=>"active",
|
98
|
+
:sub_jobs=>[
|
99
|
+
{:job=>"CanvasSync::Jobs::SyncProvisioningReportJob", :options=>{:models=>["courses"]}}
|
100
|
+
]
|
101
|
+
}]}
|
102
|
+
]]}
|
103
|
+
], {:legacy_support=>false, :updated_after=>nil}],
|
81
104
|
})
|
82
105
|
end
|
83
106
|
end
|
@@ -85,27 +108,39 @@ RSpec.describe CanvasSync do
|
|
85
108
|
context 'we are syncing roles without a term scope' do
|
86
109
|
it 'syncs roles separately even with no term scope' do
|
87
110
|
chain = CanvasSync.default_provisioning_report_chain(['roles', 'courses'])
|
88
|
-
expect(chain.
|
89
|
-
|
90
|
-
|
91
|
-
{
|
92
|
-
|
93
|
-
|
94
|
-
|
111
|
+
expect(chain.normalize!).to eq({
|
112
|
+
:job => "CanvasSync::Jobs::BeginSyncChainJob",
|
113
|
+
:parameters => [[
|
114
|
+
{:job=>"CanvasSync::JobBatches::ConcurrentBatchJob", :parameters=>[[
|
115
|
+
{:job=>"CanvasSync::Jobs::SyncRolesJob", :options=>{}},
|
116
|
+
{:job=>"CanvasSync::Jobs::SyncTermsJob", :parameters=>[{
|
117
|
+
:term_scope=>nil,
|
118
|
+
:sub_jobs=>[
|
119
|
+
{:job=>"CanvasSync::Jobs::SyncProvisioningReportJob", :options=>{:models=>["courses"]}}
|
120
|
+
]
|
121
|
+
}]}
|
122
|
+
]]}
|
123
|
+
], {:legacy_support=>false, :updated_after=>nil}],
|
95
124
|
})
|
96
125
|
end
|
97
126
|
end
|
98
127
|
|
99
128
|
context 'we are syncing admins with a term scope' do
|
100
129
|
it 'syncs the admins in a separate job that runs first' do
|
101
|
-
chain = CanvasSync.default_provisioning_report_chain(['admins', 'courses'], :active)
|
102
|
-
expect(chain.
|
103
|
-
|
104
|
-
|
105
|
-
{
|
106
|
-
|
107
|
-
|
108
|
-
|
130
|
+
chain = CanvasSync.default_provisioning_report_chain(['admins', 'courses'], term_scope: :active)
|
131
|
+
expect(chain.normalize!).to eq({
|
132
|
+
:job => "CanvasSync::Jobs::BeginSyncChainJob",
|
133
|
+
:parameters => [[
|
134
|
+
{:job=>"CanvasSync::JobBatches::ConcurrentBatchJob", :parameters=>[[
|
135
|
+
{:job=>"CanvasSync::Jobs::SyncAdminsJob", :options=>{}},
|
136
|
+
{:job=>"CanvasSync::Jobs::SyncTermsJob", :parameters=>[{
|
137
|
+
:term_scope=>"active",
|
138
|
+
:sub_jobs=>[
|
139
|
+
{:job=>"CanvasSync::Jobs::SyncProvisioningReportJob", :options=>{:models=>["courses"]}}
|
140
|
+
]
|
141
|
+
}]}
|
142
|
+
]]}
|
143
|
+
], {:legacy_support=>false, :updated_after=>nil}],
|
109
144
|
})
|
110
145
|
end
|
111
146
|
end
|
@@ -113,13 +148,19 @@ RSpec.describe CanvasSync do
|
|
113
148
|
context 'we are syncing admins without a term scope' do
|
114
149
|
it 'syncs admins separately even with no term scope' do
|
115
150
|
chain = CanvasSync.default_provisioning_report_chain(['admins', 'courses'])
|
116
|
-
expect(chain.
|
117
|
-
|
118
|
-
|
119
|
-
{
|
120
|
-
|
121
|
-
|
122
|
-
|
151
|
+
expect(chain.normalize!).to eq({
|
152
|
+
:job => "CanvasSync::Jobs::BeginSyncChainJob",
|
153
|
+
:parameters => [[
|
154
|
+
{:job=>"CanvasSync::JobBatches::ConcurrentBatchJob", :parameters=>[[
|
155
|
+
{:job=>"CanvasSync::Jobs::SyncAdminsJob", :options=>{}},
|
156
|
+
{:job=>"CanvasSync::Jobs::SyncTermsJob", :parameters=>[{
|
157
|
+
:term_scope=>nil,
|
158
|
+
:sub_jobs=>[
|
159
|
+
{:job=>"CanvasSync::Jobs::SyncProvisioningReportJob", :options=>{:models=>["courses"]}}
|
160
|
+
]
|
161
|
+
}]}
|
162
|
+
]]}
|
163
|
+
], {:legacy_support=>false, :updated_after=>nil}],
|
123
164
|
})
|
124
165
|
end
|
125
166
|
end
|
@@ -128,13 +169,19 @@ RSpec.describe CanvasSync do
|
|
128
169
|
it "appends the SyncAssignmentsJob" do
|
129
170
|
chain = CanvasSync.default_provisioning_report_chain(%w[users enrollments assignments])
|
130
171
|
|
131
|
-
expect(chain.
|
132
|
-
|
133
|
-
|
134
|
-
{
|
135
|
-
|
136
|
-
|
137
|
-
|
172
|
+
expect(chain.normalize!).to eq(
|
173
|
+
:job => "CanvasSync::Jobs::BeginSyncChainJob",
|
174
|
+
:parameters => [[
|
175
|
+
{:job=>"CanvasSync::JobBatches::ConcurrentBatchJob", :parameters=>[[
|
176
|
+
{:job=>"CanvasSync::Jobs::SyncTermsJob", :parameters=>[{
|
177
|
+
:term_scope=>nil,
|
178
|
+
:sub_jobs=>[
|
179
|
+
{:job=>"CanvasSync::Jobs::SyncAssignmentsJob", :options=>{}},
|
180
|
+
{:job=>"CanvasSync::Jobs::SyncProvisioningReportJob", :options=>{:models=>["users", "enrollments"]}}
|
181
|
+
]
|
182
|
+
}]}
|
183
|
+
]]}
|
184
|
+
], {:legacy_support=>false, :updated_after=>nil}],
|
138
185
|
)
|
139
186
|
end
|
140
187
|
end
|
@@ -143,13 +190,19 @@ RSpec.describe CanvasSync do
|
|
143
190
|
it "appends the SyncSubmissionsJob" do
|
144
191
|
chain = CanvasSync.default_provisioning_report_chain(%w[users enrollments submissions])
|
145
192
|
|
146
|
-
expect(chain.
|
147
|
-
|
148
|
-
|
149
|
-
{
|
150
|
-
|
151
|
-
|
152
|
-
|
193
|
+
expect(chain.normalize!).to eq(
|
194
|
+
:job => "CanvasSync::Jobs::BeginSyncChainJob",
|
195
|
+
:parameters => [[
|
196
|
+
{:job=>"CanvasSync::JobBatches::ConcurrentBatchJob", :parameters=>[[
|
197
|
+
{:job=>"CanvasSync::Jobs::SyncTermsJob", :parameters=>[{
|
198
|
+
:term_scope=>nil,
|
199
|
+
:sub_jobs=>[
|
200
|
+
{:job=>"CanvasSync::Jobs::SyncSubmissionsJob", :options=>{}},
|
201
|
+
{:job=>"CanvasSync::Jobs::SyncProvisioningReportJob", :options=>{:models=>["users", "enrollments"]}}
|
202
|
+
]
|
203
|
+
}]}
|
204
|
+
]]}
|
205
|
+
], {:legacy_support=>false, :updated_after=>nil}],
|
153
206
|
)
|
154
207
|
end
|
155
208
|
end
|
@@ -158,95 +211,25 @@ RSpec.describe CanvasSync do
|
|
158
211
|
it "appends the SyncAssignmentGroupsJob" do
|
159
212
|
chain = CanvasSync.default_provisioning_report_chain(%w[users enrollments assignment_groups])
|
160
213
|
|
161
|
-
expect(chain.
|
162
|
-
|
163
|
-
|
164
|
-
{
|
165
|
-
|
166
|
-
|
167
|
-
|
214
|
+
expect(chain.normalize!).to eq(
|
215
|
+
:job => "CanvasSync::Jobs::BeginSyncChainJob",
|
216
|
+
:parameters => [[
|
217
|
+
{:job=>"CanvasSync::JobBatches::ConcurrentBatchJob", :parameters=>[[
|
218
|
+
{:job=>"CanvasSync::Jobs::SyncTermsJob", :parameters=>[{
|
219
|
+
:term_scope=>nil,
|
220
|
+
:sub_jobs=>[
|
221
|
+
{:job=>"CanvasSync::Jobs::SyncAssignmentGroupsJob", :options=>{}},
|
222
|
+
{:job=>"CanvasSync::Jobs::SyncProvisioningReportJob", :options=>{:models=>["users", "enrollments"]}}
|
223
|
+
]
|
224
|
+
}]}
|
225
|
+
]]}
|
226
|
+
], {:legacy_support=>false, :updated_after=>nil}],
|
168
227
|
)
|
169
228
|
end
|
170
229
|
end
|
171
230
|
end
|
172
231
|
end
|
173
232
|
|
174
|
-
describe ".simple_report_sync" do
|
175
|
-
|
176
|
-
it 'invokes the first job in the queue and passes on the rest of the job chain' do
|
177
|
-
expected_job_chain = CanvasSync.simple_report_chain(
|
178
|
-
[
|
179
|
-
{
|
180
|
-
report_name: 'proservices_provisioning_csv',
|
181
|
-
model: 'users',
|
182
|
-
params: {
|
183
|
-
"parameters[include_deleted]" => true,
|
184
|
-
"parameters[users]" => true
|
185
|
-
}
|
186
|
-
}
|
187
|
-
]
|
188
|
-
).chain_data
|
189
|
-
first_job = expected_job_chain[:jobs].shift
|
190
|
-
|
191
|
-
expect(CanvasSync::Jobs::SyncSimpleTableJob).to receive(:perform_later)
|
192
|
-
.with(
|
193
|
-
expected_job_chain,
|
194
|
-
first_job[:options]
|
195
|
-
)
|
196
|
-
|
197
|
-
CanvasSync.simple_report_sync(
|
198
|
-
[
|
199
|
-
{
|
200
|
-
report_name: 'proservices_provisioning_csv',
|
201
|
-
model: 'users',
|
202
|
-
params: {
|
203
|
-
"parameters[include_deleted]" => true,
|
204
|
-
"parameters[users]" => true
|
205
|
-
}
|
206
|
-
}
|
207
|
-
]
|
208
|
-
)
|
209
|
-
end
|
210
|
-
|
211
|
-
it 'receives the job chain for the specified table' do
|
212
|
-
chain = CanvasSync.simple_report_chain(
|
213
|
-
[
|
214
|
-
{
|
215
|
-
report_name: 'proservices_provisioning_csv',
|
216
|
-
model: 'users',
|
217
|
-
params: {
|
218
|
-
"parameters[include_deleted]" => true,
|
219
|
-
"parameters[users]" => true
|
220
|
-
}
|
221
|
-
}
|
222
|
-
]
|
223
|
-
)
|
224
|
-
|
225
|
-
expected_job_chain = {
|
226
|
-
jobs: [
|
227
|
-
{
|
228
|
-
job: CanvasSync::Jobs::SyncSimpleTableJob.to_s,
|
229
|
-
options: {
|
230
|
-
report_name: 'proservices_provisioning_csv',
|
231
|
-
model: 'users',
|
232
|
-
mapping: 'users',
|
233
|
-
klass: 'User',
|
234
|
-
term_scope: nil,
|
235
|
-
params: {
|
236
|
-
"parameters[include_deleted]" => true,
|
237
|
-
"parameters[users]" => true
|
238
|
-
}
|
239
|
-
}
|
240
|
-
}
|
241
|
-
],
|
242
|
-
global_options: {}
|
243
|
-
}
|
244
|
-
|
245
|
-
expect(chain.chain_data).to eq(expected_job_chain)
|
246
|
-
|
247
|
-
end
|
248
|
-
end
|
249
|
-
|
250
233
|
describe ".sync_scope" do
|
251
234
|
|
252
235
|
end
|