canvas_sync 0.22.6 → 0.22.8

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 61d4f6b7e0c7f8201ee2dccdeea7e9f3149f112d35ea4ab72903ddbee892c079
4
- data.tar.gz: 72a6a5553aa892680ee6ce2dacba9ce98d200cc44bd17a40dc5648b028b63868
3
+ metadata.gz: '0882011929080b4e55e1798ae3639c4431a583dd2a31634b2b9c2ba5f450fcb4'
4
+ data.tar.gz: 7a339eef193de9b640b3d68d5474a7771d363f7dee723be49da33cf319afe610
5
5
  SHA512:
6
- metadata.gz: 5eb771935ecaa392a2fd6442136cadbe7972912381de6028c145de4e45419904de56a694a636dde1cabcbfda67fbeedfdcecd38993031194dab85f75ed529b98
7
- data.tar.gz: fd8a0c64457a2190783527dcbfff67d34ec17f6f9249b1e0f4147a0e3ef8d5b9ae66ad4e132982b341ace536db78f39b95dbd5c7447f6099d765b83c8ef897ce
6
+ metadata.gz: a54b1779112dce3d106a503cc720b74d5b54ed2688c95c9d2c3523024813a0ac34d144417a8959bc81561dc4f78a7cf9914dd124037c85376a8a35b455bd5be1
7
+ data.tar.gz: 74e8b3e7d9317bbc2bbd7f902cfbedeabfd826ddbfd70aa4c8bf57c6f05dc2f4176f7bf2c0cc0352adae4ecaa4978f57f02fc3dcbbed8d1d8130df58bbaea51d
@@ -40,14 +40,17 @@ module CanvasSync::Concerns
40
40
  options = { validate: false, on_duplicate_key_update: update_conditions }.merge(import_args)
41
41
 
42
42
  if all_pages
43
- batcher = CanvasSync::BatchProcessor.new(of: batch_size) do |batch|
44
- import(columns, batch, options)
43
+ enumer = api_array.all_pages_each.lazy
44
+
45
+ # Map the API response to instances of this model
46
+ enumer = enumer.map do |api_item|
47
+ new.assign_from_api_params(api_item)
45
48
  end
46
- api_array.all_pages_each do |api_item|
47
- item = new.assign_from_api_params(api_item)
48
- batcher << item
49
+
50
+ # Import in batches
51
+ enumer.each_slice(batch_size) do |batch|
52
+ import(columns, batch, options)
49
53
  end
50
- batcher.flush
51
54
  else
52
55
  items = api_array.map do |api_item|
53
56
  new.assign_from_api_params(api_item)
@@ -51,10 +51,11 @@ module CanvasSync::Concerns
51
51
  m = maps[mname] = {}
52
52
 
53
53
  m[:conflict_target] = Array(legacy[:conflict_target]).map(&:to_sym).map do |lct|
54
- legacy[:report_columns][lct][:database_column_name]
54
+ legacy[:report_columns]&.[](lct)&.[](:database_column_name)
55
55
  end
56
56
 
57
57
  m[:columns] = {}
58
+
58
59
  legacy[:report_columns].each do |rcol, opts|
59
60
  m[:columns][opts[:database_column_name]] = opts.except(:database_column_name).merge!(
60
61
  report_column: rcol,
@@ -68,6 +69,15 @@ module CanvasSync::Concerns
68
69
  def self.default_v1_mappings
69
70
  @legacy_mappings ||= begin
70
71
  mapping = YAML.load_file(File.join(__dir__, '../processors', "model_mappings.yml")).deep_symbolize_keys!
72
+ # Default columns can be excluded if the table has not been migrated to accept them
73
+ mapping.each do |mname, legacy|
74
+ legacy[:report_columns].select! do |rcol, opts|
75
+ model = mname.to_s&.classify&.safe_constantize
76
+ # we need to make sure this is a model otherwise they will be systematically removed - some mappings are not models (e.g xlists)
77
+ model.present? && !model.column_names.include?(opts[:database_column_name].to_s) ? false : true
78
+ end
79
+ end
80
+
71
81
  override_filepath = Rails.root.join("config/canvas_sync_provisioning_mapping.yml")
72
82
 
73
83
  if File.file?(override_filepath)
@@ -13,6 +13,7 @@ class CreateEnrollments < ActiveRecord::Migration[5.1]
13
13
  t.bigint :canvas_section_id
14
14
  t.string :workflow_state
15
15
  t.string :base_role_type
16
+ t.datetime :completed_at
16
17
 
17
18
  t.timestamps
18
19
  end
@@ -23,7 +23,7 @@ module CanvasSync
23
23
  end
24
24
  end
25
25
 
26
- def self.perform_in_batches(report_file_path, raw_mapping, klass, conflict_target, import_args: {})
26
+ def self.perform_in_batches(report_file_path, raw_mapping, klass, conflict_target, import_args: {}, &block)
27
27
  mapping = {}.with_indifferent_access
28
28
  raw_mapping.each do |db_col, opts|
29
29
  next if opts[:deprecated] && !klass.column_names.include?(db_col.to_s)
@@ -37,14 +37,27 @@ module CanvasSync
37
37
  conflict_target = Array(conflict_target).map(&:to_s)
38
38
  conflict_target_indices = conflict_target.map{|ct| database_column_names.index(ct) }
39
39
 
40
- row_ids = {}
41
- batcher = CanvasSync::BatchProcessor.new(of: batch_size) do |batch|
42
- row_ids = {}
43
- perform_import(klass, database_column_names, batch, conflict_target, import_args)
40
+ enumer = CSV.foreach(report_file_path, headers: true, header_converters: :symbol).lazy
41
+
42
+ # Optionally filter rows by a passed block
43
+ if block
44
+ enumer = enumer.filter_map do |row|
45
+ catch :skip do
46
+ block.call(row)
47
+ end
48
+ end
49
+ end
50
+
51
+ # Optionally chunk by a computed value. Mainly so we can group duplicate rows and choose one
52
+ chunker = nil
53
+ chunker = UserChunker.new if defined?(User) && klass == User && csv_column_names.include?('user_id')
54
+ if chunker
55
+ enumer = enumer.chunk{|row| chunker.key(row) }.flat_map{|key, rows| chunker.choose(key, rows) }
44
56
  end
45
57
 
46
- row_buffer_out = ->(row) {
47
- formatted_row = mapping.map do |db_col, col_def|
58
+ # Prepare the rows for import
59
+ enumer = enumer.map do |row|
60
+ mapping.map do |db_col, col_def|
48
61
  value = nil
49
62
  value = row[col_def[:report_column]] if col_def[:report_column]
50
63
 
@@ -63,33 +76,25 @@ module CanvasSync
63
76
 
64
77
  value
65
78
  end
79
+ end
66
80
 
67
- if conflict_target.present?
68
- key = conflict_target_indices.map{|ct| formatted_row[ct] }
69
- next if row_ids[key]
70
-
81
+ # Reject rows within a single batch that have the same ID
82
+ row_ids = nil
83
+ if conflict_target.present?
84
+ enumer = enumer.reject do |row|
85
+ key = conflict_target_indices.map{|ct| row[ct] }
86
+ skip = row_ids[key]
71
87
  row_ids[key] = true
88
+ skip
72
89
  end
73
-
74
- batcher << formatted_row
75
- }
76
-
77
- row_buffer = nil
78
- if defined?(User) && klass == User && csv_column_names.include?('user_id')
79
- row_buffer = UserRowBuffer.new(&row_buffer_out)
80
- else
81
- row_buffer = NullRowBuffer.new(&row_buffer_out)
82
90
  end
83
91
 
84
- CSV.foreach(report_file_path, headers: true, header_converters: :symbol) do |row|
85
- row = yield(row) if block_given?
86
- next if row.nil?
87
-
88
- row_buffer << row
92
+ # Start importing
93
+ row_ids = {}
94
+ enumer.each_slice(batch_size) do |batch|
95
+ perform_import(klass, database_column_names, batch, conflict_target, import_args)
96
+ row_ids = {}
89
97
  end
90
-
91
- row_buffer.flush
92
- batcher.flush
93
98
  end
94
99
 
95
100
  def self.perform_import(klass, columns, rows, conflict_target, import_args={})
@@ -157,52 +162,17 @@ module CanvasSync
157
162
  batch_size > 0 ? batch_size : DEFAULT_BATCH_SIZE
158
163
  end
159
164
 
160
- class RowBuffer
161
- def initialize(&block)
162
- @flush_out = block
163
- @buffered_rows = []
164
- end
165
-
166
- def <<(v)
167
- @buffered_rows << v
168
- end
169
-
170
- def flush(value = @buffered_rows)
171
- if value.is_a?(Array)
172
- value.each do |v|
173
- @flush_out.call(v)
174
- end
175
- else
176
- @flush_out.call(value)
177
- end
178
- @buffered_rows = []
179
- end
180
- end
181
-
182
- class NullRowBuffer
183
- def initialize(&block)
184
- @flush_out = block
185
- end
186
-
187
- def <<(v)
188
- @flush_out.call(v)
189
- end
190
-
191
- def flush; end
192
- end
193
-
194
165
  # Ensures that, if a User has multiple rows, one with a SIS ID is preferred.
195
166
  # This is mainly to fix issues in legacy apps - the suggested approach for new apps
196
167
  # is to sync and use the Pseudonymes table
197
- class UserRowBuffer < RowBuffer
198
- def <<(v)
199
- flush if @buffered_rows[0] && @buffered_rows[0][:canvas_user_id] != v[:canvas_user_id]
200
- super
168
+ class UserChunker
169
+ def key(row)
170
+ row[:canvas_user_id]
201
171
  end
202
172
 
203
- def flush
204
- row = @buffered_rows.find{|r| r[:user_id].present? } || @buffered_rows.last
205
- super(row.present? ? [row] : [])
173
+ def choose(key, rows)
174
+ row = rows.find{|r| r[:user_id].present? } || rows.last
175
+ row.present? ? [row] : []
206
176
  end
207
177
  end
208
178
  end
File without changes
@@ -337,7 +337,7 @@ module CanvasSync::JobBatches
337
337
  trigger_callback.call(:complete)
338
338
  end
339
339
 
340
- if all_successful # All Successfull
340
+ if all_successful # All Successful
341
341
  trigger_callback.call(:success)
342
342
  elsif pending_jobs == dead_jobs && pending_batches == stagnated_batches # Stagnated
343
343
  trigger_callback.call(:stagnated)
@@ -4,9 +4,7 @@ module CanvasSync::JobBatches
4
4
 
5
5
  attr_reader :base_job
6
6
 
7
- def initialize(base_type = SerialBatchJob, chain_id: nil)
8
- @chain_id = chain_id || SecureRandom.urlsafe_base64(10)
9
-
7
+ def initialize(base_type = SerialBatchJob)
10
8
  if base_type.is_a?(Hash)
11
9
  @base_job = base_type
12
10
  @base_job[:args] ||= @base_job[:parameters] || []
@@ -111,7 +109,7 @@ module CanvasSync::JobBatches
111
109
  return nil if matching_jobs.count == 0
112
110
 
113
111
  job = matching_jobs[0][0]
114
- job = self.class.new(job, chain_id: @chain_id) unless job.is_a?(ChainBuilder)
112
+ job = self.class.new(job) unless job.is_a?(ChainBuilder)
115
113
  job
116
114
  end
117
115
 
@@ -120,7 +118,6 @@ module CanvasSync::JobBatches
120
118
  job_def.normalize!
121
119
  else
122
120
  job_def[:job] = job_def[:job].to_s
123
- job_def[:chain_link] ||= "#{@chain_id}-#{SecureRandom.urlsafe_base64(10)}"
124
121
  if (chain = self.class.get_chain_parameter(job_def, raise_error: false)).present?
125
122
  chain.map! { |sub_job| normalize!(sub_job) }
126
123
  end
@@ -141,7 +138,7 @@ module CanvasSync::JobBatches
141
138
  args: args,
142
139
  kwargs: kwargs,
143
140
  }
