canvas_sync 0.26.1 → 0.27.1.beta2

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 (69) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +117 -20
  3. data/app/controllers/canvas_sync/api/v1/live_events_controller.rb +1 -0
  4. data/lib/canvas_sync/config.rb +1 -1
  5. data/lib/canvas_sync/importers/bulk_importer.rb +2 -0
  6. data/lib/canvas_sync/jobs/begin_sync_chain_job.rb +1 -1
  7. data/lib/canvas_sync/jobs/beta_cleanup/create_temp_tables_job.rb +30 -0
  8. data/lib/canvas_sync/jobs/beta_cleanup/delete_related_records_job.rb +125 -0
  9. data/lib/canvas_sync/jobs/beta_cleanup/delete_temp_tables_job.rb +16 -0
  10. data/lib/canvas_sync/jobs/report_starter.rb +33 -46
  11. data/lib/canvas_sync/jobs/report_sync_task.rb +273 -0
  12. data/lib/canvas_sync/jobs/sync_accounts_job.rb +10 -7
  13. data/lib/canvas_sync/jobs/sync_assignment_groups_job.rb +2 -15
  14. data/lib/canvas_sync/jobs/sync_assignment_overrides_job.rb +26 -14
  15. data/lib/canvas_sync/jobs/sync_assignments_job.rb +2 -15
  16. data/lib/canvas_sync/jobs/sync_content_migrations_job.rb +2 -15
  17. data/lib/canvas_sync/jobs/sync_context_module_items_job.rb +2 -15
  18. data/lib/canvas_sync/jobs/sync_context_modules_job.rb +2 -15
  19. data/lib/canvas_sync/jobs/sync_course_progresses_job.rb +2 -16
  20. data/lib/canvas_sync/jobs/sync_provisioning_report_job.rb +135 -14
  21. data/lib/canvas_sync/jobs/sync_rubric_assessments_job.rb +2 -10
  22. data/lib/canvas_sync/jobs/sync_rubric_associations_job.rb +2 -10
  23. data/lib/canvas_sync/jobs/sync_rubrics_job.rb +2 -10
  24. data/lib/canvas_sync/jobs/sync_scores_job.rb +2 -13
  25. data/lib/canvas_sync/jobs/sync_submissions_job.rb +9 -18
  26. data/lib/canvas_sync/jobs/term_batches_job.rb +4 -2
  27. data/lib/canvas_sync/version.rb +1 -1
  28. data/lib/canvas_sync.rb +31 -4
  29. data/spec/canvas_sync/canvas_sync_spec.rb +62 -22
  30. data/spec/canvas_sync/jobs/report_starter_spec.rb +102 -55
  31. data/spec/canvas_sync/jobs/report_sync_task_spec.rb +367 -0
  32. data/spec/canvas_sync/jobs/sync_provisioning_report_job_spec.rb +24 -35
  33. data/spec/canvas_sync/processors/assignment_groups_processor_spec.rb +3 -4
  34. data/spec/canvas_sync/processors/assignment_overrides_processor_spec.rb +7 -4
  35. data/spec/canvas_sync/processors/assignments_processor_spec.rb +3 -4
  36. data/spec/canvas_sync/processors/content_migrations_processor_spec.rb +3 -4
  37. data/spec/canvas_sync/processors/context_module_items_processor_spec.rb +4 -5
  38. data/spec/canvas_sync/processors/context_modules_processor_spec.rb +3 -4
  39. data/spec/canvas_sync/processors/course_completion_report_processor_spec.rb +7 -4
  40. data/spec/canvas_sync/processors/provisioning_report_processor_spec.rb +46 -24
  41. data/spec/canvas_sync/processors/rubric_assessments_spec.rb +3 -4
  42. data/spec/canvas_sync/processors/rubric_associations_spec.rb +3 -4
  43. data/spec/canvas_sync/processors/rubrics_processor_spec.rb +3 -4
  44. data/spec/canvas_sync/processors/submissions_processor_spec.rb +3 -4
  45. data/spec/factories/account_factory.rb +1 -1
  46. metadata +7 -33
  47. data/lib/canvas_sync/jobs/report_checker.rb +0 -108
  48. data/lib/canvas_sync/jobs/report_processor_job.rb +0 -35
  49. data/lib/canvas_sync/processors/assignment_groups_processor.rb +0 -19
  50. data/lib/canvas_sync/processors/assignment_overrides_processor.rb +0 -41
  51. data/lib/canvas_sync/processors/assignments_processor.rb +0 -19
  52. data/lib/canvas_sync/processors/content_migrations_processor.rb +0 -19
  53. data/lib/canvas_sync/processors/context_module_items_processor.rb +0 -19
  54. data/lib/canvas_sync/processors/context_modules_processor.rb +0 -19
  55. data/lib/canvas_sync/processors/course_completion_report_processor.rb +0 -20
  56. data/lib/canvas_sync/processors/provisioning_report_processor.rb +0 -149
  57. data/lib/canvas_sync/processors/rubric_assessments_processor.rb +0 -19
  58. data/lib/canvas_sync/processors/rubric_associations_processor.rb +0 -19
  59. data/lib/canvas_sync/processors/rubrics_processor.rb +0 -19
  60. data/lib/canvas_sync/processors/submissions_processor.rb +0 -19
  61. data/spec/canvas_sync/jobs/report_checker_spec.rb +0 -57
  62. data/spec/canvas_sync/jobs/report_processor_job_spec.rb +0 -25
  63. data/spec/canvas_sync/jobs/sync_assignment_groups_job_spec.rb +0 -18
  64. data/spec/canvas_sync/jobs/sync_assignments_job_spec.rb +0 -30
  65. data/spec/canvas_sync/jobs/sync_content_migrations_job_spec.rb +0 -30
  66. data/spec/canvas_sync/jobs/sync_context_module_items_job_spec.rb +0 -30
  67. data/spec/canvas_sync/jobs/sync_context_modules_job_spec.rb +0 -30
  68. data/spec/canvas_sync/jobs/sync_scores_job_spec.rb +0 -15
  69. data/spec/canvas_sync/jobs/sync_submissions_job_spec.rb +0 -23
