canvas_sync 0.16.4 → 0.17.0.beta1
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 +35 -118
- 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 +203 -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 +91 -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 +4 -31
- 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 +22 -7
- 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 +126 -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 +10 -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,17 @@ module CanvasSync | |
| 2 2 | 
             
              module Jobs
         | 
| 3 3 | 
             
                # ActiveJob class that starts a Canvas provisioning report
         | 
| 4 4 | 
             
                class SyncProvisioningReportJob < CanvasSync::Job
         | 
| 5 | 
            -
                  # @param job_chain [Hash]
         | 
| 6 5 | 
             
                  # @param options [Hash] If options contains a :term_scope a seperate provisioning report
         | 
| 7 6 | 
             
                  #   will be started for each term in that scope. :models should be an array of
         | 
| 8 7 | 
             
                  #   models to sync.
         | 
| 9 | 
            -
                  def perform( | 
| 10 | 
            -
                     | 
| 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
         | 
| 8 | 
            +
                  def perform(options)
         | 
| 9 | 
            +
                    start_report(report_params(options), options)
         | 
| 32 10 | 
             
                  end
         | 
| 33 11 |  | 
| 34 12 | 
             
                  protected
         | 
| 35 13 |  | 
| 36 | 
            -
                  def start_report(report_params,  | 
| 14 | 
            +
                  def start_report(report_params, options)
         | 
| 37 15 | 
             
                    CanvasSync::Jobs::ReportStarter.perform_later(
         | 
| 38 | 
            -
                      job_chain,
         | 
| 39 16 | 
             
                      "proservices_provisioning_csv",
         | 
| 40 17 | 
             
                      report_params,
         | 
| 41 18 | 
             
                      CanvasSync::Processors::ProvisioningReportProcessor.to_s,
         | 
| @@ -43,7 +20,7 @@ module CanvasSync | |
| 43 20 | 
             
                    )
         | 
| 44 21 | 
             
                  end
         | 
| 45 22 |  | 
| 46 | 
            -
                  def report_params(options, canvas_term_id= | 
| 23 | 
            +
                  def report_params(options, canvas_term_id = options[:canvas_term_id] || batch_context[:canvas_term_id])
         | 
| 47 24 | 
             
                    params = {
         | 
| 48 25 | 
             
                      include_deleted: true,
         | 
| 49 26 | 
             
                    }
         | 
| @@ -60,10 +37,6 @@ module CanvasSync | |
| 60 37 |  | 
| 61 38 | 
             
                    { parameters: params }
         | 
| 62 39 | 
             
                  end
         | 
| 63 | 
            -
             | 
| 64 | 
            -
                  def get_term_id(term)
         | 
| 65 | 
            -
                    term.try(:canvas_id) || term.canvas_term_id
         | 
| 66 | 
            -
                  end
         | 
| 67 40 | 
             
                end
         | 
| 68 41 | 
             
              end
         | 
| 69 42 | 
             
            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,15 @@ module CanvasSync | |
| 5 5 | 
             
                  #
         | 
| 6 6 | 
             
                  # Terms are pre-synced so that provisioning reports can be scoped to term.
         | 
| 7 7 | 
             
                  #
         | 
| 8 | 
            -
                  # @param job_chain [Hash]
         | 
| 9 8 | 
             
                  # @param options [Hash]
         | 
| 10 | 
            -
                  def perform( | 
| 11 | 
            -
                    CanvasSync.get_canvas_sync_client( | 
| 12 | 
            -
                      if  | 
| 9 | 
            +
                  def perform(options)
         | 
| 10 | 
            +
                    CanvasSync.get_canvas_sync_client(batch_context).terms("self").all_pages!.each do |term_params|
         | 
| 11 | 
            +
                      if account_id = batch_context[:account_id]
         | 
| 13 12 | 
             
                        # These branches are primarily to support Legacy apps
         | 
| 14 13 | 
             
                        if Term.respond_to?(:create_or_update) && Term.method(:create_or_update).arity.abs == 2
         | 
| 15 | 
            -
                          Term.create_or_update(term_params,  | 
| 14 | 
            +
                          Term.create_or_update(term_params, account_id)
         | 
| 16 15 | 
             
                        else
         | 
| 17 | 
            -
                          term_params[:account_id] |=  | 
| 16 | 
            +
                          term_params[:account_id] |= account_id
         | 
| 18 17 | 
             
                          update_or_create_model(Term, term_params)
         | 
| 19 18 | 
             
                        end
         | 
| 20 19 | 
             
                      else
         | 
| @@ -22,7 +21,23 @@ module CanvasSync | |
| 22 21 | 
             
                      end
         | 
| 23 22 | 
             
                    end
         | 
| 24 23 |  | 
| 25 | 
            -
                     | 
| 24 | 
            +
                    if (jobs = options[:sub_jobs]).present?
         | 
| 25 | 
            +
                      context = options[:context] || {}
         | 
| 26 | 
            +
                      if options[:term_scope]
         | 
| 27 | 
            +
                        Term.send(options[:term_scope]).find_each.map do |term|
         | 
| 28 | 
            +
                          local_context = context.merge(canvas_term_id: get_term_id(term))
         | 
| 29 | 
            +
                          JobBatches::ConcurrentBatchJob.perform_now(jobs, context: local_context)
         | 
| 30 | 
            +
                        end
         | 
| 31 | 
            +
                      else
         | 
| 32 | 
            +
                        JobBatches::ConcurrentBatchJob.perform_now(jobs, context: context)
         | 
| 33 | 
            +
                      end
         | 
| 34 | 
            +
                    end
         | 
| 35 | 
            +
                  end
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                  protected
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                  def get_term_id(term)
         | 
| 40 | 
            +
                    term.try(:canvas_id) || term.canvas_term_id
         | 
| 26 41 | 
             
                  end
         | 
| 27 42 | 
             
                end
         | 
| 28 43 | 
             
              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,42 @@ 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 | 
            +
                            :sub_jobs=>[
         | 
| 40 | 
            +
                              {:job=>"CanvasSync::Jobs::SyncProvisioningReportJob", :options=>{:models=>["courses"], :term_scope=>"active", :c=>3}}
         | 
| 41 | 
            +
                            ]
         | 
| 42 | 
            +
                          }]}
         | 
| 43 | 
            +
                        ]]}
         | 
