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
@@ -0,0 +1,367 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe CanvasSync::Jobs::ReportSyncTask do
4
+ class SyncSpecsTask < CanvasSync::Jobs::ReportSyncTask
5
+ report_name 'sync_specs_csv'
6
+
7
+ def report_parameters
8
+ merge_report_params(options, { include_all: options[:include_all] })
9
+ end
10
+ end
11
+
12
+ let(:batch_context) { { canvas_term_id: 1 }.with_indifferent_access }
13
+
14
+ def stub_batch_context(context = batch_context)
15
+ report_batch = instance_double(CanvasSync::JobBatches::Batch,
16
+ context: { report_class: 'SyncSpecsTask', report_options: {} })
17
+ parent_batch = instance_double(CanvasSync::JobBatches::Batch, context: context)
18
+
19
+ allow(CanvasSync::JobBatches::Batch).to receive(:current).and_return(report_batch)
20
+ allow(CanvasSync::JobBatches::Batch).to receive(:current_context).and_return(context)
21
+ allow(report_batch).to receive(:parent).and_return(parent_batch)
22
+ end
23
+
24
+ def create_job(job_class, context = batch_context)
25
+ job_class.new.tap { |job| allow(job).to receive(:batch_context).and_return(context) }
26
+ end
27
+
28
+ describe "#report_parameters" do
29
+ before { allow(CanvasSync::JobBatches::Batch).to receive(:current_context).and_return(batch_context) }
30
+
31
+ it "merges batch context parameters" do
32
+ task = SyncSpecsTask.new({}, { canvas_term_id: 123, updated_after: '2024-01-01' }, {})
33
+ allow(CanvasSync::JobBatches::Batch).to receive(:current_context)
34
+ .and_return({ canvas_term_id: 123, updated_after: '2024-01-01' })
35
+
36
+ expect(task.report_parameters).to eq({
37
+ parameters: { enrollment_term_id: 123, updated_after: '2024-01-01', include_all: nil }
38
+ })
39
+ end
40
+
41
+ it "merges options parameters" do
42
+ task = SyncSpecsTask.new({ canvas_term_id: 456, include_all: true }, {}, {})
43
+ allow(CanvasSync::JobBatches::Batch).to receive(:current_context).and_return({})
44
+
45
+ expect(task.report_parameters).to eq({
46
+ parameters: { enrollment_term_id: 456, include_all: true }
47
+ })
48
+ end
49
+
50
+ it "prioritizes options over batch context" do
51
+ task = SyncSpecsTask.new({ canvas_term_id: 789 }, {}, {})
52
+ allow(CanvasSync::JobBatches::Batch).to receive(:current_context)
53
+ .and_return({ canvas_term_id: 123 })
54
+
55
+ expect(task.report_parameters[:parameters][:enrollment_term_id]).to eq(789)
56
+ end
57
+
58
+ it "merges report_params and report_parameters from options" do
59
+ task = SyncSpecsTask.new({
60
+ report_params: { custom: 'value' },
61
+ report_parameters: { another: 'value' }
62
+ }, {}, {})
63
+ allow(CanvasSync::JobBatches::Batch).to receive(:current_context).and_return({})
64
+
65
+ params = task.report_parameters[:parameters]
66
+ expect(params[:custom]).to eq('value')
67
+ expect(params[:another]).to eq('value')
68
+ end
69
+ end
70
+
71
+ describe ".perform_later" do
72
+ it "creates a batch and enqueues StarterJob" do
73
+ batch = instance_double(CanvasSync::JobBatches::Batch)
74
+ allow(CanvasSync::JobBatches::Batch).to receive(:new).and_return(batch)
75
+ allow(batch).to receive(:description=)
76
+ allow(batch).to receive(:allow_context_changes=)
77
+ allow(batch).to receive(:context).and_return({})
78
+
79
+ expect(batch).to receive(:jobs) do |&block|
80
+ expect(SyncSpecsTask::StarterJob).to receive(:perform_later)
81
+ block.call
82
+ end
83
+
84
+ SyncSpecsTask.perform_later({ include_all: true })
85
+ end
86
+ end
87
+
88
+ describe ".from_context" do
89
+ it "reconstructs task from batch context" do
90
+ stub_batch_context({ canvas_term_id: 1 })
91
+ allow(CanvasSync::JobBatches::Batch.current).to receive(:context)
92
+ .and_return({ report_class: 'SyncSpecsTask', report_options: { include_all: true } })
93
+
94
+ task = CanvasSync::Jobs::ReportSyncTask.from_context
95
+
96
+ expect(task).to be_a(SyncSpecsTask)
97
+ expect(task.options).to eq({ include_all: true })
98
+ end
99
+ end
100
+
101
+ describe described_class::StarterJob do
102
+ let(:client) { instance_double(Bearcat::Client) }
103
+
104
+ before do
105
+ stub_batch_context
106
+ allow_any_instance_of(Bearcat::Client).to receive(:start_report)
107
+ .and_return("id" => 123)
108
+ end
109
+
110
+ it "starts the report and enqueues checker" do
111
+ expect_any_instance_of(Bearcat::Client).to receive(:start_report)
112
+ .with("self", "sync_specs_csv", { parameters: { enrollment_term_id: 1, include_all: nil } })
113
+ expect(SyncSpecsTask::CheckerJob).to receive(:set).with(wait: anything)
114
+ .and_return(double(perform_later: nil))
115
+
116
+ job = create_job(SyncSpecsTask::StarterJob)
117
+ job.perform
118
+
119
+ expect(batch_context[:report_attempt]).to eq(1)
120
+ expect(batch_context[:report_id]).to eq("sync_specs_csv/123")
121
+ end
122
+
123
+ it "enqueues CheckerJob with wait time" do
124
+ checker_double = double
125
+ expect(SyncSpecsTask::CheckerJob).to receive(:set).with(wait: anything)
126
+ .and_return(checker_double)
127
+ expect(checker_double).to receive(:perform_later)
128
+
129
+ job = create_job(SyncSpecsTask::StarterJob)
130
+ job.perform
131
+ end
132
+
133
+ it "sets sync_start_time in batch context" do
134
+ allow(SyncSpecsTask::CheckerJob).to receive(:set)
135
+ .and_return(double(perform_later: nil))
136
+
137
+ job = create_job(SyncSpecsTask::StarterJob)
138
+ job.perform
139
+
140
+ expect(batch_context[:sync_start_time]).to be_present
141
+ end
142
+
143
+ context "with caching enabled" do
144
+ let(:redis_double) { double('Redis') }
145
+ let(:cache_key) { "SyncBatch[batch-123]:abc123def" }
146
+
147
+ before do
148
+ # CanvasSync.redis can be called with or without a block
149
+ allow(CanvasSync).to receive(:redis) do |&block|
150
+ if block
151
+ block.call(redis_double)
152
+ else
153
+ redis_double
154
+ end
155
+ end
156
+ batch_context[:sync_batch_id] = 'batch-123'
157
+ end
158
+
159
+ it "uses cached report when available and fresh" do
160
+ batch_context[:report_caching] = { scope: :sync_batch, max_age: 23.hours }
161
+ cached_data = {
162
+ "report_id" => "sync_specs_csv/999",
163
+ "started_at" => 1.hour.ago.iso8601
164
+ }
165
+
166
+ expect(redis_double).to receive(:hgetall).with(anything).and_return(cached_data)
167
+ expect_any_instance_of(Bearcat::Client).to_not receive(:start_report)
168
+ allow(SyncSpecsTask::CheckerJob).to receive(:set).and_return(double(perform_later: nil))
169
+
170
+ job = create_job(SyncSpecsTask::StarterJob)
171
+ job.perform
172
+
173
+ expect(batch_context[:report_id]).to eq("sync_specs_csv/999")
174
+ expect(batch_context[:sync_start_time]).to eq(cached_data["started_at"])
175
+ end
176
+
177
+ it "ignores stale cached report and starts new one" do
178
+ batch_context[:report_caching] = { scope: :sync_batch, max_age: 23.hours }
179
+ stale_cached_data = {
180
+ "report_id" => "sync_specs_csv/999",
181
+ "started_at" => 25.hours.ago.iso8601
182
+ }
183
+
184
+ expect(redis_double).to receive(:hgetall).with(anything).and_return(stale_cached_data)
185
+ expect_any_instance_of(Bearcat::Client).to receive(:start_report).and_return("id" => 123)
186
+ expect(redis_double).to receive(:hset).with(anything, hash_including(:report_id, :started_at))
187
+ expect(redis_double).to receive(:expire)
188
+ allow(SyncSpecsTask::CheckerJob).to receive(:set).and_return(double(perform_later: nil))
189
+
190
+ job = create_job(SyncSpecsTask::StarterJob)
191
+ job.perform
192
+
193
+ expect(batch_context[:report_id]).to eq("sync_specs_csv/123")
194
+ end
195
+
196
+ it "stores new report in cache" do
197
+ batch_context[:report_caching] = { scope: :sync_batch, max_age: 23.hours }
198
+
199
+ expect(redis_double).to receive(:hgetall).with(anything).and_return({})
200
+ expect_any_instance_of(Bearcat::Client).to receive(:start_report).and_return("id" => 123)
201
+ expect(redis_double).to receive(:hset).with(anything, hash_including(:report_id, :started_at))
202
+ expect(redis_double).to receive(:expire).with(anything, 23.hours.to_i)
203
+ allow(SyncSpecsTask::CheckerJob).to receive(:set).and_return(double(perform_later: nil))
204
+
205
+ job = create_job(SyncSpecsTask::StarterJob)
206
+ job.perform
207
+ end
208
+
209
+ it "uses custom max_age when specified" do
210
+ batch_context[:report_caching] = { scope: :sync_batch, max_age: 12.hours }
211
+
212
+ expect(redis_double).to receive(:hgetall).with(anything).and_return({})
213
+ expect_any_instance_of(Bearcat::Client).to receive(:start_report).and_return("id" => 123)
214
+ expect(redis_double).to receive(:hset)
215
+ expect(redis_double).to receive(:expire).with(anything, 12.hours.to_i)
216
+ allow(SyncSpecsTask::CheckerJob).to receive(:set).and_return(double(perform_later: nil))
217
+
218
+ job = create_job(SyncSpecsTask::StarterJob)
219
+ job.perform
220
+ end
221
+
222
+ it "supports task-level caching options" do
223
+ task_options = { caching: { scope: :sync_batch, max_age: 6.hours } }
224
+ allow(SyncSpecsTask).to receive(:new).and_return(
225
+ SyncSpecsTask.new(task_options, batch_context, batch_context)
226
+ )
227
+
228
+ expect(redis_double).to receive(:hgetall).with(anything).and_return({})
229
+ expect_any_instance_of(Bearcat::Client).to receive(:start_report).and_return("id" => 123)
230
+ expect(redis_double).to receive(:hset)
231
+ expect(redis_double).to receive(:expire).with(anything, 6.hours.to_i)
232
+ allow(SyncSpecsTask::CheckerJob).to receive(:set).and_return(double(perform_later: nil))
233
+
234
+ job = create_job(SyncSpecsTask::StarterJob)
235
+ allow(job).to receive(:report_task).and_return(
236
+ SyncSpecsTask.new(task_options, batch_context, batch_context)
237
+ )
238
+ job.perform
239
+ end
240
+ end
241
+ end
242
+
243
+ describe described_class::CheckerJob do
244
+ let(:batch_context) {
245
+ { canvas_term_id: 1, report_id: 'sync_specs_csv/123', report_attempt: 1 }.with_indifferent_access
246
+ }
247
+ let(:client) { instance_double(Bearcat::Client) }
248
+
249
+ before do
250
+ stub_batch_context(batch_context)
251
+ allow(CanvasSync).to receive(:get_canvas_sync_client).and_return(client)
252
+ end
253
+
254
+ context "when complete" do
255
+ it "enqueues ProcessJob" do
256
+ allow(client).to receive(:report_status)
257
+ .and_return("status" => "complete", "attachment" => { "url" => "http://example.com/report.csv" })
258
+
259
+ expect(SyncSpecsTask::ProcessJob).to receive(:perform_later).with("http://example.com/report.csv")
260
+
261
+ create_job(SyncSpecsTask::CheckerJob, batch_context).perform
262
+ end
263
+ end
264
+
265
+ context "when error or deleted" do
266
+ it "retries if under max_tries" do
267
+ allow(client).to receive(:report_status).and_return("status" => "error")
268
+ expect(client).to receive(:start_report).and_return("id" => 456)
269
+ expect(SyncSpecsTask::CheckerJob).to receive(:set).and_return(double(perform_later: nil))
270
+
271
+ create_job(SyncSpecsTask::CheckerJob, batch_context).perform
272
+
273
+ expect(batch_context[:report_attempt]).to eq(2)
274
+ end
275
+
276
+ it "handles deleted status the same as error" do
277
+ allow(client).to receive(:report_status).and_return("status" => "deleted")
278
+ expect(client).to receive(:start_report).and_return("id" => 456)
279
+ expect(SyncSpecsTask::CheckerJob).to receive(:set).and_return(double(perform_later: nil))
280
+
281
+ create_job(SyncSpecsTask::CheckerJob, batch_context).perform
282
+
283
+ expect(batch_context[:report_attempt]).to eq(2)
284
+ end
285
+
286
+ it "raises FatalReportError after max_tries" do
287
+ batch_context[:report_attempt] = 3
288
+ allow(client).to receive(:report_status).and_return("status" => "error")
289
+
290
+ expect {
291
+ create_job(SyncSpecsTask::CheckerJob, batch_context).perform
292
+ }.to raise_error(CanvasSync::Jobs::ReportSyncTask::FatalReportError)
293
+ end
294
+
295
+ it "does not re-enqueue or process when errored after max_tries" do
296
+ batch_context[:report_attempt] = 3
297
+ allow(client).to receive(:report_status).and_return("status" => "error")
298
+
299
+ expect(SyncSpecsTask::CheckerJob).to_not receive(:set)
300
+ expect(SyncSpecsTask::ProcessJob).to_not receive(:perform_later)
301
+
302
+ expect {
303
+ create_job(SyncSpecsTask::CheckerJob, batch_context).perform
304
+ }.to raise_error(CanvasSync::Jobs::ReportSyncTask::FatalReportError)
305
+ end
306
+ end
307
+
308
+ context "when still processing" do
309
+ it "re-enqueues itself" do
310
+ allow(client).to receive(:report_status).and_return("status" => "running")
311
+ expect(SyncSpecsTask::CheckerJob).to receive(:set).and_return(double(perform_later: nil))
312
+
313
+ create_job(SyncSpecsTask::CheckerJob, batch_context).perform
314
+ end
315
+
316
+ it "raises FatalReportError on timeout" do
317
+ batch_context[:sync_start_time] = (DateTime.now - 25.hours).iso8601
318
+ allow(client).to receive(:report_status).and_return("status" => "running")
319
+
320
+ expect {
321
+ create_job(SyncSpecsTask::CheckerJob, batch_context).perform
322
+ }.to raise_error(CanvasSync::Jobs::ReportSyncTask::FatalReportError, /stuck/)
323
+ end
324
+ end
325
+
326
+ context "when compiling" do
327
+ it "tracks compilation start time" do
328
+ allow(client).to receive(:report_status).and_return("status" => "compiling")
329
+ expect(SyncSpecsTask::CheckerJob).to receive(:set).and_return(double(perform_later: nil))
330
+
331
+ create_job(SyncSpecsTask::CheckerJob, batch_context).perform
332
+
333
+ expect(batch_context[:compiling_since]).to be_present
334
+ end
335
+
336
+ it "raises FatalReportError on compilation timeout" do
337
+ batch_context[:compiling_since] = (DateTime.now - 4.hours).iso8601
338
+ allow(client).to receive(:report_status).and_return("status" => "compiling")
339
+
340
+ expect {
341
+ create_job(SyncSpecsTask::CheckerJob, batch_context).perform
342
+ }.to raise_error(CanvasSync::Jobs::ReportSyncTask::FatalReportError, /stuck/)
343
+ end
344
+ end
345
+ end
346
+
347
+ describe described_class::ProcessJob do
348
+ let(:batch_context) { { report_id: 'sync_specs_csv/123' }.with_indifferent_access }
349
+ let(:client) { instance_double(Bearcat::Client) }
350
+
351
+ before do
352
+ stub_batch_context(batch_context)
353
+ allow(CanvasSync).to receive(:get_canvas_sync_client).and_return(client)
354
+ end
355
+
356
+ it "downloads and processes the report" do
357
+ allow(client).to receive(:download_report)
358
+ task = instance_double(SyncSpecsTask)
359
+ allow(SyncSpecsTask).to receive(:new).and_return(task)
360
+ expect(task).to receive(:process)
361
+
362
+ job = create_job(SyncSpecsTask::ProcessJob, batch_context)
363
+ allow(job).to receive(:canvas_sync_client).and_return(client)
364
+ job.perform("http://example.com/report.csv")
365
+ end
366
+ end
367
+ end
@@ -1,50 +1,39 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  RSpec.describe CanvasSync::Jobs::SyncProvisioningReportJob do
4
- describe '#perform' do
4
+ describe '#report_parameters' do
5
5
  context 'a term scope is specified' do