@@ -1,15 +1,7 @@
1
1
  module CanvasSync
2
2
  module Jobs
3
- class SyncRubricAssociationsJob < ReportStarter
4
- # @param options [Hash]
5
- def perform(options)
6
- super(
7
- "rubric_associations_csv",
8
- merge_report_params(options),
9
- CanvasSync::Processors::RubricAssociationsProcessor.to_s,
10
- {},
11
- )
12
- end
3
+ class SyncRubricAssociationsJob < ReportSyncTask
4
+ report_name "rubric_associations_csv"
13
5
  end
14
6
  end
15
7
  end
@@ -1,15 +1,7 @@
1
1
  module CanvasSync
2
2
  module Jobs
3
- class SyncRubricsJob < ReportStarter
4
- # @param options [Hash]
5
- def perform(options)
6
- super(
7
- "rubrics_csv",
8
- merge_report_params(options),
9
- CanvasSync::Processors::RubricsProcessor.to_s,
10
- {},
11
- )
12
- end
3
+ class SyncRubricsJob < ReportSyncTask
4
+ report_name "rubrics_csv"
13
5
  end
14
6
  end
15
7
  end
@@ -1,18 +1,7 @@
1
1
  module CanvasSync
2
2
  module Jobs
3
- class SyncScoresJob < ReportStarter
4
- # @param options [Hash]
5
- def perform(options)
6
- super(
7
- "proserv_scores_data_csv",
8
- merge_report_params(options),
9
- CanvasSync::Processors::NormalProcessor.to_s,
10
- {
11
- klass: 'Score',
12
- mapping: 'scores'
13
- },
14
- )
15
- end
3
+ class SyncScoresJob < ReportSyncTask
4
+ report_name "proserv_scores_data_csv"
16
5
  end
17
6
  end
18
7
  end
@@ -1,23 +1,14 @@
1
1
  module CanvasSync
2
2
  module Jobs
