canvas_sync 0.16.4 → 0.21.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (260) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +235 -151
  3. data/app/controllers/{api → canvas_sync/api}/v1/health_check_controller.rb +1 -1
  4. data/app/controllers/canvas_sync/api/v1/live_events_controller.rb +122 -0
  5. data/app/models/canvas_sync/sync_batch.rb +5 -0
  6. data/config/initializers/apartment.rb +10 -1
  7. data/config/routes.rb +7 -0
  8. data/db/migrate/20170915210836_create_canvas_sync_job_log.rb +12 -31
  9. data/db/migrate/20180725155729_add_job_id_to_canvas_sync_job_logs.rb +4 -13
  10. data/db/migrate/20190916154829_add_fork_count_to_canvas_sync_job_logs.rb +3 -11
  11. data/db/migrate/20201018210836_create_canvas_sync_sync_batches.rb +11 -0
  12. data/db/migrate/20201030210836_add_full_sync_to_canvas_sync_sync_batch.rb +7 -0
  13. data/lib/canvas_sync/batch_processor.rb +41 -0
  14. data/lib/canvas_sync/concerns/ability_helper.rb +72 -0
  15. data/lib/canvas_sync/concerns/account/ancestry.rb +2 -0
  16. data/lib/canvas_sync/concerns/account/base.rb +15 -0
  17. data/lib/canvas_sync/concerns/api_syncable.rb +17 -10
  18. data/lib/canvas_sync/concerns/live_event_sync.rb +46 -0
  19. data/lib/canvas_sync/concerns/role/base.rb +57 -0
  20. data/lib/canvas_sync/concerns/sync_mapping.rb +120 -0
  21. data/lib/canvas_sync/engine.rb +80 -0
  22. data/lib/canvas_sync/generators/install_generator.rb +1 -0
  23. data/lib/canvas_sync/generators/install_live_events_generator.rb +0 -1
  24. data/lib/canvas_sync/generators/templates/migrations/create_content_migrations.rb +24 -0
  25. data/lib/canvas_sync/generators/templates/migrations/create_course_nicknames.rb +17 -0
  26. data/lib/canvas_sync/generators/templates/migrations/create_grading_period_groups.rb +18 -0
  27. data/lib/canvas_sync/generators/templates/migrations/create_grading_periods.rb +22 -0
  28. data/lib/canvas_sync/generators/templates/migrations/create_learning_outcome_results.rb +46 -0
  29. data/lib/canvas_sync/generators/templates/migrations/create_learning_outcomes.rb +30 -0
  30. data/lib/canvas_sync/generators/templates/migrations/create_rubric_assessments.rb +31 -0
  31. data/lib/canvas_sync/generators/templates/migrations/create_rubric_associations.rb +36 -0
  32. data/lib/canvas_sync/generators/templates/migrations/create_rubrics.rb +38 -0
  33. data/lib/canvas_sync/generators/templates/migrations/create_user_observers.rb +17 -0
  34. data/lib/canvas_sync/generators/templates/migrations/create_users.rb +0 -1
  35. data/lib/canvas_sync/generators/templates/models/account.rb +3 -0
  36. data/lib/canvas_sync/generators/templates/models/admin.rb +2 -0
  37. data/lib/canvas_sync/generators/templates/models/assignment.rb +3 -0
  38. data/lib/canvas_sync/generators/templates/models/assignment_group.rb +3 -0
  39. data/lib/canvas_sync/generators/templates/models/content_migration.rb +12 -0
  40. data/lib/canvas_sync/generators/templates/models/context_module.rb +3 -0
  41. data/lib/canvas_sync/generators/templates/models/context_module_item.rb +3 -0
  42. data/lib/canvas_sync/generators/templates/models/course.rb +11 -0
  43. data/lib/canvas_sync/generators/templates/models/course_nickname.rb +13 -0
  44. data/lib/canvas_sync/generators/templates/models/enrollment.rb +14 -0
  45. data/lib/canvas_sync/generators/templates/models/grading_period.rb +10 -0
  46. data/lib/canvas_sync/generators/templates/models/grading_period_group.rb +9 -0
  47. data/lib/canvas_sync/generators/templates/models/group.rb +2 -0
  48. data/lib/canvas_sync/generators/templates/models/group_membership.rb +2 -0
  49. data/lib/canvas_sync/generators/templates/models/learning_outcome.rb +24 -0
  50. data/lib/canvas_sync/generators/templates/models/learning_outcome_result.rb +48 -0
  51. data/lib/canvas_sync/generators/templates/models/pseudonym.rb +2 -0
  52. data/lib/canvas_sync/generators/templates/models/role.rb +2 -0
  53. data/lib/canvas_sync/generators/templates/models/rubric.rb +29 -0
  54. data/lib/canvas_sync/generators/templates/models/rubric_assessment.rb +17 -0
  55. data/lib/canvas_sync/generators/templates/models/rubric_association.rb +14 -0
  56. data/lib/canvas_sync/generators/templates/models/section.rb +9 -0
  57. data/lib/canvas_sync/generators/templates/models/submission.rb +3 -0
  58. data/lib/canvas_sync/generators/templates/models/term.rb +3 -0
  59. data/lib/canvas_sync/generators/templates/models/user.rb +11 -0
  60. data/lib/canvas_sync/generators/templates/models/user_observer.rb +13 -0
  61. data/lib/canvas_sync/generators/templates/services/live_events/assignment_event.rb +1 -1
  62. data/lib/canvas_sync/generators/templates/services/live_events/assignment_group_event.rb +1 -1
  63. data/lib/canvas_sync/generators/templates/services/live_events/course_event.rb +1 -3
  64. data/lib/canvas_sync/generators/templates/services/live_events/course_section_event.rb +1 -1
  65. data/lib/canvas_sync/generators/templates/services/live_events/enrollment_event.rb +1 -1
  66. data/lib/canvas_sync/generators/templates/services/live_events/grade_event.rb +1 -1
  67. data/lib/canvas_sync/generators/templates/services/live_events/module_event.rb +1 -1
  68. data/lib/canvas_sync/generators/templates/services/live_events/module_item_event.rb +1 -1
  69. data/lib/canvas_sync/generators/templates/services/live_events/submission_event.rb +1 -1
  70. data/lib/canvas_sync/generators/templates/services/live_events/syllabus_event.rb +1 -1
  71. data/lib/canvas_sync/generators/templates/services/live_events/user_event.rb +1 -3
  72. data/lib/canvas_sync/importers/bulk_importer.rb +138 -31
  73. data/lib/canvas_sync/job.rb +7 -5
  74. data/lib/canvas_sync/job_batches/active_job.rb +108 -0
  75. data/lib/canvas_sync/job_batches/batch.rb +543 -0
  76. data/lib/canvas_sync/job_batches/callback.rb +149 -0
  77. data/lib/canvas_sync/job_batches/chain_builder.rb +249 -0
  78. data/lib/canvas_sync/job_batches/context_hash.rb +159 -0
  79. data/lib/canvas_sync/job_batches/hier_batch_ids.lua +25 -0
  80. data/lib/canvas_sync/job_batches/jobs/base_job.rb +7 -0
  81. data/lib/canvas_sync/job_batches/jobs/concurrent_batch_job.rb +22 -0
  82. data/lib/canvas_sync/job_batches/jobs/managed_batch_job.rb +170 -0
  83. data/lib/canvas_sync/job_batches/jobs/serial_batch_job.rb +22 -0
  84. data/lib/canvas_sync/job_batches/pool.rb +245 -0
  85. data/lib/canvas_sync/job_batches/pool_refill.lua +47 -0
  86. data/lib/canvas_sync/job_batches/redis_model.rb +69 -0
  87. data/lib/canvas_sync/job_batches/redis_script.rb +163 -0
  88. data/lib/canvas_sync/job_batches/schedule_callback.lua +14 -0
  89. data/lib/canvas_sync/job_batches/sidekiq/web/batches_assets/css/styles.less +182 -0
  90. data/lib/canvas_sync/job_batches/sidekiq/web/batches_assets/js/batch_tree.js +108 -0
  91. data/lib/canvas_sync/job_batches/sidekiq/web/batches_assets/js/util.js +2 -0
  92. data/lib/canvas_sync/job_batches/sidekiq/web/helpers.rb +41 -0
  93. data/lib/canvas_sync/job_batches/sidekiq/web/views/_batch_tree.erb +6 -0
  94. data/lib/canvas_sync/job_batches/sidekiq/web/views/_batches_table.erb +44 -0
  95. data/lib/canvas_sync/job_batches/sidekiq/web/views/_common.erb +13 -0
  96. data/lib/canvas_sync/job_batches/sidekiq/web/views/_jobs_table.erb +21 -0
  97. data/lib/canvas_sync/job_batches/sidekiq/web/views/_pagination.erb +26 -0
  98. data/lib/canvas_sync/job_batches/sidekiq/web/views/batch.erb +81 -0
  99. data/lib/canvas_sync/job_batches/sidekiq/web/views/batches.erb +23 -0
  100. data/lib/canvas_sync/job_batches/sidekiq/web/views/pool.erb +137 -0
  101. data/lib/canvas_sync/job_batches/sidekiq/web/views/pools.erb +47 -0
  102. data/lib/canvas_sync/job_batches/sidekiq/web.rb +218 -0
  103. data/lib/canvas_sync/job_batches/sidekiq.rb +136 -0
  104. data/lib/canvas_sync/job_batches/status.rb +91 -0
  105. data/lib/canvas_sync/jobs/begin_sync_chain_job.rb +99 -0
  106. data/lib/canvas_sync/jobs/canvas_process_waiter.rb +41 -0
  107. data/lib/canvas_sync/jobs/report_checker.rb +70 -8
  108. data/lib/canvas_sync/jobs/report_processor_job.rb +4 -7
  109. data/lib/canvas_sync/jobs/report_starter.rb +34 -20
  110. data/lib/canvas_sync/jobs/sync_accounts_job.rb +3 -5
  111. data/lib/canvas_sync/jobs/sync_admins_job.rb +2 -4
  112. data/lib/canvas_sync/jobs/sync_assignment_groups_job.rb +2 -4
  113. data/lib/canvas_sync/jobs/sync_assignments_job.rb +2 -4
  114. data/lib/canvas_sync/jobs/sync_content_migrations_job.rb +20 -0
  115. data/lib/canvas_sync/jobs/sync_context_module_items_job.rb +2 -4
  116. data/lib/canvas_sync/jobs/sync_context_modules_job.rb +2 -4
  117. data/lib/canvas_sync/jobs/sync_provisioning_report_job.rb +16 -50
  118. data/lib/canvas_sync/jobs/sync_roles_job.rb +2 -5
  119. data/lib/canvas_sync/jobs/sync_rubric_assessments_job.rb +15 -0
  120. data/lib/canvas_sync/jobs/sync_rubric_associations_job.rb +15 -0
  121. data/lib/canvas_sync/jobs/sync_rubrics_job.rb +15 -0
  122. data/lib/canvas_sync/jobs/sync_simple_table_job.rb +11 -32
  123. data/lib/canvas_sync/jobs/sync_submissions_job.rb +6 -4
  124. data/lib/canvas_sync/jobs/sync_terms_job.rb +9 -8
  125. data/lib/canvas_sync/jobs/term_batches_job.rb +50 -0
  126. data/lib/canvas_sync/{generators/templates/services/live_events/base_event.rb → live_events/base_handler.rb} +6 -10
  127. data/lib/canvas_sync/live_events/process_event_job.rb +26 -0
  128. data/lib/canvas_sync/live_events.rb +38 -0
  129. data/lib/canvas_sync/misc_helper.rb +63 -0
  130. data/lib/canvas_sync/processors/assignment_groups_processor.rb +3 -8
  131. data/lib/canvas_sync/processors/assignments_processor.rb +3 -8
  132. data/lib/canvas_sync/processors/content_migrations_processor.rb +19 -0
  133. data/lib/canvas_sync/processors/context_module_items_processor.rb +3 -8
  134. data/lib/canvas_sync/processors/context_modules_processor.rb +3 -8
  135. data/lib/canvas_sync/processors/model_mappings.yml +420 -0
  136. data/lib/canvas_sync/processors/normal_processor.rb +3 -3
  137. data/lib/canvas_sync/processors/provisioning_report_processor.rb +42 -55
  138. data/lib/canvas_sync/processors/report_processor.rb +15 -9
  139. data/lib/canvas_sync/processors/rubric_assessments_processor.rb +19 -0
  140. data/lib/canvas_sync/processors/rubric_associations_processor.rb +19 -0
  141. data/lib/canvas_sync/processors/rubrics_processor.rb +19 -0
  142. data/lib/canvas_sync/processors/submissions_processor.rb +3 -8
  143. data/lib/canvas_sync/record.rb +103 -0
  144. data/lib/canvas_sync/version.rb +1 -1
  145. data/lib/canvas_sync.rb +124 -125
  146. data/spec/canvas_sync/canvas_sync_spec.rb +224 -155
  147. data/spec/canvas_sync/jobs/canvas_process_waiter_spec.rb +34 -0
  148. data/spec/canvas_sync/jobs/job_spec.rb +9 -17
  149. data/spec/canvas_sync/jobs/report_checker_spec.rb +1 -3
  150. data/spec/canvas_sync/jobs/report_processor_job_spec.rb +0 -3
  151. data/spec/canvas_sync/jobs/report_starter_spec.rb +19 -28
  152. data/spec/canvas_sync/jobs/sync_admins_job_spec.rb +1 -4
  153. data/spec/canvas_sync/jobs/sync_assignment_groups_job_spec.rb +2 -1
  154. data/spec/canvas_sync/jobs/sync_assignments_job_spec.rb +3 -2
  155. data/spec/canvas_sync/jobs/sync_content_migrations_job_spec.rb +30 -0
  156. data/spec/canvas_sync/jobs/sync_context_module_items_job_spec.rb +3 -2
  157. data/spec/canvas_sync/jobs/sync_context_modules_job_spec.rb +3 -2
  158. data/spec/canvas_sync/jobs/sync_provisioning_report_job_spec.rb +7 -41
  159. data/spec/canvas_sync/jobs/sync_roles_job_spec.rb +1 -4
  160. data/spec/canvas_sync/jobs/sync_simple_table_job_spec.rb +5 -12
  161. data/spec/canvas_sync/jobs/sync_submissions_job_spec.rb +8 -2
  162. data/spec/canvas_sync/jobs/sync_terms_job_spec.rb +1 -4
  163. data/spec/canvas_sync/live_events/live_event_sync_spec.rb +27 -0
  164. data/spec/canvas_sync/live_events/live_events_controller_spec.rb +54 -0
  165. data/spec/canvas_sync/live_events/process_event_job_spec.rb +38 -0
  166. data/spec/canvas_sync/misc_helper_spec.rb +58 -0
  167. data/spec/canvas_sync/models/assignment_spec.rb +1 -1
  168. data/spec/canvas_sync/processors/content_migrations_processor_spec.rb +13 -0
  169. data/spec/canvas_sync/processors/provisioning_report_processor_spec.rb +101 -1
  170. data/spec/canvas_sync/processors/rubric_assessments_spec.rb +16 -0
  171. data/spec/canvas_sync/processors/rubric_associations_spec.rb +16 -0
  172. data/spec/canvas_sync/processors/rubrics_processor_spec.rb +17 -0
  173. data/spec/dummy/app/models/account.rb +6 -0
  174. data/spec/dummy/app/models/admin.rb +2 -0
  175. data/spec/dummy/app/models/assignment.rb +3 -0
  176. data/spec/dummy/app/models/assignment_group.rb +3 -0
  177. data/spec/dummy/app/models/content_migration.rb +18 -0
  178. data/spec/dummy/app/models/context_module.rb +3 -0
  179. data/spec/dummy/app/models/context_module_item.rb +3 -0
  180. data/spec/dummy/app/models/course.rb +11 -0
  181. data/spec/dummy/app/models/course_nickname.rb +19 -0
  182. data/spec/dummy/app/models/enrollment.rb +14 -0
  183. data/spec/dummy/app/models/grading_period.rb +16 -0
  184. data/spec/dummy/app/models/grading_period_group.rb +15 -0
  185. data/spec/dummy/app/models/group.rb +2 -0
  186. data/spec/dummy/app/models/group_membership.rb +2 -0
  187. data/spec/dummy/app/models/learning_outcome.rb +30 -0
  188. data/spec/dummy/app/models/learning_outcome_result.rb +54 -0
  189. data/spec/dummy/app/models/pseudonym.rb +16 -0
  190. data/spec/dummy/app/models/role.rb +2 -0
  191. data/spec/dummy/app/models/rubric.rb +35 -0
  192. data/spec/dummy/app/models/rubric_assessment.rb +22 -0
  193. data/spec/dummy/app/models/rubric_association.rb +20 -0
  194. data/spec/dummy/app/models/section.rb +9 -0
  195. data/spec/dummy/app/models/submission.rb +4 -0
  196. data/spec/dummy/app/models/term.rb +3 -0
  197. data/spec/dummy/app/models/user.rb +11 -0
  198. data/spec/dummy/app/models/user_observer.rb +19 -0
  199. data/spec/dummy/app/services/live_events/assignment_event.rb +1 -1
  200. data/spec/dummy/app/services/live_events/course_event.rb +1 -3
  201. data/spec/dummy/app/services/live_events/course_section_event.rb +1 -1
  202. data/spec/dummy/app/services/live_events/enrollment_event.rb +1 -1
  203. data/spec/dummy/app/services/live_events/grade_event.rb +1 -1
  204. data/spec/dummy/app/services/live_events/module_event.rb +1 -1
  205. data/spec/dummy/app/services/live_events/module_item_event.rb +1 -1
  206. data/spec/dummy/app/services/live_events/submission_event.rb +1 -1
  207. data/spec/dummy/app/services/live_events/syllabus_event.rb +1 -1
  208. data/spec/dummy/app/services/live_events/user_event.rb +1 -3
  209. data/spec/dummy/config/environments/test.rb +2 -0
  210. data/spec/dummy/config/routes.rb +1 -0
  211. data/spec/dummy/db/migrate/20201016181346_create_pseudonyms.rb +24 -0
  212. data/spec/dummy/db/migrate/20210907233329_create_user_observers.rb +23 -0
  213. data/spec/dummy/db/migrate/20210907233330_create_grading_periods.rb +28 -0
  214. data/spec/dummy/db/migrate/20211001184920_create_grading_period_groups.rb +24 -0
  215. data/spec/dummy/db/migrate/20220308072643_create_content_migrations.rb +30 -0
  216. data/spec/dummy/db/migrate/20220712210559_create_learning_outcomes.rb +36 -0
  217. data/spec/dummy/db/migrate/{20190702203620_create_users.rb → 20220926221926_create_users.rb} +0 -1
  218. data/spec/dummy/db/migrate/20240408223326_create_course_nicknames.rb +23 -0
  219. data/spec/dummy/db/migrate/20240509105100_create_rubrics.rb +44 -0
  220. data/spec/dummy/db/migrate/20240510094100_create_rubric_associations.rb +42 -0
  221. data/spec/dummy/db/migrate/20240510101100_create_rubric_assessments.rb +37 -0
  222. data/spec/dummy/db/migrate/20240523101010_create_learning_outcome_results.rb +52 -0
  223. data/spec/dummy/db/schema.rb +244 -5
  224. data/spec/factories/user_factory.rb +0 -1
  225. data/spec/job_batching/active_job_spec.rb +107 -0
  226. data/spec/job_batching/batch_spec.rb +489 -0
  227. data/spec/job_batching/callback_spec.rb +38 -0
  228. data/spec/job_batching/context_hash_spec.rb +54 -0
  229. data/spec/job_batching/flow_spec.rb +82 -0
  230. data/spec/job_batching/integration/fail_then_succeed.rb +42 -0
  231. data/spec/job_batching/integration/integration.rb +57 -0
  232. data/spec/job_batching/integration/nested.rb +88 -0
  233. data/spec/job_batching/integration/simple.rb +47 -0
  234. data/spec/job_batching/integration/workflow.rb +134 -0
  235. data/spec/job_batching/integration_helper.rb +50 -0
  236. data/spec/job_batching/pool_spec.rb +161 -0
  237. data/spec/job_batching/sidekiq_spec.rb +125 -0
  238. data/spec/job_batching/status_spec.rb +76 -0
  239. data/spec/job_batching/support/base_job.rb +14 -0
  240. data/spec/job_batching/support/sample_callback.rb +2 -0
  241. data/spec/spec_helper.rb +17 -0
  242. data/spec/support/fixtures/reports/content_migrations.csv +3 -0
  243. data/spec/support/fixtures/reports/course_nicknames.csv +3 -0
  244. data/spec/support/fixtures/reports/grading_period_groups.csv +2 -0
  245. data/spec/support/fixtures/reports/grading_periods.csv +3 -0
  246. data/spec/support/fixtures/reports/learning_outcome_results.csv +3 -0
  247. data/spec/support/fixtures/reports/learning_outcomes.csv +3 -0
  248. data/spec/support/fixtures/reports/provisioning_csv_unzipped/courses.csv +3 -0
  249. data/spec/support/fixtures/reports/provisioning_csv_unzipped/users.csv +4 -0
  250. data/spec/support/fixtures/reports/rubric_assessments.csv +3 -0
  251. data/spec/support/fixtures/reports/rubric_associations.csv +3 -0
  252. data/spec/support/fixtures/reports/rubrics.csv +3 -0
  253. data/spec/support/fixtures/reports/user_observers.csv +3 -0
  254. data/spec/support/fixtures/reports/users.csv +3 -2
  255. data/spec/support/fixtures/reports/xlist.csv +1 -1
  256. metadata +329 -27
  257. data/app/controllers/api/v1/live_events_controller.rb +0 -18
  258. data/lib/canvas_sync/job_chain.rb +0 -57
  259. data/lib/canvas_sync/jobs/fork_gather.rb +0 -59
  260. data/spec/canvas_sync/jobs/fork_gather_spec.rb +0 -73
