canvas_sync 0.16.5 → 0.17.0.beta5

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 (75) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +49 -137
  3. data/app/models/canvas_sync/sync_batch.rb +5 -0
  4. data/db/migrate/20201018210836_create_canvas_sync_sync_batches.rb +11 -0
  5. data/lib/canvas_sync.rb +35 -97
  6. data/lib/canvas_sync/importers/bulk_importer.rb +4 -7
  7. data/lib/canvas_sync/job.rb +4 -10
  8. data/lib/canvas_sync/job_batches/batch.rb +403 -0
  9. data/lib/canvas_sync/job_batches/batch_aware_job.rb +62 -0
  10. data/lib/canvas_sync/job_batches/callback.rb +152 -0
  11. data/lib/canvas_sync/job_batches/chain_builder.rb +220 -0
  12. data/lib/canvas_sync/job_batches/context_hash.rb +147 -0
  13. data/lib/canvas_sync/job_batches/jobs/base_job.rb +7 -0
  14. data/lib/canvas_sync/job_batches/jobs/concurrent_batch_job.rb +19 -0
  15. data/lib/canvas_sync/job_batches/jobs/serial_batch_job.rb +75 -0
  16. data/lib/canvas_sync/job_batches/sidekiq.rb +93 -0
  17. data/lib/canvas_sync/job_batches/status.rb +83 -0
  18. data/lib/canvas_sync/jobs/begin_sync_chain_job.rb +35 -0
  19. data/lib/canvas_sync/jobs/report_checker.rb +3 -6
  20. data/lib/canvas_sync/jobs/report_processor_job.rb +2 -5
  21. data/lib/canvas_sync/jobs/report_starter.rb +28 -20
  22. data/lib/canvas_sync/jobs/sync_accounts_job.rb +3 -5
  23. data/lib/canvas_sync/jobs/sync_admins_job.rb +2 -4
  24. data/lib/canvas_sync/jobs/sync_assignment_groups_job.rb +2 -4
  25. data/lib/canvas_sync/jobs/sync_assignments_job.rb +2 -4
  26. data/lib/canvas_sync/jobs/sync_context_module_items_job.rb +2 -4
  27. data/lib/canvas_sync/jobs/sync_context_modules_job.rb +2 -4
  28. data/lib/canvas_sync/jobs/sync_provisioning_report_job.rb +4 -34
  29. data/lib/canvas_sync/jobs/sync_roles_job.rb +2 -5
  30. data/lib/canvas_sync/jobs/sync_simple_table_job.rb +11 -32
  31. data/lib/canvas_sync/jobs/sync_submissions_job.rb +2 -4
  32. data/lib/canvas_sync/jobs/sync_terms_job.rb +25 -8
  33. data/lib/canvas_sync/processors/assignment_groups_processor.rb +2 -3
  34. data/lib/canvas_sync/processors/assignments_processor.rb +2 -3
  35. data/lib/canvas_sync/processors/context_module_items_processor.rb +2 -3
  36. data/lib/canvas_sync/processors/context_modules_processor.rb +2 -3
  37. data/lib/canvas_sync/processors/normal_processor.rb +1 -2
  38. data/lib/canvas_sync/processors/provisioning_report_processor.rb +2 -10
  39. data/lib/canvas_sync/processors/submissions_processor.rb +2 -3
  40. data/lib/canvas_sync/version.rb +1 -1
  41. data/spec/canvas_sync/canvas_sync_spec.rb +136 -153
  42. data/spec/canvas_sync/jobs/job_spec.rb +9 -17
  43. data/spec/canvas_sync/jobs/report_checker_spec.rb +1 -3
  44. data/spec/canvas_sync/jobs/report_processor_job_spec.rb +0 -3
  45. data/spec/canvas_sync/jobs/report_starter_spec.rb +19 -28
  46. data/spec/canvas_sync/jobs/sync_admins_job_spec.rb +1 -4
  47. data/spec/canvas_sync/jobs/sync_assignment_groups_job_spec.rb +2 -1
  48. data/spec/canvas_sync/jobs/sync_assignments_job_spec.rb +3 -2
  49. data/spec/canvas_sync/jobs/sync_context_module_items_job_spec.rb +3 -2
  50. data/spec/canvas_sync/jobs/sync_context_modules_job_spec.rb +3 -2
  51. data/spec/canvas_sync/jobs/sync_provisioning_report_job_spec.rb +3 -35
  52. data/spec/canvas_sync/jobs/sync_roles_job_spec.rb +1 -4
  53. data/spec/canvas_sync/jobs/sync_simple_table_job_spec.rb +5 -12
  54. data/spec/canvas_sync/jobs/sync_submissions_job_spec.rb +2 -1
  55. data/spec/canvas_sync/jobs/sync_terms_job_spec.rb +1 -4
  56. data/spec/dummy/config/environments/test.rb +2 -0
  57. data/spec/dummy/db/schema.rb +9 -1
  58. data/spec/job_batching/batch_aware_job_spec.rb +100 -0
  59. data/spec/job_batching/batch_spec.rb +372 -0
  60. data/spec/job_batching/callback_spec.rb +38 -0
  61. data/spec/job_batching/flow_spec.rb +88 -0
  62. data/spec/job_batching/integration/integration.rb +57 -0
  63. data/spec/job_batching/integration/nested.rb +88 -0
  64. data/spec/job_batching/integration/simple.rb +47 -0
  65. data/spec/job_batching/integration/workflow.rb +134 -0
  66. data/spec/job_batching/integration_helper.rb +48 -0
  67. data/spec/job_batching/sidekiq_spec.rb +124 -0
  68. data/spec/job_batching/status_spec.rb +92 -0
  69. data/spec/job_batching/support/base_job.rb +14 -0
  70. data/spec/job_batching/support/sample_callback.rb +2 -0
  71. data/spec/spec_helper.rb +17 -0
  72. metadata +85 -8
  73. data/lib/canvas_sync/job_chain.rb +0 -102
  74. data/lib/canvas_sync/jobs/fork_gather.rb +0 -74
  75. data/spec/canvas_sync/jobs/fork_gather_spec.rb +0 -73
