canvas_sync 0.17.20 → 0.17.23.beta1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +24 -1
- data/lib/canvas_sync/concerns/sync_mapping.rb +112 -0
- data/lib/canvas_sync/generators/install_generator.rb +1 -0
- data/lib/canvas_sync/generators/templates/migrations/create_grading_period_groups.rb +22 -0
- data/lib/canvas_sync/generators/templates/migrations/create_grading_periods.rb +22 -0
- data/lib/canvas_sync/generators/templates/migrations/create_user_observers.rb +17 -0
- data/lib/canvas_sync/generators/templates/models/grading_period.rb +8 -0
- data/lib/canvas_sync/generators/templates/models/grading_period_group.rb +9 -0
- data/lib/canvas_sync/generators/templates/models/user_observer.rb +11 -0
- data/lib/canvas_sync/importers/bulk_importer.rb +27 -16
- data/lib/canvas_sync/job_batches/chain_builder.rb +1 -1
- data/lib/canvas_sync/processors/assignment_groups_processor.rb +1 -7
- data/lib/canvas_sync/processors/assignments_processor.rb +1 -7
- data/lib/canvas_sync/processors/context_module_items_processor.rb +1 -7
- data/lib/canvas_sync/processors/context_modules_processor.rb +1 -7
- data/lib/canvas_sync/processors/model_mappings.yml +68 -0
- data/lib/canvas_sync/processors/normal_processor.rb +3 -3
- data/lib/canvas_sync/processors/provisioning_report_processor.rb +21 -63
- data/lib/canvas_sync/processors/report_processor.rb +14 -9
- data/lib/canvas_sync/processors/submissions_processor.rb +1 -7
- data/lib/canvas_sync/record.rb +4 -0
- data/lib/canvas_sync/version.rb +1 -1
- data/lib/canvas_sync.rb +4 -1
- data/spec/canvas_sync/processors/provisioning_report_processor_spec.rb +40 -0
- data/spec/dummy/app/models/grading_period.rb +14 -0
- data/spec/dummy/app/models/grading_period_group.rb +15 -0
- data/spec/dummy/app/models/user_observer.rb +17 -0
- data/spec/dummy/db/migrate/20210907233329_create_user_observers.rb +23 -0
- data/spec/dummy/db/migrate/20210907233330_create_grading_periods.rb +28 -0
- data/spec/dummy/db/migrate/20210907233331_create_grading_period_groups.rb +28 -0
- data/spec/dummy/db/schema.rb +42 -1
- data/spec/dummy/log/development.log +1105 -1186
- data/spec/dummy/log/test.log +2555 -43038
- data/spec/support/fixtures/reports/grading_period_groups.csv +2 -0
- data/spec/support/fixtures/reports/grading_periods.csv +3 -0
- data/spec/support/fixtures/reports/user_observers.csv +3 -0
- metadata +34 -25
- data/spec/dummy/db/test.sqlite3 +0 -0
@@ -13,12 +13,12 @@ module CanvasSync
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def initialize(report_file_path, options)
|
16
|
-
|
16
|
+
m = mapping[options[:mapping].to_sym]
|
17
17
|
CanvasSync::Importers::BulkImporter.import(
|
18
18
|
report_file_path,
|
19
|
-
|
19
|
+
m[:report_columns],
|
20
20
|
options[:klass].constantize,
|
21
|
-
|
21
|
+
m[:conflict_target],
|
22
22
|
import_args: options
|
23
23
|
)
|
24
24
|
end
|
@@ -69,94 +69,52 @@ module CanvasSync
|
|
69
69
|
end
|
70
70
|
|
71
71
|
def bulk_process_users(report_file_path)
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
import_args: @options
|
78
|
-
)
|
72
|
+
do_bulk_import(report_file_path, User, options: @options)
|
73
|
+
end
|
74
|
+
|
75
|
+
def bulk_process_user_observers(report_file_path)
|
76
|
+
do_bulk_import(report_file_path, UserObserver, options: @options)
|
79
77
|
end
|
80
78
|
|
81
79
|
def bulk_process_pseudonyms(report_file_path)
|
82
|
-
|
83
|
-
report_file_path,
|
84
|
-
mapping[:pseudonyms][:report_columns],
|
85
|
-
Pseudonym,
|
86
|
-
mapping[:pseudonyms][:conflict_target].to_sym,
|
87
|
-
import_args: @options
|
88
|
-
)
|
80
|
+
do_bulk_import(report_file_path, Pseudonym, options: @options)
|
89
81
|
end
|
90
82
|
|
91
83
|
def bulk_process_accounts(report_file_path)
|
92
|
-
|
93
|
-
report_file_path,
|
94
|
-
mapping[:accounts][:report_columns],
|
95
|
-
Account,
|
96
|
-
mapping[:accounts][:conflict_target].to_sym,
|
97
|
-
import_args: @options
|
98
|
-
)
|
84
|
+
do_bulk_import(report_file_path, Account, options: @options)
|
99
85
|
end
|
100
86
|
|
101
87
|
def bulk_process_courses(report_file_path)
|
102
|
-
|
103
|
-
report_file_path,
|
104
|
-
mapping[:courses][:report_columns],
|
105
|
-
Course,
|
106
|
-
mapping[:courses][:conflict_target].to_sym,
|
107
|
-
import_args: @options
|
108
|
-
)
|
88
|
+
do_bulk_import(report_file_path, Course, options: @options)
|
109
89
|
end
|
110
90
|
|
111
91
|
def bulk_process_enrollments(report_file_path)
|
112
|
-
|
113
|
-
report_file_path,
|
114
|
-
mapping[:enrollments][:report_columns],
|
115
|
-
Enrollment,
|
116
|
-
mapping[:enrollments][:conflict_target].to_sym,
|
117
|
-
import_args: @options
|
118
|
-
)
|
92
|
+
do_bulk_import(report_file_path, Enrollment, options: @options)
|
119
93
|
end
|
120
94
|
|
121
95
|
def bulk_process_sections(report_file_path)
|
122
|
-
|
123
|
-
report_file_path,
|
124
|
-
mapping[:sections][:report_columns],
|
125
|
-
Section,
|
126
|
-
mapping[:sections][:conflict_target].to_sym,
|
127
|
-
import_args: @options
|
128
|
-
)
|
96
|
+
do_bulk_import(report_file_path, Section, options: @options)
|
129
97
|
end
|
130
98
|
|
131
99
|
def bulk_process_xlist(report_file_path)
|
132
|
-
|
133
|
-
report_file_path,
|
134
|
-
mapping[:xlist][:report_columns],
|
135
|
-
Section,
|
136
|
-
mapping[:xlist][:conflict_target].to_sym,
|
137
|
-
import_args: @options
|
138
|
-
)
|
100
|
+
do_bulk_import(report_file_path, Section, options: @options, mapping_key: :xlist)
|
139
101
|
end
|
140
102
|
|
141
103
|
def bulk_process_groups(report_file_path)
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
104
|
+
do_bulk_import(report_file_path, Group, options: @options)
|
105
|
+
end
|
106
|
+
|
107
|
+
def bulk_process_grading_periods(report_file_path)
|
108
|
+
do_bulk_import(report_file_path, GradingPeriod, options: @options)
|
109
|
+
end
|
110
|
+
|
111
|
+
def bulk_process_grading_period_groups(report_file_path)
|
112
|
+
do_bulk_import(report_file_path, GradingPeriodGroup, options: @options)
|
149
113
|
end
|
150
114
|
|
151
115
|
# Note that group membership is singular because we override the model name param in sync_provisioning_report_job
|
152
116
|
def bulk_process_group_membership(report_file_path)
|
153
|
-
|
154
|
-
report_file_path,
|
155
|
-
mapping[:group_memberships][:report_columns],
|
156
|
-
GroupMembership,
|
157
|
-
mapping[:group_memberships][:conflict_target].to_sym,
|
158
|
-
import_args: @options
|
159
|
-
)
|
117
|
+
do_bulk_import(report_file_path, GroupMembership, options: @options)
|
160
118
|
end
|
161
119
|
end
|
162
120
|
end
|
@@ -5,17 +5,22 @@ module CanvasSync
|
|
5
5
|
# Base report processing class
|
6
6
|
class ReportProcessor
|
7
7
|
def mapping
|
8
|
-
|
9
|
-
|
10
|
-
override_filepath = Rails.root.join("config/canvas_sync_provisioning_mapping.yml")
|
8
|
+
SyncMapping::Mapping.default_mappings
|
9
|
+
end
|
11
10
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
end
|
11
|
+
def mapping_for(model, key = nil)
|
12
|
+
model.try(:get_sync_mapping, key) || mapping[key || SyncMapping::Mapping.normalize_model_name(model)]
|
13
|
+
end
|
16
14
|
|
17
|
-
|
18
|
-
|
15
|
+
def do_bulk_import(report_file_path, model, options: {}, mapping_key: nil)
|
16
|
+
m = mapping_for(model, mapping_key)
|
17
|
+
CanvasSync::Importers::BulkImporter.import(
|
18
|
+
report_file_path,
|
19
|
+
m[:report_columns],
|
20
|
+
model,
|
21
|
+
m[:conflict_target],
|
22
|
+
import_args: options
|
23
|
+
)
|
19
24
|
end
|
20
25
|
end
|
21
26
|
end
|
@@ -12,13 +12,7 @@ module CanvasSync
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def initialize(report_file_path, options)
|
15
|
-
|
16
|
-
report_file_path,
|
17
|
-
mapping[:submissions][:report_columns],
|
18
|
-
Submission,
|
19
|
-
mapping[:submissions][:conflict_target].to_sym,
|
20
|
-
import_args: options
|
21
|
-
)
|
15
|
+
do_bulk_import(report_file_path, Submission, options: options)
|
22
16
|
end
|
23
17
|
end
|
24
18
|
end
|
data/lib/canvas_sync/record.rb
CHANGED
data/lib/canvas_sync/version.rb
CHANGED
data/lib/canvas_sync.rb
CHANGED
@@ -41,6 +41,9 @@ module CanvasSync
|
|
41
41
|
context_modules
|
42
42
|
context_module_items
|
43
43
|
xlist
|
44
|
+
user_observers
|
45
|
+
grading_periods
|
46
|
+
grading_period_groups
|
44
47
|
].freeze
|
45
48
|
|
46
49
|
SUPPORTED_TERM_SCOPE_MODELS = %w[
|
@@ -176,7 +179,7 @@ module CanvasSync
|
|
176
179
|
# These Models use the provisioning report, but are not term-scoped,
|
177
180
|
# so we sync them outside of the term scoping to ensure work is not duplicated
|
178
181
|
if term_scope.present?
|
179
|
-
models -= (first_provisioning_models = models & ['users', 'pseudonyms'])
|
182
|
+
models -= (first_provisioning_models = models & ['users', 'pseudonyms', 'user_observers'])
|
180
183
|
current_chain.insert(generate_provisioning_jobs(first_provisioning_models, options))
|
181
184
|
end
|
182
185
|
|
@@ -62,6 +62,46 @@ RSpec.describe CanvasSync::Processors::ProvisioningReportProcessor do
|
|
62
62
|
expect(group.canvas_user_id).to eq 10
|
63
63
|
end
|
64
64
|
|
65
|
+
it 'processes user_observers' do
|
66
|
+
expect {
|
67
|
+
subject.process('spec/support/fixtures/reports/user_observers.csv', { models: ['user_observers'] }, 1)
|
68
|
+
}.to change { UserObserver.count }.by(2)
|
69
|
+
obj = UserObserver.find_by(observed_user_id: 3)
|
70
|
+
expect(obj.workflow_state).to eq 'active'
|
71
|
+
expect(obj.observing_user_id).to eq 21
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'processes grading_periods' do
|
75
|
+
expect {
|
76
|
+
subject.process('spec/support/fixtures/reports/grading_periods.csv', { models: ['grading_periods'] }, 1)
|
77
|
+
}.to change { GradingPeriod.count }.by(2)
|
78
|
+
obj = GradingPeriod.find_by(canvas_id: 1)
|
79
|
+
puts obj.inspect
|
80
|
+
expect(obj.title).to eq 'Period 1'
|
81
|
+
expect(obj.weight).to eq 0.2
|
82
|
+
expect(obj.workflow_state).to eq 'active'
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'processes grading_period_groups' do
|
86
|
+
expect {
|
87
|
+
subject.process('spec/support/fixtures/reports/grading_period_groups.csv', { models: ['grading_period_groups'] }, 1)
|
88
|
+
}.to change { GradingPeriodGroup.count }.by(1)
|
89
|
+
obj = GradingPeriodGroup.find_by(canvas_id: 1)
|
90
|
+
puts obj.inspect
|
91
|
+
expect(obj.title).to eq 'Test Group'
|
92
|
+
expect(obj.workflow_state).to eq 'active'
|
93
|
+
end
|
94
|
+
|
95
|
+
it 'model with composite key behaves as expected' do
|
96
|
+
expect {
|
97
|
+
subject.process('spec/support/fixtures/reports/user_observers.csv', { models: ['user_observers'] }, 1)
|
98
|
+
}.to change { UserObserver.count }.by(2)
|
99
|
+
|
100
|
+
expect {
|
101
|
+
subject.process('spec/support/fixtures/reports/user_observers.csv', { models: ['user_observers'] }, 1)
|
102
|
+
}.to change { UserObserver.count }.by(0)
|
103
|
+
end
|
104
|
+
|
65
105
|
context 'options[:models] is multiple models' do
|
66
106
|
it 'extracts the ZIP and processes each model' do
|
67
107
|
user_count = User.count
|
@@ -0,0 +1,14 @@
|
|
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 GradingPeriod < ApplicationRecord
|
10
|
+
include CanvasSync::Record
|
11
|
+
|
12
|
+
validates :canvas_id, uniqueness: true, presence: true
|
13
|
+
belongs_to :grading_period_group, primary_key: :canvas_id, foreign_key: :canvas_grading_period_group_id, optional: true
|
14
|
+
end
|
@@ -0,0 +1,15 @@
|
|
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 GradingPeriodGroup < ApplicationRecord
|
10
|
+
include CanvasSync::Record
|
11
|
+
|
12
|
+
validates :canvas_id, uniqueness: true, presence: true
|
13
|
+
belongs_to :course, primary_key: :canvas_id, foreign_key: :canvas_course_id, optional: true
|
14
|
+
belongs_to :account, primary_key: :canvas_id, foreign_key: :canvas_account_id, optional: true
|
15
|
+
end
|
@@ -0,0 +1,17 @@
|
|
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 UserObserver < ApplicationRecord
|
10
|
+
include CanvasSync::Record
|
11
|
+
include CanvasSync::Concerns::ApiSyncable
|
12
|
+
|
13
|
+
validates :canvas_id, uniqueness: true, presence: true
|
14
|
+
|
15
|
+
belongs_to :observing_user, primary_key: :canvas_id, foreign_key: :observing_user_id, class_name: 'User', optional: true
|
16
|
+
belongs_to :observed_user, primary_key: :canvas_id, foreign_key: :observed_user_id, class_name: 'User', optional: true
|
17
|
+
end
|
@@ -0,0 +1,23 @@
|
|
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 CreateUserObservers < ActiveRecord::Migration[5.1]
|
10
|
+
def change
|
11
|
+
create_table :user_observers do |t|
|
12
|
+
t.bigint :observing_user_id
|
13
|
+
t.bigint :observed_user_id
|
14
|
+
t.string :workflow_state
|
15
|
+
|
16
|
+
t.timestamps
|
17
|
+
end
|
18
|
+
|
19
|
+
add_index :user_observers, [:observed_user_id, :observing_user_id], unique: true
|
20
|
+
add_index :user_observers, :observing_user_id
|
21
|
+
add_index :user_observers, :observed_user_id
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,28 @@
|
|
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 CreateGradingPeriods < ActiveRecord::Migration[5.1]
|
10
|
+
def change
|
11
|
+
create_table :grading_periods do |t|
|
12
|
+
t.bigint :canvas_id, null: false
|
13
|
+
t.string :title
|
14
|
+
t.float :weight
|
15
|
+
t.datetime :start_date
|
16
|
+
t.datetime :end_date
|
17
|
+
t.datetime :close_date
|
18
|
+
t.bigint :canvas_grading_period_group_id
|
19
|
+
|
20
|
+
t.string :workflow_state
|
21
|
+
|
22
|
+
t.timestamps
|
23
|
+
end
|
24
|
+
|
25
|
+
add_index :grading_periods, :canvas_id, unique: true
|
26
|
+
add_index :grading_periods, :canvas_grading_period_group_id
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,28 @@
|
|
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 CreateGradingPeriodGroups < ActiveRecord::Migration[5.1]
|
10
|
+
def change
|
11
|
+
create_table :grading_period_groups do |t|
|
12
|
+
t.bigint :canvas_id, null: false
|
13
|
+
t.bigint :canvas_course_id
|
14
|
+
t.bigint :canvas_account_id
|
15
|
+
t.string :title
|
16
|
+
t.boolean :weighted
|
17
|
+
t.boolean :display_totals_for_all_grading_periods
|
18
|
+
|
19
|
+
t.string :workflow_state
|
20
|
+
|
21
|
+
t.timestamps
|
22
|
+
end
|
23
|
+
|
24
|
+
add_index :grading_period_groups, :canvas_id, unique: true
|
25
|
+
add_index :grading_period_groups, :canvas_course_id
|
26
|
+
add_index :grading_period_groups, :canvas_account_id
|
27
|
+
end
|
28
|
+
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: 2021_09_07_233331) do
|
14
14
|
|
15
15
|
# These are extensions that must be enabled in order to support this database
|
16
16
|
enable_extension "plpgsql"
|
@@ -173,6 +173,36 @@ ActiveRecord::Schema.define(version: 2020_10_30_210836) do
|
|
173
173
|
t.index ["canvas_user_id"], name: "index_enrollments_on_canvas_user_id"
|
174
174
|
end
|
175
175
|
|
176
|
+
create_table "grading_period_groups", force: :cascade do |t|
|
177
|
+
t.bigint "canvas_id", null: false
|
178
|
+
t.bigint "canvas_course_id"
|
179
|
+
t.bigint "canvas_account_id"
|
180
|
+
t.string "title"
|
181
|
+
t.boolean "weighted"
|
182
|
+
t.boolean "display_totals_for_all_grading_periods"
|
183
|
+
t.string "workflow_state"
|
184
|
+
t.datetime "created_at", null: false
|
185
|
+
t.datetime "updated_at", null: false
|
186
|
+
t.index ["canvas_account_id"], name: "index_grading_period_groups_on_canvas_account_id"
|
187
|
+
t.index ["canvas_course_id"], name: "index_grading_period_groups_on_canvas_course_id"
|
188
|
+
t.index ["canvas_id"], name: "index_grading_period_groups_on_canvas_id", unique: true
|
189
|
+
end
|
190
|
+
|
191
|
+
create_table "grading_periods", force: :cascade do |t|
|
192
|
+
t.bigint "canvas_id", null: false
|
193
|
+
t.string "title"
|
194
|
+
t.float "weight"
|
195
|
+
t.datetime "start_date"
|
196
|
+
t.datetime "end_date"
|
197
|
+
t.datetime "close_date"
|
198
|
+
t.bigint "canvas_grading_period_group_id"
|
199
|
+
t.string "workflow_state"
|
200
|
+
t.datetime "created_at", null: false
|
201
|
+
t.datetime "updated_at", null: false
|
202
|
+
t.index ["canvas_grading_period_group_id"], name: "index_grading_periods_on_canvas_grading_period_group_id"
|
203
|
+
t.index ["canvas_id"], name: "index_grading_periods_on_canvas_id", unique: true
|
204
|
+
end
|
205
|
+
|
176
206
|
create_table "group_memberships", force: :cascade do |t|
|
177
207
|
t.bigint "canvas_id", null: false
|
178
208
|
t.bigint "canvas_user_id", null: false
|
@@ -275,6 +305,17 @@ ActiveRecord::Schema.define(version: 2020_10_30_210836) do
|
|
275
305
|
t.index ["canvas_id"], name: "index_terms_on_canvas_id", unique: true
|
276
306
|
end
|
277
307
|
|
308
|
+
create_table "user_observers", force: :cascade do |t|
|
309
|
+
t.bigint "observing_user_id"
|
310
|
+
t.bigint "observed_user_id"
|
311
|
+
t.string "workflow_state"
|
312
|
+
t.datetime "created_at", null: false
|
313
|
+
t.datetime "updated_at", null: false
|
314
|
+
t.index ["observed_user_id", "observing_user_id"], name: "index_user_observers_on_observed_user_id_and_observing_user_id", unique: true
|
315
|
+
t.index ["observed_user_id"], name: "index_user_observers_on_observed_user_id"
|
316
|
+
t.index ["observing_user_id"], name: "index_user_observers_on_observing_user_id"
|
317
|
+
end
|
318
|
+
|
278
319
|
create_table "users", force: :cascade do |t|
|
279
320
|
t.bigint "canvas_id", null: false
|
280
321
|
t.string "sis_id"
|