144
- self.class.new(hsh, chain_id: @chain_id).apply_block(&blk) if blk.present?
141
+ self.class.new(hsh).apply_block(&blk) if blk.present?
145
142
  hsh
146
143
  end
147
144
 
@@ -242,24 +239,6 @@ module CanvasSync::JobBatches
242
239
  job_class.perform_later(*job_args, **job_kwargs)
243
240
  end
244
241
  end
245
-
246
- def link_to_batch!(chain_link, batch)
247
- # Or make chains a separate entity - Chains show batches, but batches don't show chain?
248
- # Or "Annotate" a Batch with chain data - could extract chain id from any job entry
249
- end
250
-
251
- def annotate_batch!(batch, chain)
252
-
253
- end
254
-
255
- def handle_step_complete(status, opts)
256
- chain_link = opts[:chain_link]
257
- chain_id, chain_step_id = chain_link.split('-')
258
-
259
- CanvasSync::JobBatches::Batch.redis.multi do |r|
260
- r.hset("CHAIN-#{chain_id}-steps", chain_step_id, "complete")
261
- end
262
- end
263
242
  end
264
243
  end
265
244
 
@@ -144,10 +144,6 @@ module CanvasSync::JobBatches
144
144
  if next_job[:chain_link].present?
145
145
  # Annotate Batch with chain-step info
146
146
  batch.context["csb:chain_link"] = next_job[:chain_link]
147
- # TODO Add Fiber Batch to chain-link
148
- # With the exception of the top of the Chain, all nested ManagedBatch Roots should be within a Fiber,
149
- # so we shouldn't really need to make the Root checkin with the chain
150
- # ...except to cleanup the chain
151
147
  batch.on(:complete, "#{ChainBuilder.to_s}.chain_step_complete", chain_link: next_job[:chain_link])
152
148
  end
153
149
 
@@ -49,7 +49,6 @@ module CanvasSync::JobBatches
49
49
  end
50
50
 
51
51
  def success?
52
- # TODO (Race Condition) This might not be valid if checked from a :complete callback
53
52
  'true' == Batch.redis { |r| r.hget("BID-#{bid}", 'success') }
54
53
  end
55
54
 
@@ -6,6 +6,8 @@ module CanvasSync::JobUniqueness
6
6
  context_class.new(data, **kwargs)
7
7
  end
8
8
 
9
+ attr_reader :lock_id
10
+
9
11
  # { job_clazz, jid, queue, args?, kwargs?, base_key? }
10
12
  def initialize(data, job_instance: nil, config: nil)
11
13
  @base_key = data[:base_key]
@@ -14,9 +16,7 @@ module CanvasSync::JobUniqueness
14
16
  @config = config || @context_data[:config]
15
17
 
16
18
  # TODO Consider (somewhere) updating the lock_id to the BID of the wrapping Batch (when applicable)
17
- @lock_id ||= data[:lid] || Thread.current[:unique_jobs_previous_context]&.lock_id
18
- @lock_id_locked = @lock_id.present?
19
- @lock_id ||= job_id
19
+ @lock_id ||= data[:lid] || Thread.current[:unique_jobs_previous_context]&.lock_id || job_id
20
20
  end
21
21
 
22
22
  # This is primarily for rehydrating in a Batch Callback, so it is unlikely that args and kwargs are needed.
@@ -84,18 +84,6 @@ module CanvasSync::JobUniqueness
84
84
  end
85
85
  end
86
86
 
87
- def lock_id
88
- @lock_id_locked = true
89
- @lock_id
90
- end
91
-
92
- def lock_id=(new_id)
93
- raise "Lock ID already set" if @lock_id_locked
94
- return unless new_id.present?
95
- @lock_id = new_id
96
- @lock_id_locked = true
97
- end
98
-
99
87
  def job_id
100
88
  @context_data[:jid]
101
89
  end
@@ -12,17 +12,14 @@ module CanvasSync
12
12
  # Override the delta-syncing date if:
13
13
  # 1. the Term hasn't been synced before or
14
14
  # 2. the Term underwent a period of not syncing
15
+ term_last_sync = CanvasSync.redis.get(self.class.last_sync_key(term_id))
15
16
  if batch_context[:updated_after]
16
- term_last_sync = CanvasSync.redis.get(self.class.last_sync_key(term_id))
17
17
  if !term_last_sync.present? || batch_context[:updated_after] > term_last_sync
18
18
  local_context[:updated_after] = term_last_sync.presence
19
19
  end
20
20
  end
21
21
 
22
22
  JobBatches::ManagedBatchJob.make_batch(jobs, ordered: false, concurrency: true) do |b|