@@ -5,12 +5,10 @@ RSpec.describe CanvasSync::Jobs::ReportChecker do
5
5
  let(:report_id) { 1 }
6
6
  let(:report_name) { 'provisioning_csv' }
7
7
  let(:processor) { 'FakeProcessor' }
8
- let(:job_chain) { { jobs: [], global_options: {} } }
9
8
 
10
9
  describe '#perform' do
11
10
  def start_job
12
11
  CanvasSync::Jobs::ReportChecker.perform_now(
13
- job_chain,
14
12
  'provisioning_csv',
15
13
  report_id,
16
14
  processor,
@@ -25,7 +23,7 @@ RSpec.describe CanvasSync::Jobs::ReportChecker do
25
23
  .and_return({ 'status' => 'complete', 'attachment' => { 'url' => 'blah' } })
26
24
 
27
25
  expect(CanvasSync::Jobs::ReportProcessorJob).to receive(:perform_later)
28
- .with(job_chain, report_name, 'blah', processor, {}, report_id)
26
+ .with(report_name, 'blah', processor, {}, report_id)
29
27
 
30
28
  start_job
31
29
  end
@@ -6,17 +6,14 @@ RSpec.describe CanvasSync::Jobs::ReportProcessorJob do
6
6
  let(:report_name) { 'provisioning_csv' }
7
7
  let(:report_url) { 'https://test.instructure.com/sample_report_download' }
8
8
  let(:processor) { FakeProcessor.to_s }
9
- let(:job_chain) { { jobs: [], global_options: {} } }
10
9
  let(:report_id) { 1 }
11
10
 
12
11
  describe '#perform' do
13
12
  it 'downloads the report to a file and then calls the process method on the processor, and then invokes the next job' do
14
13
  expect(IO).to receive(:copy_stream)
15
14
  expect(FakeProcessor).to receive(:process)
16
- expect(CanvasSync).to receive(:invoke_next).with(job_chain)
17
15
 
18
16
  CanvasSync::Jobs::ReportProcessorJob.perform_now(
19
- job_chain,
20
17
  report_name,
21
18
  report_url,
22
19
  processor,
@@ -16,7 +16,6 @@ RSpec.describe CanvasSync::Jobs::ReportStarter do
16
16
  expect(CanvasSync::Jobs::ReportChecker).to receive(:set).and_call_original
17
17
 
18
18
  CanvasSync::Jobs::ReportStarter.perform_now(
19
- { jobs: [], global_options: {} },
20
19
  report_name,
21
20
  report_params,
22
21
  processor,
@@ -24,30 +23,27 @@ RSpec.describe CanvasSync::Jobs::ReportStarter do
24
23
  end
25
24
 
26
25
  context 'allow_redownloads is true' do
27
- context 'the report has already been cached' do
28
- it 'runs the report checker for the already started report' do
29
- expect_any_instance_of(Bearcat::Client).to_not receive(:start_report)
30
- job_chain = { jobs: [], global_options: { report_name => 1 } }
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)
31
29
 
32
- expect(CanvasSync::Jobs::ReportChecker).to receive(:set).and_return(report_checker_double)
33
- expect(report_checker_double).to receive(:perform_later).with(
34
- job_chain,
35
- report_name,
36
- 1,
37
- processor,
38
- options
39
- )
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
+ # )
40
37
 
41
- CanvasSync::Jobs::ReportStarter.perform_now(
42
- job_chain,
43
- report_name,
44
- report_params,
45
- processor,
46
- options,
47
- allow_redownloads: true
48
- )
49
- end
50
- end
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
51
47
 
52
48
  context 'the report has not been started before' do
53
49
  it 'starts a new report and caches the report id' do
@@ -55,12 +51,8 @@ RSpec.describe CanvasSync::Jobs::ReportStarter do
55
51
  .with('self', report_name, report_params)
56
52
  .and_return({ 'id' => 1 })
57
53
 
58
- orig_job_chain = { jobs: [], global_options: {} }
59
- new_job_chain = { jobs: [], global_options: { report_name => 1 } }
60
-
61
54
  expect(CanvasSync::Jobs::ReportChecker).to receive(:set).and_return(report_checker_double)
62
55
  expect(report_checker_double).to receive(:perform_later).with(
63
- new_job_chain,
64
56
  report_name,
65
57
  1,
66
58
  processor,
@@ -68,7 +60,6 @@ RSpec.describe CanvasSync::Jobs::ReportStarter do
68
60
  )
69
61
 
70
62
  CanvasSync::Jobs::ReportStarter.perform_now(
71
- orig_job_chain,
72
63
  report_name,
73
64
  report_params,
74
65
  processor,
@@ -4,13 +4,10 @@ RSpec.describe CanvasSync::Jobs::SyncAdminsJob do
4
4
  describe '#perform' do
5
5
  let!(:account) { FactoryGirl.create(:account, canvas_id: 1) }
6
6
  let(:admin_params) { open_canvas_fixture('admins') }
7
- let(:job_chain) { { jobs: [], global_options: {}} }
8
7
 
9
8
  it 'retrieves all admins from the Canvas API and then invokes the next job' do
10
- expect(CanvasSync).to receive(:invoke_next).with(job_chain)
11
-
12
9
  expect {
13
- CanvasSync::Jobs::SyncAdminsJob.perform_now(job_chain, {})
10
+ CanvasSync::Jobs::SyncAdminsJob.perform_now({})
14
11
  }.to change { Admin.count }.by(admin_params.length)
15
12
  end
16
13
  end
@@ -10,7 +10,8 @@ RSpec.describe CanvasSync::Jobs::SyncAssignmentGroupsJob do
10
10
 
11
11
  expect(CanvasSync::Jobs::ReportChecker).to receive(:set).and_call_original
12
12
 
13
- CanvasSync::Jobs::SyncAssignmentGroupsJob.perform_now({ jobs: [], global_options: { canvas_term_id: 1 } }, {})
13
+ set_batch_context(canvas_term_id: 1)
14
+ CanvasSync::Jobs::SyncAssignmentGroupsJob.perform_now({})
14
15
  end
15
16
  end
16
17
  end
@@ -10,7 +10,8 @@ RSpec.describe CanvasSync::Jobs::SyncAssignmentsJob do
10
10
 
11
11
  expect(CanvasSync::Jobs::ReportChecker).to receive(:set).and_call_original
12
12
 
13
- CanvasSync::Jobs::SyncAssignmentsJob.perform_now({ jobs: [], global_options: { canvas_term_id: 1 } }, {})
13
+ set_batch_context(canvas_term_id: 1)
14
+ CanvasSync::Jobs::SyncAssignmentsJob.perform_now({})
14
15
  end
15
16
  end
16
17
 
@@ -22,7 +23,7 @@ RSpec.describe CanvasSync::Jobs::SyncAssignmentsJob do
22
23
 
23
24
  expect(CanvasSync::Jobs::ReportChecker).to receive(:set).and_call_original
24
25
 
25
- CanvasSync::Jobs::SyncAssignmentsJob.perform_now({ jobs: [], global_options: {} }, {})
26
+ CanvasSync::Jobs::SyncAssignmentsJob.perform_now({})
26
27
  end
27
28
  end
28
29
  end
@@ -10,7 +10,8 @@ RSpec.describe CanvasSync::Jobs::SyncContextModuleItemsJob do
10
10
 
11
11
  expect(CanvasSync::Jobs::ReportChecker).to receive(:set).and_call_original
12
12
 
13
- CanvasSync::Jobs::SyncContextModuleItemsJob.perform_now({ jobs: [], global_options: { canvas_term_id: 1 } }, {})
13
+ set_batch_context(canvas_term_id: 1)
14
+ CanvasSync::Jobs::SyncContextModuleItemsJob.perform_now({})
14
15
  end
15
16
  end
16
17
 
@@ -22,7 +23,7 @@ RSpec.describe CanvasSync::Jobs::SyncContextModuleItemsJob do
22
23
 
23
24
  expect(CanvasSync::Jobs::ReportChecker).to receive(:set).and_call_original
24
25
 
25
- CanvasSync::Jobs::SyncContextModuleItemsJob.perform_now({ jobs: [], global_options: {} }, {})
26
+ CanvasSync::Jobs::SyncContextModuleItemsJob.perform_now({})
26
27
  end
27
28
  end
28
29
  end
@@ -10,7 +10,8 @@ RSpec.describe CanvasSync::Jobs::SyncContextModulesJob do
10
10
 
11
11
  expect(CanvasSync::Jobs::ReportChecker).to receive(:set).and_call_original
12
12
 
13
- CanvasSync::Jobs::SyncContextModulesJob.perform_now({ jobs: [], global_options: { canvas_term_id: 1 } }, {})
13
+ set_batch_context(canvas_term_id: 1)
14
+ CanvasSync::Jobs::SyncContextModulesJob.perform_now({})
14
15
  end
15
16
  end
16
17
 
@@ -22,7 +23,7 @@ RSpec.describe CanvasSync::Jobs::SyncContextModulesJob do
22
23
 
23
24
  expect(CanvasSync::Jobs::ReportChecker).to receive(:set).and_call_original
24
25
 
25
- CanvasSync::Jobs::SyncContextModulesJob.perform_now({ jobs: [], global_options: {} }, {})
26
+ CanvasSync::Jobs::SyncContextModulesJob.perform_now({})
26
27
  end
27
28
  end
28
29
  end
@@ -2,59 +2,29 @@ require 'spec_helper'
2
2
 
3
3
  RSpec.describe CanvasSync::Jobs::SyncProvisioningReportJob do
4
4
  describe '#perform' do
5
- let(:job_chain) { {jobs: [], global_options: {}} }
6
-
7
5
  context 'a term scope is specified' do
8
- let!(:active_term_1) { FactoryGirl.create(:term) }
9
- let!(:active_term_2) { FactoryGirl.create(:term) }
10
- let!(:inactive_term_1) { FactoryGirl.create(:term, workflow_state: 'inactive') }
6
+ let!(:term) { FactoryGirl.create(:term) }
11
7
 
12
8
  it 'enqueues a ReportStarter for a provisioning report for the specified models for each term' do
13
- expected_job_chain = Marshal.load(Marshal.dump(job_chain))
14
- expected_job_chain[:global_options][:canvas_term_id] = active_term_1.canvas_id
15
- expected_job_chain[:global_options] = hash_including(expected_job_chain[:global_options])
16
-
17
- expect(CanvasSync::Jobs::ReportStarter).to receive(:perform_later)
18
- .with(
19
- hash_including(expected_job_chain),
20
- 'proservices_provisioning_csv',
21
- {
22
- parameters: {
23
- include_deleted: true,
24
- 'users' => true,
25
- 'courses' => true,
26
- enrollment_term_id: active_term_1.canvas_id
27
- }
28
- },
29
- CanvasSync::Processors::ProvisioningReportProcessor.to_s,
30
- { models: ['users', 'courses'], term_scope: 'active' }
31
- )
32
-
33
- expected_job_chain_2 = Marshal.load(Marshal.dump(job_chain))
34
- expected_job_chain_2[:global_options][:canvas_term_id] = active_term_2.canvas_id
35
- expected_job_chain_2[:global_options] = hash_including(expected_job_chain_2[:global_options])
36
-
37
9
  expect(CanvasSync::Jobs::ReportStarter).to receive(:perform_later)
38
10
  .with(
39
- hash_including(expected_job_chain_2),
40
11
  'proservices_provisioning_csv',
41
12
  {
42
13
  parameters: {
43
14
  include_deleted: true,
44
15
  'users' => true,
45
16
  'courses' => true,
46
- enrollment_term_id: active_term_2.canvas_id
17
+ enrollment_term_id: term.canvas_id
47
18
  }
48
19
  },
49
20
  CanvasSync::Processors::ProvisioningReportProcessor.to_s,
50
21
  { models: ['users', 'courses'], term_scope: 'active' }
51
22
  )
52
23
 
24
+ set_batch_context(canvas_term_id: term.canvas_id)
53
25
  CanvasSync::Jobs::SyncProvisioningReportJob.perform_now(
54
- job_chain,
55
26
  { models: ['users', 'courses'], term_scope: 'active' }
56
27
  )
57
- expect(CanvasSync::JobLog.last.fork_count).to eq 2
58
28
  end
59
29
  end
60
30
 
@@ -62,7 +32,6 @@ RSpec.describe CanvasSync::Jobs::SyncProvisioningReportJob do
62
32
  it 'enqueues a single ReportStarter for a provisioning report across all terms for the specified models' do
63
33
  expect(CanvasSync::Jobs::ReportStarter).to receive(:perform_later)
64
34
  .with(
65
- job_chain,
66
35
  'proservices_provisioning_csv',
67
36
  {
68
37
  parameters: {
@@ -76,7 +45,6 @@ RSpec.describe CanvasSync::Jobs::SyncProvisioningReportJob do
76
45
  )
77
46
 
78
47
  CanvasSync::Jobs::SyncProvisioningReportJob.perform_now(
79
- job_chain,
80
48
  { models: ['users', 'courses'] }
81
49
  )
82
50
  end
@@ -4,13 +4,10 @@ RSpec.describe CanvasSync::Jobs::SyncRolesJob do
4
4
  describe '#perform' do
5
5
  let!(:account) { FactoryGirl.create(:account, canvas_id: 1) }
6
6
  let(:role_params) { open_canvas_fixture('roles') }
7
- let(:job_chain) { { jobs: [], global_options: {}} }
8
7
 
9
8
  it 'retrieves all roles from the Canvas API and then invokes the next job' do
10
- expect(CanvasSync).to receive(:invoke_next).with(job_chain)
11
-
12
9
  expect {
13
- CanvasSync::Jobs::SyncRolesJob.perform_now(job_chain, {})
10
+ CanvasSync::Jobs::SyncRolesJob.perform_now({})
14
11
  }.to change { Role.count }.by(role_params.length)
15
12
  end
16
13
  end
@@ -2,25 +2,17 @@ require 'spec_helper'
2
2
 
3
3
  RSpec.describe CanvasSync::Jobs::SyncSimpleTableJob do
4
4
  describe '#perform' do
5
- let(:job_chain) { {jobs: [], global_options: {}} }
6
-
7
5
  context 'Simple report' do
8
- let!(:active_term_1) { FactoryGirl.create(:term) }
9
- let!(:inactive_term_1) { FactoryGirl.create(:term, workflow_state: 'inactive') }
6
+ let!(:term) { FactoryGirl.create(:term) }
10
7
 
11
8
  it 'enqueues a ReportStarter for a provisioning report for the specified model for a term' do
12
- expected_job_chain = Marshal.load(Marshal.dump(job_chain))
13
- expected_job_chain[:global_options][:canvas_term_id] = active_term_1.canvas_id
14
- expected_job_chain[:global_options] = hash_including(expected_job_chain[:global_options])
15
-
16
9
  expect(CanvasSync::Jobs::ReportStarter).to receive(:perform_later)
17
10
  .with(
18
- hash_including(expected_job_chain),
19
11
  'proservices_provisioning_csv',
20
12
  {
21
13
  "parameters[include_deleted]" => true,
22
14
  "parameters[courses]" => true,
23
- "parameters[enrollment_term_id]" => active_term_1.canvas_id
15
+ "parameters[enrollment_term_id]" => term.canvas_id
24
16
  },
25
17
  CanvasSync::Processors::NormalProcessor.to_s,
26
18
  {
@@ -32,13 +24,14 @@ RSpec.describe CanvasSync::Jobs::SyncSimpleTableJob do
32
24
  params: {
33
25
  "parameters[include_deleted]" => true,
34
26
  "parameters[courses]" => true,
35
- "parameters[enrollment_term_id]" => active_term_1.canvas_id
27
+ "parameters[enrollment_term_id]" => term.canvas_id
36
28
  }
37
29
  }
38
30
  )
39
31
 
32
+ set_batch_context(canvas_term_id: term.canvas_id)
33
+
40
34
  CanvasSync::Jobs::SyncSimpleTableJob.perform_now(
41
- job_chain,
42
35
  {
43
36
  report_name: 'proservices_provisioning_csv',
44
37
  model: 'courses',
@@ -10,7 +10,8 @@ RSpec.describe CanvasSync::Jobs::SyncSubmissionsJob do
10
10
 
11
11
  expect(CanvasSync::Jobs::ReportChecker).to receive(:set).and_call_original
12
12
 
13
- CanvasSync::Jobs::SyncSubmissionsJob.perform_now({ jobs: [], global_options: { canvas_term_id: 1 } }, {})
13
+ set_batch_context(canvas_term_id: 1)
14
+ CanvasSync::Jobs::SyncSubmissionsJob.perform_now({})
14
15
  end
15
16
  end
16
17
  end
@@ -3,13 +3,10 @@ require 'spec_helper'
3
3
  RSpec.describe CanvasSync::Jobs::SyncTermsJob do
4
4
  describe '#perform' do
5
5
  let(:term_params) { open_canvas_fixture('terms')['enrollment_terms'] }
6
- let(:job_chain) { { jobs: [], global_options: {}} }
7
6
 
8
7
  it 'retrieves all terms from the Canvas API and then invokes the next job' do
9
- expect(CanvasSync).to receive(:invoke_next).with(job_chain)
10
-
11
8
  expect {
12
- CanvasSync::Jobs::SyncTermsJob.perform_now(job_chain, {})
9
+ CanvasSync::Jobs::SyncTermsJob.perform_now({})
13
10
  }.to change { Term.count }.by(term_params.length)
14
11
  end
15
12
  end
@@ -37,6 +37,8 @@ Rails.application.configure do
37
37
  # Print deprecation notices to the stderr.
38
38
  config.active_support.deprecation = :stderr
39
39
 
40
+ config.active_job.queue_adapter = :test
41
+
40
42
  # Raises error for missing translations
41
43
  # config.action_view.raise_on_missing_translations = true
42
44
  end
@@ -10,7 +10,7 @@
10
10
  #
11
11
  # It's strongly recommended that you check this file into your version control system.
12
12
 
13
- ActiveRecord::Schema.define(version: 2020_10_16_181346) do
13
+ ActiveRecord::Schema.define(version: 2020_10_18_210836) do
14
14
 
15
15
  # These are extensions that must be enabled in order to support this database
16
16
  enable_extension "plpgsql"
@@ -99,6 +99,14 @@ ActiveRecord::Schema.define(version: 2020_10_16_181346) do
99
99
  t.index ["job_id"], name: "index_canvas_sync_job_logs_on_job_id"
100
100
  end
101
101
 
102
+ create_table "canvas_sync_sync_batches", id: :serial, force: :cascade do |t|
103
+ t.datetime "started_at"
104
+ t.datetime "completed_at"
105
+ t.string "status"
106
+ t.datetime "created_at"
107
+ t.datetime "updated_at"
108
+ end
109
+
102
110
  create_table "context_module_items", force: :cascade do |t|
103
111
  t.bigint "canvas_id"
104
112
  t.bigint "canvas_context_module_id"
@@ -0,0 +1,100 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe CanvasSync::JobBatches::BatchAwareJob do
4
+ include ActiveJob::TestHelper
5
+
6
+ after do
7
+ clear_enqueued_jobs
8
+ clear_performed_jobs
9
+ end
10
+
11
+ context "When Performing" do
12
+ context 'when without batch' do
13
+ it 'just yields' do
14
+ expect(CanvasSync::JobBatches::Batch).not_to receive(:process_successful_job)
15
+ expect(CanvasSync::JobBatches::Batch).not_to receive(:process_failed_job)
16
+ expect_any_instance_of(BatchTestJobBase).to receive(:perform)
17
+
18
+ BatchTestJobBase.perform_now
19
+ end
20
+ end
21
+
22
+ context 'when in batch' do
23
+ let(:bid) { 'SAMPLEBID' }
24
+
25
+ context 'when successful' do
26
+ it 'yields' do
27
+ expect_any_instance_of(BatchTestJobBase).to receive(:perform)
28
+ BatchTestJobBase.perform_now
29
+ end
30
+
31
+ it 'calls process_successful_job' do
32
+ job = BatchTestJobBase.new
33
+ job.instance_variable_set(:@bid, bid)
34
+ expect(CanvasSync::JobBatches::Batch).to receive(:process_successful_job).with(bid, job.job_id)
35
+ job.perform_now
36
+ end
37
+ end
38
+
39
+ context 'when failed' do
40
+ it 'calls process_failed_job and reraises exception' do
41
+ reraised = false
42
+ job = FailingBatchTestJobBase.new
43
+ job.instance_variable_set(:@bid, bid)
44
+ expect(CanvasSync::JobBatches::Batch).to receive(:process_failed_job)
45
+ begin
46
+ job.perform_now
47
+ rescue
48
+ reraised = true
49
+ end
50
+ expect(reraised).to be_truthy
51
+ end
52
+ end
53
+ end
54
+ end
55
+
56
+ context "When Enqueueing" do
57
+ context 'when without batch' do
58
+ it 'just yields' do
59
+ expect(CanvasSync::JobBatches::Batch).not_to receive(:increment_job_queue)
60
+ BatchTestJobBase.perform_later
61
+ expect(BatchTestJobBase).to have_been_enqueued
62
+ end
63
+ end
64
+
65
+ context 'when in batch' do
66
+ let(:bid) { 'SAMPLEBID' }
67
+
68
+ before do
69
+ Thread.current[:batch] = CanvasSync::JobBatches::Batch.new(bid)
70
+ Thread.current[:batch].instance_variable_set(:@open, true)
71
+ end
72
+
73
+ it 'yields' do
74
+ expect {
75
+ BatchTestJobBase.perform_later
76
+ }.to enqueue_job(BatchTestJobBase)
77
+ end
78
+
79
+ it 'assigns bid to job metadata' do
80
+ job = BatchTestJobBase.perform_later
81
+ expect(job.bid).to eq bid
82
+ expect(job.serialize['batch_id']).to eq bid
83
+ end
84
+ end
85
+ end
86
+
87
+ context 'worker' do
88
+ it 'defines method bid' do
89
+ expect(ActiveJob::Base.instance_methods).to include(:bid)
90
+ end
91
+
92
+ it 'defines method batch' do
93
+ expect(ActiveJob::Base.instance_methods).to include(:batch)
94
+ end
95
+
96
+ it 'defines method valid_within_batch?' do
97
+ expect(ActiveJob::Base.instance_methods).to include(:valid_within_batch?)
98
+ end
99
+ end
100
+ end