3
- class SyncSubmissionsJob < ReportStarter
4
- # Syncs Submissions
5
- #
6
- # Starts a report processor for the submission report
7
- # (the proserv_student_submissions_csv report must be enabled)
8
- #
9
- # @param options [Hash]
10
- def perform(options)
11
- super(
12
- "proserv_student_submissions_csv",
13
- merge_report_params(options, {
14
- include_all: options[:include_all],
15
- enrollment_batch_size: options[:enrollment_batch_size],
16
- include_all_except: options[:include_all_except]
17
- }, {}),
18
- CanvasSync::Processors::SubmissionsProcessor.to_s,
19
- {},
20
- )
3
+ class SyncSubmissionsJob < ReportSyncTask
4
+ report_name "proserv_student_submissions_csv"
5
+
6
+ def report_parameters
7
+ merge_report_params(options, {
8
+ include_all: options[:include_all],
9
+ enrollment_batch_size: options[:enrollment_batch_size],
10
+ include_all_except: options[:include_all_except]
11
+ })
21
12
  end
22
13
  end
23
14
  end
@@ -28,13 +28,15 @@ module CanvasSync
28
28
  end
29
29
 
30
30
  JobBatches::ManagedBatchJob.make_batch(jobs, ordered: false, concurrency: 8) do |b|
31
- b.description = "TermBatchJob(#{term_id}) Root"
31
+ b.description = "Term##{term_id} Fork"
32
32
  b.context = local_context
33
33
  b.on(:success, "#{self.class.to_s}.batch_finished") unless options[:mark_synced] == false
34
34
  end
35
35
  end
36
36
  else
37
- JobBatches::ConcurrentBatchJob.make_batch(jobs, context: context, concurrency: 8)
37
+ JobBatches::ConcurrentBatchJob.make_batch(jobs, context: context, concurrency: 8) do |b|
38
+ b.description = "All Terms"
39
+ end
38
40
  end
39
41
  end
40
42
  end
@@ -1,3 +1,3 @@
1
1
  module CanvasSync
2
- VERSION = "0.26.1".freeze
2
+ VERSION = "0.27.1.beta2".freeze
3
3
  end
data/lib/canvas_sync.rb CHANGED
@@ -10,14 +10,12 @@ require "canvas_sync/api_syncable"
10
10
  require "canvas_sync/record"
11
11
  require "canvas_sync/live_events"
12
12
  require "canvas_sync/jobs/report_starter"
13
- require "canvas_sync/jobs/report_checker"
14
- require "canvas_sync/jobs/report_processor_job"
15
13
  require "canvas_sync/batch_processor"
16
14
  require "canvas_sync/config"
17
15
 
18
16
  require "joblin"
19
17
 
20
- Dir[File.dirname(__FILE__) + "/canvas_sync/jobs/*.rb"].each { |file| require file }
18
+ Dir[File.dirname(__FILE__) + "/canvas_sync/jobs/**/*.rb"].each { |file| require file }
21
19
  Dir[File.dirname(__FILE__) + "/canvas_sync/processors/*.rb"].each { |file| require file }
22
20
  Dir[File.dirname(__FILE__) + "/canvas_sync/importers/*.rb"].each { |file| require file }
23
21
  Dir[File.dirname(__FILE__) + "/canvas_sync/generators/*.rb"].each { |file| require file }
@@ -172,6 +170,11 @@ module CanvasSync
172
170
  options: {},
173
171
  **kwargs
174
172
  ) # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/LineLength
173
+ if CanvasSync::SyncBatch.where(batch_genre: 'beta_cleanup', status: 'processing').count > 0
174
+ Rails.logger.warn("There is currently a batch of genre 'beta_cleanup' in progress, skipping new provisioning sync to avoid conflicts.")
175
+ return
176
+ end
177
+
175
178
  return unless models.present?
176
179
  models.map! &:to_s
177
180
  term_scope = term_scope.to_s if term_scope
@@ -201,6 +204,7 @@ module CanvasSync
201
204
 
202
205
  root_chain = base_canvas_sync_chain(**kwargs, globals: options[:global] || kwargs[:globals])
203
206
  concurrent_root_chain = JobBatches::ChainBuilder.new(JobBatches::ConcurrentBatchJob)
207
+ concurrent_root_chain.kwargs[:description] = "Default Concurrent Batch"
204
208
  root_chain << concurrent_root_chain