6
6
  let!(:term) { FactoryBot.create(:term) }
7
7
 
8
- it 'enqueues a ReportStarter for a provisioning report for the specified models for each term' do
9
- expect_any_instance_of(CanvasSync::Jobs::ReportStarter).to receive(:start_report)
10
- .with(
11
- 'self',
12
- 'proservices_provisioning_csv',
13
- {
14
- parameters: {
15
- include_deleted: true,
16
- 'users' => true,
17
- 'courses' => true,
18
- enrollment_term_id: term.canvas_id,
19
- }
20
- },
21
- )
8
+ it 'includes term_id and model parameters' do
9
+ task = described_class.new({ models: ['users', 'courses'], term_scope: 'active' }, {}, {})
10
+ allow(CanvasSync::JobBatches::Batch).to receive(:current_context).and_return({ canvas_term_id: term.canvas_id })
22
11
 
23
- set_batch_context(canvas_term_id: term.canvas_id)
24
- CanvasSync::Jobs::SyncProvisioningReportJob.perform_now(
25
- { models: ['users', 'courses'], term_scope: 'active' }
26
- )
12
+ params = task.report_parameters
13
+ expect(params).to eq({
14
+ parameters: {
15
+ include_deleted: true,
16
+ 'users' => true,
17
+ 'courses' => true,
18
+ enrollment_term_id: term.canvas_id,
19
+ }
20
+ })
27
21
  end