@@ -10,6 +10,32 @@ RSpec.describe CanvasSync::Processors::ProvisioningReportProcessor do
10
10
  }.to change { User.count }.by(2)
11
11
  end
12
12
 
13
+ context "with User#sis_id column" do
14
+ before do
15
+ self.use_transactional_tests = false
16
+ ActiveRecord::Migration.add_column :users, :sis_id, :string
17
+ User.reset_column_information
18
+ User.instance_variable_set(:@schema_columns_hash, nil)
19
+ end
20
+
21
+ after do
22
+ ActiveRecord::Migration.remove_column :users, :sis_id
23
+ User.reset_column_information
24
+ User.instance_variable_set(:@schema_columns_hash, nil)
25
+ self.use_transactional_tests = true
26
+ end
27
+
28
+ it 'uses keeps support with old installations' do
29
+ subject.process('spec/support/fixtures/reports/users.csv', { models: ['users'] }, 1)
30
+ expect(User.find_by(canvas_id: 2).sis_id).to eq 'sis_id_2'
31
+ end
32
+
33
+ it 'uses a User row with a sis_id' do
34
+ subject.process('spec/support/fixtures/reports/users.csv', { models: ['users'] }, 1)
35
+ expect(User.find_by(canvas_id: 2).sis_id).to eq 'sis_id_2'
36
+ end
37
+ end
38
+
13
39
  it 'processes courses' do