205
209
  current_chain = concurrent_root_chain
206
210
 
@@ -260,10 +264,33 @@ module CanvasSync
260
264
  if given_models.include?('pseudonyms')
261
265
  root_chain << Concerns::UserViaPseudonym::RefreshUserCachesJob
262
266
  end
263
-
264
267
  root_chain
265
268
  end
266
269
 
270
+ # wrapper around the default provisioning chain for the weekly beta refresh
271
+ def default_beta_cleanup_chain(models, term_scope: nil, term_scoped_models: DEFAULT_TERM_SCOPE_MODELS, options: {}, **kwargs)
272
+ updated_after = kwargs[:updated_after] || 2.weeks.ago
273
+
274
+ job_chain = default_provisioning_report_chain(
275
+ models,
276
+ term_scope: term_scope,
277
+ term_scoped_models: term_scoped_models,
278
+ batch_genre: 'beta_cleanup',
279
+ updated_after:,
280
+ options: options,
281
+ **kwargs
282
+ )
283
+ return if job_chain.nil?
284
+
285
+ # We add a job to create temporary tables at the start of the chain for each model
286
+ # and transfer data into it in order to compare it later with the re-synced data
287
+ job_chain.insert_at(0, { job: CanvasSync::Jobs::BetaCleanup::CreateTempTablesJob.to_s, options: { models:, updated_after: } })
288
+ # >> CanvasSync default provisioning chain would be in this position HERE <<
289
+ job_chain.insert({ job: CanvasSync::Jobs::BetaCleanup::DeleteRelatedRecordsJob.to_s, options: { models: } })
290
+ job_chain.insert({ job: CanvasSync::Jobs::BetaCleanup::DeleteTempTablesJob.to_s, options: { models: } })
291
+ job_chain
292
+ end
293
+
267
294
  def base_canvas_sync_chain(
268
295
  legacy_support: false, # Import records 1 by 1 instead of with bulk upserts
269
296
  account_id: nil, # legacy/non PandaPal apps
@@ -30,7 +30,7 @@ RSpec.describe CanvasSync do
30
30
  provisioning: { c: 3 },
31
31
  global: { d: 4 },
32
32
  })
33
- expect(chain.normalize!).to eq({
33
+ expect(chain.normalize!).to match({
34
34
  :job => "CanvasSync::Jobs::BeginSyncChainJob",
35
35
  :args => [
36
36
  [
@@ -51,7 +51,7 @@ RSpec.describe CanvasSync do
51
51
  },
52
52
  ],
53
53
  ],
54
- :kwargs=>{},
54
+ :kwargs=>{ description: String },
55
55
  },
56
56
  ],
57
57
  ],
@@ -62,7 +62,7 @@ RSpec.describe CanvasSync do
62
62
  context 'we are syncing users with a term scope' do
63
63
  it 'syncs the users in a separate job that runs first' do
64
64
  chain = CanvasSync.default_provisioning_report_chain(['users', 'courses'], term_scope: :active)
