canvas_sync 0.13.0 → 0.14.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/lib/canvas_sync.rb +2 -0
- 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/models/account.rb +1 -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/user.rb +1 -0
- data/lib/canvas_sync/jobs/sync_provisioning_report_job.rb +2 -0
- data/lib/canvas_sync/processors/model_mappings.yml +59 -0
- data/lib/canvas_sync/processors/provisioning_report_processor.rb +19 -0
- data/lib/canvas_sync/version.rb +1 -1
- 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/20200415171620_create_groups.rb +29 -0
- data/spec/dummy/db/migrate/20200416214248_create_group_memberships.rb +24 -0
- data/spec/dummy/db/schema.rb +30 -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
- metadata +28 -13
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/log/development.log +0 -1248
- data/spec/dummy/log/test.log +0 -43258
- data/spec/support/fixtures/reports/provisioning_csv_unzipped/courses.csv +0 -3
- data/spec/support/fixtures/reports/provisioning_csv_unzipped/users.csv +0 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 6dc939cb0559d835965e4b61416fa79f19fdb0a4
|
4
|
+
data.tar.gz: 9e075f746f42ae230ed6219c8e16b00b77526748
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c4acb86d39b2aaf09ee9de7ae33d689bc28570babd3086098634fa85e0cca9f8144b22193e3b0d1e21c659e31c807e00899b670d0e52f8549e214b899aae17e2
|
7
|
+
data.tar.gz: a18ac0d166e5e61b24f0a00a0284db3c73ea9bf5ea642f4ac11ccbab0a7b436222d68e4930ed2c3f75d517fe0ef9ebb1bb4752019ea29c988f9ab27e92388f70
|
data/lib/canvas_sync.rb
CHANGED
@@ -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
|
@@ -12,6 +12,7 @@ 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
|
15
16
|
|
16
17
|
api_syncable({
|
17
18
|
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
|
@@ -9,6 +9,7 @@ class User < ApplicationRecord
|
|
9
9
|
has_many :admins, primary_key: :canvas_id, foreign_key: :canvas_user_id
|
10
10
|
has_many :admin_roles, through: :admins, source: :role
|
11
11
|
has_many :submissions, primary_key: :canvas_id, foreign_key: :canvas_user_id
|
12
|
+
has_many :group_memberships, primary_key: :canvas_id, foreign_key: :canvas_user_id
|
12
13
|
|
13
14
|
api_syncable({
|
14
15
|
sis_id: :sis_user_id,
|
@@ -326,3 +326,62 @@ context_module_items:
|
|
326
326
|
assignment_id:
|
327
327
|
database_column_name: canvas_assignment_id
|
328
328
|
type: integer
|
329
|
+
|
330
|
+
groups:
|
331
|
+
conflict_target: canvas_group_id
|
332
|
+
report_columns:
|
333
|
+
canvas_group_id:
|
334
|
+
database_column_name: canvas_id
|
335
|
+
type: integer
|
336
|
+
group_id:
|
337
|
+
database_column_name: sis_id
|
338
|
+
type: string
|
339
|
+
canvas_group_category_id:
|
340
|
+
database_column_name: canvas_group_category_id
|
341
|
+
type: integer
|
342
|
+
group_category_id:
|
343
|
+
database_column_name: group_category_sis_id
|
344
|
+
type: integer
|
345
|
+
canvas_account_id:
|
346
|
+
database_column_name: canvas_account_id
|
347
|
+
type: integer
|
348
|
+
canvas_course_id:
|
349
|
+
database_column_name: canvas_course_id
|
350
|
+
type: integer
|
351
|
+
name:
|
352
|
+
database_column_name: name
|
353
|
+
type: string
|
354
|
+
status:
|
355
|
+
database_column_name: workflow_state
|
356
|
+
type: string
|
357
|
+
context_id:
|
358
|
+
database_column_name: context_id
|
359
|
+
type: integer
|
360
|
+
context_type:
|
361
|
+
database_column_name: context_type
|
362
|
+
type: string
|
363
|
+
max_membership:
|
364
|
+
database_column_name: max_membership
|
365
|
+
type: integer
|
366
|
+
|
367
|
+
group_memberships:
|
368
|
+
conflict_target: canvas_group_membership_id
|
369
|
+
report_columns:
|
370
|
+
canvas_group_membership_id:
|
371
|
+
database_column_name: canvas_id
|
372
|
+
type: integer
|
373
|
+
canvas_group_id:
|
374
|
+
database_column_name: canvas_group_id
|
375
|
+
type: integer
|
376
|
+
group_id:
|
377
|
+
database_column_name: group_sis_id
|
378
|
+
type: string
|
379
|
+
canvas_user_id:
|
380
|
+
database_column_name: canvas_user_id
|
381
|
+
type: integer
|
382
|
+
user_id:
|
383
|
+
database_column_name: user_sis_id
|
384
|
+
type: string
|
385
|
+
status:
|
386
|
+
database_column_name: workflow_state
|
387
|
+
type: string
|
@@ -122,6 +122,25 @@ module CanvasSync
|
|
122
122
|
mapping[:xlist][:conflict_target].to_sym,
|
123
123
|
)
|
124
124
|
end
|
125
|
+
|
126
|
+
def bulk_process_groups(report_file_path)
|
127
|
+
CanvasSync::Importers::BulkImporter.import(
|
128
|
+
report_file_path,
|
129
|
+
mapping[:groups][:report_columns],
|
130
|
+
Group,
|
131
|
+
mapping[:groups][:conflict_target].to_sym,
|
132
|
+
)
|
133
|
+
end
|
134
|
+
|
135
|
+
# Note that group membership is singular because we override the model name param in sync_provisioning_report_job
|
136
|
+
def bulk_process_group_membership(report_file_path)
|
137
|
+
CanvasSync::Importers::BulkImporter.import(
|
138
|
+
report_file_path,
|
139
|
+
mapping[:group_memberships][:report_columns],
|
140
|
+
GroupMembership,
|
141
|
+
mapping[:group_memberships][:conflict_target].to_sym,
|
142
|
+
)
|
143
|
+
end
|
125
144
|
end
|
126
145
|
end
|
127
146
|
end
|
data/lib/canvas_sync/version.rb
CHANGED
@@ -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
|