canvas_sync 0.22.0 → 0.22.2
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/lib/canvas_sync/job_batches/batch.rb +80 -62
- data/lib/canvas_sync/job_batches/compat/active_job.rb +1 -1
- data/lib/canvas_sync/job_batches/compat/sidekiq.rb +1 -1
- data/lib/canvas_sync/job_batches/jobs/managed_batch_job.rb +8 -1
- data/lib/canvas_sync/job_batches/pool.rb +20 -9
- data/lib/canvas_sync/jobs/canvas_process_waiter.rb +1 -1
- data/lib/canvas_sync/version.rb +1 -1
- data/spec/canvas_sync/jobs/sync_admins_job_spec.rb +1 -1
- data/spec/canvas_sync/jobs/sync_provisioning_report_job_spec.rb +1 -1
- data/spec/canvas_sync/jobs/sync_roles_job_spec.rb +1 -1
- data/spec/canvas_sync/jobs/sync_simple_table_job_spec.rb +1 -1
- data/spec/canvas_sync/models/accounts_spec.rb +1 -1
- data/spec/canvas_sync/models/admins_spec.rb +2 -2
- data/spec/canvas_sync/models/assignment_group_spec.rb +1 -1
- data/spec/canvas_sync/models/assignment_spec.rb +3 -3
- data/spec/canvas_sync/models/context_module_item_spec.rb +1 -1
- data/spec/canvas_sync/models/context_module_spec.rb +1 -1
- data/spec/canvas_sync/models/course_spec.rb +1 -1
- data/spec/canvas_sync/models/enrollment_spec.rb +1 -1
- data/spec/canvas_sync/models/group_membership_spec.rb +1 -1
- data/spec/canvas_sync/models/group_spec.rb +1 -1
- data/spec/canvas_sync/models/roles_spec.rb +2 -2
- data/spec/canvas_sync/models/section_spec.rb +1 -1
- data/spec/canvas_sync/models/submission_spec.rb +1 -1
- data/spec/canvas_sync/models/term_spec.rb +6 -6
- data/spec/canvas_sync/models/user_spec.rb +1 -1
- data/spec/canvas_sync/services/module_event_spec.rb +1 -1
- data/spec/canvas_sync/services/module_item_event_spec.rb +1 -1
- data/spec/factories/account_factory.rb +4 -4
- data/spec/factories/admin_factory.rb +4 -4
- data/spec/factories/assignment_factory.rb +1 -1
- data/spec/factories/assignment_group_factory.rb +3 -3
- data/spec/factories/context_module_factory.rb +4 -4
- data/spec/factories/context_module_item_factory.rb +2 -2
- data/spec/factories/course_factory.rb +3 -3
- data/spec/factories/enrollment_factory.rb +1 -1
- data/spec/factories/group_factory.rb +3 -3
- data/spec/factories/group_membership_factory.rb +2 -2
- data/spec/factories/role_factory.rb +4 -4
- data/spec/factories/section_factory.rb +1 -1
- data/spec/factories/submission_factory.rb +1 -1
- data/spec/factories/term_factory.rb +5 -5
- data/spec/factories/user_factory.rb +4 -4
- data/spec/job_batching/batch_spec.rb +2 -2
- data/spec/job_batching/compat/active_job_spec.rb +1 -1
- data/spec/job_batching/compat/sidekiq_spec.rb +2 -2
- data/spec/job_batching/status_spec.rb +1 -1
- data/spec/spec_helper.rb +5 -2
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9c79e88e0f642fadba95afa7f6b6960a511144ad41d6c6333febc010e7fe2e3e
|
4
|
+
data.tar.gz: 26ab8638f656d00f93cbd0393d46b5e0a711ab7dfa94d60bf98bcb5fb42a1a7b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d06042a0cb184a7f1efdfaf3b3e755967d97d13c8ed4a9d436eaedb5f7ebe0de0007ab58e8b6f1ad1fc520d4be1e6c139d81b292c7edb79dd8c6d3b6b491c879
|
7
|
+
data.tar.gz: cf3240e17d1df90858e1216c7e1ad8db3d92835d9ad10a17a3fc0f85a309058462e13a121ef156dee75b08adc05731f68a486de7c22c3b3b78cfab65395dca0f
|
@@ -98,30 +98,14 @@ module CanvasSync::JobBatches
|
|
98
98
|
def jobs
|
99
99
|
raise NoBlockGivenError unless block_given?
|
100
100
|
|
101
|
-
|
102
|
-
parent_bid = Thread.current[CURRENT_BATCH_THREAD_KEY]&.bid
|
103
|
-
|
104
|
-
redis.multi do |r|
|
105
|
-
r.hset(@bidkey, "parent_bid", parent_bid.to_s) if parent_bid
|
106
|
-
r.expire(@bidkey, BID_EXPIRE_TTL)
|
107
|
-
|
108
|
-
if parent_bid
|
109
|
-
r.hincrby("BID-#{parent_bid}", "children", 1)
|
110
|
-
r.expire("BID-#{parent_bid}", BID_EXPIRE_TTL)
|
111
|
-
r.zadd("BID-#{parent_bid}-bids", created_at, bid)
|
112
|
-
else
|
113
|
-
r.zadd("BID-ROOT-bids", created_at, bid)
|
114
|
-
end
|
115
|
-
end
|
101
|
+
persist!
|
116
102
|
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
else
|
122
|
-
assert_batch_is_open
|
123
|
-
end
|
103
|
+
# TODO This keep_open! block is probably desired, but it has some caveats:
|
104
|
+
# - Old logic didn't auto-clean empty batches
|
105
|
+
# - Could be an issue if the Thread crashes at a bad moment (do we even need to plan for this?)
|
106
|
+
# - Technically there could be a race condition without it, but such hasn't been observed
|
124
107
|
|
108
|
+
# keep_open! do
|
125
109
|
begin
|
126
110
|
parent = Thread.current[CURRENT_BATCH_THREAD_KEY]
|
127
111
|
Thread.current[CURRENT_BATCH_THREAD_KEY] = self
|
@@ -129,13 +113,16 @@ module CanvasSync::JobBatches
|
|
129
113
|
ensure
|
130
114
|
Thread.current[CURRENT_BATCH_THREAD_KEY] = parent
|
131
115
|
end
|
116
|
+
# end
|
132
117
|
|
133
118
|
nil
|
134
119
|
end
|
135
120
|
|
136
|
-
|
137
|
-
|
138
|
-
|
121
|
+
# Mark this Batch as a placeholder. It will be persisted to Redis, but no jobs will be added.
|
122
|
+
# From here, you can either use `.jobs` on the batch to add jobs as usual, or call `.let_close!` to allow cleanup to occur.
|
123
|
+
def placeholder!
|
124
|
+
# TODO Provide a stable `let_close!` token?
|
125
|
+
persist!
|
139
126
|
end
|
140
127
|
|
141
128
|
def invalidate_all
|
@@ -157,35 +144,36 @@ module CanvasSync::JobBatches
|
|
157
144
|
batch.parent ? valid && valid?(batch.parent) : valid
|
158
145
|
end
|
159
146
|
|
160
|
-
def keep_open!
|
147
|
+
def keep_open!(token = SecureRandom.urlsafe_base64(10))
|
161
148
|
if block_given?
|
162
149
|
begin
|
163
|
-
keep_open!
|
150
|
+
token = keep_open!(token)
|
164
151
|
yield
|
165
152
|
ensure
|
166
|
-
let_close!
|
153
|
+
let_close!(token)
|
167
154
|
end
|
168
155
|
else
|
169
|
-
|
170
|
-
|
171
|
-
|
156
|
+
persist!
|
157
|
+
|
158
|
+
redis.multi do |r|
|
159
|
+
r.sadd("#{@bidkey}-holds", token)
|
160
|
+
r.expire("#{@bidkey}-holds", BID_EXPIRE_TTL)
|
161
|
+
end
|
172
162
|
|
173
|
-
|
174
|
-
_, failed, pending, children, complete, success = redis.multi do |r|
|
175
|
-
r.hset(@bidkey, 'keep_open', "false")
|
163
|
+
assert_batch_is_open
|
176
164
|
|
177
|
-
|
178
|
-
r.hincrby("BID-#{bid}", "pending", 0)
|
179
|
-
r.hincrby("BID-#{bid}", "children", 0)
|
180
|
-
r.scard("BID-#{bid}-batches-complete")
|
181
|
-
r.scard("BID-#{bid}-batches-success")
|
165
|
+
token
|
182
166
|
end
|
167
|
+
end
|
183
168
|
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
169
|
+
def let_close!(token = :unset)
|
170
|
+
self.class.with_callback_check(bid, only: %i[complete success]) do |r|
|
171
|
+
if token == :unset # Legacy
|
172
|
+
r.del("#{@bidkey}-holds")
|
173
|
+
r.hset(@bidkey, 'keep_open', "false")
|
174
|
+
else
|
175
|
+
r.srem("#{@bidkey}-holds", token)
|
176
|
+
end
|
189
177
|
end
|
190
178
|
end
|
191
179
|
|
@@ -203,6 +191,23 @@ module CanvasSync::JobBatches
|
|
203
191
|
with_batch(nil, &blk)
|
204
192
|
end
|
205
193
|
|
194
|
+
def append_jobs(jids)
|
195
|
+
jids = Array(jids)
|
196
|
+
jids = jids.uniq
|
197
|
+
return unless jids.size > 0
|
198
|
+
|
199
|
+
redis do |r|
|
200
|
+
tme = Time.now.utc.to_f
|
201
|
+
added = r.zadd(@bidkey + "-jids", jids.map{|jid| [tme, jid] }, nx: true)
|
202
|
+
r.multi do |r|
|
203
|
+
r.hincrby(@bidkey, "pending", added)
|
204
|
+
r.hincrby(@bidkey, "job_count", added)
|
205
|
+
r.expire(@bidkey, BID_EXPIRE_TTL)
|
206
|
+
r.expire(@bidkey + "-jids", BID_EXPIRE_TTL)
|
207
|
+
end
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
206
211
|
protected
|
207
212
|
|
208
213
|
def redis_key
|
@@ -214,28 +219,34 @@ module CanvasSync::JobBatches
|
|
214
219
|
redis.zadd("batches", created_at, bid) if INDEX_ALL_BATCHES
|
215
220
|
end
|
216
221
|
|
217
|
-
private
|
218
|
-
|
219
222
|
def assert_batch_is_open
|
220
223
|
unless defined?(@closed)
|
221
|
-
@closed = redis.hget(@bidkey, '
|
224
|
+
@closed = redis.hget(@bidkey, 'complete') == 'true'
|
222
225
|
end
|
223
226
|
raise "Cannot add jobs to Batch #{} bid - it has already entered the callback-stage" if @closed
|
224
227
|
end
|
225
228
|
|
226
|
-
def
|
227
|
-
|
228
|
-
|
229
|
+
def persist!
|
230
|
+
if !@existing && !@initialized
|
231
|
+
parent_bid = Thread.current[CURRENT_BATCH_THREAD_KEY]&.bid
|
229
232
|
|
230
|
-
|
231
|
-
|
232
|
-
added = r.zadd(@bidkey + "-jids", jids.map{|jid| [tme, jid] }, nx: true)
|
233
|
-
r.multi do |r|
|
234
|
-
r.hincrby(@bidkey, "pending", added)
|
235
|
-
r.hincrby(@bidkey, "job_count", added)
|
233
|
+
redis.multi do |r|
|
234
|
+
r.hset(@bidkey, "parent_bid", parent_bid.to_s) if parent_bid
|
236
235
|
r.expire(@bidkey, BID_EXPIRE_TTL)
|
237
|
-
|
236
|
+
|
237
|
+
if parent_bid
|
238
|
+
r.hincrby("BID-#{parent_bid}", "children", 1)
|
239
|
+
r.expire("BID-#{parent_bid}", BID_EXPIRE_TTL)
|
240
|
+
r.zadd("BID-#{parent_bid}-bids", created_at, bid)
|
241
|
+
else
|
242
|
+
r.zadd("BID-ROOT-bids", created_at, bid)
|
243
|
+
end
|
238
244
|
end
|
245
|
+
|
246
|
+
flush_pending_attrs
|
247
|
+
@context&.save!
|
248
|
+
|
249
|
+
@initialized = true
|
239
250
|
end
|
240
251
|
end
|
241
252
|
|
@@ -269,6 +280,7 @@ module CanvasSync::JobBatches
|
|
269
280
|
# Misc
|
270
281
|
r.hget("BID-#{bid}", "parent_bid")
|
271
282
|
r.hget("BID-#{bid}", "keep_open")
|
283
|
+
r.scard("BID-#{bid}-holds")
|
272
284
|
|
273
285
|
# Jobs
|
274
286
|
r.hincrby("BID-#{bid}", "pending", 0)
|
@@ -295,13 +307,18 @@ module CanvasSync::JobBatches
|
|
295
307
|
# "failed" = dead or retrying
|
296
308
|
# "complete" = successful or failed
|
297
309
|
|
298
|
-
parent_bid, keep_open, \
|
310
|
+
parent_bid, keep_open, holds, \
|
299
311
|
pending_jobs, failed_jobs, dead_jobs, \
|
300
312
|
child_batches, complete_batches, success_batches, failed_batches, stagnated_batches \
|
301
313
|
= actual_results
|
302
314
|
|
303
315
|
pending_batches = child_batches - success_batches
|
304
316
|
|
317
|
+
if keep_open == 'true' || (holds && holds > 0)
|
318
|
+
except << :complete
|
319
|
+
except << :success
|
320
|
+
end
|
321
|
+
|
305
322
|
trigger_callback = ->(callback) {
|
306
323
|
next if except.include?(callback.to_sym)
|
307
324
|
next unless only.include?(callback.to_sym)
|
@@ -360,11 +377,10 @@ module CanvasSync::JobBatches
|
|
360
377
|
batch_key = "BID-#{bid}"
|
361
378
|
callback_key = "#{batch_key}-callbacks-#{event}"
|
362
379
|
|
363
|
-
callbacks, queue, parent_bid, callback_params = redis do |r|
|
364
|
-
return unless r.exists?(batch_key)
|
365
|
-
return if r.hget(batch_key, 'keep_open') == 'true'
|
366
|
-
|
380
|
+
exists, callbacks, queue, parent_bid, callback_params = redis do |r|
|
367
381
|
r.multi do |r|
|
382
|
+
r.exists?(batch_key)
|
383
|
+
|
368
384
|
r.smembers(callback_key)
|
369
385
|
r.hget(batch_key, "callback_queue")
|
370
386
|
r.hget(batch_key, "parent_bid")
|
@@ -372,6 +388,8 @@ module CanvasSync::JobBatches
|
|
372
388
|
end
|
373
389
|
end
|
374
390
|
|
391
|
+
return unless exists
|
392
|
+
|
375
393
|
queue ||= "default"
|
376
394
|
parent_bid = !parent_bid || parent_bid.empty? ? nil : parent_bid # Basically parent_bid.blank?
|
377
395
|
|
@@ -45,7 +45,7 @@ module CanvasSync::JobBatches
|
|
45
45
|
|
46
46
|
def call(_worker, msg, _queue, _redis_pool = nil)
|
47
47
|
if (batch = Thread.current[CURRENT_BATCH_THREAD_KEY]) && should_handle_batch?(msg)
|
48
|
-
batch.
|
48
|
+
batch.append_jobs(msg['jid']) if (msg['bid'] = batch.bid)
|
49
49
|
end
|
50
50
|
yield
|
51
51
|
end
|
@@ -54,7 +54,7 @@ module CanvasSync::JobBatches
|
|
54
54
|
root_batch.context["managed_batch_bid"] = man_batch_id if man_batch_id
|
55
55
|
|
56
56
|
if concurrency < sub_jobs.count
|
57
|
-
root_batch.
|
57
|
+
root_batch.placeholder!
|
58
58
|
concurrency.times do
|
59
59
|
perform_next_sequence_job(man_batch_id, skip_preflight: true)
|
60
60
|
end
|
@@ -140,6 +140,13 @@ module CanvasSync::JobBatches
|
|
140
140
|
Batch.new.tap do |batch|
|
141
141
|
batch.description = "Managed Batch Fiber (#{man_batch_id})"
|
142
142
|
batch.on(:success, "#{self.to_s}.job_succeeded_callback", managed_batch_id: man_batch_id)
|
143
|
+
|
144
|
+
if next_job[:chain_link].present?
|
145
|
+
# Annotate Batch with chain-step info
|
146
|
+
batch.context["csb:chain_link"] = next_job[:chain_link]
|
147
|
+
batch.on(:complete, "#{ChainBuilder.to_s}.chain_step_complete", chain_link: next_job[:chain_link])
|
148
|
+
end
|
149
|
+
|
143
150
|
batch.jobs do
|
144
151
|
ChainBuilder.enqueue_job(next_job)
|
145
152
|
end
|
@@ -42,7 +42,7 @@ module CanvasSync::JobBatches
|
|
42
42
|
wrapper.description = "Pool Job Wrapper (PID: #{pid})"
|
43
43
|
checkin_event = (on_failed_job == :wait) ? :success : :complete
|
44
44
|
wrapper.on(checkin_event, "#{self.class.to_s}.job_checked_in", pool_id: pid)
|
45
|
-
wrapper.
|
45
|
+
wrapper.placeholder!
|
46
46
|
|
47
47
|
job_desc = job_desc.symbolize_keys
|
48
48
|
job_desc = job_desc.merge!(
|
@@ -55,21 +55,31 @@ module CanvasSync::JobBatches
|
|
55
55
|
refill_allotment unless skip_refill
|
56
56
|
end
|
57
57
|
|
58
|
-
def keep_open!
|
58
|
+
def keep_open!(token = SecureRandom.urlsafe_base64(10))
|
59
59
|
if block_given?
|
60
60
|
begin
|
61
|
-
keep_open!
|
61
|
+
token = keep_open!(token)
|
62
62
|
yield
|
63
63
|
ensure
|
64
|
-
let_close!
|
64
|
+
let_close!(token)
|
65
65
|
end
|
66
66
|
else
|
67
|
-
redis.
|
67
|
+
redis.multi do |r|
|
68
|
+
r.sadd("#{redis_key}-holds", token)
|
69
|
+
r.expire("#{redis_key}-holds", Batch::BID_EXPIRE_TTL)
|
70
|
+
end
|
71
|
+
token
|
68
72
|
end
|
69
73
|
end
|
70
74
|
|
71
|
-
def let_close!
|
72
|
-
|
75
|
+
def let_close!(token = :unset)
|
76
|
+
if token == :unset # Legacy
|
77
|
+
redis.del("#{redis_key}-holds")
|
78
|
+
redis.hset(redis_key, 'keep_open', 'false')
|
79
|
+
else
|
80
|
+
redis.srem("#{redis_key}-holds", token)
|
81
|
+
end
|
82
|
+
|
73
83
|
cleanup_if_empty
|
74
84
|
end
|
75
85
|
|
@@ -87,15 +97,16 @@ module CanvasSync::JobBatches
|
|
87
97
|
def cleanup_if_empty
|
88
98
|
self.order
|
89
99
|
|
90
|
-
activec, pactivec, pendingc, clean_when_empty, keep_open = redis.multi do |r|
|
100
|
+
activec, pactivec, pendingc, clean_when_empty, keep_open, holds = redis.multi do |r|
|
91
101
|
r.hlen("#{redis_key}-active")
|
92
102
|
r.hget(redis_key, "_active_count")
|
93
103
|
pending_count(r)
|
94
104
|
r.hget(redis_key, 'clean_when_empty')
|
95
105
|
r.hget(redis_key, 'keep_open')
|
106
|
+
r.scard("#{redis_key}-holds")
|
96
107
|
end
|
97
108
|
|
98
|
-
return if keep_open == 'true' || clean_when_empty == 'false'
|
109
|
+
return if keep_open == 'true' || clean_when_empty == 'false' || (holds && holds > 0)
|
99
110
|
|
100
111
|
if activec <= 0 && (pactivec.try(:to_i) || 0) <= 0 && pendingc <= 0
|
101
112
|
cleanup_redis
|
@@ -9,7 +9,7 @@ module CanvasSync::Jobs
|
|
9
9
|
|
10
10
|
if %w[completed complete imported imported_with_messages].include? status
|
11
11
|
InvokeCallbackWorker.perform_later(build_next_job(next_job, kwargs, response)) if next_job
|
12
|
-
elsif %w[failed error failed_with_messages].include? status
|
12
|
+
elsif %w[failed error failed_with_messages imports_failed exports_failed].include? status
|
13
13
|
if kwargs[:on_failure].is_a?(Hash)
|
14
14
|
InvokeCallbackWorker.perform_later(build_next_job(kwargs[:on_failure], kwargs, response))
|
15
15
|
else
|
data/lib/canvas_sync/version.rb
CHANGED
@@ -2,7 +2,7 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
RSpec.describe CanvasSync::Jobs::SyncAdminsJob do
|
4
4
|
describe '#perform' do
|
5
|
-
let!(:account) {
|
5
|
+
let!(:account) { FactoryBot.create(:account, canvas_id: 1) }
|
6
6
|
let(:admin_params) { open_canvas_fixture('admins') }
|
7
7
|
|
8
8
|
it 'retrieves all admins from the Canvas API and then invokes the next job' do
|
@@ -3,7 +3,7 @@ require 'spec_helper'
|
|
3
3
|
RSpec.describe CanvasSync::Jobs::SyncProvisioningReportJob do
|
4
4
|
describe '#perform' do
|
5
5
|
context 'a term scope is specified' do
|
6
|
-
let!(:term) {
|
6
|
+
let!(:term) { FactoryBot.create(:term) }
|
7
7
|
|
8
8
|
it 'enqueues a ReportStarter for a provisioning report for the specified models for each term' do
|
9
9
|
expect_any_instance_of(CanvasSync::Jobs::ReportStarter).to receive(:start_report)
|
@@ -2,7 +2,7 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
RSpec.describe CanvasSync::Jobs::SyncRolesJob do
|
4
4
|
describe '#perform' do
|
5
|
-
let!(:account) {
|
5
|
+
let!(:account) { FactoryBot.create(:account, canvas_id: 1) }
|
6
6
|
let(:role_params) { open_canvas_fixture('roles') }
|
7
7
|
|
8
8
|
it 'retrieves all roles from the Canvas API and then invokes the next job' do
|
@@ -3,7 +3,7 @@ require 'spec_helper'
|
|
3
3
|
RSpec.describe CanvasSync::Jobs::SyncSimpleTableJob do
|
4
4
|
describe '#perform' do
|
5
5
|
context 'Simple report' do
|
6
|
-
let!(:term) {
|
6
|
+
let!(:term) { FactoryBot.create(:term) }
|
7
7
|
|
8
8
|
it 'enqueues a ReportStarter for a provisioning report for the specified model for a term' do
|
9
9
|
expect(CanvasSync::Jobs::ReportStarter).to receive(:perform_later)
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
RSpec.describe Admin, type: :model do
|
4
|
-
let(:subject) {
|
4
|
+
let(:subject) { FactoryBot.create(:admin) }
|
5
5
|
|
6
6
|
describe 'validations' do
|
7
7
|
it { should validate_presence_of(:canvas_id) }
|
@@ -26,7 +26,7 @@ RSpec.describe Admin, type: :model do
|
|
26
26
|
end
|
27
27
|
|
28
28
|
context 'the admin already exists' do
|
29
|
-
let!(:existing_admin) {
|
29
|
+
let!(:existing_admin) { FactoryBot.create(:admin, canvas_id: admin_params['id']) }
|
30
30
|
|
31
31
|
it 'updates it' do
|
32
32
|
expect {
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
RSpec.describe AssignmentGroup, type: :model do
|
4
|
-
let(:subject) {
|
4
|
+
let(:subject) { FactoryBot.create(:assignment_group) }
|
5
5
|
|
6
6
|
describe 'validations' do
|
7
7
|
it { should validate_presence_of(:canvas_id) }
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
3
|
RSpec.describe Assignment, type: :model do
|
4
|
-
let(:subject) {
|
4
|
+
let(:subject) { FactoryBot.create(:assignment) }
|
5
5
|
|
6
6
|
describe "validations" do
|
7
7
|
it { should validate_presence_of(:canvas_id) }
|
@@ -31,8 +31,8 @@ RSpec.describe Assignment, type: :model do
|
|
31
31
|
it { should have_many(:context_modules).through(:context_module_items) }
|
32
32
|
|
33
33
|
describe "context" do
|
34
|
-
let!(:other_course) {
|
35
|
-
let!(:matching_course) {
|
34
|
+
let!(:other_course) { FactoryBot.create(:course) }
|
35
|
+
let!(:matching_course) { FactoryBot.create(:course) }
|
36
36
|
|
37
37
|
before do
|
38
38
|
subject.update(canvas_context_type: "Course", canvas_context_id: matching_course.canvas_id)
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
3
|
RSpec.describe ContextModuleItem, type: :model do
|
4
|
-
let(:subject) {
|
4
|
+
let(:subject) { FactoryBot.create(:context_module_item) }
|
5
5
|
|
6
6
|
describe "associations" do
|
7
7
|
it { should belong_to(:context_module) }
|
@@ -2,7 +2,7 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
RSpec.describe GroupMembership, type: :model do
|
4
4
|
let(:subject) {
|
5
|
-
|
5
|
+
FactoryBot.create(:group_membership, group: FactoryBot.create(:group), user: FactoryBot.create(:user))
|
6
6
|
}
|
7
7
|
|
8
8
|
describe 'validations' do
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
RSpec.describe Role, type: :model do
|
4
|
-
let(:subject) {
|
4
|
+
let(:subject) { FactoryBot.create(:role) }
|
5
5
|
|
6
6
|
describe 'validations' do
|
7
7
|
it { should validate_presence_of(:canvas_id) }
|
@@ -27,7 +27,7 @@ RSpec.describe Role, type: :model do
|
|
27
27
|
end
|
28
28
|
|
29
29
|
context 'the role already exists' do
|
30
|
-
let!(:existing_role) {
|
30
|
+
let!(:existing_role) { FactoryBot.create(:role, canvas_id: role_params['id']) }
|
31
31
|
|
32
32
|
it 'updates it' do
|
33
33
|
expect {
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
RSpec.describe Term, type: :model do
|
4
|
-
let(:subject) {
|
4
|
+
let(:subject) { FactoryBot.create(:term) }
|
5
5
|
|
6
6
|
describe 'validations' do
|
7
7
|
it { should validate_presence_of(:canvas_id) }
|
@@ -18,10 +18,10 @@ RSpec.describe Term, type: :model do
|
|
18
18
|
|
19
19
|
describe 'scopes' do
|
20
20
|
describe '.active' do
|
21
|
-
let!(:active_term) {
|
22
|
-
let!(:inactive_term) {
|
23
|
-
let!(:completed_term) {
|
24
|
-
let!(:unstarted_term) {
|
21
|
+
let!(:active_term) { FactoryBot.create(:term, workflow_state: 'active', start_at: 2.days.ago, end_at: 3.days.from_now) }
|
22
|
+
let!(:inactive_term) { FactoryBot.create(:term, workflow_state: 'inactive') }
|
23
|
+
let!(:completed_term) { FactoryBot.create(:term, start_at: 2.months.ago, end_at: 1.month.ago) }
|
24
|
+
let!(:unstarted_term) { FactoryBot.create(:term, start_at: 6.months.from_now, end_at: 1.year.from_now) }
|
25
25
|
|
26
26
|
it 'returns terms with an active workflow_state that have a start_at 15 days in the future or earlier and an end_at 15 days in the past or later' do
|
27
27
|
expect(Term.active).to match_array([active_term])
|
@@ -50,7 +50,7 @@ RSpec.describe Term, type: :model do
|
|
50
50
|
end
|
51
51
|
|
52
52
|
context 'the term already exists' do
|
53
|
-
let!(:existing_term) {
|
53
|
+
let!(:existing_term) { FactoryBot.create(:term, canvas_id: term_params['id']) }
|
54
54
|
|
55
55
|
it 'updates it' do
|
56
56
|
expect {
|
@@ -16,7 +16,7 @@ RSpec.describe LiveEvents::ModuleEvent do
|
|
16
16
|
|
17
17
|
describe "#perform" do
|
18
18
|
context "the module already exists" do
|
19
|
-
let!(:context_module) {
|
19
|
+
let!(:context_module) { FactoryBot.create(:context_module, canvas_id: payload["body"][:module_id]) }
|
20
20
|
|
21
21
|
xit "updates it" do
|
22
22
|
expect {
|
@@ -16,7 +16,7 @@ RSpec.describe LiveEvents::ModuleItemEvent do
|
|
16
16
|
|
17
17
|
describe "#perform" do
|
18
18
|
context "the module item already exists" do
|
19
|
-
let!(:cmi) {
|
19
|
+
let!(:cmi) { FactoryBot.create(:context_module_item, canvas_id: payload["body"][:module_item_id]) }
|
20
20
|
|
21
21
|
xit "updates it" do
|
22
22
|
expect {
|
@@ -1,10 +1,10 @@
|
|
1
|
-
|
1
|
+
FactoryBot.define do
|
2
2
|
factory :account do
|
3
3
|
canvas_id { SecureRandom.random_number(100_000_000) }
|
4
4
|
sis_id { SecureRandom.hex }
|
5
|
-
canvas_parent_account_id 1
|
5
|
+
canvas_parent_account_id { 1 }
|
6
6
|
sis_parent_account_id { SecureRandom.hex }
|
7
|
-
name "Account name"
|
8
|
-
workflow_state "active"
|
7
|
+
name { "Account name" }
|
8
|
+
workflow_state { "active" }
|
9
9
|
end
|
10
10
|
end
|
@@ -1,9 +1,9 @@
|
|
1
|
-
|
1
|
+
FactoryBot.define do
|
2
2
|
factory :admin do
|
3
3
|
canvas_id { SecureRandom.random_number(100_000_000) }
|
4
|
-
role_name 'Cool Role'
|
4
|
+
role_name { 'Cool Role' }
|
5
5
|
canvas_role_id { SecureRandom.random_number(100_000_000) }
|
6
|
-
canvas_user_id 1
|
7
|
-
workflow_state 'active'
|
6
|
+
canvas_user_id { 1 }
|
7
|
+
workflow_state { 'active' }
|
8
8
|
end
|
9
9
|
end
|
@@ -1,8 +1,8 @@
|
|
1
|
-
|
1
|
+
FactoryBot.define do
|
2
2
|
factory :assignment_group do
|
3
3
|
sequence(:canvas_id) { |n| n }
|
4
|
-
name 'Dummy Assignment Group'
|
5
|
-
workflow_state 'available'
|
4
|
+
name { 'Dummy Assignment Group' }
|
5
|
+
workflow_state { 'available' }
|
6
6
|
canvas_created_at {1.week.ago}
|
7
7
|
canvas_updated_at {1.day.ago}
|
8
8
|
end
|
@@ -1,8 +1,8 @@
|
|
1
|
-
|
1
|
+
FactoryBot.define do
|
2
2
|
factory :context_module do
|
3
3
|
sequence(:canvas_id) { |n| n }
|
4
|
-
name "Context Module"
|
5
|
-
workflow_state "available"
|
6
|
-
context {
|
4
|
+
name { "Context Module" }
|
5
|
+
workflow_state { "available" }
|
6
|
+
context { FactoryBot.create(:course) }
|
7
7
|
end
|
8
8
|
end
|
@@ -1,9 +1,9 @@
|
|
1
|
-
|
1
|
+
FactoryBot.define do
|
2
2
|
factory :course do
|
3
3
|
canvas_id { SecureRandom.random_number(100_000_000) }
|
4
4
|
sis_id { SecureRandom.hex }
|
5
|
-
course_code 'Cool Course'
|
6
|
-
name 'Really Really Cool Course'
|
5
|
+
course_code { 'Cool Course' }
|
6
|
+
name { 'Really Really Cool Course' }
|
7
7
|
start_at { 3.days.ago }
|
8
8
|
end_at { 3.weeks.from_now }
|
9
9
|
end
|
@@ -1,8 +1,8 @@
|
|
1
|
-
|
1
|
+
FactoryBot.define do
|
2
2
|
factory :group do
|
3
3
|
canvas_id { SecureRandom.random_number(100_000_000) }
|
4
4
|
sis_id { SecureRandom.hex }
|
5
|
-
name 'Some User Group'
|
6
|
-
workflow_state 'available'
|
5
|
+
name { 'Some User Group' }
|
6
|
+
workflow_state { 'available' }
|
7
7
|
end
|
8
8
|
end
|
@@ -1,8 +1,8 @@
|
|
1
|
-
|
1
|
+
FactoryBot.define do
|
2
2
|
factory :role do
|
3
|
-
label 'Cool Role'
|
4
|
-
base_role_type 'AccountMembership'
|
3
|
+
label { 'Cool Role' }
|
4
|
+
base_role_type { 'AccountMembership' }
|
5
5
|
canvas_id { SecureRandom.random_number(100_000_000) }
|
6
|
-
workflow_state 'active'
|
6
|
+
workflow_state { 'active' }
|
7
7
|
end
|
8
8
|
end
|
@@ -1,10 +1,10 @@
|
|
1
|
-
|
1
|
+
FactoryBot.define do
|
2
2
|
factory :term do
|
3
|
-
name 'Cool Term'
|
4
|
-
start_at 3.days.ago
|
5
|
-
end_at 3.days.from_now
|
3
|
+
name { 'Cool Term' }
|
4
|
+
start_at { 3.days.ago }
|
5
|
+
end_at { 3.days.from_now }
|
6
6
|
canvas_id { SecureRandom.random_number(100_000_000) }
|
7
|
-
workflow_state 'active'
|
7
|
+
workflow_state { 'active' }
|
8
8
|
sis_id { SecureRandom.hex }
|
9
9
|
end
|
10
10
|
end
|
@@ -1,8 +1,8 @@
|
|
1
|
-
|
1
|
+
FactoryBot.define do
|
2
2
|
factory :user do
|
3
3
|
canvas_id { SecureRandom.random_number(100_000_000) }
|
4
|
-
email "cooldude@coolsite.com"
|
5
|
-
first_name "Cool"
|
6
|
-
last_name "Dude"
|
4
|
+
email { "cooldude@coolsite.com" }
|
5
|
+
first_name { "Cool" }
|
6
|
+
last_name { "Dude" }
|
7
7
|
end
|
8
8
|
end
|
@@ -223,7 +223,7 @@ RSpec.describe CanvasSync::JobBatches::Batch do
|
|
223
223
|
|
224
224
|
context 'complete' do
|
225
225
|
before { batch.on(:complete, Object) }
|
226
|
-
# before { batch.
|
226
|
+
# before { batch.append_jobs(bid) }
|
227
227
|
# before { batch.jobs do BatchTestWorker.perform_async end }
|
228
228
|
# before { CanvasSync::JobBatches::Batch.process_failed_job(bid, 'failed-job-id') }
|
229
229
|
|
@@ -341,7 +341,7 @@ RSpec.describe CanvasSync::JobBatches::Batch do
|
|
341
341
|
end
|
342
342
|
end
|
343
343
|
|
344
|
-
describe '#
|
344
|
+
describe '#append_jobs' do
|
345
345
|
let(:batch) { CanvasSync::JobBatches::Batch.new }
|
346
346
|
|
347
347
|
it 'increments pending' do
|
@@ -57,7 +57,7 @@ RSpec.describe CanvasSync::JobBatches::Compat::ActiveJob do
|
|
57
57
|
context "When Enqueueing" do
|
58
58
|
context 'when without batch' do
|
59
59
|
it 'just yields' do
|
60
|
-
expect(CanvasSync::JobBatches::Batch).not_to receive(:
|
60
|
+
expect(CanvasSync::JobBatches::Batch).not_to receive(:append_jobs)
|
61
61
|
BatchTestJobBase.perform_later
|
62
62
|
expect(BatchTestJobBase).to have_been_enqueued
|
63
63
|
end
|
@@ -48,7 +48,7 @@ RSpec.describe CanvasSync::JobBatches::Compat::Sidekiq do
|
|
48
48
|
context 'when without batch' do
|
49
49
|
it 'just yields' do
|
50
50
|
yielded = false
|
51
|
-
expect(CanvasSync::JobBatches::Batch).not_to receive(:
|
51
|
+
expect(CanvasSync::JobBatches::Batch).not_to receive(:append_jobs)
|
52
52
|
subject.call(nil, {}, nil) { yielded = true }
|
53
53
|
expect(yielded).to be_truthy
|
54
54
|
end
|
@@ -67,7 +67,7 @@ RSpec.describe CanvasSync::JobBatches::Compat::Sidekiq do
|
|
67
67
|
end
|
68
68
|
|
69
69
|
it 'increments job queue' do
|
70
|
-
# expect(CanvasSync::JobBatches::Batch).to receive(:
|
70
|
+
# expect(CanvasSync::JobBatches::Batch).to receive(:append_jobs).with(bid)
|
71
71
|
# subject.call(nil, { 'jid' => jid }, nil) {}
|
72
72
|
end
|
73
73
|
|
@@ -34,7 +34,7 @@ RSpec.describe CanvasSync::JobBatches::Batch::Status do
|
|
34
34
|
end
|
35
35
|
|
36
36
|
context 'when more than 0' do
|
37
|
-
before { batch.
|
37
|
+
before { batch.append_jobs(bid) }
|
38
38
|
before { CanvasSync::JobBatches::Batch.process_failed_job(bid, 'FAILEDID') }
|
39
39
|
|
40
40
|
it 'returns failed jobs' do
|
data/spec/spec_helper.rb
CHANGED
@@ -7,7 +7,7 @@ require File.expand_path("../dummy/config/environment.rb", __FILE__)
|
|
7
7
|
require "bundler/setup"
|
8
8
|
require 'rspec/rails'
|
9
9
|
require 'spec_helper'
|
10
|
-
require '
|
10
|
+
require 'factory_bot_rails'
|
11
11
|
require 'timecop'
|
12
12
|
require 'webmock/rspec'
|
13
13
|
require 'support/fake_canvas'
|
@@ -16,6 +16,9 @@ require 'pry'
|
|
16
16
|
require 'pry-nav'
|
17
17
|
require 'with_model'
|
18
18
|
|
19
|
+
require 'redis'
|
20
|
+
Redis.silence_deprecations = true
|
21
|
+
|
19
22
|
require 'sidekiq/testing'
|
20
23
|
Sidekiq::Testing.fake!
|
21
24
|
Sidekiq::Testing.server_middleware do |chain|
|
@@ -29,7 +32,7 @@ ActiveRecord::Migration.maintain_test_schema!
|
|
29
32
|
RSpec.configure do |config|
|
30
33
|
config.extend WithModel
|
31
34
|
|
32
|
-
config.include
|
35
|
+
config.include FactoryBot::Syntax::Methods
|
33
36
|
config.use_transactional_fixtures = true
|
34
37
|
config.infer_spec_type_from_file_location!
|
35
38
|
config.filter_rails_from_backtrace!
|
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.
|
4
|
+
version: 0.22.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Instructure CustomDev
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-08-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -95,7 +95,7 @@ dependencies:
|
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '0'
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
|
-
name:
|
98
|
+
name: factory_bot_rails
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
100
100
|
requirements:
|
101
101
|
- - ">="
|