65
- expect(chain.normalize!).to eq({
65
+ expect(chain.normalize!).to match({
66
66
  :job => "CanvasSync::Jobs::BeginSyncChainJob",
67
67
  :args => [[
68
68
  {
@@ -82,7 +82,7 @@ RSpec.describe CanvasSync do
82
82
  }
83
83
  ]
84
84
  ],
85
- :kwargs=>{},
85
+ :kwargs=>{ description: String },
86
86
  }
87
87
  ]],
88
88
  :kwargs => {:legacy_support=>false, :updated_after=>nil, :full_sync_every=>nil, :batch_genre=>nil},
@@ -93,7 +93,7 @@ RSpec.describe CanvasSync do
93
93
  context 'we are syncing users without a term scope' do
94
94
  it 'syncs users along with the rest of the provisioning report' do
95
95
  chain = CanvasSync.default_provisioning_report_chain(['users', 'courses'])
96
- expect(chain.normalize!).to eq({
96
+ expect(chain.normalize!).to match({
97
97
  :job => "CanvasSync::Jobs::BeginSyncChainJob",
98
98
  :args => [[
99
99
  {
@@ -109,7 +109,7 @@ RSpec.describe CanvasSync do
109
109
  }
110
110
  }
111
111
  ]],
112
- :kwargs=>{}
112
+ :kwargs=>{ description: String }
113
113
  }
114
114
  ]],
115
115
  :kwargs => {:legacy_support=>false, :updated_after=>nil, :full_sync_every=>nil, :batch_genre=>nil},
@@ -120,7 +120,7 @@ RSpec.describe CanvasSync do
120
120
  context 'we are syncing roles with a term scope' do
121
121
  it 'syncs the roles in a separate job that runs first' do
122
122
  chain = CanvasSync.default_provisioning_report_chain(['roles', 'courses'], term_scope: :active)
123
- expect(chain.normalize!).to eq({
123
+ expect(chain.normalize!).to match({
124
124
  :job => "CanvasSync::Jobs::BeginSyncChainJob",
125
125
  :args => [[
126
126
  {
@@ -136,7 +136,7 @@ RSpec.describe CanvasSync do
136
136
  }
137
137
  },
138
138
  ]],
139
- :kwargs=>{}
139
+ :kwargs=>{ description: String }
140
140
  }
141
141
  ]],
142
142
  :kwargs => {:batch_genre=>nil, :full_sync_every=>nil, :legacy_support=>false, :updated_after=>nil},
@@ -147,7 +147,7 @@ RSpec.describe CanvasSync do
147
147
  context 'we are syncing roles without a term scope' do
148
148
  it 'syncs roles separately even with no term scope' do
149
149
  chain = CanvasSync.default_provisioning_report_chain(['roles', 'courses'])
150
- expect(chain.normalize!).to eq({
150
+ expect(chain.normalize!).to match({
151
151
  :job => "CanvasSync::Jobs::BeginSyncChainJob",
152
152
  :args => [[
153
153
  {
@@ -163,7 +163,7 @@ RSpec.describe CanvasSync do
163
163
  }
164
164
  }
165
165
  ]],
166
- :kwargs=>{}
166
+ :kwargs=>{ description: String }
167
167
  }
168
168
  ]],
169
169
  :kwargs => {:batch_genre=>nil, :full_sync_every=>nil, :legacy_support=>false, :updated_after=>nil},
@@ -172,7 +172,7 @@ RSpec.describe CanvasSync do
172
172
 
173
173
  it 'passes along options to the roles job' do
174
174
  chain = CanvasSync.default_provisioning_report_chain(['roles', 'courses'], options: { roles: { show_inherited: true } } )
175
- expect(chain.normalize!).to eq({
175
+ expect(chain.normalize!).to match({
176
176
  :job => "CanvasSync::Jobs::BeginSyncChainJob",
177
177
  :args => [[
178
178
  {
@@ -188,7 +188,7 @@ RSpec.describe CanvasSync do
188
188
  }
189
189
  }
190
190
  ]],
191
- :kwargs=>{}
191
+ :kwargs=>{ description: String }
192
192
  }
193
193
  ]],
194
194
  :kwargs => {:batch_genre=>nil, :full_sync_every=>nil, :legacy_support=>false, :updated_after=>nil},
@@ -200,7 +200,7 @@ RSpec.describe CanvasSync do
200
200
  context 'we are syncing admins with a term scope' do
201
201
  it 'syncs the admins in a separate job that runs first' do
202
202
  chain = CanvasSync.default_provisioning_report_chain(['admins', 'courses'], term_scope: :active)
203
- expect(chain.normalize!).to eq({
203
+ expect(chain.normalize!).to match({
204
204
  :job => "CanvasSync::Jobs::BeginSyncChainJob",
205
205
  :args => [[
206
206
  {
@@ -216,7 +216,7 @@ RSpec.describe CanvasSync do
216
216
  }
217
217
  }
218
218
  ]],
219
- :kwargs=>{}
219
+ :kwargs=>{ description: String }
220
220
  }
221
221
  ]],
222
222
  :kwargs => {:batch_genre=>nil, :full_sync_every=>nil, :legacy_support=>false, :updated_after=>nil},
@@ -227,7 +227,7 @@ RSpec.describe CanvasSync do
227
227
  context 'we are syncing admins without a term scope' do
228
228
  it 'syncs admins separately even with no term scope' do
229
229
  chain = CanvasSync.default_provisioning_report_chain(['admins', 'courses'])
230
- expect(chain.normalize!).to eq({
230
+ expect(chain.normalize!).to match({
231
231
  :job => "CanvasSync::Jobs::BeginSyncChainJob",
232
232
  :args => [[
233
233
  {
@@ -243,7 +243,7 @@ RSpec.describe CanvasSync do
243
243
  }
244
244
  }
245
245
  ]],
246
- :kwargs=>{}
246
+ :kwargs=>{ description: String }
247
247
  }
248
248
  ]],
249
249
  :kwargs => {:batch_genre=>nil, :full_sync_every=>nil, :legacy_support=>false, :updated_after=>nil},
@@ -255,7 +255,7 @@ RSpec.describe CanvasSync do
255
255
  it "appends the SyncAssignmentsJob" do
256
256
  chain = CanvasSync.default_provisioning_report_chain(%w[users enrollments assignments])
257
257
 
258
- expect(chain.normalize!).to eq({
258
+ expect(chain.normalize!).to match({
259
259
  :job => "CanvasSync::Jobs::BeginSyncChainJob",
260
260
  :args => [[
261
261
  {
@@ -274,7 +274,7 @@ RSpec.describe CanvasSync do
274
274
  }
275
275
  }
276
276
  ]],
277
- :kwargs=>{}
277
+ :kwargs=>{ description: String }
278
278
  }
279
279
  ]],
280
280
  :kwargs => {:batch_genre=>nil, :full_sync_every=>nil, :legacy_support=>false, :updated_after=>nil},
@@ -286,7 +286,7 @@ RSpec.describe CanvasSync do
286
286
  it "appends the SyncSubmissionsJob" do
287
287
  chain = CanvasSync.default_provisioning_report_chain(%w[users enrollments submissions])
288
288
 
289
- expect(chain.normalize!).to eq({
289
+ expect(chain.normalize!).to match({
290
290
  :job => "CanvasSync::Jobs::BeginSyncChainJob",
291
291
  :args => [[
292
292
  {
@@ -305,7 +305,7 @@ RSpec.describe CanvasSync do
305
305
  }
306
306
  }
307
307
  ]],
308
- :kwargs=>{}
308
+ :kwargs=>{ description: String }
309
309
  }
310
310
  ]],
311
311
  :kwargs => {:batch_genre=>nil, :full_sync_every=>nil, :legacy_support=>false, :updated_after=>nil},
@@ -317,7 +317,7 @@ RSpec.describe CanvasSync do
317
317
  it "appends the SyncAssignmentGroupsJob" do
318
318
  chain = CanvasSync.default_provisioning_report_chain(%w[users enrollments assignment_groups])
319
319
 
320
- expect(chain.normalize!).to eq({
320
+ expect(chain.normalize!).to match({
321
321
  :job => "CanvasSync::Jobs::BeginSyncChainJob",
322
322
  :args => [[
323
323
  {
@@ -336,7 +336,7 @@ RSpec.describe CanvasSync do
336
336
  }
337
337
  }
338
338
  ]],
339
- :kwargs=>{}
339
+ :kwargs=>{ description: String }
340
340
  }
341
341
  ]],
342
342
  :kwargs => {:batch_genre=>nil, :full_sync_every=>nil, :legacy_support=>false, :updated_after=>nil},
@@ -344,6 +344,46 @@ RSpec.describe CanvasSync do
344
344
  end
345
345
  end
346
346
  end
347
+ context "there is a beta cleanup batch in progress" do
348
+ it "does not start a provisioning sync" do
349
+ CanvasSync::SyncBatch.create!(batch_genre: "beta_cleanup", status: "processing")
350
+ expect(CanvasSync.default_beta_cleanup_chain(%w[users])).to be_nil
351
+ end
352
+ end
353
+ end
354
+
355
+ describe ".default_beta_cleanup_chain" do
356
+ it "creates a batch of genre 'beta_cleanup'" do
357
+ updated_after = 2.weeks.ago
358
+ chain = CanvasSync.default_beta_cleanup_chain(%w[users enrollments], updated_after:)
359
+ expect(chain.normalize!).to eq({
360
+ :job=>"CanvasSync::Jobs::BeginSyncChainJob",
361
+ :args=>
362
+ [[{:job=>"CanvasSync::Jobs::BetaCleanup::CreateTempTablesJob",
363
+ :options=>
364
+ {:models=>["users", "enrollments"], :updated_after=>updated_after}},
365
+ {:job=>"Joblin::Batching::ConcurrentBatchJob",
366
+ :args=>
367
+ [[{:job=>"CanvasSync::Jobs::SyncProvisioningReportJob", :options=>{:models=>["users"]}},
368
+ {:job=>"CanvasSync::Jobs::SyncTermsJob",
369
+ :args=>[],
370
+ :kwargs=>
371
+ {:term_scope=>nil,
372
+ :sub_jobs=>
373
+ [{:job=>"CanvasSync::Jobs::SyncProvisioningReportJob",
374
+ :options=>{:models=>["enrollments"]}}]}}]],
375
+ :kwargs=>{:description=>"Default Concurrent Batch"}},
376
+ {:job=>"CanvasSync::Jobs::BetaCleanup::DeleteRelatedRecordsJob",
377
+ :options=>{:models=>["users", "enrollments"]}},
378
+ {:job=>"CanvasSync::Jobs::BetaCleanup::DeleteTempTablesJob",
379
+ :options=>{:models=>["users", "enrollments"]}}]],
380
+ :kwargs=>
381
+ {:legacy_support=>false,
382
+ :updated_after=>updated_after,
383
+ :full_sync_every=>nil,
384
+ :batch_genre=>"beta_cleanup"}
385
+ })
386
+ end
347
387
  end
348
388
 
349
389
  describe ".sync_scope" do
@@ -4,69 +4,116 @@ RSpec.describe CanvasSync::Jobs::ReportStarter do
4
4
  let(:report_params) { { 'parameters[users]' => true } }
5
5
  let(:report_name) { 'provisioning_csv' }
6
6
  let(:processor) { 'CoolProcessor' }
7
- let(:report_checker_double) { double }
8
7
  let(:options) { { models: ['users'] } }
9
8
 
10
9
  describe '#perform' do
11
- it 'tells Canvas to start the report and then enqueues a ReportChecker with the report id' do
12
- expect_any_instance_of(Bearcat::Client).to receive(:start_report)
13
- .with('self', report_name, report_params)
14
- .and_return({ 'id' => 1 })
10
+ it 'delegates to LegacyReportShimTask with merged options' do
11
+ expect(CanvasSync::Jobs::LegacyReportShimTask).to receive(:perform_later) do |merged_options|
12
+ expect(merged_options[:models]).to eq(['users'])
13
+ expect(merged_options[:legacy_report_starter][:report]).to eq(report_name)
14
+ expect(merged_options[:legacy_report_starter][:params]).to eq(report_params)
15
+ expect(merged_options[:legacy_report_starter][:processor]).to eq(processor)
16
+ end
17
+
18
+ CanvasSync::Jobs::ReportStarter.perform_now(
19
+ report_name,
20
+ report_params,
21
+ processor,
22
+ options
23
+ )
24
+ end
25
+
26
+ it 'passes through allow_redownloads option' do
27
+ expect(CanvasSync::Jobs::LegacyReportShimTask).to receive(:perform_later)
28
+
29
+ CanvasSync::Jobs::ReportStarter.perform_now(
30
+ report_name,
31
+ report_params,
32
+ processor,
33
+ options,
34
+ allow_redownloads: true
35
+ )
36
+ end
37
+
38
+ it 'preserves original options' do
39
+ options_with_extras = options.merge({
40
+ account_id: '12345',
41
+ canvas_term_id: 99
42
+ })
15
43
 
16
- expect(CanvasSync::Jobs::ReportChecker).to receive(:set).and_call_original
44
+ expect(CanvasSync::Jobs::LegacyReportShimTask).to receive(:perform_later) do |merged_options|
45
+ expect(merged_options[:account_id]).to eq('12345')
46
+ expect(merged_options[:canvas_term_id]).to eq(99)
47
+ expect(merged_options[:models]).to eq(['users'])
48
+ end
17
49
 
18
50
  CanvasSync::Jobs::ReportStarter.perform_now(
19
- report_name,
20
- report_params,
21
- processor,
22
- options)
51
+ report_name,
52
+ report_params,
53
+ processor,
54
+ options_with_extras
55
+ )
23
56
  end
