canvas_sync 0.13.0 → 0.16.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/canvas_sync.rb +69 -15
- data/lib/canvas_sync/concerns/api_syncable.rb +1 -1
- data/lib/canvas_sync/concerns/legacy_columns.rb +5 -4
- data/lib/canvas_sync/generators/templates/migrations/create_group_memberships.rb +18 -0
- data/lib/canvas_sync/generators/templates/migrations/create_groups.rb +23 -0
- data/lib/canvas_sync/generators/templates/migrations/create_pseudonyms.rb +18 -0
- data/lib/canvas_sync/generators/templates/migrations/create_submissions.rb +1 -0
- data/lib/canvas_sync/generators/templates/models/account.rb +4 -0
- data/lib/canvas_sync/generators/templates/models/course.rb +1 -0
- data/lib/canvas_sync/generators/templates/models/group.rb +19 -0
- data/lib/canvas_sync/generators/templates/models/group_membership.rb +17 -0
- data/lib/canvas_sync/generators/templates/models/pseudonym.rb +8 -0
- data/lib/canvas_sync/generators/templates/models/submission.rb +1 -0
- data/lib/canvas_sync/generators/templates/models/user.rb +2 -0
- data/lib/canvas_sync/jobs/sync_provisioning_report_job.rb +2 -0
- data/lib/canvas_sync/processors/model_mappings.yml +81 -0
- data/lib/canvas_sync/processors/provisioning_report_processor.rb +28 -0
- data/lib/canvas_sync/version.rb +1 -1
- data/spec/canvas_sync/canvas_sync_spec.rb +5 -2
- data/spec/canvas_sync/models/accounts_spec.rb +3 -0
- data/spec/canvas_sync/models/course_spec.rb +4 -0
- data/spec/canvas_sync/models/group_membership_spec.rb +26 -0
- data/spec/canvas_sync/models/group_spec.rb +26 -0
- data/spec/canvas_sync/models/user_spec.rb +2 -0
- data/spec/canvas_sync/processors/provisioning_report_processor_spec.rb +20 -0
- data/spec/dummy/app/models/account.rb +1 -0
- data/spec/dummy/app/models/course.rb +1 -0
- data/spec/dummy/app/models/group.rb +25 -0
- data/spec/dummy/app/models/group_membership.rb +23 -0
- data/spec/dummy/app/models/user.rb +1 -0
- data/spec/dummy/db/migrate/20190702203627_create_submissions.rb +1 -0
- data/spec/dummy/db/migrate/20200415171620_create_groups.rb +29 -0
- data/spec/dummy/db/migrate/20200416214248_create_group_memberships.rb +24 -0
- data/spec/dummy/db/schema.rb +31 -1
- data/spec/factories/group_factory.rb +8 -0
- data/spec/factories/group_membership_factory.rb +6 -0
- data/spec/support/fixtures/reports/group_memberships.csv +3 -0
- data/spec/support/fixtures/reports/groups.csv +3 -0
- data/spec/support/fixtures/reports/submissions.csv +3 -3
- metadata +33 -10
- data/lib/canvas_sync/jobs/sync_users_job.rb +0 -26
- data/spec/canvas_sync/jobs/sync_users_job_spec.rb +0 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3c6655d28b3ac244a94cd59da9f76f6878658bff43d1ca071dd7718b82a505ad
|
4
|
+
data.tar.gz: e8ee3801761dd8a84d80ea162ff11e079b219e1d1992788aecd49451c59efaf4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 47a9f7e858cb510f191d1c62f99f112384dc62d3d9d62365369bad5b275d0168d1d5ace94a32b7f76921ee072ae49d3b940e6d56c2aeb51601e9daf52c86b36e
|
7
|
+
data.tar.gz: 84c5b5c9816a2ff8578bb32892739a8737fb6049526f24ef1416d7a5f404fc385f808ca9a7739b1d971baf06f81fe172351015332fe56a67a2e64417158e60d3
|
data/lib/canvas_sync.rb
CHANGED
@@ -22,7 +22,10 @@ Dir[File.dirname(__FILE__) + "/canvas_sync/concerns/**/*.rb"].each { |file| req
|
|
22
22
|
module CanvasSync
|
23
23
|
SUPPORTED_MODELS = %w[
|
24
24
|
users
|
25
|
+
pseudonyms
|
25
26
|
courses
|
27
|
+
groups
|
28
|
+
group_memberships
|
26
29
|
accounts
|
27
30
|
terms
|
28
31
|
enrollments
|
@@ -143,6 +146,10 @@ module CanvasSync
|
|
143
146
|
terms.each do |t|
|
144
147
|
return scope.send(t) if scope.respond_to?(t)
|
145
148
|
end
|
149
|
+
model = scope.try(:model) || scope
|
150
|
+
if model.try(:column_names)&.include?(:workflow_state)
|
151
|
+
return scope.where.not(workflow_state: %w[deleted])
|
152
|
+
end
|
146
153
|
Rails.logger.warn("Could not filter Syncable Scope for model '#{scope.try(:model)&.name || scope.name}'")
|
147
154
|
scope
|
148
155
|
end
|
@@ -193,7 +200,6 @@ module CanvasSync
|
|
193
200
|
model_job_map = {
|
194
201
|
terms: CanvasSync::Jobs::SyncTermsJob,
|
195
202
|
accounts: CanvasSync::Jobs::SyncAccountsJob,
|
196
|
-
users: CanvasSync::Jobs::SyncUsersJob,
|
197
203
|
roles: CanvasSync::Jobs::SyncRolesJob,
|
198
204
|
admins: CanvasSync::Jobs::SyncAdminsJob,
|
199
205
|
|
@@ -221,35 +227,41 @@ module CanvasSync
|
|
221
227
|
|
222
228
|
# Accounts, users, roles, and admins are synced before provisioning because they cannot be scoped to term
|
223
229
|
try_add_model_job.call('accounts')
|
224
|
-
|
230
|
+
|
231
|
+
# These Models use the provisioning report, but are not term-scoped,
|
232
|
+
# so we sync them before to ensure work is not duplicated
|
233
|
+
if term_scope.present?
|
234
|
+
models -= (first_provisioning_models = models & ['users', 'pseudonyms'])
|
235
|
+
jobs.concat(
|
236
|
+
generate_provisioning_jobs(first_provisioning_models, options)
|
237
|
+
)
|
238
|
+
end
|
239
|
+
|
225
240
|
try_add_model_job.call('roles')
|
226
241
|
try_add_model_job.call('admins')
|
227
|
-
|
228
242
|
pre_provisioning_jobs = jobs
|
229
|
-
jobs = []
|
230
243
|
|
231
244
|
###############################
|
232
245
|
# Post provisioning report jobs
|
233
246
|
###############################
|
234
247
|
|
248
|
+
jobs = []
|
235
249
|
try_add_model_job.call('assignments')
|
236
250
|
try_add_model_job.call('submissions')
|
237
251
|
try_add_model_job.call('assignment_groups')
|
238
252
|
try_add_model_job.call('context_modules')
|
239
253
|
try_add_model_job.call('context_module_items')
|
240
|
-
|
241
254
|
post_provisioning_jobs = jobs
|
242
255
|
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
jobs += post_provisioning_jobs
|
256
|
+
###############################
|
257
|
+
# Main provisioning job and queueing
|
258
|
+
###############################
|
259
|
+
|
260
|
+
jobs = [
|
261
|
+
*pre_provisioning_jobs,
|
262
|
+
*generate_provisioning_jobs(models, options, job_options: { term_scope: term_scope }, only_split: ['users']),
|
263
|
+
*post_provisioning_jobs,
|
264
|
+
]
|
253
265
|
|
254
266
|
global_options = { legacy_support: legacy_support }
|
255
267
|
global_options[:account_id] = account_id if account_id.present?
|
@@ -258,6 +270,48 @@ module CanvasSync
|
|
258
270
|
JobChain.new(jobs: jobs, global_options: global_options)
|
259
271
|
end
|
260
272
|
|
273
|
+
def group_by_job_options(model_list, options_hash, only_split: nil, default_key: :provisioning)
|
274
|
+
dup_models = [ *model_list ]
|
275
|
+
unique_option_models = {}
|
276
|
+
|
277
|
+
filtered_models = only_split ? (only_split & model_list) : model_list
|
278
|
+
filtered_models.each do |m|
|
279
|
+
mopts = options_hash[m.to_sym] || options_hash[default_key]
|
280
|
+
unique_option_models[mopts] ||= []
|
281
|
+
unique_option_models[mopts] << m
|
282
|
+
dup_models.delete(m)
|
283
|
+
end
|
284
|
+
|
285
|
+
if dup_models.present?
|
286
|
+
mopts = options_hash[default_key]
|
287
|
+
unique_option_models[mopts] ||= []
|
288
|
+
unique_option_models[mopts].concat(dup_models)
|
289
|
+
end
|
290
|
+
|
291
|
+
unique_option_models
|
292
|
+
end
|
293
|
+
|
294
|
+
def generate_provisioning_jobs(model_list, options_hash, job_options: {}, only_split: nil, default_key: :provisioning)
|
295
|
+
# Group the model options as best we can.
|
296
|
+
# This is mainly for backwards compatibility, since 'users' was previously it's own job
|
297
|
+
unique_option_models = group_by_job_options(
|
298
|
+
model_list,
|
299
|
+
options_hash,
|
300
|
+
only_split: only_split,
|
301
|
+
default_key: default_key,
|
302
|
+
)
|
303
|
+
|
304
|
+
unique_option_models.map do |mopts, models|
|
305
|
+
opts = { models: models }
|
306
|
+
opts.merge!(job_options)
|
307
|
+
opts.merge!(mopts) if mopts.present?
|
308
|
+
{
|
309
|
+
job: CanvasSync::Jobs::SyncProvisioningReportJob.to_s,
|
310
|
+
options: opts,
|
311
|
+
}
|
312
|
+
end
|
313
|
+
end
|
314
|
+
|
261
315
|
# Calls the canvas_sync_client in your app. If you have specified an account
|
262
316
|
# ID when starting the job it will pass the account ID to your canvas_sync_client method.
|
263
317
|
#
|
@@ -146,7 +146,7 @@ module CanvasSync::Concerns
|
|
146
146
|
# Apply a response Hash from the API to this model's attributes and save if changed?
|
147
147
|
# @param [Hash] api_params API-format Hash
|
148
148
|
# @return [self] self
|
149
|
-
def update_from_api_params(
|
149
|
+
def update_from_api_params(*args)
|
150
150
|
assign_from_api_params(*args)
|
151
151
|
save if changed?
|
152
152
|
end
|
@@ -15,13 +15,14 @@ module CanvasSync::Concerns
|
|
15
15
|
private
|
16
16
|
|
17
17
|
def legacy_column_apply(cls)
|
18
|
-
|
19
|
-
|
18
|
+
return if cls.abstract_class
|
19
|
+
cid_column = "canvas_#{cls.name.downcase}_id"
|
20
|
+
column_names = cls.columns.map(&:name)
|
20
21
|
return if column_names.include?('canvas_id') && column_names.include?(cid_column)
|
21
22
|
if column_names.include?('canvas_id')
|
22
|
-
|
23
|
+
cls.alias_attribute(cid_column.to_sym, :canvas_id)
|
23
24
|
elsif column_names.include?(cid_column)
|
24
|
-
|
25
|
+
cls.alias_attribute(:canvas_id, cid_column.to_sym)
|
25
26
|
end
|
26
27
|
rescue ActiveRecord::StatementInvalid
|
27
28
|
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# <%= autogenerated_migration_warning %>
|
2
|
+
|
3
|
+
class CreateGroupMemberships < ActiveRecord::Migration[5.1]
|
4
|
+
def change
|
5
|
+
create_table :group_memberships do |t|
|
6
|
+
t.bigint :canvas_id, null: false
|
7
|
+
t.bigint :canvas_user_id, null: false
|
8
|
+
t.bigint :canvas_group_id, null: false
|
9
|
+
t.string :group_sis_id
|
10
|
+
t.string :user_sis_id
|
11
|
+
t.string :workflow_state
|
12
|
+
|
13
|
+
t.timestamps
|
14
|
+
end
|
15
|
+
|
16
|
+
add_index :group_memberships, :canvas_id, unique: true
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# <%= autogenerated_migration_warning %>
|
2
|
+
|
3
|
+
class CreateGroups < ActiveRecord::Migration[5.1]
|
4
|
+
def change
|
5
|
+
create_table :groups do |t|
|
6
|
+
t.bigint :canvas_id, null: false
|
7
|
+
t.string :sis_id
|
8
|
+
t.bigint :canvas_group_category_id
|
9
|
+
t.string :group_category_sis_id
|
10
|
+
t.bigint :canvas_account_id
|
11
|
+
t.bigint :canvas_course_id
|
12
|
+
t.string :name
|
13
|
+
t.string :workflow_state
|
14
|
+
t.bigint :context_id
|
15
|
+
t.string :context_type
|
16
|
+
t.integer :max_membership
|
17
|
+
|
18
|
+
t.timestamps
|
19
|
+
end
|
20
|
+
|
21
|
+
add_index :groups, :canvas_id, unique: true
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# <%= autogenerated_migration_warning %>
|
2
|
+
|
3
|
+
class CreatePseudonyms < ActiveRecord::Migration[5.1]
|
4
|
+
def change
|
5
|
+
create_table :pseudonyms do |t|
|
6
|
+
t.bigint :canvas_id, null: false
|
7
|
+
t.bigint :canvas_user_id
|
8
|
+
t.string :sis_id
|
9
|
+
t.string :unique_id
|
10
|
+
t.string :workflow_state
|
11
|
+
|
12
|
+
t.timestamps
|
13
|
+
end
|
14
|
+
|
15
|
+
add_index :pseudonyms, :canvas_id, unique: true
|
16
|
+
add_index :pseudonyms, :canvas_user_id
|
17
|
+
end
|
18
|
+
end
|
@@ -12,6 +12,10 @@ class Account < ApplicationRecord
|
|
12
12
|
primary_key: :canvas_id, foreign_key: :canvas_parent_account_id
|
13
13
|
has_many :sub_accounts, class_name: 'Account',
|
14
14
|
primary_key: :canvas_id, foreign_key: :canvas_parent_account_id
|
15
|
+
has_many :groups, primary_key: :canvas_id, foreign_key: :canvas_account_id
|
16
|
+
|
17
|
+
scope :active, -> { where.not(workflow_state: 'deleted') }
|
18
|
+
# scope :should_canvas_sync, -> { active } # Optional - uses .active if not given
|
15
19
|
|
16
20
|
api_syncable({
|
17
21
|
name: :name,
|
@@ -11,6 +11,7 @@ class Course < ApplicationRecord
|
|
11
11
|
has_many :assignments, as: :context, primary_key: :canvas_id, foreign_key: :canvas_context_id, foreign_type: :canvas_context_type
|
12
12
|
has_many :submissions, primary_key: :canvas_id, foreign_key: :canvas_course_id
|
13
13
|
has_many :assignment_groups, primary_key: :canvas_id, foreign_key: :canvas_course_id
|
14
|
+
has_many :groups, primary_key: :canvas_id, foreign_key: :canvas_course_id
|
14
15
|
|
15
16
|
api_syncable({
|
16
17
|
sis_id: :sis_course_id,
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# <%= autogenerated_model_warning %>
|
2
|
+
|
3
|
+
class Group < ApplicationRecord
|
4
|
+
include CanvasSync::Record
|
5
|
+
include CanvasSync::Concerns::ApiSyncable
|
6
|
+
|
7
|
+
validates :canvas_id, uniqueness: true, presence: true
|
8
|
+
belongs_to :course, primary_key: :canvas_id, foreign_key: :canvas_course_id, optional: true
|
9
|
+
belongs_to :account, primary_key: :canvas_id, foreign_key: :canvas_account_id, optional: true
|
10
|
+
has_many :group_memberships, primary_key: :canvas_id, foreign_key: :canvas_group_id
|
11
|
+
|
12
|
+
api_syncable({
|
13
|
+
canvas_id: :id,
|
14
|
+
name: :name,
|
15
|
+
canvas_course_id: :course_id,
|
16
|
+
sis_id: :sis_group_id,
|
17
|
+
workflow_state: ->(r){ 'available' },
|
18
|
+
}, -> (api) { api.group(canvas_id) })
|
19
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# <%= autogenerated_model_warning %>
|
2
|
+
|
3
|
+
class GroupMembership < ApplicationRecord
|
4
|
+
include CanvasSync::Record
|
5
|
+
include CanvasSync::Concerns::ApiSyncable
|
6
|
+
|
7
|
+
validates :canvas_id, uniqueness: true, presence: true
|
8
|
+
belongs_to :group, primary_key: :canvas_id, foreign_key: :canvas_group_id
|
9
|
+
belongs_to :user, primary_key: :canvas_id, foreign_key: :canvas_user_id
|
10
|
+
|
11
|
+
api_syncable({
|
12
|
+
canvas_id: :id,
|
13
|
+
canvas_group_id: :group_id,
|
14
|
+
canvas_user_id: :user_id,
|
15
|
+
workflow_state: :workflow_state,
|
16
|
+
}, -> (api) { api.group_membership(canvas_group_id, canvas_id) })
|
17
|
+
end
|
@@ -5,10 +5,12 @@ class User < ApplicationRecord
|
|
5
5
|
include CanvasSync::Concerns::ApiSyncable
|
6
6
|
|
7
7
|
validates :canvas_id, uniqueness: true, presence: true
|
8
|
+
has_many :pseudonyms, primary_key: :canvas_id, foreign_key: :canvas_user_id
|
8
9
|
has_many :enrollments, primary_key: :canvas_id, foreign_key: :canvas_user_id
|
9
10
|
has_many :admins, primary_key: :canvas_id, foreign_key: :canvas_user_id
|
10
11
|
has_many :admin_roles, through: :admins, source: :role
|
11
12
|
has_many :submissions, primary_key: :canvas_id, foreign_key: :canvas_user_id
|
13
|
+
has_many :group_memberships, primary_key: :canvas_id, foreign_key: :canvas_user_id
|
12
14
|
|
13
15
|
api_syncable({
|
14
16
|
sis_id: :sis_user_id,
|
@@ -29,6 +29,25 @@ users:
|
|
29
29
|
database_column_name: login_id
|
30
30
|
type: string
|
31
31
|
|
32
|
+
pseudonyms:
|
33
|
+
conflict_target: pseudonym_id
|
34
|
+
report_columns:
|
35
|
+
pseudonym_id:
|
36
|
+
database_column_name: canvas_id
|
37
|
+
type: integer
|
38
|
+
canvas_user_id:
|
39
|
+
database_column_name: canvas_user_id
|
40
|
+
type: integer
|
41
|
+
sis_user_id:
|
42
|
+
database_column_name: sis_id
|
43
|
+
type: string
|
44
|
+
unique_id:
|
45
|
+
database_column_name: unique_id
|
46
|
+
type: string
|
47
|
+
status:
|
48
|
+
database_column_name: workflow_state
|
49
|
+
type: string
|
50
|
+
|
32
51
|
accounts:
|
33
52
|
conflict_target: canvas_account_id
|
34
53
|
report_columns:
|
@@ -230,6 +249,9 @@ submissions:
|
|
230
249
|
submission_date:
|
231
250
|
database_column_name: submitted_at
|
232
251
|
type: datetime
|
252
|
+
due_at:
|
253
|
+
database_column_name: due_at
|
254
|
+
type: datetime
|
233
255
|
graded_date:
|
234
256
|
database_column_name: graded_at
|
235
257
|
type: datetime
|
@@ -326,3 +348,62 @@ context_module_items:
|
|
326
348
|
assignment_id:
|
327
349
|
database_column_name: canvas_assignment_id
|
328
350
|
type: integer
|
351
|
+
|
352
|
+
groups:
|
353
|
+
conflict_target: canvas_group_id
|
354
|
+
report_columns:
|
355
|
+
canvas_group_id:
|
356
|
+
database_column_name: canvas_id
|
357
|
+
type: integer
|
358
|
+
group_id:
|
359
|
+
database_column_name: sis_id
|
360
|
+
type: string
|
361
|
+
canvas_group_category_id:
|
362
|
+
database_column_name: canvas_group_category_id
|
363
|
+
type: integer
|
364
|
+
group_category_id:
|
365
|
+
database_column_name: group_category_sis_id
|
366
|
+
type: integer
|
367
|
+
canvas_account_id:
|
368
|
+
database_column_name: canvas_account_id
|
369
|
+
type: integer
|
370
|
+
canvas_course_id:
|
371
|
+
database_column_name: canvas_course_id
|
372
|
+
type: integer
|
373
|
+
name:
|
374
|
+
database_column_name: name
|
375
|
+
type: string
|
376
|
+
status:
|
377
|
+
database_column_name: workflow_state
|
378
|
+
type: string
|
379
|
+
context_id:
|
380
|
+
database_column_name: context_id
|
381
|
+
type: integer
|
382
|
+
context_type:
|
383
|
+
database_column_name: context_type
|
384
|
+
type: string
|
385
|
+
max_membership:
|
386
|
+
database_column_name: max_membership
|
387
|
+
type: integer
|
388
|
+
|
389
|
+
group_memberships:
|
390
|
+
conflict_target: canvas_group_membership_id
|
391
|
+
report_columns:
|
392
|
+
canvas_group_membership_id:
|
393
|
+
database_column_name: canvas_id
|
394
|
+
type: integer
|
395
|
+
canvas_group_id:
|
396
|
+
database_column_name: canvas_group_id
|
397
|
+
type: integer
|
398
|
+
group_id:
|
399
|
+
database_column_name: group_sis_id
|
400
|
+
type: string
|
401
|
+
canvas_user_id:
|
402
|
+
database_column_name: canvas_user_id
|
403
|
+
type: integer
|
404
|
+
user_id:
|
405
|
+
database_column_name: user_sis_id
|
406
|
+
type: string
|
407
|
+
status:
|
408
|
+
database_column_name: workflow_state
|
409
|
+
type: string
|
@@ -78,6 +78,15 @@ module CanvasSync
|
|
78
78
|
)
|
79
79
|
end
|
80
80
|
|
81
|
+
def bulk_process_pseudonyms(report_file_path)
|
82
|
+
CanvasSync::Importers::BulkImporter.import(
|
83
|
+
report_file_path,
|
84
|
+
mapping[:pseudonyms][:report_columns],
|
85
|
+
Pseudonym,
|
86
|
+
mapping[:pseudonyms][:conflict_target].to_sym,
|
87
|
+
)
|
88
|
+
end
|
89
|
+
|
81
90
|
def bulk_process_accounts(report_file_path)
|
82
91
|
CanvasSync::Importers::BulkImporter.import(
|
83
92
|
report_file_path,
|
@@ -122,6 +131,25 @@ module CanvasSync
|
|
122
131
|
mapping[:xlist][:conflict_target].to_sym,
|
123
132
|
)
|
124
133
|
end
|
134
|
+
|
135
|
+
def bulk_process_groups(report_file_path)
|
136
|
+
CanvasSync::Importers::BulkImporter.import(
|
137
|
+
report_file_path,
|
138
|
+
mapping[:groups][:report_columns],
|
139
|
+
Group,
|
140
|
+
mapping[:groups][:conflict_target].to_sym,
|
141
|
+
)
|
142
|
+
end
|
143
|
+
|
144
|
+
# Note that group membership is singular because we override the model name param in sync_provisioning_report_job
|
145
|
+
def bulk_process_group_membership(report_file_path)
|
146
|
+
CanvasSync::Importers::BulkImporter.import(
|
147
|
+
report_file_path,
|
148
|
+
mapping[:group_memberships][:report_columns],
|
149
|
+
GroupMembership,
|
150
|
+
mapping[:group_memberships][:conflict_target].to_sym,
|
151
|
+
)
|
152
|
+
end
|
125
153
|
end
|
126
154
|
end
|
127
155
|
end
|
data/lib/canvas_sync/version.rb
CHANGED
@@ -34,7 +34,7 @@ RSpec.describe CanvasSync do
|
|
34
34
|
expect(chain.chain_data).to eq({
|
35
35
|
jobs: [
|
36
36
|
{ job: CanvasSync::Jobs::SyncTermsJob.to_s, options: { a: 1 } },
|
37
|
-
{ job: CanvasSync::Jobs::
|
37
|
+
{ job: CanvasSync::Jobs::SyncProvisioningReportJob.to_s, options: { models: ['users'], b: 2 } },
|
38
38
|
{ job: CanvasSync::Jobs::SyncProvisioningReportJob.to_s, options: { term_scope: 'active', models: ['courses'], c: 3 } }
|
39
39
|
],
|
40
40
|
global_options: { legacy_support: false, d: 4 }
|
@@ -47,7 +47,7 @@ RSpec.describe CanvasSync do
|
|
47
47
|
expect(chain.chain_data).to eq({
|
48
48
|
jobs: [
|
49
49
|
{ job: CanvasSync::Jobs::SyncTermsJob.to_s, options: {} },
|
50
|
-
{ job: CanvasSync::Jobs::
|
50
|
+
{ job: CanvasSync::Jobs::SyncProvisioningReportJob.to_s, options: { models: ['users'] } },
|
51
51
|
{ job: CanvasSync::Jobs::SyncProvisioningReportJob.to_s, options: { term_scope: 'active', models: ['courses'] } }
|
52
52
|
],
|
53
53
|
global_options: { legacy_support: false }
|
@@ -247,4 +247,7 @@ RSpec.describe CanvasSync do
|
|
247
247
|
end
|
248
248
|
end
|
249
249
|
|
250
|
+
describe ".sync_scope" do
|
251
|
+
|
252
|
+
end
|
250
253
|
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe GroupMembership, type: :model do
|
4
|
+
let(:subject) {
|
5
|
+
FactoryGirl.create(:group_membership, group: FactoryGirl.create(:group), user: FactoryGirl.create(:user))
|
6
|
+
}
|
7
|
+
|
8
|
+
describe 'validations' do
|
9
|
+
it { should validate_presence_of(:canvas_id) }
|
10
|
+
it { should validate_uniqueness_of(:canvas_id) }
|
11
|
+
end
|
12
|
+
|
13
|
+
describe 'associations' do
|
14
|
+
it do
|
15
|
+
should belong_to(:group)
|
16
|
+
.with_primary_key(:canvas_id)
|
17
|
+
.with_foreign_key(:canvas_group_id)
|
18
|
+
end
|
19
|
+
|
20
|
+
it do
|
21
|
+
should belong_to(:user)
|
22
|
+
.with_primary_key(:canvas_id)
|
23
|
+
.with_foreign_key(:canvas_user_id)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe Group, type: :model do
|
4
|
+
let(:subject) { FactoryGirl.create(:group) }
|
5
|
+
|
6
|
+
describe 'validations' do
|
7
|
+
it { should validate_presence_of(:canvas_id) }
|
8
|
+
it { should validate_uniqueness_of(:canvas_id) }
|
9
|
+
end
|
10
|
+
|
11
|
+
describe 'associations' do
|
12
|
+
it { should have_many(:group_memberships) }
|
13
|
+
|
14
|
+
it do
|
15
|
+
should belong_to(:course)
|
16
|
+
.with_primary_key(:canvas_id)
|
17
|
+
.with_foreign_key(:canvas_course_id)
|
18
|
+
end
|
19
|
+
|
20
|
+
it do
|
21
|
+
should belong_to(:account)
|
22
|
+
.with_primary_key(:canvas_id)
|
23
|
+
.with_foreign_key(:canvas_account_id)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -42,6 +42,26 @@ RSpec.describe CanvasSync::Processors::ProvisioningReportProcessor do
|
|
42
42
|
expect(cross_listed_section.canvas_nonxlist_course_id).to eq 2
|
43
43
|
end
|
44
44
|
|
45
|
+
it 'processes groups' do
|
46
|
+
expect {
|
47
|
+
subject.process('spec/support/fixtures/reports/groups.csv', { models: ['groups'] }, 1)
|
48
|
+
}.to change { Group.count }.by(2)
|
49
|
+
group = Group.find_by_name('Group1')
|
50
|
+
expect(group.workflow_state).to eq 'available'
|
51
|
+
expect(group.canvas_account_id).to eq 1
|
52
|
+
expect(group.canvas_id).to eq 50
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'processes group memberships' do
|
56
|
+
expect {
|
57
|
+
subject.process('spec/support/fixtures/reports/group_memberships.csv', { models: ['group_membership'] }, 1)
|
58
|
+
}.to change { GroupMembership.count }.by(2)
|
59
|
+
group = GroupMembership.find_by_canvas_id(50)
|
60
|
+
expect(group.workflow_state).to eq 'accepted'
|
61
|
+
expect(group.canvas_group_id).to eq 1
|
62
|
+
expect(group.canvas_user_id).to eq 10
|
63
|
+
end
|
64
|
+
|
45
65
|
context 'options[:models] is multiple models' do
|
46
66
|
it 'extracts the ZIP and processes each model' do
|
47
67
|
user_count = User.count
|
@@ -18,6 +18,7 @@ class Account < ApplicationRecord
|
|
18
18
|
primary_key: :canvas_id, foreign_key: :canvas_parent_account_id
|
19
19
|
has_many :sub_accounts, class_name: 'Account',
|
20
20
|
primary_key: :canvas_id, foreign_key: :canvas_parent_account_id
|
21
|
+
has_many :groups, primary_key: :canvas_id, foreign_key: :canvas_account_id
|
21
22
|
|
22
23
|
api_syncable({
|
23
24
|
name: :name,
|
@@ -17,6 +17,7 @@ class Course < ApplicationRecord
|
|
17
17
|
has_many :assignments, as: :context, primary_key: :canvas_id, foreign_key: :canvas_context_id, foreign_type: :canvas_context_type
|
18
18
|
has_many :submissions, primary_key: :canvas_id, foreign_key: :canvas_course_id
|
19
19
|
has_many :assignment_groups, primary_key: :canvas_id, foreign_key: :canvas_course_id
|
20
|
+
has_many :groups, primary_key: :canvas_id, foreign_key: :canvas_course_id
|
20
21
|
|
21
22
|
api_syncable({
|
22
23
|
sis_id: :sis_course_id,
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# #
|
2
|
+
# AUTO GENERATED MODEL
|
3
|
+
# This model was auto generated by the CanvasSync Gem.
|
4
|
+
# You can customize it as needed, but make sure you test
|
5
|
+
# any changes you make to the auto generated methods.
|
6
|
+
#
|
7
|
+
|
8
|
+
|
9
|
+
class Group < ApplicationRecord
|
10
|
+
include CanvasSync::Record
|
11
|
+
include CanvasSync::Concerns::ApiSyncable
|
12
|
+
|
13
|
+
validates :canvas_id, uniqueness: true, presence: true
|
14
|
+
belongs_to :course, primary_key: :canvas_id, foreign_key: :canvas_course_id, optional: true
|
15
|
+
belongs_to :account, primary_key: :canvas_id, foreign_key: :canvas_account_id, optional: true
|
16
|
+
has_many :group_memberships, primary_key: :canvas_id, foreign_key: :canvas_group_id
|
17
|
+
|
18
|
+
api_syncable({
|
19
|
+
canvas_id: :id,
|
20
|
+
name: :name,
|
21
|
+
canvas_course_id: :course_id,
|
22
|
+
sis_id: :sis_group_id,
|
23
|
+
workflow_state: ->(r){ 'available' },
|
24
|
+
}, -> (api) { api.group(canvas_id) })
|
25
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# #
|
2
|
+
# AUTO GENERATED MODEL
|
3
|
+
# This model was auto generated by the CanvasSync Gem.
|
4
|
+
# You can customize it as needed, but make sure you test
|
5
|
+
# any changes you make to the auto generated methods.
|
6
|
+
#
|
7
|
+
|
8
|
+
|
9
|
+
class GroupMembership < ApplicationRecord
|
10
|
+
include CanvasSync::Record
|
11
|
+
include CanvasSync::Concerns::ApiSyncable
|
12
|
+
|
13
|
+
validates :canvas_id, uniqueness: true, presence: true
|
14
|
+
belongs_to :group, primary_key: :canvas_id, foreign_key: :canvas_group_id
|
15
|
+
belongs_to :user, primary_key: :canvas_id, foreign_key: :canvas_user_id
|
16
|
+
|
17
|
+
api_syncable({
|
18
|
+
canvas_id: :id,
|
19
|
+
canvas_group_id: :group_id,
|
20
|
+
canvas_user_id: :user_id,
|
21
|
+
workflow_state: :workflow_state,
|
22
|
+
}, -> (api) { api.group_membership(canvas_group_id, canvas_id) })
|
23
|
+
end
|
@@ -15,6 +15,7 @@ class User < ApplicationRecord
|
|
15
15
|
has_many :admins, primary_key: :canvas_id, foreign_key: :canvas_user_id
|
16
16
|
has_many :admin_roles, through: :admins, source: :role
|
17
17
|
has_many :submissions, primary_key: :canvas_id, foreign_key: :canvas_user_id
|
18
|
+
has_many :group_memberships, primary_key: :canvas_id, foreign_key: :canvas_user_id
|
18
19
|
|
19
20
|
api_syncable({
|
20
21
|
sis_id: :sis_user_id,
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# #
|
2
|
+
# AUTO GENERATED MIGRATION
|
3
|
+
# This migration was auto generated by the CanvasSync Gem.
|
4
|
+
# You can add new columns to this table, but removing or
|
5
|
+
# re-naming ones created here may break Canvas Syncing.
|
6
|
+
#
|
7
|
+
|
8
|
+
|
9
|
+
class CreateGroups < ActiveRecord::Migration[5.1]
|
10
|
+
def change
|
11
|
+
create_table :groups do |t|
|
12
|
+
t.bigint :canvas_id, null: false
|
13
|
+
t.string :sis_id
|
14
|
+
t.bigint :canvas_group_category_id
|
15
|
+
t.string :group_category_sis_id
|
16
|
+
t.bigint :canvas_account_id
|
17
|
+
t.bigint :canvas_course_id
|
18
|
+
t.string :name
|
19
|
+
t.string :workflow_state
|
20
|
+
t.bigint :context_id
|
21
|
+
t.string :context_type
|
22
|
+
t.integer :max_membership
|
23
|
+
|
24
|
+
t.timestamps
|
25
|
+
end
|
26
|
+
|
27
|
+
add_index :groups, :canvas_id, unique: true
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# #
|
2
|
+
# AUTO GENERATED MIGRATION
|
3
|
+
# This migration was auto generated by the CanvasSync Gem.
|
4
|
+
# You can add new columns to this table, but removing or
|
5
|
+
# re-naming ones created here may break Canvas Syncing.
|
6
|
+
#
|
7
|
+
|
8
|
+
|
9
|
+
class CreateGroupMemberships < ActiveRecord::Migration[5.1]
|
10
|
+
def change
|
11
|
+
create_table :group_memberships do |t|
|
12
|
+
t.bigint :canvas_id, null: false
|
13
|
+
t.bigint :canvas_user_id, null: false
|
14
|
+
t.bigint :canvas_group_id, null: false
|
15
|
+
t.string :group_sis_id
|
16
|
+
t.string :user_sis_id
|
17
|
+
t.string :workflow_state
|
18
|
+
|
19
|
+
t.timestamps
|
20
|
+
end
|
21
|
+
|
22
|
+
add_index :group_memberships, :canvas_id, unique: true
|
23
|
+
end
|
24
|
+
end
|
data/spec/dummy/db/schema.rb
CHANGED
@@ -10,7 +10,7 @@
|
|
10
10
|
#
|
11
11
|
# It's strongly recommended that you check this file into your version control system.
|
12
12
|
|
13
|
-
ActiveRecord::Schema.define(version:
|
13
|
+
ActiveRecord::Schema.define(version: 2020_04_16_214248) do
|
14
14
|
|
15
15
|
# These are extensions that must be enabled in order to support this database
|
16
16
|
enable_extension "plpgsql"
|
@@ -162,6 +162,35 @@ ActiveRecord::Schema.define(version: 20190927204546) do
|
|
162
162
|
t.index ["canvas_user_id"], name: "index_enrollments_on_canvas_user_id"
|
163
163
|
end
|
164
164
|
|
165
|
+
create_table "group_memberships", force: :cascade do |t|
|
166
|
+
t.bigint "canvas_id", null: false
|
167
|
+
t.bigint "canvas_user_id", null: false
|
168
|
+
t.bigint "canvas_group_id", null: false
|
169
|
+
t.string "group_sis_id"
|
170
|
+
t.string "user_sis_id"
|
171
|
+
t.string "workflow_state"
|
172
|
+
t.datetime "created_at", null: false
|
173
|
+
t.datetime "updated_at", null: false
|
174
|
+
t.index ["canvas_id"], name: "index_group_memberships_on_canvas_id", unique: true
|
175
|
+
end
|
176
|
+
|
177
|
+
create_table "groups", force: :cascade do |t|
|
178
|
+
t.bigint "canvas_id", null: false
|
179
|
+
t.string "sis_id"
|
180
|
+
t.bigint "canvas_group_category_id"
|
181
|
+
t.string "group_category_sis_id"
|
182
|
+
t.bigint "canvas_account_id"
|
183
|
+
t.bigint "canvas_course_id"
|
184
|
+
t.string "name"
|
185
|
+
t.string "workflow_state"
|
186
|
+
t.bigint "context_id"
|
187
|
+
t.string "context_type"
|
188
|
+
t.integer "max_membership"
|
189
|
+
t.datetime "created_at", null: false
|
190
|
+
t.datetime "updated_at", null: false
|
191
|
+
t.index ["canvas_id"], name: "index_groups_on_canvas_id", unique: true
|
192
|
+
end
|
193
|
+
|
165
194
|
create_table "roles", force: :cascade do |t|
|
166
195
|
t.integer "canvas_id", null: false
|
167
196
|
t.string "label"
|
@@ -196,6 +225,7 @@ ActiveRecord::Schema.define(version: 20190927204546) do
|
|
196
225
|
t.bigint "canvas_assignment_id"
|
197
226
|
t.bigint "canvas_user_id"
|
198
227
|
t.datetime "submitted_at"
|
228
|
+
t.datetime "due_at"
|
199
229
|
t.datetime "graded_at"
|
200
230
|
t.float "score"
|
201
231
|
t.float "points_possible"
|
@@ -0,0 +1,3 @@
|
|
1
|
+
canvas_group_id,group_id,canvas_group_category_id,group_category_id,canvas_account_id,account_id,canvas_course_id,course_id,name,status,created_by_sis,context_id,context_type,max_membership
|
2
|
+
50,sis1,10,,1,,,,Group1,available,false,1,Account,
|
3
|
+
51,sis2,2,,,,1,coursesis,Group2,available,false,1,Course,1
|
@@ -1,3 +1,3 @@
|
|
1
|
-
"canvas user id","sis user id","user name","canvas course id","sis course id","course name","assignment id","assignment name","submission date","graded date","score","points possible","submission id","workflow state","excused"
|
2
|
-
1,1,userName,1,1,courseName,1,assignmentName,2017-09-21 18:28:15 UTC,2017-09-21 19:36:23 UTC,5,10,1,graded,true
|
3
|
-
1,1,userName,1,1,courseName,2,assignment2Name,2017-09-21 18:28:15 UTC,2017-09-21 19:36:23 UTC,5,10,2,submitted,false
|
1
|
+
"canvas user id","sis user id","user name","canvas course id","sis course id","course name","assignment id","assignment name","submission date","graded date","score","points possible","submission id","workflow state","excused","due at"
|
2
|
+
1,1,userName,1,1,courseName,1,assignmentName,2017-09-21 18:28:15 UTC,2017-09-21 19:36:23 UTC,5,10,1,graded,true,2017-09-27 18:28:15 UTC
|
3
|
+
1,1,userName,1,1,courseName,2,assignment2Name,2017-09-21 18:28:15 UTC,2017-09-21 19:36:23 UTC,5,10,2,submitted,false,2017-09-28 18:28:15 UTC
|
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.
|
4
|
+
version: 0.16.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nate Collings
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-09-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -304,7 +304,7 @@ dependencies:
|
|
304
304
|
- - ">="
|
305
305
|
- !ruby/object:Gem::Version
|
306
306
|
version: '0'
|
307
|
-
description:
|
307
|
+
description:
|
308
308
|
email:
|
309
309
|
- ncollings@instructure.com
|
310
310
|
executables: []
|
@@ -338,6 +338,9 @@ files:
|
|
338
338
|
- lib/canvas_sync/generators/templates/migrations/create_context_modules.rb
|
339
339
|
- lib/canvas_sync/generators/templates/migrations/create_courses.rb
|
340
340
|
- lib/canvas_sync/generators/templates/migrations/create_enrollments.rb
|
341
|
+
- lib/canvas_sync/generators/templates/migrations/create_group_memberships.rb
|
342
|
+
- lib/canvas_sync/generators/templates/migrations/create_groups.rb
|
343
|
+
- lib/canvas_sync/generators/templates/migrations/create_pseudonyms.rb
|
341
344
|
- lib/canvas_sync/generators/templates/migrations/create_roles.rb
|
342
345
|
- lib/canvas_sync/generators/templates/migrations/create_sections.rb
|
343
346
|
- lib/canvas_sync/generators/templates/migrations/create_submissions.rb
|
@@ -351,6 +354,9 @@ files:
|
|
351
354
|
- lib/canvas_sync/generators/templates/models/context_module_item.rb
|
352
355
|
- lib/canvas_sync/generators/templates/models/course.rb
|
353
356
|
- lib/canvas_sync/generators/templates/models/enrollment.rb
|
357
|
+
- lib/canvas_sync/generators/templates/models/group.rb
|
358
|
+
- lib/canvas_sync/generators/templates/models/group_membership.rb
|
359
|
+
- lib/canvas_sync/generators/templates/models/pseudonym.rb
|
354
360
|
- lib/canvas_sync/generators/templates/models/role.rb
|
355
361
|
- lib/canvas_sync/generators/templates/models/section.rb
|
356
362
|
- lib/canvas_sync/generators/templates/models/submission.rb
|
@@ -387,7 +393,6 @@ files:
|
|
387
393
|
- lib/canvas_sync/jobs/sync_simple_table_job.rb
|
388
394
|
- lib/canvas_sync/jobs/sync_submissions_job.rb
|
389
395
|
- lib/canvas_sync/jobs/sync_terms_job.rb
|
390
|
-
- lib/canvas_sync/jobs/sync_users_job.rb
|
391
396
|
- lib/canvas_sync/processors/assignment_groups_processor.rb
|
392
397
|
- lib/canvas_sync/processors/assignments_processor.rb
|
393
398
|
- lib/canvas_sync/processors/context_module_items_processor.rb
|
@@ -416,7 +421,6 @@ files:
|
|
416
421
|
- spec/canvas_sync/jobs/sync_simple_table_job_spec.rb
|
417
422
|
- spec/canvas_sync/jobs/sync_submissions_job_spec.rb
|
418
423
|
- spec/canvas_sync/jobs/sync_terms_job_spec.rb
|
419
|
-
- spec/canvas_sync/jobs/sync_users_job_spec.rb
|
420
424
|
- spec/canvas_sync/models/accounts_spec.rb
|
421
425
|
- spec/canvas_sync/models/admins_spec.rb
|
422
426
|
- spec/canvas_sync/models/assignment_group_spec.rb
|
@@ -425,6 +429,8 @@ files:
|
|
425
429
|
- spec/canvas_sync/models/context_module_spec.rb
|
426
430
|
- spec/canvas_sync/models/course_spec.rb
|
427
431
|
- spec/canvas_sync/models/enrollment_spec.rb
|
432
|
+
- spec/canvas_sync/models/group_membership_spec.rb
|
433
|
+
- spec/canvas_sync/models/group_spec.rb
|
428
434
|
- spec/canvas_sync/models/roles_spec.rb
|
429
435
|
- spec/canvas_sync/models/section_spec.rb
|
430
436
|
- spec/canvas_sync/models/submission_spec.rb
|
@@ -450,6 +456,8 @@ files:
|
|
450
456
|
- spec/dummy/app/models/context_module_item.rb
|
451
457
|
- spec/dummy/app/models/course.rb
|
452
458
|
- spec/dummy/app/models/enrollment.rb
|
459
|
+
- spec/dummy/app/models/group.rb
|
460
|
+
- spec/dummy/app/models/group_membership.rb
|
453
461
|
- spec/dummy/app/models/role.rb
|
454
462
|
- spec/dummy/app/models/section.rb
|
455
463
|
- spec/dummy/app/models/submission.rb
|
@@ -510,6 +518,8 @@ files:
|
|
510
518
|
- spec/dummy/db/migrate/20190702203632_create_context_module_items.rb
|
511
519
|
- spec/dummy/db/migrate/20190927204545_create_roles.rb
|
512
520
|
- spec/dummy/db/migrate/20190927204546_create_admins.rb
|
521
|
+
- spec/dummy/db/migrate/20200415171620_create_groups.rb
|
522
|
+
- spec/dummy/db/migrate/20200416214248_create_group_memberships.rb
|
513
523
|
- spec/dummy/db/schema.rb
|
514
524
|
- spec/dummy/db/test.sqlite3
|
515
525
|
- spec/dummy/log/development.log
|
@@ -522,6 +532,8 @@ files:
|
|
522
532
|
- spec/factories/context_module_item_factory.rb
|
523
533
|
- spec/factories/course_factory.rb
|
524
534
|
- spec/factories/enrollment_factory.rb
|
535
|
+
- spec/factories/group_factory.rb
|
536
|
+
- spec/factories/group_membership_factory.rb
|
525
537
|
- spec/factories/role_factory.rb
|
526
538
|
- spec/factories/section_factory.rb
|
527
539
|
- spec/factories/submission_factory.rb
|
@@ -540,6 +552,8 @@ files:
|
|
540
552
|
- spec/support/fixtures/reports/context_modules.csv
|
541
553
|
- spec/support/fixtures/reports/courses.csv
|
542
554
|
- spec/support/fixtures/reports/enrollments.csv
|
555
|
+
- spec/support/fixtures/reports/group_memberships.csv
|
556
|
+
- spec/support/fixtures/reports/groups.csv
|
543
557
|
- spec/support/fixtures/reports/provisioning_csv
|
544
558
|
- spec/support/fixtures/reports/provisioning_csv_unzipped/courses.csv
|
545
559
|
- spec/support/fixtures/reports/provisioning_csv_unzipped/users.csv
|
@@ -550,7 +564,7 @@ files:
|
|
550
564
|
homepage: https://instructure.com
|
551
565
|
licenses: []
|
552
566
|
metadata: {}
|
553
|
-
post_install_message:
|
567
|
+
post_install_message:
|
554
568
|
rdoc_options: []
|
555
569
|
require_paths:
|
556
570
|
- lib
|
@@ -565,8 +579,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
565
579
|
- !ruby/object:Gem::Version
|
566
580
|
version: '0'
|
567
581
|
requirements: []
|
568
|
-
rubygems_version: 3.
|
569
|
-
signing_key:
|
582
|
+
rubygems_version: 3.1.2
|
583
|
+
signing_key:
|
570
584
|
specification_version: 4
|
571
585
|
summary: Gem for generating Canvas models and migrations and syncing data from Canvas
|
572
586
|
test_files:
|
@@ -586,7 +600,6 @@ test_files:
|
|
586
600
|
- spec/canvas_sync/jobs/sync_simple_table_job_spec.rb
|
587
601
|
- spec/canvas_sync/jobs/sync_submissions_job_spec.rb
|
588
602
|
- spec/canvas_sync/jobs/sync_terms_job_spec.rb
|
589
|
-
- spec/canvas_sync/jobs/sync_users_job_spec.rb
|
590
603
|
- spec/canvas_sync/models/accounts_spec.rb
|
591
604
|
- spec/canvas_sync/models/admins_spec.rb
|
592
605
|
- spec/canvas_sync/models/assignment_group_spec.rb
|
@@ -595,6 +608,8 @@ test_files:
|
|
595
608
|
- spec/canvas_sync/models/context_module_spec.rb
|
596
609
|
- spec/canvas_sync/models/course_spec.rb
|
597
610
|
- spec/canvas_sync/models/enrollment_spec.rb
|
611
|
+
- spec/canvas_sync/models/group_membership_spec.rb
|
612
|
+
- spec/canvas_sync/models/group_spec.rb
|
598
613
|
- spec/canvas_sync/models/roles_spec.rb
|
599
614
|
- spec/canvas_sync/models/section_spec.rb
|
600
615
|
- spec/canvas_sync/models/submission_spec.rb
|
@@ -620,6 +635,8 @@ test_files:
|
|
620
635
|
- spec/dummy/app/models/context_module_item.rb
|
621
636
|
- spec/dummy/app/models/course.rb
|
622
637
|
- spec/dummy/app/models/enrollment.rb
|
638
|
+
- spec/dummy/app/models/group.rb
|
639
|
+
- spec/dummy/app/models/group_membership.rb
|
623
640
|
- spec/dummy/app/models/role.rb
|
624
641
|
- spec/dummy/app/models/section.rb
|
625
642
|
- spec/dummy/app/models/submission.rb
|
@@ -680,6 +697,8 @@ test_files:
|
|
680
697
|
- spec/dummy/db/migrate/20190702203632_create_context_module_items.rb
|
681
698
|
- spec/dummy/db/migrate/20190927204545_create_roles.rb
|
682
699
|
- spec/dummy/db/migrate/20190927204546_create_admins.rb
|
700
|
+
- spec/dummy/db/migrate/20200415171620_create_groups.rb
|
701
|
+
- spec/dummy/db/migrate/20200416214248_create_group_memberships.rb
|
683
702
|
- spec/dummy/db/schema.rb
|
684
703
|
- spec/dummy/db/test.sqlite3
|
685
704
|
- spec/dummy/log/development.log
|
@@ -692,6 +711,8 @@ test_files:
|
|
692
711
|
- spec/factories/context_module_item_factory.rb
|
693
712
|
- spec/factories/course_factory.rb
|
694
713
|
- spec/factories/enrollment_factory.rb
|
714
|
+
- spec/factories/group_factory.rb
|
715
|
+
- spec/factories/group_membership_factory.rb
|
695
716
|
- spec/factories/role_factory.rb
|
696
717
|
- spec/factories/section_factory.rb
|
697
718
|
- spec/factories/submission_factory.rb
|
@@ -710,6 +731,8 @@ test_files:
|
|
710
731
|
- spec/support/fixtures/reports/context_modules.csv
|
711
732
|
- spec/support/fixtures/reports/courses.csv
|
712
733
|
- spec/support/fixtures/reports/enrollments.csv
|
734
|
+
- spec/support/fixtures/reports/group_memberships.csv
|
735
|
+
- spec/support/fixtures/reports/groups.csv
|
713
736
|
- spec/support/fixtures/reports/provisioning_csv
|
714
737
|
- spec/support/fixtures/reports/provisioning_csv_unzipped/courses.csv
|
715
738
|
- spec/support/fixtures/reports/provisioning_csv_unzipped/users.csv
|
@@ -1,26 +0,0 @@
|
|
1
|
-
module CanvasSync
|
2
|
-
module Jobs
|
3
|
-
class SyncUsersJob < ReportStarter
|
4
|
-
# Starts a provisioning report for just users.
|
5
|
-
#
|
6
|
-
# Provisioning reports do not scope users by term, so when we are
|
7
|
-
# running provisioning by term we sync users first so we don't duplicate
|
8
|
-
# the work of syncing all users for each term.
|
9
|
-
#
|
10
|
-
# @param job_chain [Hash]
|
11
|
-
# @param options [Hash]
|
12
|
-
def perform(job_chain, options)
|
13
|
-
super(
|
14
|
-
job_chain,
|
15
|
-
"proservices_provisioning_csv",
|
16
|
-
merge_report_params(job_chain, options, {
|
17
|
-
users: true,
|
18
|
-
include_deleted: true,
|
19
|
-
}, term_scope: false),
|
20
|
-
CanvasSync::Processors::ProvisioningReportProcessor.to_s,
|
21
|
-
{ models: ["users"] },
|
22
|
-
)
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
@@ -1,15 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
RSpec.describe CanvasSync::Jobs::SyncUsersJob do
|
4
|
-
describe '#perform' do
|
5
|
-
it 'enqueues a ReportStarter for a provisioning report across all terms with just users' do
|
6
|
-
expect_any_instance_of(Bearcat::Client).to receive(:start_report)
|
7
|
-
.with('self', 'proservices_provisioning_csv', { parameters: { users: true, include_deleted: true } })
|
8
|
-
.and_return({ 'id' => 1 })
|
9
|
-
|
10
|
-
expect(CanvasSync::Jobs::ReportChecker).to receive(:set).and_call_original
|
11
|
-
|
12
|
-
CanvasSync::Jobs::SyncUsersJob.perform_now({ jobs: [], global_options: {}}, {})
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|