14
40
  expect {
15
41
  subject.process('spec/support/fixtures/reports/courses.csv', { models: ['courses'] }, 1)
@@ -35,11 +61,18 @@ RSpec.describe CanvasSync::Processors::ProvisioningReportProcessor do
35
61
  end
36
62
 
37
63
  it 'processes xlist' do
64
+ subject.process('spec/support/fixtures/reports/sections.csv', { models: ['sections'] }, 1)
65
+ expect(Section.find_by(canvas_id: 2).name).to eq "Lame Section"
66
+
38
67
  subject.process('spec/support/fixtures/reports/xlist.csv', { models: ['xlist'] }, 1)
68
+
39
69
  expect(Section.where.not(canvas_nonxlist_course_id: nil).count).to eq 1
40
70
  cross_listed_section = Section.where.not(canvas_nonxlist_course_id: nil).first
41
71
  expect(cross_listed_section.canvas_id).to eq 2
42
- expect(cross_listed_section.canvas_nonxlist_course_id).to eq 2
72
+ expect(cross_listed_section.canvas_nonxlist_course_id).to eq 3
73
+
74
+ expect(cross_listed_section.canvas_course_id).to eq 2
75
+ expect(cross_listed_section.name).to eq "Lame Section"
43
76
  end
44
77
 
45
78
  it 'processes groups' do
@@ -62,6 +95,73 @@ RSpec.describe CanvasSync::Processors::ProvisioningReportProcessor do
62
95
  expect(group.canvas_user_id).to eq 10
63
96
  end
64
97
 
98
+ it 'processes user_observers' do
99
+ expect {
100
+ subject.process('spec/support/fixtures/reports/user_observers.csv', { models: ['user_observers'] }, 1)
101
+ }.to change { UserObserver.count }.by(2)
102
+ obj = UserObserver.find_by(observed_user_id: 3)
103
+ expect(obj.workflow_state).to eq 'active'
104
+ expect(obj.observing_user_id).to eq 21
105
+ end
106
+
107
+ it 'processes grading_periods' do
108
+ expect {
109
+ subject.process('spec/support/fixtures/reports/grading_periods.csv', { models: ['grading_periods'] }, 1)
110
+ }.to change { GradingPeriod.count }.by(2)
111
+ obj = GradingPeriod.find_by(canvas_id: 1)
112
+ puts obj.inspect
113
+ expect(obj.title).to eq 'Period 1'
114
+ expect(obj.weight).to eq 0.2
115
+ expect(obj.workflow_state).to eq 'active'
116
+ end
117
+
118
+ it 'processes grading_period_groups' do
119
+ expect {
120
+ subject.process('spec/support/fixtures/reports/grading_period_groups.csv', { models: ['grading_period_groups'] }, 1)
121
+ }.to change { GradingPeriodGroup.count }.by(1)
122
+ obj = GradingPeriodGroup.find_by(canvas_id: 1)
123
+ puts obj.inspect
124
+ expect(obj.title).to eq 'Test Group'
125
+ expect(obj.workflow_state).to eq 'active'
126
+ end
127
+
128
+ it 'processes learning_outcomes' do
129
+ expect {
130
+ subject.process('spec/support/fixtures/reports/learning_outcomes.csv', { models: ['learning_outcomes'] }, 1)
131
+ }.to change { LearningOutcome.count }.by(2)
132
+ end
133
+
134
+ it 'processes learning_outcome_results' do
135
+ expect {
136
+ subject.process('spec/support/fixtures/reports/learning_outcome_results.csv', { models: ['learning_outcome_results'] }, 1)
137
+ }.to change { LearningOutcomeResult.count }.by(2)
138
+
139
+ columns = LearningOutcomeResult.attribute_names - ['id', 'created_at', 'updated_at']
140
+ expect(LearningOutcomeResult.all.pluck(columns.join(','))).to eq([
141
+ [1, 1, 'Course', 1, 'RubricAssociation', 1, 1, 1, true, true, 1, 'RubricAssessment', '2012-01-01T00:00:00Z', 'Learning Outcome Result 1', 1.0, 1, 'LearningOutcomeGroup', 1, 5.0, 5.0, 5.0, 5.0, 'active'],
142
+ [2, 2, 'Course', 2, 'RubricAssociation', 2, 2, 2, true, true, 2, 'RubricAssessment', '2013-01-01T00:00:00Z', 'Learning Outcome Result 2', 2.0, 2, 'LearningOutcomeGroup', 1, 10.0, 10.0, 10.0, 10.0, 'active']
143
+ ])
144
+ end
145
+
146
+ it 'processes course_nicknames' do
147
+ CourseNickname.create(canvas_user_preference_value_id: 42, canvas_course_id: 42, canvas_user_id: 42, nickname: 'test')
148
+ expect(CourseNickname.all.pluck(:canvas_user_preference_value_id)).to include(42)
149
+ expect {
150
+ subject.process('spec/support/fixtures/reports/course_nicknames.csv', { models: ['course_nicknames'] }, 1)
151
+ }.to change { CourseNickname.count }.by(1)
152
+ expect(CourseNickname.all.pluck(:canvas_user_preference_value_id)).not_to include(42)
153
+ end
154
+
155
+ it 'model with composite key behaves as expected' do
156
+ expect {
157
+ subject.process('spec/support/fixtures/reports/user_observers.csv', { models: ['user_observers'] }, 1)
158
+ }.to change { UserObserver.count }.by(2)
159
+
160
+ expect {
161
+ subject.process('spec/support/fixtures/reports/user_observers.csv', { models: ['user_observers'] }, 1)
162
+ }.to change { UserObserver.count }.by(0)
163
+ end
164
+
65
165
  context 'options[:models] is multiple models' do
66
166
  it 'extracts the ZIP and processes each model' do
67
167
  user_count = User.count
@@ -0,0 +1,16 @@
1
+ require "spec_helper"
2
+
3
+ RSpec.describe CanvasSync::Processors::RubricAssessmentsProcessor do
4
+ let(:subject) { CanvasSync::Processors::RubricAssessmentsProcessor }
5
+
6
+ describe "#process" do
7
+ it 'processes rubric assessments' do
8
+ expect {
9
+ subject.process('spec/support/fixtures/reports/rubric_assessments.csv', { models: ['rubric_assessments'] }, 1)
10
+ }.to change { RubricAssessment.count }.by(2)
11
+ rubric_assessment = RubricAssessment.first
12
+ expect(rubric_assessment.canvas_rubric_association_id).to eq(1)
13
+ expect(rubric_assessment.score).to eq(10)
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ require "spec_helper"
2
+
3
+ RSpec.describe CanvasSync::Processors::RubricAssociationsProcessor do
4
+ let(:subject) { CanvasSync::Processors::RubricAssociationsProcessor }
5
+
6
+ describe "#process" do
7
+ it 'processes rubric associations' do
8
+ expect {
9
+ subject.process('spec/support/fixtures/reports/rubric_associations.csv', { models: ['rubric_associations'] }, 1)
10
+ }.to change { RubricAssociation.count }.by(2)
11
+ rubric_association = RubricAssociation.first
12
+ expect(rubric_association.title).to eq("Rubric Association Title")
13
+ expect(rubric_association.summary_data).to eq("Rubric Association Summary Data")
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,17 @@
1
+ require "spec_helper"
2
+
3
+ RSpec.describe CanvasSync::Processors::RubricsProcessor do
4
+ let(:subject) { CanvasSync::Processors::RubricsProcessor }
5
+
6
+ describe "#process" do
7
+ it 'inserts rubrics' do
8
+ expect {
9
+ subject.process('spec/support/fixtures/reports/rubrics.csv', { models: ['rubrics'] }, 1)
10
+ }.to change { Rubric.count }.by(2)
11
+ rubric = Rubric.first
12
+ expect(rubric.title).to eq("Assignment 1")
13
+ expect(rubric.description).to eq("Assignment 1 description")
14
+ end
15
+
16
+ end
17
+ end
@@ -10,6 +10,9 @@ class Account < ApplicationRecord
10
10
  include CanvasSync::Record
11
11
  include CanvasSync::Concerns::ApiSyncable
12
12
  # include CanvasSync::Concerns::Account::Ancestry # Add support for the ancestry Gem
13
+ # include CanvasSync::Concerns::LiveEventSync
14
+
15
+ canvas_sync_features :defaults
13
16
 
14
17
  validates :canvas_id, uniqueness: true, presence: true
15
18
 
@@ -20,6 +23,9 @@ class Account < ApplicationRecord
20
23
  primary_key: :canvas_id, foreign_key: :canvas_parent_account_id
21
24
  has_many :groups, primary_key: :canvas_id, foreign_key: :canvas_account_id
22
25
 
26
+ scope :active, -> { where.not(workflow_state: 'deleted') }
27
+ # scope :should_canvas_sync, -> { active } # Optional - uses .active if not given
28
+
23
29
  api_syncable({
24
30
  name: :name,
25
31
  workflow_state: :workflow_state,
@@ -10,6 +10,8 @@ class Admin < ApplicationRecord
10
10
  include CanvasSync::Record
11
11
  include CanvasSync::Concerns::ApiSyncable
12
12
 
13
+ canvas_sync_features :defaults
14
+
13
15
  validates :canvas_id, uniqueness: true, presence: true
14
16
  belongs_to :account, primary_key: :canvas_id, foreign_key: :canvas_account_id, optional: true
15
17
  belongs_to :user, primary_key: :canvas_id, foreign_key: :canvas_user_id, optional: true
@@ -9,6 +9,9 @@
9
9
  class Assignment < ApplicationRecord
10
10
  include CanvasSync::Record
11
11
  include CanvasSync::Concerns::ApiSyncable
12
+ # include CanvasSync::Concerns::LiveEventSync
13
+
14
+ canvas_sync_features :defaults
12
15
 
13
16
  validates :canvas_id, uniqueness: true, presence: true
14
17
  belongs_to :context, polymorphic: true, optional: true, primary_key: :canvas_id, foreign_key: :canvas_context_id, foreign_type: :canvas_context_type
@@ -9,6 +9,9 @@
9
9
  class AssignmentGroup < ApplicationRecord
10
10
  include CanvasSync::Record
11
11
  include CanvasSync::Concerns::ApiSyncable
12
+ # include CanvasSync::Concerns::LiveEventSync
13
+
14
+ canvas_sync_features :defaults
12
15
 
13
16
  validates :canvas_id, uniqueness: true, presence: true
14
17
  belongs_to :course, primary_key: :canvas_id, foreign_key: :canvas_course_id, optional: true
@@ -0,0 +1,18 @@
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 ContentMigration < ApplicationRecord
10
+ include CanvasSync::Record
11
+ include CanvasSync::Concerns::ApiSyncable
12
+
13
+ canvas_sync_features :defaults
14
+
15
+ validates :canvas_id, uniqueness: true, presence: true
16
+ belongs_to :context, polymorphic: true, optional: true, primary_key: :canvas_id, foreign_key: :canvas_context_id, foreign_type: :canvas_context_type
17
+
18
+ end
@@ -12,6 +12,9 @@
12
12
  class ContextModule < ApplicationRecord
13
13
  include CanvasSync::Record
14
14
  include CanvasSync::Concerns::ApiSyncable
15
+ # include CanvasSync::Concerns::LiveEventSync
16
+
17
+ canvas_sync_features :defaults
15
18
 
16
19
  belongs_to :context, polymorphic: true, optional: true, primary_key: :canvas_id, foreign_key: :canvas_context_id, foreign_type: :canvas_context_type
17
20
  has_many :context_module_items, primary_key: :canvas_id, foreign_key: :canvas_context_module_id
@@ -9,6 +9,9 @@
9
9
  class ContextModuleItem < ApplicationRecord
10
10
  include CanvasSync::Record
11
11
  include CanvasSync::Concerns::ApiSyncable
12
+ # include CanvasSync::Concerns::LiveEventSync
13
+
14
+ canvas_sync_features :defaults
12
15
 
13
16
  belongs_to :context_module, primary_key: :canvas_id, foreign_key: :canvas_context_module_id, optional: true
14
17
  belongs_to :content, polymorphic: true, optional: true, primary_key: :canvas_id, foreign_key: :canvas_content_id, foreign_type: :canvas_content_type
@@ -10,6 +10,16 @@ class Course < ApplicationRecord
10
10
  include CanvasSync::Record
11
11
  include CanvasSync::Concerns::ApiSyncable
12
12
 
13
+ canvas_sync_features :defaults
14
+
15
+ # include CanvasSync::Concerns::LiveEventSync
16
+ # after_process_live_event do
17
+ # if account.nil?
18
+ # acc = Account.new(canvas_id: canvas_account_id)
19
+ # acc.sync_from_api
20
+ # end
21
+ # end
22
+
13
23
  validates :canvas_id, uniqueness: true, presence: true
14
24
  belongs_to :term, foreign_key: :canvas_term_id, primary_key: :canvas_id, optional: true
15
25
  has_many :enrollments, primary_key: :canvas_id, foreign_key: :canvas_course_id
@@ -18,6 +28,7 @@ class Course < ApplicationRecord
18
28
  has_many :submissions, primary_key: :canvas_id, foreign_key: :canvas_course_id
19
29
  has_many :assignment_groups, primary_key: :canvas_id, foreign_key: :canvas_course_id
20
30
  has_many :groups, primary_key: :canvas_id, foreign_key: :canvas_course_id
31
+ has_many :rubrics, as: :context, primary_key: :canvas_id, foreign_key: :canvas_context_id, foreign_type: :canvas_context_type
21
32
 
22
33
  api_syncable({
23
34
  sis_id: :sis_course_id,
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ # # #
4
+ # AUTO GENERATED MIGRATION
5
+ # This migration was auto generated by the CanvasSync Gem.
6
+ # You can add new columns to this table, but removing or
7
+ # re-naming ones created here may break Canvas Syncing.
8
+ #
9
+
10
+
11
+ class CourseNickname < ApplicationRecord
12
+ include CanvasSync::Record
13
+ include CanvasSync::Concerns::ApiSyncable
14
+
15
+ canvas_sync_features :defaults
16
+
17
+ belongs_to :user, primary_key: :canvas_id, foreign_key: :canvas_user_id, optional: true
18
+ belongs_to :course, primary_key: :canvas_id, foreign_key: :canvas_course_id, optional: true
19
+ end
@@ -10,6 +10,20 @@ class Enrollment < ApplicationRecord
10
10
  include CanvasSync::Record
11
11
  include CanvasSync::Concerns::ApiSyncable
12
12
 
13
+ canvas_sync_features :defaults
14
+
15
+ # include CanvasSync::Concerns::LiveEventSync
16
+ # after_process_live_event do
17
+ # if user.nil?
18
+ # u = User.new(canvas_id: canvas_user_id)
19
+ # u.sync_from_api
20
+ # end
21
+ # if course.nil?
22
+ # c = Course.new(canvas_id: canvas_course_id)
23
+ # c.sync_from_api
24
+ # end
25
+ # end
26
+
13
27
  validates :canvas_id, uniqueness: true, presence: true
14
28
  belongs_to :user, primary_key: :canvas_id, foreign_key: :canvas_user_id, optional: true
15
29
  belongs_to :role, primary_key: :canvas_id, foreign_key: :canvas_role_id, optional: true
@@ -0,0 +1,16 @@
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
+ canvas_sync_features :defaults
13
+
14
+ validates :canvas_id, uniqueness: true, presence: true
15
+ belongs_to :grading_period_group, primary_key: :canvas_id, foreign_key: :canvas_grading_period_group_id, optional: true
16
+ 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
+ canvas_sync_features :defaults
13
+
14
+ validates :canvas_id, uniqueness: true, presence: true
15
+ end
@@ -10,6 +10,8 @@ class Group < ApplicationRecord
10
10
  include CanvasSync::Record
11
11
  include CanvasSync::Concerns::ApiSyncable
12
12
 
13
+ canvas_sync_features :defaults
14
+
13
15
  validates :canvas_id, uniqueness: true, presence: true
14
16
  belongs_to :course, primary_key: :canvas_id, foreign_key: :canvas_course_id, optional: true
15
17
  belongs_to :account, primary_key: :canvas_id, foreign_key: :canvas_account_id, optional: true
@@ -10,6 +10,8 @@ class GroupMembership < ApplicationRecord
10
10
  include CanvasSync::Record
11
11
  include CanvasSync::Concerns::ApiSyncable
12
12
 
13
+ canvas_sync_features :defaults
14
+
13
15
  validates :canvas_id, uniqueness: true, presence: true
14
16
  belongs_to :group, primary_key: :canvas_id, foreign_key: :canvas_group_id
15
17
  belongs_to :user, primary_key: :canvas_id, foreign_key: :canvas_user_id
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ # # #
4
+ # AUTO GENERATED MIGRATION
5
+ # This migration was auto generated by the CanvasSync Gem.
6
+ # You can add new columns to this table, but removing or
7
+ # re-naming ones created here may break Canvas Syncing.
8
+ #
9
+
10
+
11
+ class LearningOutcome < ApplicationRecord
12
+ include CanvasSync::Record
13
+ include CanvasSync::Concerns::ApiSyncable
14
+
15
+ canvas_sync_features :defaults
16
+
17
+ belongs_to :context, polymorphic: true, optional: true, primary_key: :canvas_id, foreign_key: :canvas_context_id, foreign_type: :canvas_context_type
18
+
19
+ api_syncable({
20
+ canvas_id: :id,
21
+ canvas_context_id: :context_id,
22
+ canvas_context_type: :context_type,
23
+ name: :title,
24
+ friendly_name: :display_name,
25
+ vendor_guid: :vendor_guid,
26
+ calculation_method: :calculation_method,
27
+ calculation_int: :calculation_int,
28
+ description: :description
29
+ }, ->(api) { api.get("/api/v1/outcomes/#{canvas_id}") })
30
+ end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ # # #
4
+ # AUTO GENERATED MIGRATION
5
+ # This migration was auto generated by the CanvasSync Gem.
6
+ # You can add new columns to this table, but removing or
7
+ # re-naming ones created here may break Canvas Syncing.
8
+ #
9
+
10
+
11
+ class LearningOutcomeResult < ActiveRecord::Base
12
+ include CanvasSync::Record
13
+ include CanvasSync::Concerns::ApiSyncable
14
+
15
+ belongs_to :user, primary_key: :canvas_id, foreign_key: :canvas_user_id, optional: true
16
+ belongs_to :learning_outcome, primary_key: :canvas_id, foreign_key: :canvas_learning_outcome_id, optional: true
17
+ belongs_to :alignment, class_name: "ContentTag", primary_key: :canvas_id, foreign_key: :canvas_content_tag_id, optional: true
18
+ belongs_to :association_object,
19
+ polymorphic: [:rubric_association, :assignment],
20
+ foreign_key: :association_id,
21
+ foreign_type: :association_type,
22
+ optional: true
23
+ belongs_to :artifact,
24
+ polymorphic: [:rubric_assessment, :submission],
25
+ primary_key: :canvas_artifact_id,
26
+ foreign_key: :canvas_artifact_id,
27
+ foreign_type: :canvas_artifact_type,
28
+ optional: true
29
+
30
+ belongs_to :context, polymorphic: [:course], primary_key: :canvas_id, foreign_key: :canvas_context_id, foreign_type: :canvas_context_type, optional: true
31
+
32
+ # Not yet implemented in CanvasSync
33
+ # belongs_to :associated_asset,
34
+ # polymorphic:
35
+ # [:assessment_question,
36
+ # :assignment,
37
+ # { quiz: "Quizzes::Quiz", assessment: "LiveAssessments::Assessment" }],
38
+ # polymorphic_prefix: true
39
+
40
+ # Not yet implemented in CanvasSync
41
+ # has_many :learning_outcome_question_results, dependent: :destroy
42
+
43
+ api_syncable({
44
+ canvas_id: :id,
45
+ canvas_content_tag_id: :links&.[]("alignment"),
46
+ canvas_learning_outcome_id: :links&.[]("learning_outcome"),
47
+ canvas_user_id: :links&.[]("user"),
48
+ score: :score,
49
+ assessed_at: :submitted_or_assessed_at,
50
+ percent: :percent
51
+ }, ->(api) {
52
+ api.get("/api/v1/courses/#{self.canvas_context_id}/#{self.canvas_id}")&.find { |item| item[:id] == self.canvas_id }
53
+ })
54
+ end
@@ -0,0 +1,16 @@
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 Pseudonym < ApplicationRecord
10
+ include CanvasSync::Record
11
+
12
+ canvas_sync_features :defaults
13
+
14
+ validates :canvas_id, uniqueness: true, presence: true
15
+ belongs_to :user, primary_key: :canvas_id, foreign_key: :canvas_user_id
16
+ end
@@ -10,6 +10,8 @@ class Role < ApplicationRecord
10
10
  include CanvasSync::Record
11
11
  include CanvasSync::Concerns::ApiSyncable
12
12
 
13
+ canvas_sync_features :defaults
14
+
13
15
  validates :canvas_id, uniqueness: true, presence: true
14
16
  has_many :admins, foreign_key: :canvas_role_id, primary_key: :canvas_id
15
17
 
@@ -0,0 +1,35 @@
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 Rubric < ApplicationRecord
10
+ include CanvasSync::Record
11
+ include CanvasSync::Concerns::ApiSyncable
12
+
13
+ canvas_sync_features :defaults
14
+
15
+ validates :canvas_id, uniqueness: true, presence: true
16
+ belongs_to :user, primary_key: :canvas_id, foreign_key: :canvas_user_id, optional: true
17
+ belongs_to :rubric, primary_key: :canvas_id, foreign_key: :canvas_rubric_id , optional: true # based on another rubric
18
+ belongs_to :context, polymorphic: true, primary_key: :canvas_id, foreign_key: :canvas_context_id, foreign_type: :canvas_context_type, optional: true
19
+
20
+ has_many :rubric_associations, primary_key: :canvas_id, foreign_key: :canvas_association_id, foreign_type: :canvas_association_type
21
+ has_many :rubric_assessments, through: :rubric_associations, dependent: :destroy
22
+
23
+ api_syncable({
24
+ canvas_id: :id,
25
+ title: :title,
26
+ canvas_context_id: :context_id,
27
+ canvas_context_type: :context_type,
28
+ points_possible: :points_possible,
29
+ reusable: :reusable,
30
+ read_only: :read_only,
31
+ free_form_criterion_comments: :free_form_criterion_comments,
32
+ hide_score_total: :hide_score_total,
33
+ data: :data,
34
+ }, -> (api) { api.get("api/v1/accounts/#{canvas_root_account_id}/rubrics/#{canvas_id}") })
35
+ end
@@ -0,0 +1,22 @@
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 RubricAssessment < ApplicationRecord
10
+ include CanvasSync::Record
11
+
12
+ canvas_sync_features :defaults
13
+
14
+ validates :canvas_id, uniqueness: true, presence: true
15
+
16
+ belongs_to :rubric, primary_key: :canvas_id, foreign_key: :canvas_rubric_id, optional: true
17
+ belongs_to :rubric_association, primary_key: :canvas_id, foreign_key: :canvas_rubric_association_id, optional: true
18
+ belongs_to :user, primary_key: :canvas_id, foreign_key: :canvas_user_id, optional: true
19
+ belongs_to :assessor, class_name: "User", primary_key: :canvas_id, foreign_key: :canvas_assessor_id, optional: true
20
+ belongs_to :artifact, polymorphic: true, primary_key: :canvas_id, foreign_type: :canvas_artifact_type, foreign_key: :canvas_artifact_id, optional: true
21
+
22
+ end
@@ -0,0 +1,20 @@
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 RubricAssociation < ApplicationRecord
10
+ include CanvasSync::Record
11
+
12
+ canvas_sync_features :defaults
13
+
14
+ validates :canvas_id, uniqueness: true, presence: true
15
+ belongs_to :rubric, primary_key: :canvas_id, foreign_key: :canvas_rubric_id, optional: true
16
+ belongs_to :association_object, polymorphic: true, primary_key: :canvas_id, foreign_type: :canvas_association_type, foreign_key: :canvas_association_id, optional: true
17
+ belongs_to :context, polymorphic: true, primary_key: :canvas_id, foreign_key: :canvas_context_id, foreign_type: :canvas_context_type, optional: true
18
+
19
+ has_many :rubric_assessments
20
+ end
@@ -10,6 +10,15 @@ class Section < ApplicationRecord
10
10
  include CanvasSync::Record
11
11
  include CanvasSync::Concerns::ApiSyncable
12
12
 
13
+ canvas_sync_features :defaults
14
+
15
+ # include CanvasSync::Concerns::LiveEventSync
16
+ # after_process_live_event do
17
+ # # A section change could constitute a crosslisting change, which means
18
+ # # we need to make sure all our enrollments are pointing to the correct course
19
+ # enrollments.update_all(canvas_course_id: canvas_course_id)
20
+ # end
21
+
13
22
  validates :canvas_id, uniqueness: true, presence: true
14
23
  belongs_to :course, primary_key: :canvas_id, foreign_key: :canvas_course_id, optional: true
15
24
  has_many :enrollments, primary_key: :canvas_id, foreign_key: :canvas_section_id
@@ -9,6 +9,9 @@
9
9
  class Submission < ApplicationRecord
10
10
  include CanvasSync::Record
11
11
  include CanvasSync::Concerns::ApiSyncable
12
+ # include CanvasSync::Concerns::LiveEventSync
13
+
14
+ canvas_sync_features :defaults
12
15
 
13
16
  validates :canvas_id, uniqueness: true, presence: true
14
17
  belongs_to :assignment, primary_key: :canvas_id, foreign_key: :canvas_assignment_id, optional: true
@@ -20,6 +23,7 @@ class Submission < ApplicationRecord
20
23
  canvas_user_id: :user_id,
21
24
  submitted_at: :submitted_at,
22
25
  graded_at: :graded_at,
26
+ cached_due_date: :due_at,
23
27
  score: :score,
24
28
  excused: :excused,
25
29
  workflow_state: :workflow_state,
@@ -10,8 +10,11 @@ class Term < ApplicationRecord
10
10
  include CanvasSync::Record
11
11
  include CanvasSync::Concerns::ApiSyncable
12
12
 
13
+ canvas_sync_features :defaults
14
+
13
15
  validates :canvas_id, uniqueness: true, presence: true
14
16
  has_many :courses, foreign_key: :canvas_term_id, primary_key: :canvas_id
17
+ belongs_to :grading_period_group, primary_key: :canvas_id, foreign_key: :grading_period_group_id, optional: true
15
18
 
16
19
  api_syncable({
17
20
  canvas_id: :id,
@@ -10,7 +10,18 @@ class User < ApplicationRecord
10
10
  include CanvasSync::Record
11
11
  include CanvasSync::Concerns::ApiSyncable
12
12
 
13
+ canvas_sync_features :defaults
14
+
15
+ # include CanvasSync::Concerns::LiveEventSync
16
+ # around_process_live_event do |user, blk|
17
+ # blk.call
18
+ # rescue Footrest::HttpError::Unauthorized => e
19
+ # # This can happen when a new user is created, but hasn't setup a login on Canvas yet.
20
+ # Rails.logger.info("Failed to fetch user #{canvas_user_id}: #{e.backtrace}")
21
+ # end
22
+
13
23
  validates :canvas_id, uniqueness: true, presence: true
24
+ has_many :pseudonyms, primary_key: :canvas_id, foreign_key: :canvas_user_id
14
25
  has_many :enrollments, primary_key: :canvas_id, foreign_key: :canvas_user_id
15
26
  has_many :admins, primary_key: :canvas_id, foreign_key: :canvas_user_id
16
27
  has_many :admin_roles, through: :admins, source: :role