57
+ end
58
+
59
+ describe 'LegacyReportShimTask' do
60
+ let(:legacy_options) do
61
+ {
62
+ models: ['users'],
63
+ legacy_report_starter: {
64
+ report: report_name,
65
+ params: report_params,
66
+ processor: processor
67
+ }
68
+ }
69
+ end
70
+
71
+ describe '#report_name' do
72
+ it 'extracts report name from legacy options' do
73
+ task = CanvasSync::Jobs::LegacyReportShimTask.new(legacy_options, {}, {})
74
+ expect(task.report_name).to eq(report_name)
75
+ end
76
+ end
77
+
78
+ describe '#report_parameters' do
79
+ it 'extracts report parameters from legacy options' do
80
+ task = CanvasSync::Jobs::LegacyReportShimTask.new(legacy_options, {}, {})
81
+ expect(task.report_parameters).to eq(report_params)
82
+ end
83
+ end
84
+
85
+ describe '#process' do
86
+ it 'calls the processor class with file, options, and account_id' do
87
+ processor_class = double('CoolProcessor')
88
+ stub_const('CoolProcessor', processor_class)
89
+
90
+ task = CanvasSync::Jobs::LegacyReportShimTask.new(legacy_options, {}, {})
91
+ allow(task).to receive(:batch_context).and_return({})
92
+
93
+ expect(processor_class).to receive(:process).with(
94
+ '/path/to/file.csv',
95
+ legacy_options,
96
+ 'self'
97
+ )
98
+
99
+ task.process('/path/to/file.csv')
100
+ end
101
+
102
+ it 'uses account_id from options if present' do
103
+ processor_class = double('CoolProcessor')
104
+ stub_const('CoolProcessor', processor_class)
105
+
106
+ options_with_account = legacy_options.merge(account_id: '12345')
107
+ task = CanvasSync::Jobs::LegacyReportShimTask.new(options_with_account, {}, {})
108
+ allow(task).to receive(:batch_context).and_return({})
109
+
110
+ expect(processor_class).to receive(:process).with(
111
+ '/path/to/file.csv',
112
+ options_with_account,
113
+ '12345'
114
+ )
24
115
 