28
22
  end
29
23
 
30
24
  context 'a term scope is not specified' do
31
- it 'enqueues a single ReportStarter for a provisioning report across all terms for the specified models' do
32
- expect_any_instance_of(CanvasSync::Jobs::ReportStarter).to receive(:start_report)
33
- .with(
34
- 'self',
35
- 'proservices_provisioning_csv',
36
- {
37
- parameters: {
38
- include_deleted: true,
39
- 'users' => true,
40
- 'courses' => true,
41
- }
42
- },
43
- )
25
+ it 'includes model parameters without term_id' do
26
+ task = described_class.new({ models: ['users', 'courses'] }, {}, {})
27
+ allow(CanvasSync::JobBatches::Batch).to receive(:current_context).and_return({})
44
28
 
45
- CanvasSync::Jobs::SyncProvisioningReportJob.perform_now(
46
- { models: ['users', 'courses'] }
47
- )
29
+ params = task.report_parameters
30
+ expect(params).to eq({
31
+ parameters: {
32
+ include_deleted: true,
33
+ 'users' => true,
34
+ 'courses' => true,
35
+ }
36
+ })
48
37
  end
49
38
  end
50
39
  end
@@ -1,12 +1,11 @@
1
1
  require "spec_helper"
2
2
 
3
- RSpec.describe CanvasSync::Processors::AssignmentGroupsProcessor do
4
- let(:subject) { CanvasSync::Processors::AssignmentGroupsProcessor }
5
-
3
+ RSpec.describe CanvasSync::Jobs::SyncAssignmentGroupsJob do
6
4
  describe "#process" do
