canvas_sync 0.17.20 → 0.17.23.beta5
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/README.md +24 -1
- data/config/initializers/apartment.rb +10 -0
- data/lib/canvas_sync/concerns/sync_mapping.rb +114 -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/term.rb +1 -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 +9781 -42513
- 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
|
+
CanvasSync::Concerns::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 || CanvasSync::Concerns::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', 'grading_periods', 'grading_period_groups'])
|
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"
|