| 44 | 
            +
                      ], {:legacy_support=>false, :updated_after=>nil, :d=>4}],
         | 
| 41 45 | 
             
                    })
         | 
| 42 46 | 
             
                  end
         | 
| 43 47 |  | 
| 44 48 | 
             
                  context 'we are syncing users with a term scope' do
         | 
| 45 49 | 
             
                    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 | 
            -
             | 
| 50 | 
            +
                      chain = CanvasSync.default_provisioning_report_chain(['users', 'courses'], term_scope: :active)
         | 
| 51 | 
            +
                      expect(chain.normalize!).to eq({
         | 
| 52 | 
            +
                        :job => "CanvasSync::Jobs::BeginSyncChainJob",
         | 
| 53 | 
            +
                        :parameters => [[
         | 
| 54 | 
            +
                          {:job=>"CanvasSync::JobBatches::ConcurrentBatchJob", :parameters=>[[
         | 
| 55 | 
            +
                            {:job=>"CanvasSync::Jobs::SyncProvisioningReportJob", :options=>{:models=>["users"]}},
         | 
| 56 | 
            +
                            {:job=>"CanvasSync::Jobs::SyncTermsJob", :parameters=>[{
         | 
| 57 | 
            +
                              :sub_jobs=>[
         | 
| 58 | 
            +
                                {:job=>"CanvasSync::Jobs::SyncProvisioningReportJob", :options=>{:models=>["courses"], :term_scope=>"active"}}
         | 
| 59 | 
            +
                              ]
         | 
| 60 | 
            +
                            }]}
         | 
| 61 | 
            +
                          ]]}
         | 
| 62 | 
            +
                        ], {:legacy_support=>false, :updated_after=>nil}]
         | 
| 54 63 | 
             
                      })
         | 