7
5
  it "inserts assignment_groups" do
6
+ task = described_class.new({}, {}, {})
8
7
  expect {
9
- subject.process("spec/support/fixtures/reports/assignment_groups.csv", {}, 1)
8
+ task.process("spec/support/fixtures/reports/assignment_groups.csv")
10
9
  }.to change { AssignmentGroup.count }.by(2)
11
10
  end
12
11
  end
@@ -1,10 +1,11 @@
1
1
  require "spec_helper"
2
2
 
3
- RSpec.describe CanvasSync::Processors::AssignmentOverridesProcessor do
3
+ RSpec.describe CanvasSync::Jobs::SyncAssignmentOverridesJob do
4
4
  describe '#process' do
5
5
  it 'inserts assignment overrides' do
6
+ task = described_class.new({}, {}, {})
6
7
  expect {
7
- described_class.process('spec/support/fixtures/reports/assignment_overrides.csv', {}, 1)
8
+ task.process('spec/support/fixtures/reports/assignment_overrides.csv')
8
9
  }.to change { AssignmentOverride.count }.by(2)
9
10
 
10
11
  override = AssignmentOverride.first
@@ -23,12 +24,14 @@ RSpec.describe CanvasSync::Processors::AssignmentOverridesProcessor do
23
24
 
24
25
  context 'record already present in the database' do