23
- # TODO If we do a Chain UI, this will need to checkin somehow to indicate that the chain forked
24
- # Or chain steps just show a summary - eg "Started", "X Jobs Running", "Done" or "X Jobs Running, Y Jobs Done" - and not individual forks
25
- # For a step to be considered done, all previous sibling-level steps must be done and no batches pending
26
23
  b.description = "TermBatchJob(#{term_id}) Root"
27
24
  b.context = local_context
28
25
  b.on(:success, "#{self.class.to_s}.batch_finished") unless options[:mark_synced] == false
@@ -159,6 +159,9 @@ enrollments:
159
159
  base_role_type:
160
160
  database_column_name: base_role_type
161
161
  type: string
162
+ completed_at:
163
+ database_column_name: completed_at
164
+ type: datetime
162
165
 
163
166
  sections:
164
167
  conflict_target: canvas_section_id
@@ -1,3 +1,3 @@
1
1
  module CanvasSync
2
- VERSION = "0.22.6".freeze
2
+ VERSION = "0.22.8".freeze
3
3
  end
@@ -2,6 +2,18 @@ require 'spec_helper'
2
2
 
3
3
  RSpec.describe CanvasSync do
4
4
  describe '.provisioning_sync' do
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'], term_scope: nil).normalize![:args][0]
7
+
8
+ expect(CanvasSync::Jobs::BeginSyncChainJob).to receive(:perform_later)
9
+ .with(
10
+ expected_job_chain,
11
+ anything
12
+ )
13
+
14
+ CanvasSync.provisioning_sync(['courses'])
15
+ end
16
+
5
17
  context 'an invalid model is passed in' do
6
18
  it 'raises a helpful exception' do
7
19
  expect {
@@ -18,25 +30,22 @@ RSpec.describe CanvasSync do
18
30
  provisioning: { c: 3 },
19
31
  global: { d: 4 },
20
32
  })