| 55 64 | 
             
                    end
         | 
| 56 65 | 
             
                  end
         | 
| @@ -58,26 +67,36 @@ RSpec.describe CanvasSync do | |
| 58 67 | 
             
                  context 'we are syncing users without a term scope' do
         | 
| 59 68 | 
             
                    it 'syncs users along with the rest of the provisioning report' do
         | 
| 60 69 | 
             
                      chain = CanvasSync.default_provisioning_report_chain(['users', 'courses'])
         | 
| 61 | 
            -
                      expect(chain. | 
| 62 | 
            -
                         | 
| 63 | 
            -
             | 
| 64 | 
            -
                          { | 
| 65 | 
            -
             | 
| 66 | 
            -
             | 
| 70 | 
            +
                      expect(chain.normalize!).to eq({
         | 
| 71 | 
            +
                        :job => "CanvasSync::Jobs::BeginSyncChainJob",
         | 
| 72 | 
            +
                        :parameters => [[
         | 
| 73 | 
            +
                          {:job=>"CanvasSync::JobBatches::ConcurrentBatchJob", :parameters=>[[
         | 
| 74 | 
            +
                            {:job=>"CanvasSync::Jobs::SyncTermsJob", :parameters=>[{
         | 
| 75 | 
            +
                              :sub_jobs=>[
         | 
| 76 | 
            +
                                {:job=>"CanvasSync::Jobs::SyncProvisioningReportJob", :options=>{:models=>["users", "courses"], :term_scope=>nil}}
         | 
| 77 | 
            +
                              ]
         | 
| 78 | 
            +
                            }]}
         | 
| 79 | 
            +
                          ]]}
         | 
| 80 | 
            +
                        ], {:legacy_support=>false, :updated_after=>nil}],
         | 
| 67 81 | 
             
                      })
         | 
| 68 82 | 
             
                    end
         | 
| 69 83 | 
             
                  end
         | 
| 70 84 |  | 
| 71 85 | 
             
                  context 'we are syncing roles with a term scope' do
         | 
| 72 86 | 
             
                    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 | 
            -
             | 
| 87 | 
            +
                      chain = CanvasSync.default_provisioning_report_chain(['roles', 'courses'], term_scope: :active)
         | 
| 88 | 
            +
                      expect(chain.normalize!).to eq({
         | 
| 89 | 
            +
                        :job => "CanvasSync::Jobs::BeginSyncChainJob",
         | 
| 90 | 
            +
                        :parameters => [[
         | 
| 91 | 
            +
                          {:job=>"CanvasSync::JobBatches::ConcurrentBatchJob", :parameters=>[[
         | 
| 92 | 
            +
                            {:job=>"CanvasSync::Jobs::SyncRolesJob", :options=>{}},
         | 
| 93 | 
            +
                            {:job=>"CanvasSync::Jobs::SyncTermsJob", :parameters=>[{
         | 
| 94 | 
            +
                              :sub_jobs=>[
         | 
| 95 | 
            +
                                {:job=>"CanvasSync::Jobs::SyncProvisioningReportJob", :options=>{:models=>["courses"], :term_scope=>"active"}}
         | 
| 96 | 
            +
                              ]
         | 
| 97 | 
            +
                            }]}
         | 
| 98 | 
            +
                          ]]}
         | 
| 99 | 
            +
                        ], {:legacy_support=>false, :updated_after=>nil}],
         | 
| 81 100 | 
             
                      })
         | 
| 82 101 | 
             
                    end
         | 
| 83 102 | 
             
                  end
         | 
| @@ -85,27 +104,37 @@ RSpec.describe CanvasSync do | |
| 85 104 | 
             
                  context 'we are syncing roles without a term scope' do
         | 
| 86 105 | 
             
                    it 'syncs roles separately even with no term scope' do
         | 
| 87 106 | 
             
                      chain = CanvasSync.default_provisioning_report_chain(['roles', 'courses'])
         | 
| 88 | 
            -
                      expect(chain. | 
| 89 | 
            -
                         | 
| 90 | 
            -
             | 
| 91 | 
            -
                          { | 
| 92 | 
            -
             | 
| 93 | 
            -
             | 
| 94 | 
            -
             | 
| 107 | 
            +
                      expect(chain.normalize!).to eq({
         | 
| 108 | 
            +
                        :job => "CanvasSync::Jobs::BeginSyncChainJob",
         | 
| 109 | 
            +
                        :parameters => [[
         | 
| 110 | 
            +
                          {:job=>"CanvasSync::JobBatches::ConcurrentBatchJob", :parameters=>[[
         | 
| 111 | 
            +
                            {:job=>"CanvasSync::Jobs::SyncRolesJob", :options=>{}},
         | 
| 112 | 
            +
                            {:job=>"CanvasSync::Jobs::SyncTermsJob", :parameters=>[{
         | 
| 113 | 
            +
                              :sub_jobs=>[
         | 
| 114 | 
            +
                                {:job=>"CanvasSync::Jobs::SyncProvisioningReportJob", :options=>{:models=>["courses"], :term_scope=>nil}}
         | 
| 115 | 
            +
                              ]
         | 
| 116 | 
            +
                            }]}
         | 
| 117 | 
            +
                          ]]}
         | 
| 118 | 
            +
                        ], {:legacy_support=>false, :updated_after=>nil}],
         | 
| 95 119 | 
             
                      })
         | 
| 96 120 | 
             
                    end
         | 
| 97 121 | 
             
                  end
         | 
| 98 122 |  | 
| 99 123 | 
             
                  context 'we are syncing admins with a term scope' do
         | 
| 100 124 | 
             
                    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 | 
            -
             | 
| 125 | 
            +
                      chain = CanvasSync.default_provisioning_report_chain(['admins', 'courses'], term_scope: :active)
         | 
| 126 | 
            +
                      expect(chain.normalize!).to eq({
         | 
| 127 | 
            +
                        :job => "CanvasSync::Jobs::BeginSyncChainJob",
         | 
| 128 | 
            +
                        :parameters => [[
         | 
| 129 | 
            +
                          {:job=>"CanvasSync::JobBatches::ConcurrentBatchJob", :parameters=>[[
         | 
| 130 | 
            +
                            {:job=>"CanvasSync::Jobs::SyncAdminsJob", :options=>{}},
         | 
| 131 | 
            +
                            {:job=>"CanvasSync::Jobs::SyncTermsJob", :parameters=>[{
         | 
| 132 | 
            +
                              :sub_jobs=>[
         | 
| 133 | 
            +
                                {:job=>"CanvasSync::Jobs::SyncProvisioningReportJob", :options=>{:models=>["courses"], :term_scope=>"active"}}
         | 
| 134 | 
            +
                              ]
         | 
| 135 | 
            +
                            }]}
         | 
| 136 | 
            +
                          ]]}
         | 
| 137 | 
            +
                        ], {:legacy_support=>false, :updated_after=>nil}],
         | 
| 109 138 | 
             
                      })
         | 
| 110 139 | 
             
                    end
         | 
| 111 140 | 
             
                  end
         | 
| @@ -113,13 +142,18 @@ RSpec.describe CanvasSync do | |
| 113 142 | 
             
                  context 'we are syncing admins without a term scope' do
         | 
| 114 143 | 
             
                    it 'syncs admins separately even with no term scope' do
         | 
| 115 144 | 
             
                      chain = CanvasSync.default_provisioning_report_chain(['admins', 'courses'])
         | 
| 116 | 
            -
                      expect(chain. | 
| 117 | 
            -
                         | 
| 118 | 
            -
             | 
| 119 | 
            -
                          { | 
| 120 | 
            -
             | 
| 121 | 
            -
             | 
| 122 | 
            -
             | 
| 145 | 
            +
                      expect(chain.normalize!).to eq({
         | 
| 146 | 
            +
                        :job => "CanvasSync::Jobs::BeginSyncChainJob",
         | 
| 147 | 
            +
                        :parameters => [[
         | 
| 148 | 
            +
                          {:job=>"CanvasSync::JobBatches::ConcurrentBatchJob", :parameters=>[[
         | 
| 149 | 
            +
                            {:job=>"CanvasSync::Jobs::SyncAdminsJob", :options=>{}},
         | 
| 150 | 
            +
                            {:job=>"CanvasSync::Jobs::SyncTermsJob", :parameters=>[{
         | 
| 151 | 
            +
                              :sub_jobs=>[
         | 
| 152 | 
            +
                                {:job=>"CanvasSync::Jobs::SyncProvisioningReportJob", :options=>{:models=>["courses"], :term_scope=>nil}}
         | 
| 153 | 
            +
                              ]
         | 
| 154 | 
            +
                            }]}
         | 
| 155 | 
            +
                          ]]}
         | 
| 156 | 
            +
                        ], {:legacy_support=>false, :updated_after=>nil}],
         | 
| 123 157 | 
             
                      })
         | 
| 124 158 | 
             
                    end
         | 
| 125 159 | 
             
                  end
         | 
| @@ -128,13 +162,18 @@ RSpec.describe CanvasSync do | |
| 128 162 | 
             
                    it "appends the SyncAssignmentsJob" do
         | 
| 129 163 | 
             
                      chain = CanvasSync.default_provisioning_report_chain(%w[users enrollments assignments])
         | 
| 130 164 |  | 
| 131 | 
            -
                      expect(chain. | 
| 132 | 
            -
                         | 
| 133 | 
            -
             | 
| 134 | 
            -
                          { | 
| 135 | 
            -
             | 
| 136 | 
            -
             | 
| 137 | 
            -
             | 
| 165 | 
            +
                      expect(chain.normalize!).to eq(
         | 
| 166 | 
            +
                        :job => "CanvasSync::Jobs::BeginSyncChainJob",
         | 
| 167 | 
            +
                        :parameters => [[
         | 
| 168 | 
            +
                          {:job=>"CanvasSync::JobBatches::ConcurrentBatchJob", :parameters=>[[
         | 
| 169 | 
            +
                            {:job=>"CanvasSync::Jobs::SyncTermsJob", :parameters=>[{
         | 
| 170 | 
            +
                              :sub_jobs=>[
         | 
| 171 | 
            +
                                {:job=>"CanvasSync::Jobs::SyncAssignmentsJob", :options=>{}},
         | 
| 172 | 
            +
                                {:job=>"CanvasSync::Jobs::SyncProvisioningReportJob", :options=>{:models=>["users", "enrollments"], :term_scope=>nil}}
         | 
| 173 | 
            +
                              ]
         | 
| 174 | 
            +
                            }]}
         | 
| 175 | 
            +
                          ]]}
         | 
| 176 | 
            +
                        ], {:legacy_support=>false, :updated_after=>nil}],
         | 
| 138 177 | 
             
                      )
         | 
| 139 178 | 
             
                    end
         | 
| 140 179 | 
             
                  end
         | 
| @@ -143,13 +182,18 @@ RSpec.describe CanvasSync do | |
| 143 182 | 
             
                    it "appends the SyncSubmissionsJob" do
         | 
| 144 183 | 
             
                      chain = CanvasSync.default_provisioning_report_chain(%w[users enrollments submissions])
         | 
| 145 184 |  | 
| 146 | 
            -
                      expect(chain. | 
| 147 | 
            -
                         | 
| 148 | 
            -
             | 
| 149 | 
            -
                          { | 
| 150 | 
            -
             | 
| 151 | 
            -
             | 
| 152 | 
            -
             | 
| 185 | 
            +
                      expect(chain.normalize!).to eq(
         | 
| 186 | 
            +
                        :job => "CanvasSync::Jobs::BeginSyncChainJob",
         | 
| 187 | 
            +
                        :parameters => [[
         | 
| 188 | 
            +
                          {:job=>"CanvasSync::JobBatches::ConcurrentBatchJob", :parameters=>[[
         | 
| 189 | 
            +
                            {:job=>"CanvasSync::Jobs::SyncTermsJob", :parameters=>[{
         | 
| 190 | 
            +
                              :sub_jobs=>[
         | 
| 191 | 
            +
                                {:job=>"CanvasSync::Jobs::SyncSubmissionsJob", :options=>{}},
         | 
| 192 | 
            +
                                {:job=>"CanvasSync::Jobs::SyncProvisioningReportJob", :options=>{:models=>["users", "enrollments"], :term_scope=>nil}}
         | 
| 193 | 
            +
                              ]
         | 
| 194 | 
            +
                            }]}
         | 
| 195 | 
            +
                          ]]}
         | 
| 196 | 
            +
                        ], {:legacy_support=>false, :updated_after=>nil}],
         | 
| 153 197 | 
             
                      )
         | 
| 154 198 | 
             
                    end
         | 
| 155 199 | 
             
                  end
         | 
| @@ -158,95 +202,24 @@ RSpec.describe CanvasSync do | |
| 158 202 | 
             
                    it "appends the SyncAssignmentGroupsJob" do
         | 
| 159 203 | 
             
                      chain = CanvasSync.default_provisioning_report_chain(%w[users enrollments assignment_groups])
         | 
| 160 204 |  | 
| 161 | 
            -
                      expect(chain. | 
| 162 | 
            -
                         | 
| 163 | 
            -
             | 
| 164 | 
            -
                          { | 
| 165 | 
            -
             | 
| 166 | 
            -
             | 
| 167 | 
            -
             | 
| 205 | 
            +
                      expect(chain.normalize!).to eq(
         | 
| 206 | 
            +
                        :job => "CanvasSync::Jobs::BeginSyncChainJob",
         | 
| 207 | 
            +
                        :parameters => [[
         | 
| 208 | 
            +
                          {:job=>"CanvasSync::JobBatches::ConcurrentBatchJob", :parameters=>[[
         | 
| 209 | 
            +
                            {:job=>"CanvasSync::Jobs::SyncTermsJob", :parameters=>[{
         | 
| 210 | 
            +
                              :sub_jobs=>[
         | 
| 211 | 
            +
                                {:job=>"CanvasSync::Jobs::SyncAssignmentGroupsJob", :options=>{}},
         | 
| 212 | 
            +
                                {:job=>"CanvasSync::Jobs::SyncProvisioningReportJob", :options=>{:models=>["users", "enrollments"], :term_scope=>nil}}
         | 
| 213 | 
            +
                              ]
         | 
| 214 | 
            +
                            }]}
         | 
| 215 | 
            +
                          ]]}
         | 
| 216 | 
            +
                        ], {:legacy_support=>false, :updated_after=>nil}],
         | 
| 168 217 | 
             
                      )
         | 
| 169 218 | 
             
                    end
         | 
| 170 219 | 
             
                  end
         | 
| 171 220 | 
             
                end
         | 
| 172 221 | 
             
              end
         | 
| 173 222 |  | 
| 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 223 | 
             
              describe ".sync_scope" do
         | 
| 251 224 |  | 
| 252 225 | 
             
              end
         |