25
26
  before do
26
- described_class.process('spec/support/fixtures/reports/assignment_overrides.csv', {}, 1)
27
+ task = described_class.new({}, {}, {})
28
+ task.process('spec/support/fixtures/reports/assignment_overrides.csv')
27
29
  end
28
30
 
29
31
  it 'updates the override' do
32
+ task = described_class.new({}, {}, {})
30
33
  expect {
31
- described_class.process('spec/support/fixtures/reports/assignment_overrides_conflict.csv', {}, 1)
34
+ task.process('spec/support/fixtures/reports/assignment_overrides_conflict.csv')
32
35
  }.to change { AssignmentOverride.count }.by(0)
33
36
 
34
37
  override = AssignmentOverride.first
@@ -1,12 +1,11 @@
1
1
  require "spec_helper"
2
2
 
3
- RSpec.describe CanvasSync::Processors::AssignmentsProcessor do
4
- let(:subject) { CanvasSync::Processors::AssignmentsProcessor }
5
-
3
+ RSpec.describe CanvasSync::Jobs::SyncAssignmentsJob do
6
4
  describe "#process" do
7
5
  it "inserts assignments" do
6
+ task = described_class.new({}, {}, {})
8
7
  expect {
9
- subject.process("spec/support/fixtures/reports/assignments.csv", {}, 1)
8
+ task.process("spec/support/fixtures/reports/assignments.csv")
10
9
  }.to change { Assignment.count }.by(2)