21
- expect(chain.normalize!).to match({
33
+ expect(chain.normalize!).to eq({
22
34
  :job => "CanvasSync::Jobs::BeginSyncChainJob",
23
- :chain_link=>String,
24
35
  :args => [
25
36
  [
26
37
  {
27
38
  :job=>"CanvasSync::JobBatches::ConcurrentBatchJob",
28
- :chain_link=>String,
29
39
  :args=>[
30
40
  [
31
- {:job=>"CanvasSync::Jobs::SyncProvisioningReportJob", :chain_link=>String, :options=>{:models=>["users"], :b=>2}},
41
+ {:job=>"CanvasSync::Jobs::SyncProvisioningReportJob", :options=>{:models=>["users"], :b=>2}},
32
42
  {
33
43
  :job=>"CanvasSync::Jobs::SyncTermsJob",
34
- :chain_link=>String,
35
44
  :args=>[],
36
45
  :kwargs=>{
37
46
  :term_scope=>"active",
38
47
  :sub_jobs=>[
39
- {:job=>"CanvasSync::Jobs::SyncProvisioningReportJob", :chain_link=>String, :options=>{:models=>["courses"], :c=>3}},
48
+ {:job=>"CanvasSync::Jobs::SyncProvisioningReportJob", :options=>{:models=>["courses"], :c=>3}},
40
49
  ],
41
50
  },
42
51
  },
@@ -53,23 +62,20 @@ RSpec.describe CanvasSync do
53
62
  context 'we are syncing users with a term scope' do
54
63
  it 'syncs the users in a separate job that runs first' do
55
64
  chain = CanvasSync.default_provisioning_report_chain(['users', 'courses'], term_scope: :active)
56
- expect(chain.normalize!).to match({
65
+ expect(chain.normalize!).to eq({
57
66
  :job => "CanvasSync::Jobs::BeginSyncChainJob",
58
- :chain_link=>String,
59
67
  :args => [[
60
68
  {
61
69
  :job=>"CanvasSync::JobBatches::ConcurrentBatchJob",
62
- :chain_link=>String,
63
70
  :args=>[
64
71
  [
65
- {:job=>"CanvasSync::Jobs::SyncProvisioningReportJob", :chain_link=>String, :options=>{:models=>["users"]}},
72
+ {:job=>"CanvasSync::Jobs::SyncProvisioningReportJob", :options=>{:models=>["users"]}},
66
73
  {
67
74
  :job=>"CanvasSync::Jobs::SyncTermsJob",
68
- :chain_link=>String,
69
75
  :args=>[],
70
76
  :kwargs=>{
71
77
  :sub_jobs=>[
72
- {:job=>"CanvasSync::Jobs::SyncProvisioningReportJob", :chain_link=>String, :options=>{:models=>["courses"]}}
78
+ {:job=>"CanvasSync::Jobs::SyncProvisioningReportJob", :options=>{:models=>["courses"]}}
73
79
  ],
74
80
  :term_scope=>"active",
75
81
  }
@@ -87,20 +93,17 @@ RSpec.describe CanvasSync do
87
93
  context 'we are syncing users without a term scope' do
88
94
  it 'syncs users along with the rest of the provisioning report' do
89
95
  chain = CanvasSync.default_provisioning_report_chain(['users', 'courses'])
90
- expect(chain.normalize!).to match({
96
+ expect(chain.normalize!).to eq({
91
97
  :job => "CanvasSync::Jobs::BeginSyncChainJob",
92
- :chain_link=>String,
93
98
  :args => [[
94
99
  {
95
100
  :job=>"CanvasSync::JobBatches::ConcurrentBatchJob",
96
- :chain_link=>String,
97
101
  :args=>[[
98
102
  {
99
103
  :job=>"CanvasSync::Jobs::SyncTermsJob",
100
- :chain_link=>String,
101
104
  :args=>[],
102
105
  :kwargs=>{
103
- :sub_jobs=>[{:job=>"CanvasSync::Jobs::SyncProvisioningReportJob", :chain_link=>String, :options=>{:models=>["users", "courses"]}}],
106
+ :sub_jobs=>[{:job=>"CanvasSync::Jobs::SyncProvisioningReportJob", :options=>{:models=>["users", "courses"]}}],
104
107
  :term_scope=>nil,
105
108
  }
106
109
  }
@@ -116,21 +119,18 @@ RSpec.describe CanvasSync do
116
119
  context 'we are syncing roles with a term scope' do
117
120
  it 'syncs the roles in a separate job that runs first' do
118
121
  chain = CanvasSync.default_provisioning_report_chain(['roles', 'courses'], term_scope: :active)
119
- expect(chain.normalize!).to match({
122
+ expect(chain.normalize!).to eq({
120
123
  :job => "CanvasSync::Jobs::BeginSyncChainJob",
121
- :chain_link=>String,
122
124
  :args => [[
123
125
  {
124
126
  :job=>"CanvasSync::JobBatches::ConcurrentBatchJob",
125
- :chain_link=>String,
126
127
  :args=>[[
127
- {:job=>"CanvasSync::Jobs::SyncRolesJob", :chain_link=>String, :options=>{}},
128
+ {:job=>"CanvasSync::Jobs::SyncRolesJob", :options=>{}},
128
129
  {
129
130
  :job=>"CanvasSync::Jobs::SyncTermsJob",
130
- :chain_link=>String,
131
131
  :args=>[],
132
132
  :kwargs=>{
133
- :sub_jobs=>[{:job=>"CanvasSync::Jobs::SyncProvisioningReportJob", :chain_link=>String, :options=>{:models=>["courses"]}}],
133
+ :sub_jobs=>[{:job=>"CanvasSync::Jobs::SyncProvisioningReportJob", :options=>{:models=>["courses"]}}],
134
134
  :term_scope=>"active",
135
135
  }
136
136
  },
@@ -146,21 +146,18 @@ RSpec.describe CanvasSync do
146
146
  context 'we are syncing roles without a term scope' do
147
147
  it 'syncs roles separately even with no term scope' do
148
148
  chain = CanvasSync.default_provisioning_report_chain(['roles', 'courses'])
149
- expect(chain.normalize!).to match({
149
+ expect(chain.normalize!).to eq({
150
150
  :job => "CanvasSync::Jobs::BeginSyncChainJob",
151
- :chain_link=>String,
152
151
  :args => [[
153
152
  {
154
153
  :job=>"CanvasSync::JobBatches::ConcurrentBatchJob",
155
- :chain_link=>String,
156
154
  :args=>[[
157
- {:job=>"CanvasSync::Jobs::SyncRolesJob", :chain_link=>String, :options=>{}},
155
+ {:job=>"CanvasSync::Jobs::SyncRolesJob", :options=>{}},
158
156
  {
159
157
  :job=>"CanvasSync::Jobs::SyncTermsJob",
160
- :chain_link=>String,
161
158
  :args=>[],
162
159
  :kwargs=>{
163
- :sub_jobs=>[{:job=>"CanvasSync::Jobs::SyncProvisioningReportJob", :chain_link=>String, :options=>{:models=>["courses"]}}],
160
+ :sub_jobs=>[{:job=>"CanvasSync::Jobs::SyncProvisioningReportJob", :options=>{:models=>["courses"]}}],
164
161
  :term_scope=>nil,
165
162
  }
166
163
  }
@@ -176,21 +173,18 @@ RSpec.describe CanvasSync do
176
173
  context 'we are syncing admins with a term scope' do
177
174
  it 'syncs the admins in a separate job that runs first' do
178
175
  chain = CanvasSync.default_provisioning_report_chain(['admins', 'courses'], term_scope: :active)
179
- expect(chain.normalize!).to match({
176
+ expect(chain.normalize!).to eq({
180
177
  :job => "CanvasSync::Jobs::BeginSyncChainJob",
181
- :chain_link=>String,
182
178
  :args => [[
183
179
  {
184
180
  :job=>"CanvasSync::JobBatches::ConcurrentBatchJob",
185
- :chain_link=>String,
186
181
  :args=>[[
187
- {:job=>"CanvasSync::Jobs::SyncAdminsJob", :chain_link=>String, :options=>{}},
182
+ {:job=>"CanvasSync::Jobs::SyncAdminsJob", :options=>{}},
188
183
  {
189
184
  :job=>"CanvasSync::Jobs::SyncTermsJob",
190
- :chain_link=>String,
191
185
  :args=>[],
192
186
  :kwargs=>{
193
- :sub_jobs=>[{:job=>"CanvasSync::Jobs::SyncProvisioningReportJob", :chain_link=>String, :options=>{:models=>["courses"]}}],
187
+ :sub_jobs=>[{:job=>"CanvasSync::Jobs::SyncProvisioningReportJob", :options=>{:models=>["courses"]}}],
194
188
  :term_scope=>"active"
195
189
  }
196
190
  }
@@ -206,21 +200,18 @@ RSpec.describe CanvasSync do
206
200
  context 'we are syncing admins without a term scope' do
207
201
  it 'syncs admins separately even with no term scope' do
208
202
  chain = CanvasSync.default_provisioning_report_chain(['admins', 'courses'])
209
- expect(chain.normalize!).to match({
203
+ expect(chain.normalize!).to eq({
210
204
  :job => "CanvasSync::Jobs::BeginSyncChainJob",
211
- :chain_link=>String,
212
205
  :args => [[
213
206
  {
214
207
  :job=>"CanvasSync::JobBatches::ConcurrentBatchJob",
215
- :chain_link=>String,
216
208
  :args=>[[
217
- {:job=>"CanvasSync::Jobs::SyncAdminsJob", :chain_link=>String, :options=>{}},
209
+ {:job=>"CanvasSync::Jobs::SyncAdminsJob", :options=>{}},
218
210
  {
219
211
  :job=>"CanvasSync::Jobs::SyncTermsJob",
220
- :chain_link=>String,
221
212
  :args=>[],
222
213
  :kwargs=>{
223
- :sub_jobs=>[{:job=>"CanvasSync::Jobs::SyncProvisioningReportJob", :chain_link=>String, :options=>{:models=>["courses"]}}],
214
+ :sub_jobs=>[{:job=>"CanvasSync::Jobs::SyncProvisioningReportJob", :options=>{:models=>["courses"]}}],
224
215
  :term_scope=>nil
225
216
  }
226
217
  }
@@ -237,22 +228,19 @@ RSpec.describe CanvasSync do
237
228
  it "appends the SyncAssignmentsJob" do
238
229
  chain = CanvasSync.default_provisioning_report_chain(%w[users enrollments assignments])
239
230
 
240
- expect(chain.normalize!).to match({
231
+ expect(chain.normalize!).to eq({
241
232
  :job => "CanvasSync::Jobs::BeginSyncChainJob",
242
- :chain_link=>String,
243
233
  :args => [[
244
234
  {
245
235
  :job=>"CanvasSync::JobBatches::ConcurrentBatchJob",
246
- :chain_link=>String,
247
236
  :args=>[[
248
237
  {
249
238
  :job=>"CanvasSync::Jobs::SyncTermsJob",
250
- :chain_link=>String,
251
239
  :args=>[],
252
240
  :kwargs=>{
253
241
  :sub_jobs=>[
254
- {:job=>"CanvasSync::Jobs::SyncAssignmentsJob", :chain_link=>String, :options=>{}},
255
- {:job=>"CanvasSync::Jobs::SyncProvisioningReportJob", :chain_link=>String, :options=>{:models=>["users", "enrollments"]}}
242
+ {:job=>"CanvasSync::Jobs::SyncAssignmentsJob", :options=>{}},
243
+ {:job=>"CanvasSync::Jobs::SyncProvisioningReportJob", :options=>{:models=>["users", "enrollments"]}}
256
244
  ],
257
245
  :term_scope=>nil
258
246
  }
@@ -270,22 +258,19 @@ RSpec.describe CanvasSync do
270
258
  it "appends the SyncSubmissionsJob" do
271
259
  chain = CanvasSync.default_provisioning_report_chain(%w[users enrollments submissions])
272
260
 
273
- expect(chain.normalize!).to match({
261
+ expect(chain.normalize!).to eq({
274
262
  :job => "CanvasSync::Jobs::BeginSyncChainJob",
275
- :chain_link=>String,
276
263
  :args => [[
277
264
  {
278
265
  :job=>"CanvasSync::JobBatches::ConcurrentBatchJob",
279
- :chain_link=>String,
280
266
  :args=>[[
281
267
  {
282
268
  :job=>"CanvasSync::Jobs::SyncTermsJob",
283
- :chain_link=>String,
284
269
  :args=>[],
285
270
  :kwargs=>{
286
271
  :sub_jobs=>[
287
- {:job=>"CanvasSync::Jobs::SyncSubmissionsJob", :chain_link=>String, :options=>{}},
288
- {:job=>"CanvasSync::Jobs::SyncProvisioningReportJob", :chain_link=>String, :options=>{:models=>["users", "enrollments"]}}
272
+ {:job=>"CanvasSync::Jobs::SyncSubmissionsJob", :options=>{}},
273
+ {:job=>"CanvasSync::Jobs::SyncProvisioningReportJob", :options=>{:models=>["users", "enrollments"]}}
289
274
  ],
290
275
  :term_scope=>nil
291
276
  }
@@ -303,22 +288,19 @@ RSpec.describe CanvasSync do
303
288
  it "appends the SyncAssignmentGroupsJob" do
304
289
  chain = CanvasSync.default_provisioning_report_chain(%w[users enrollments assignment_groups])
305
290
 
306
- expect(chain.normalize!).to match({
291
+ expect(chain.normalize!).to eq({
307
292
  :job => "CanvasSync::Jobs::BeginSyncChainJob",
308
- :chain_link=>String,
309
293
  :args => [[
310
294
  {
311
295
  :job=>"CanvasSync::JobBatches::ConcurrentBatchJob",
312
- :chain_link=>String,
313
296
  :args=>[[
314
297
  {
315
298
  :job=>"CanvasSync::Jobs::SyncTermsJob",
316
- :chain_link=>String,
317
299
  :args=>[],
318
300
  :kwargs=>{
319
301
  :sub_jobs=>[
320
- {:job=>"CanvasSync::Jobs::SyncAssignmentGroupsJob", :chain_link=>String, :options=>{}},
321
- {:job=>"CanvasSync::Jobs::SyncProvisioningReportJob", :chain_link=>String, :options=>{:models=>["users", "enrollments"]}}
302
+ {:job=>"CanvasSync::Jobs::SyncAssignmentGroupsJob", :options=>{}},
303
+ {:job=>"CanvasSync::Jobs::SyncProvisioningReportJob", :options=>{:models=>["users", "enrollments"]}}
322
304
  ],
323
305
  :term_scope=>nil
324
306
  }
@@ -12,6 +12,10 @@ RSpec.describe CanvasSync::Processors::ProvisioningReportProcessor do
12
12
 
13
13
  context "with User#sis_id column" do
14
14
  before do
15
+ # this could be refactored into a method that prevents caching the variables unless the environment is prod
16
+ CanvasSync::Concerns::SyncMapping::Mapping.instance_variable_set(:@mappings, nil)
17
+ CanvasSync::Concerns::SyncMapping::Mapping.instance_variable_set(:@legacy_mappings, nil)
18
+
15
19
  self.use_transactional_tests = false
16
20
  ActiveRecord::Migration.add_column :users, :sis_id, :string
17
21
  User.reset_column_information
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -19,6 +19,7 @@ class CreateEnrollments < ActiveRecord::Migration[5.1]
19
19
  t.bigint :canvas_section_id
20
20
  t.string :workflow_state
21
21
  t.string :base_role_type
22
+ t.datetime :completed_at
22
23
 
23
24
  t.timestamps
24
25
  end
@@ -210,6 +210,7 @@ ActiveRecord::Schema.define(version: 2024_05_23_101010) do
210
210
  t.bigint "canvas_section_id"
211
211
  t.string "workflow_state"
212
212
  t.string "base_role_type"
213
+ t.datetime "completed_at"
213
214
  t.datetime "created_at", null: false
214
215
  t.datetime "updated_at", null: false
215
216
  t.index ["canvas_course_id"], name: "index_enrollments_on_canvas_course_id"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: canvas_sync
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.22.6
4
+ version: 0.22.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Instructure CustomDev
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-11-19 00:00:00.000000000 Z
11
+ date: 2024-12-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '5.2'
19
+ version: 7.1.0
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '5.2'
26
+ version: 7.1.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -220,20 +220,6 @@ dependencies:
220
220
  - - ">="
221
221
  - !ruby/object:Gem::Version
222
222
  version: '0'
223
- - !ruby/object:Gem::Dependency
224
- name: apartment
225
- requirement: !ruby/object:Gem::Requirement
226
- requirements:
227
- - - ">="
228
- - !ruby/object:Gem::Version
229
- version: '0'
230
- type: :development
231
- prerelease: false
232
- version_requirements: !ruby/object:Gem::Requirement
233
- requirements:
234
- - - ">="
235
- - !ruby/object:Gem::Version
236
- version: '0'
237
223
  - !ruby/object:Gem::Dependency
238
224
  name: with_model
239
225
  requirement: !ruby/object:Gem::Requirement
@@ -266,14 +252,14 @@ dependencies:
266
252
  name: sidekiq
267
253
  requirement: !ruby/object:Gem::Requirement
268
254
  requirements:
269
- - - "<"
255
+ - - "~>"
270
256
  - !ruby/object:Gem::Version
271
257
  version: '7.0'
272
258
  type: :development
273
259
  prerelease: false
274
260
  version_requirements: !ruby/object:Gem::Requirement
275
261
  requirements:
276
- - - "<"
262
+ - - "~>"
277
263
  - !ruby/object:Gem::Version
278
264
  version: '7.0'
279
265
  - !ruby/object:Gem::Dependency
@@ -430,7 +416,7 @@ dependencies:
430
416
  - - ">="
431
417
  - !ruby/object:Gem::Version
432
418
  version: '0'
433
- description:
419
+ description:
434
420
  email:
435
421
  - pseng@instructure.com
436
422
  executables: []
@@ -458,7 +444,6 @@ files:
458
444
  - lib/canvas_sync/concerns/account/ancestry.rb
459
445
  - lib/canvas_sync/concerns/account/base.rb
460
446
  - lib/canvas_sync/concerns/api_syncable.rb
461
- - lib/canvas_sync/concerns/auto_relations.rb
462
447
  - lib/canvas_sync/concerns/legacy_columns.rb
463
448
  - lib/canvas_sync/concerns/live_event_sync.rb
464
449
  - lib/canvas_sync/concerns/role/base.rb
@@ -868,7 +853,7 @@ files:
868
853
  homepage: https://instructure.com
869
854
  licenses: []
870
855
  metadata: {}
871
- post_install_message:
856
+ post_install_message:
872
857
  rdoc_options: []
873
858
  require_paths:
874
859
  - lib
@@ -883,241 +868,241 @@ required_rubygems_version: !ruby/object:Gem::Requirement
883
868
  - !ruby/object:Gem::Version
884
869
  version: '0'
885
870
  requirements: []
886
- rubygems_version: 3.0.3.1
887
- signing_key:
871
+ rubygems_version: 3.5.16
872
+ signing_key:
888
873
  specification_version: 4
889
874
  summary: Gem for generating Canvas models and migrations and syncing data from Canvas
890
875
  test_files:
891
- - spec/spec_helper.rb
876
+ - spec/canvas_sync/canvas_sync_spec.rb
877
+ - spec/canvas_sync/jobs/canvas_process_waiter_spec.rb
878
+ - spec/canvas_sync/jobs/job_spec.rb
879
+ - spec/canvas_sync/jobs/report_checker_spec.rb
880
+ - spec/canvas_sync/jobs/report_processor_job_spec.rb
881
+ - spec/canvas_sync/jobs/report_starter_spec.rb
882
+ - spec/canvas_sync/jobs/sync_admins_job_spec.rb
883
+ - spec/canvas_sync/jobs/sync_assignment_groups_job_spec.rb
884
+ - spec/canvas_sync/jobs/sync_assignments_job_spec.rb
885
+ - spec/canvas_sync/jobs/sync_content_migrations_job_spec.rb
886
+ - spec/canvas_sync/jobs/sync_context_module_items_job_spec.rb
887
+ - spec/canvas_sync/jobs/sync_context_modules_job_spec.rb
888
+ - spec/canvas_sync/jobs/sync_provisioning_report_job_spec.rb
889
+ - spec/canvas_sync/jobs/sync_roles_job_spec.rb
890
+ - spec/canvas_sync/jobs/sync_simple_table_job_spec.rb
891
+ - spec/canvas_sync/jobs/sync_submissions_job_spec.rb
892
+ - spec/canvas_sync/jobs/sync_terms_job_spec.rb
893
+ - spec/canvas_sync/live_events/live_event_sync_spec.rb
894
+ - spec/canvas_sync/live_events/live_events_controller_spec.rb
895
+ - spec/canvas_sync/live_events/process_event_job_spec.rb
896
+ - spec/canvas_sync/misc_helper_spec.rb
897
+ - spec/canvas_sync/models/accounts_spec.rb
898
+ - spec/canvas_sync/models/admins_spec.rb
899
+ - spec/canvas_sync/models/assignment_group_spec.rb
900
+ - spec/canvas_sync/models/assignment_spec.rb
901
+ - spec/canvas_sync/models/context_module_item_spec.rb
902
+ - spec/canvas_sync/models/context_module_spec.rb
903
+ - spec/canvas_sync/models/course_spec.rb
904
+ - spec/canvas_sync/models/enrollment_spec.rb
905
+ - spec/canvas_sync/models/group_membership_spec.rb
906
+ - spec/canvas_sync/models/group_spec.rb
907
+ - spec/canvas_sync/models/roles_spec.rb
908
+ - spec/canvas_sync/models/section_spec.rb
909
+ - spec/canvas_sync/models/submission_spec.rb
910
+ - spec/canvas_sync/models/term_spec.rb
911
+ - spec/canvas_sync/models/user_spec.rb
912
+ - spec/canvas_sync/processors/assignment_groups_processor_spec.rb
913
+ - spec/canvas_sync/processors/assignments_processor_spec.rb
914
+ - spec/canvas_sync/processors/content_migrations_processor_spec.rb
915
+ - spec/canvas_sync/processors/context_module_items_processor_spec.rb
916
+ - spec/canvas_sync/processors/context_modules_processor_spec.rb
917
+ - spec/canvas_sync/processors/course_completion_report_processor_spec.rb
918
+ - spec/canvas_sync/processors/normal_processor_spec.rb
919
+ - spec/canvas_sync/processors/provisioning_report_processor_spec.rb
920
+ - spec/canvas_sync/processors/rubric_assessments_spec.rb
921
+ - spec/canvas_sync/processors/rubric_associations_spec.rb
922
+ - spec/canvas_sync/processors/rubrics_processor_spec.rb
923
+ - spec/canvas_sync/processors/submissions_processor_spec.rb
924
+ - spec/canvas_sync/services/module_event_spec.rb
925
+ - spec/canvas_sync/services/module_item_event_spec.rb
926
+ - spec/dummy/README.rdoc
927
+ - spec/dummy/Rakefile
928
+ - spec/dummy/app/models/account.rb
929
+ - spec/dummy/app/models/admin.rb
930
+ - spec/dummy/app/models/application_record.rb
931
+ - spec/dummy/app/models/assignment.rb
892
932
  - spec/dummy/app/models/assignment_group.rb
893
- - spec/dummy/app/models/learning_outcome_result.rb
933
+ - spec/dummy/app/models/content_migration.rb
894
934
  - spec/dummy/app/models/context_module.rb
895
- - spec/dummy/app/models/account.rb
896
- - spec/dummy/app/models/pseudonym.rb
897
- - spec/dummy/app/models/group_membership.rb
898
- - spec/dummy/app/models/grading_period.rb
935
+ - spec/dummy/app/models/context_module_item.rb
936
+ - spec/dummy/app/models/course.rb
937
+ - spec/dummy/app/models/course_nickname.rb
899
938
  - spec/dummy/app/models/course_progress.rb
900
- - spec/dummy/app/models/rubric_association.rb
901
- - spec/dummy/app/models/content_migration.rb
902
939
  - spec/dummy/app/models/enrollment.rb
903
- - spec/dummy/app/models/assignment.rb
940
+ - spec/dummy/app/models/grading_period.rb
941
+ - spec/dummy/app/models/grading_period_group.rb
904
942
  - spec/dummy/app/models/group.rb
905
- - spec/dummy/app/models/user_observer.rb
906
- - spec/dummy/app/models/admin.rb
907
- - spec/dummy/app/models/course_nickname.rb
908
- - spec/dummy/app/models/section.rb
943
+ - spec/dummy/app/models/group_membership.rb
909
944
  - spec/dummy/app/models/learning_outcome.rb
945
+ - spec/dummy/app/models/learning_outcome_result.rb
946
+ - spec/dummy/app/models/pseudonym.rb
910
947
  - spec/dummy/app/models/role.rb
911
- - spec/dummy/app/models/grading_period_group.rb
912
- - spec/dummy/app/models/term.rb
913
- - spec/dummy/app/models/submission.rb
914
- - spec/dummy/app/models/context_module_item.rb
915
- - spec/dummy/app/models/rubric_assessment.rb
916
- - spec/dummy/app/models/course.rb
917
- - spec/dummy/app/models/application_record.rb
918
948
  - spec/dummy/app/models/rubric.rb
949
+ - spec/dummy/app/models/rubric_assessment.rb
950
+ - spec/dummy/app/models/rubric_association.rb
951
+ - spec/dummy/app/models/section.rb
952
+ - spec/dummy/app/models/submission.rb
953
+ - spec/dummy/app/models/term.rb
919
954
  - spec/dummy/app/models/user.rb
920
- - spec/dummy/app/services/live_events/course_section_updated_event.rb
921
- - spec/dummy/app/services/live_events/submission_event.rb
922
- - spec/dummy/app/services/live_events/grade_event.rb
923
- - spec/dummy/app/services/live_events/module_item_event.rb
955
+ - spec/dummy/app/models/user_observer.rb
956
+ - spec/dummy/app/services/live_events/assignment_created_event.rb
957
+ - spec/dummy/app/services/live_events/assignment_event.rb
958
+ - spec/dummy/app/services/live_events/assignment_updated_event.rb
924
959
  - spec/dummy/app/services/live_events/base_event.rb
925
- - spec/dummy/app/services/live_events/grade_changed_event.rb
926
- - spec/dummy/app/services/live_events/user_updated_event.rb
927
- - spec/dummy/app/services/live_events/enrollment_event.rb
928
- - spec/dummy/app/services/live_events/module_item_updated_event.rb
929
960
  - spec/dummy/app/services/live_events/course_created_event.rb
930
- - spec/dummy/app/services/live_events/syllabus_updated_event.rb
931
961
  - spec/dummy/app/services/live_events/course_event.rb
932
- - spec/dummy/app/services/live_events/user_event.rb
933
- - spec/dummy/app/services/live_events/user_created_event.rb
934
- - spec/dummy/app/services/live_events/course_updated_event.rb
935
- - spec/dummy/app/services/live_events/module_item_created_event.rb
936
962
  - spec/dummy/app/services/live_events/course_section_created_event.rb
937
- - spec/dummy/app/services/live_events/syllabus_event.rb
938
- - spec/dummy/app/services/live_events/submission_updated_event.rb
939
963
  - spec/dummy/app/services/live_events/course_section_event.rb
940
- - spec/dummy/app/services/live_events/module_updated_event.rb
964
+ - spec/dummy/app/services/live_events/course_section_updated_event.rb
965
+ - spec/dummy/app/services/live_events/course_updated_event.rb
941
966
  - spec/dummy/app/services/live_events/enrollment_created_event.rb
942
- - spec/dummy/app/services/live_events/assignment_created_event.rb
943
- - spec/dummy/app/services/live_events/assignment_event.rb
944
- - spec/dummy/app/services/live_events/module_event.rb
967
+ - spec/dummy/app/services/live_events/enrollment_event.rb
945
968
  - spec/dummy/app/services/live_events/enrollment_updated_event.rb
946
- - spec/dummy/app/services/live_events/assignment_updated_event.rb
947
- - spec/dummy/app/services/live_events/submission_created_event.rb
969
+ - spec/dummy/app/services/live_events/grade_changed_event.rb
970
+ - spec/dummy/app/services/live_events/grade_event.rb
948
971
  - spec/dummy/app/services/live_events/module_created_event.rb
972
+ - spec/dummy/app/services/live_events/module_event.rb
973
+ - spec/dummy/app/services/live_events/module_item_created_event.rb
974
+ - spec/dummy/app/services/live_events/module_item_event.rb
975
+ - spec/dummy/app/services/live_events/module_item_updated_event.rb
976
+ - spec/dummy/app/services/live_events/module_updated_event.rb
977
+ - spec/dummy/app/services/live_events/submission_created_event.rb
978
+ - spec/dummy/app/services/live_events/submission_event.rb
979
+ - spec/dummy/app/services/live_events/submission_updated_event.rb
980
+ - spec/dummy/app/services/live_events/syllabus_event.rb
981
+ - spec/dummy/app/services/live_events/syllabus_updated_event.rb
982
+ - spec/dummy/app/services/live_events/user_created_event.rb
983
+ - spec/dummy/app/services/live_events/user_event.rb
984
+ - spec/dummy/app/services/live_events/user_updated_event.rb
949
985
  - spec/dummy/bin/rails
950
- - spec/dummy/config/secrets.yml
951
- - spec/dummy/config/routes.rb
952
- - spec/dummy/config/environments/development.rb
953
- - spec/dummy/config/environments/test.rb
954
- - spec/dummy/config/environment.rb
955
986
  - spec/dummy/config/application.rb
956
- - spec/dummy/config/database.yml
957
987
  - spec/dummy/config/boot.rb
988
+ - spec/dummy/config/database.yml
989
+ - spec/dummy/config/environment.rb
990
+ - spec/dummy/config/environments/development.rb
991
+ - spec/dummy/config/environments/test.rb
992
+ - spec/dummy/config/initializers/assets.rb
958
993
  - spec/dummy/config/initializers/session_store.rb
959
994
  - spec/dummy/config/initializers/wrap_parameters.rb
960
- - spec/dummy/config/initializers/assets.rb
995
+ - spec/dummy/config/routes.rb
996
+ - spec/dummy/config/secrets.yml
961
997
  - spec/dummy/config.ru
962
- - spec/dummy/Rakefile
963
- - spec/dummy/db/schema.rb
964
- - spec/dummy/db/migrate/20200416214248_create_group_memberships.rb
965
- - spec/dummy/db/migrate/20190702203627_create_submissions.rb
998
+ - spec/dummy/db/migrate/20190702203621_create_courses.rb
999
+ - spec/dummy/db/migrate/20190702203622_create_accounts.rb
1000
+ - spec/dummy/db/migrate/20190702203623_create_terms.rb
966
1001
  - spec/dummy/db/migrate/20190702203624_create_enrollments.rb
1002
+ - spec/dummy/db/migrate/20190702203625_create_sections.rb
1003
+ - spec/dummy/db/migrate/20190702203626_create_assignments.rb
1004
+ - spec/dummy/db/migrate/20190702203627_create_submissions.rb
967
1005
  - spec/dummy/db/migrate/20190702203630_create_assignment_groups.rb
968
- - spec/dummy/db/migrate/20240828161300_create_course_progresses.rb
1006
+ - spec/dummy/db/migrate/20190702203631_create_context_modules.rb
969
1007
  - spec/dummy/db/migrate/20190702203632_create_context_module_items.rb
970
- - spec/dummy/db/migrate/20240408223326_create_course_nicknames.rb
971
- - spec/dummy/db/migrate/20190702203622_create_accounts.rb
1008
+ - spec/dummy/db/migrate/20190927204545_create_roles.rb
1009
+ - spec/dummy/db/migrate/20190927204546_create_admins.rb
1010
+ - spec/dummy/db/migrate/20200415171620_create_groups.rb
1011
+ - spec/dummy/db/migrate/20200416214248_create_group_memberships.rb
1012
+ - spec/dummy/db/migrate/20201016181346_create_pseudonyms.rb
972
1013
  - spec/dummy/db/migrate/20210907233329_create_user_observers.rb
973
- - spec/dummy/db/migrate/20220712210559_create_learning_outcomes.rb
974
1014
  - spec/dummy/db/migrate/20210907233330_create_grading_periods.rb
975
- - spec/dummy/db/migrate/20240509105100_create_rubrics.rb
976
- - spec/dummy/db/migrate/20240523101010_create_learning_outcome_results.rb
977
- - spec/dummy/db/migrate/20240510094100_create_rubric_associations.rb
1015
+ - spec/dummy/db/migrate/20211001184920_create_grading_period_groups.rb
978
1016
  - spec/dummy/db/migrate/20220308072643_create_content_migrations.rb
979
- - spec/dummy/db/migrate/20190702203621_create_courses.rb
980
- - spec/dummy/db/migrate/20190927204546_create_admins.rb
981
- - spec/dummy/db/migrate/20190702203623_create_terms.rb
982
- - spec/dummy/db/migrate/20190927204545_create_roles.rb
1017
+ - spec/dummy/db/migrate/20220712210559_create_learning_outcomes.rb
983
1018
  - spec/dummy/db/migrate/20220926221926_create_users.rb
984
- - spec/dummy/db/migrate/20190702203625_create_sections.rb
985
- - spec/dummy/db/migrate/20201016181346_create_pseudonyms.rb
986
- - spec/dummy/db/migrate/20190702203626_create_assignments.rb
1019
+ - spec/dummy/db/migrate/20240408223326_create_course_nicknames.rb
1020
+ - spec/dummy/db/migrate/20240509105100_create_rubrics.rb
1021
+ - spec/dummy/db/migrate/20240510094100_create_rubric_associations.rb
987
1022
  - spec/dummy/db/migrate/20240510101100_create_rubric_assessments.rb
988
- - spec/dummy/db/migrate/20190702203631_create_context_modules.rb
989
- - spec/dummy/db/migrate/20211001184920_create_grading_period_groups.rb
990
- - spec/dummy/db/migrate/20200415171620_create_groups.rb
991
- - spec/dummy/README.rdoc
992
- - spec/canvas_sync/models/enrollment_spec.rb
993
- - spec/canvas_sync/models/admins_spec.rb
994
- - spec/canvas_sync/models/section_spec.rb
995
- - spec/canvas_sync/models/context_module_spec.rb
996
- - spec/canvas_sync/models/roles_spec.rb
997
- - spec/canvas_sync/models/term_spec.rb
998
- - spec/canvas_sync/models/assignment_spec.rb
999
- - spec/canvas_sync/models/submission_spec.rb
1000
- - spec/canvas_sync/models/context_module_item_spec.rb
1001
- - spec/canvas_sync/models/accounts_spec.rb
1002
- - spec/canvas_sync/models/assignment_group_spec.rb
1003
- - spec/canvas_sync/models/group_spec.rb
1004
- - spec/canvas_sync/models/group_membership_spec.rb
1005
- - spec/canvas_sync/models/user_spec.rb
1006
- - spec/canvas_sync/models/course_spec.rb
1007
- - spec/canvas_sync/misc_helper_spec.rb
1008
- - spec/canvas_sync/processors/context_module_items_processor_spec.rb
1009
- - spec/canvas_sync/processors/context_modules_processor_spec.rb
1010
- - spec/canvas_sync/processors/rubric_assessments_spec.rb
1011
- - spec/canvas_sync/processors/rubric_associations_spec.rb
1012
- - spec/canvas_sync/processors/normal_processor_spec.rb
1013
- - spec/canvas_sync/processors/provisioning_report_processor_spec.rb
1014
- - spec/canvas_sync/processors/course_completion_report_processor_spec.rb
1015
- - spec/canvas_sync/processors/content_migrations_processor_spec.rb
1016
- - spec/canvas_sync/processors/submissions_processor_spec.rb
1017
- - spec/canvas_sync/processors/assignments_processor_spec.rb
1018
- - spec/canvas_sync/processors/rubrics_processor_spec.rb
1019
- - spec/canvas_sync/processors/assignment_groups_processor_spec.rb
1020
- - spec/canvas_sync/jobs/report_checker_spec.rb
1021
- - spec/canvas_sync/jobs/canvas_process_waiter_spec.rb
1022
- - spec/canvas_sync/jobs/sync_simple_table_job_spec.rb
1023
- - spec/canvas_sync/jobs/job_spec.rb
1024
- - spec/canvas_sync/jobs/sync_context_modules_job_spec.rb
1025
- - spec/canvas_sync/jobs/report_starter_spec.rb
1026
- - spec/canvas_sync/jobs/sync_content_migrations_job_spec.rb
1027
- - spec/canvas_sync/jobs/sync_assignments_job_spec.rb
1028
- - spec/canvas_sync/jobs/sync_submissions_job_spec.rb
1029
- - spec/canvas_sync/jobs/sync_provisioning_report_job_spec.rb
1030
- - spec/canvas_sync/jobs/sync_assignment_groups_job_spec.rb
1031
- - spec/canvas_sync/jobs/sync_admins_job_spec.rb
1032
- - spec/canvas_sync/jobs/sync_roles_job_spec.rb
1033
- - spec/canvas_sync/jobs/sync_terms_job_spec.rb
1034
- - spec/canvas_sync/jobs/sync_context_module_items_job_spec.rb
1035
- - spec/canvas_sync/jobs/report_processor_job_spec.rb
1036
- - spec/canvas_sync/canvas_sync_spec.rb
1037
- - spec/canvas_sync/services/module_item_event_spec.rb
1038
- - spec/canvas_sync/services/module_event_spec.rb
1039
- - spec/canvas_sync/live_events/live_event_sync_spec.rb
1040
- - spec/canvas_sync/live_events/live_events_controller_spec.rb
1041
- - spec/canvas_sync/live_events/process_event_job_spec.rb
1042
- - spec/job_uniqueness/spec_helper.rb
1043
- - spec/job_uniqueness/lock_context_spec.rb
1044
- - spec/job_uniqueness/on_conflict_spec.rb
1045
- - spec/job_uniqueness/compat/sidekiq_spec.rb
1046
- - spec/job_uniqueness/compat/active_job_spec.rb
1047
- - spec/job_uniqueness/on_conflict/reschedule_spec.rb
1048
- - spec/job_uniqueness/on_conflict/raise_spec.rb
1049
- - spec/job_uniqueness/on_conflict/log_spec.rb
1050
- - spec/job_uniqueness/unique_job_common_spec.rb
1051
- - spec/job_uniqueness/support/test_worker.rb
1052
- - spec/job_uniqueness/support/lock_strategy.rb
1053
- - spec/job_uniqueness/support/on_conflict.rb
1054
- - spec/job_uniqueness/strategy/until_executed_spec.rb
1055
- - spec/job_uniqueness/strategy/until_and_while_executing_spec.rb
1056
- - spec/job_uniqueness/strategy/until_executing_spec.rb
1057
- - spec/job_uniqueness/strategy/until_expired_spec.rb
1058
- - spec/job_uniqueness/strategy/while_executing_spec.rb
1059
- - spec/job_uniqueness/strategy/base_spec.rb
1023
+ - spec/dummy/db/migrate/20240523101010_create_learning_outcome_results.rb
1024
+ - spec/dummy/db/migrate/20240828161300_create_course_progresses.rb
1025
+ - spec/dummy/db/schema.rb
1026
+ - spec/factories/account_factory.rb
1027
+ - spec/factories/admin_factory.rb
1028
+ - spec/factories/assignment_factory.rb
1029
+ - spec/factories/assignment_group_factory.rb
1030
+ - spec/factories/context_module_factory.rb
1031
+ - spec/factories/context_module_item_factory.rb
1032
+ - spec/factories/course_factory.rb
1033
+ - spec/factories/enrollment_factory.rb
1034
+ - spec/factories/group_factory.rb
1035
+ - spec/factories/group_membership_factory.rb
1036
+ - spec/factories/role_factory.rb
1037
+ - spec/factories/section_factory.rb
1038
+ - spec/factories/submission_factory.rb
1039
+ - spec/factories/term_factory.rb
1040
+ - spec/factories/user_factory.rb
1060
1041
  - spec/job_batching/batch_spec.rb
1061
- - spec/job_batching/pool_spec.rb
1062
- - spec/job_batching/context_hash_spec.rb
1063
- - spec/job_batching/compat/sidekiq_spec.rb
1042
+ - spec/job_batching/callback_spec.rb
1064
1043
  - spec/job_batching/compat/active_job_spec.rb
1044
+ - spec/job_batching/compat/sidekiq_spec.rb
1045
+ - spec/job_batching/context_hash_spec.rb
1046
+ - spec/job_batching/flow_spec.rb
1047
+ - spec/job_batching/integration/fail_then_succeed.rb
1048
+ - spec/job_batching/integration/integration.rb
1065
1049
  - spec/job_batching/integration/nested.rb
1066
- - spec/job_batching/integration/workflow.rb
1067
1050
  - spec/job_batching/integration/simple.rb
1068
- - spec/job_batching/integration/integration.rb
1069
- - spec/job_batching/integration/fail_then_succeed.rb
1051
+ - spec/job_batching/integration/workflow.rb
1070
1052
  - spec/job_batching/integration_helper.rb
1071
- - spec/job_batching/flow_spec.rb
1053
+ - spec/job_batching/pool_spec.rb
1072
1054
  - spec/job_batching/status_spec.rb
1073
1055
  - spec/job_batching/support/base_job.rb
1074
1056
  - spec/job_batching/support/sample_callback.rb
1075
- - spec/job_batching/callback_spec.rb
1057
+ - spec/job_uniqueness/compat/active_job_spec.rb
1058
+ - spec/job_uniqueness/compat/sidekiq_spec.rb
1059
+ - spec/job_uniqueness/lock_context_spec.rb
1060
+ - spec/job_uniqueness/on_conflict/log_spec.rb
1061
+ - spec/job_uniqueness/on_conflict/raise_spec.rb
1062
+ - spec/job_uniqueness/on_conflict/reschedule_spec.rb
1063
+ - spec/job_uniqueness/on_conflict_spec.rb
1064
+ - spec/job_uniqueness/spec_helper.rb
1065
+ - spec/job_uniqueness/strategy/base_spec.rb
1066
+ - spec/job_uniqueness/strategy/until_and_while_executing_spec.rb
1067
+ - spec/job_uniqueness/strategy/until_executed_spec.rb
1068
+ - spec/job_uniqueness/strategy/until_executing_spec.rb
1069
+ - spec/job_uniqueness/strategy/until_expired_spec.rb
1070
+ - spec/job_uniqueness/strategy/while_executing_spec.rb
1071
+ - spec/job_uniqueness/support/lock_strategy.rb
1072
+ - spec/job_uniqueness/support/on_conflict.rb
1073
+ - spec/job_uniqueness/support/test_worker.rb
1074
+ - spec/job_uniqueness/unique_job_common_spec.rb
1075
+ - spec/spec_helper.rb
1076
1076
  - spec/support/fake_canvas.rb
1077
- - spec/support/fixtures/canvas_responses/roles.json
1078
1077
  - spec/support/fixtures/canvas_responses/admins.json
1078
+ - spec/support/fixtures/canvas_responses/module.json
1079
1079
  - spec/support/fixtures/canvas_responses/module_item.json
1080
+ - spec/support/fixtures/canvas_responses/roles.json
1080
1081
  - spec/support/fixtures/canvas_responses/terms.json
1081
- - spec/support/fixtures/canvas_responses/module.json
1082
- - spec/support/fixtures/reports/groups.csv
1083
- - spec/support/fixtures/reports/grading_period_groups.csv
1084
- - spec/support/fixtures/reports/learning_outcomes.csv
1082
+ - spec/support/fixtures/reports/assignment_groups.csv
1083
+ - spec/support/fixtures/reports/assignments.csv
1084
+ - spec/support/fixtures/reports/content_migrations.csv
1085
1085
  - spec/support/fixtures/reports/context_module_items.csv
1086
1086
  - spec/support/fixtures/reports/context_modules.csv
1087
- - spec/support/fixtures/reports/group_memberships.csv
1088
- - spec/support/fixtures/reports/content_migrations.csv
1089
- - spec/support/fixtures/reports/users.csv
1090
- - spec/support/fixtures/reports/submissions.csv
1091
- - spec/support/fixtures/reports/course_progresses_conflict.csv
1092
1087
  - spec/support/fixtures/reports/course_nicknames.csv
1088
+ - spec/support/fixtures/reports/course_progresses.csv
1089
+ - spec/support/fixtures/reports/course_progresses_conflict.csv
1090
+ - spec/support/fixtures/reports/courses.csv
1093
1091
  - spec/support/fixtures/reports/enrollments.csv
1094
- - spec/support/fixtures/reports/sections.csv
1095
- - spec/support/fixtures/reports/assignments.csv
1092
+ - spec/support/fixtures/reports/grading_period_groups.csv
1096
1093
  - spec/support/fixtures/reports/grading_periods.csv
1097
- - spec/support/fixtures/reports/courses.csv
1098
- - spec/support/fixtures/reports/rubric_associations.csv
1099
- - spec/support/fixtures/reports/xlist.csv
1094
+ - spec/support/fixtures/reports/group_memberships.csv
1095
+ - spec/support/fixtures/reports/groups.csv
1096
+ - spec/support/fixtures/reports/learning_outcome_results.csv
1097
+ - spec/support/fixtures/reports/learning_outcomes.csv
1100
1098
  - spec/support/fixtures/reports/provisioning_csv
1101
- - spec/support/fixtures/reports/user_observers.csv
1102
- - spec/support/fixtures/reports/rubrics.csv
1103
- - spec/support/fixtures/reports/assignment_groups.csv
1104
- - spec/support/fixtures/reports/course_progresses.csv
1105
- - spec/support/fixtures/reports/rubric_assessments.csv
1106
- - spec/support/fixtures/reports/provisioning_csv_unzipped/users.csv
1107
1099
  - spec/support/fixtures/reports/provisioning_csv_unzipped/courses.csv
1108
- - spec/support/fixtures/reports/learning_outcome_results.csv
1109
- - spec/factories/course_factory.rb
1110
- - spec/factories/admin_factory.rb
1111
- - spec/factories/group_membership_factory.rb
1112
- - spec/factories/user_factory.rb
1113
- - spec/factories/role_factory.rb
1114
- - spec/factories/assignment_factory.rb
1115
- - spec/factories/term_factory.rb
1116
- - spec/factories/group_factory.rb
1117
- - spec/factories/section_factory.rb
1118
- - spec/factories/enrollment_factory.rb
1119
- - spec/factories/context_module_factory.rb
1120
- - spec/factories/context_module_item_factory.rb
1121
- - spec/factories/submission_factory.rb
1122
- - spec/factories/assignment_group_factory.rb
1123
- - spec/factories/account_factory.rb
1100
+ - spec/support/fixtures/reports/provisioning_csv_unzipped/users.csv
1101
+ - spec/support/fixtures/reports/rubric_assessments.csv
1102
+ - spec/support/fixtures/reports/rubric_associations.csv
1103
+ - spec/support/fixtures/reports/rubrics.csv
1104
+ - spec/support/fixtures/reports/sections.csv
1105
+ - spec/support/fixtures/reports/submissions.csv
1106
+ - spec/support/fixtures/reports/user_observers.csv
1107
+ - spec/support/fixtures/reports/users.csv
1108
+ - spec/support/fixtures/reports/xlist.csv
@@ -1,11 +0,0 @@
1
- module CanvasSync::Concerns
2
- module AutoRelations
3
- extend ActiveSupport::Concern
4
-
5
- # CanvasSync::Record.define_feature self, default: true
6
-
7
- included do
8
-
9
- end
10
- end
11
- end