25
- context 'allow_redownloads is true' do
26
- # context 'the report has already been cached' do
27
- # it 'runs the report checker for the already started report' do
28
- # expect_any_instance_of(Bearcat::Client).to_not receive(:start_report)
29
-
30
- # expect(CanvasSync::Jobs::ReportChecker).to receive(:set).and_return(report_checker_double)
31
- # expect(report_checker_double).to receive(:perform_later).with(
32
- # report_name,
33
- # 1,
34
- # processor,
35
- # options
36
- # )
37
-
38
- # CanvasSync::Jobs::ReportStarter.perform_now(
39
- # report_name,
40
- # report_params,
41
- # processor,
42
- # options,
43
- # allow_redownloads: true
44
- # )
45
- # end
46
- # end
47
-
48
- context 'the report has not been started before' do
49
- it 'starts a new report and caches the report id' do
50
- expect_any_instance_of(Bearcat::Client).to receive(:start_report)
51
- .with('self', report_name, report_params)
52
- .and_return({ 'id' => 1 })
53
-
54
- expect(CanvasSync::Jobs::ReportChecker).to receive(:set).and_return(report_checker_double)
55
- expect(report_checker_double).to receive(:perform_later).with(
56
- report_name,
57
- 1,
58
- processor,
59
- options
60
- )
61
-
62
- CanvasSync::Jobs::ReportStarter.perform_now(
63
- report_name,
64
- report_params,
65
- processor,
66
- options,
67
- allow_redownloads: true
68
- )
69
- end
116
+ task.process('/path/to/file.csv')
70
117
  end
71
118
  end
72
119
  end