11
10
  end
12
11
  end
@@ -1,12 +1,11 @@
1
1
  require "spec_helper"
2
2
 
3
- RSpec.describe CanvasSync::Processors::ContentMigrationsProcessor do
4
- let(:subject) { CanvasSync::Processors::ContentMigrationsProcessor }
5
-
3
+ RSpec.describe CanvasSync::Jobs::SyncContentMigrationsJob do
6
4
  describe "#process" do
7
5
  it "inserts content migrations" do
6
+ task = described_class.new({}, {}, {})
8
7
  expect {
9
- subject.process("spec/support/fixtures/reports/content_migrations.csv", {}, 1)
8
+ task.process("spec/support/fixtures/reports/content_migrations.csv")
10
9
  }.to change { ContentMigration.count }.by(2)
11
10
  end
12
11
  end
@@ -1,12 +1,11 @@
1
1
  require "spec_helper"
2
2
 
3
- RSpec.describe CanvasSync::Processors::ContextModuleItemsProcessor do
4
- let(:subject) { CanvasSync::Processors::ContextModuleItemsProcessor }
5
-
3
+ RSpec.describe CanvasSync::Jobs::SyncContextModuleItemsJob do
6
4
  describe "#process" do
7
- it "inserts context modules" do
5
+ it "inserts context module items" do
6
+ task = described_class.new({}, {}, {})
8
7
  expect {
9
- subject.process("spec/support/fixtures/reports/context_module_items.csv", {}, 1)
8
+ task.process("spec/support/fixtures/reports/context_module_items.csv")
10
9
  }.to change { ContextModuleItem.count }.by(2)
11
10
  end
12
11
  end
@@ -1,12 +1,11 @@
1
1
  require "spec_helper"
2
2
 
3
- RSpec.describe CanvasSync::Processors::ContextModulesProcessor do
4
- let(:subject) { CanvasSync::Processors::ContextModulesProcessor }
5
-
3
+ RSpec.describe CanvasSync::Jobs::SyncContextModulesJob do
6
4
  describe "#process" do
7
5
  it "inserts context modules" do
6
+ task = described_class.new({}, {}, {})
8
7
  expect {
9
- subject.process("spec/support/fixtures/reports/context_modules.csv", {}, 1)
8
+ task.process("spec/support/fixtures/reports/context_modules.csv")
10
9
  }.to change { ContextModule.count }.by(2)
11
10
  expect(ContextModule.last).to have_attributes(
12
11
  canvas_id: 23,
@@ -1,11 +1,12 @@
1
1
  require "spec_helper"
2
2
 
3
- RSpec.describe CanvasSync::Processors::CourseCompletionReportProcessor do
3
+ RSpec.describe CanvasSync::Jobs::SyncCourseProgressesJob do
4
4
 
5
5
  describe '#process' do
6
6
  it 'inserts course progresses' do
7
+ task = described_class.new({}, {}, {})
7
8
  expect {
8
- described_class.process('spec/support/fixtures/reports/course_progresses.csv', {}, 1)
9
+ task.process('spec/support/fixtures/reports/course_progresses.csv')
9
10
  }.to change { CourseProgress.count }.by(2)
10
11
  cp = CourseProgress.first
11
12
  expect(cp).to have_attributes(
@@ -26,12 +27,14 @@ RSpec.describe CanvasSync::Processors::CourseCompletionReportProcessor do
26
27
 
27
28
  context 'record already present in the database' do
28
29
  before do
29
- described_class.process('spec/support/fixtures/reports/course_progresses.csv', {}, 1)
30
+ task = described_class.new({}, {}, {})
31
+ task.process('spec/support/fixtures/reports/course_progresses.csv')
30
32
  end
31
33
 
32
34
  it 'updates the course progress' do
35
+ task = described_class.new({}, {}, {})
33
36
  expect {
34
- described_class.process('spec/support/fixtures/reports/course_progresses_conflict.csv', {}, 1)
37
+ task.process('spec/support/fixtures/reports/course_progresses_conflict.csv')
35
38
  }.to change { CourseProgress.count }.by(0)
36
39
  cp = CourseProgress.first
37
40
  expect(cp).to have_attributes(