canvas_sync 0.3.6 → 0.3.7

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 54bb6b7603e9eb4a7f2fbc7d88fa6354c2cd52bc23a840ba78c6400d963566c7
4
- data.tar.gz: 1028c665074ab1bea726ca6e9f5e33540678b6779b8246588339130a96be1584
3
+ metadata.gz: 909d10005caebf8b944e5a2974c3ce652b6258d7cf09fe20927a56a5075e3ed8
4
+ data.tar.gz: b529e9db0073aecedfdc66d254b3671fac73385cf29f2e9eee3e1c975afffa58
5
5
  SHA512:
6
- metadata.gz: 1d70812e869e445f11c21339dfb82df08cf01c68ff807009871bfe1604c2608bde446578202a7b01f92f1faea9b01f85bed0cca1f60eae856530edbecbe86eb2
7
- data.tar.gz: da8887bdf95dc211ee9f8e32c2dd1751476c464526efc9e69f6eba5c93d73c9796442312c6b3d04c074315114211cc1fc8da5557d8fa677829867efb53423843
6
+ metadata.gz: 0f9a6dc8f671dae6cfbeb5bc274e8656393a4c22e3dd462e4a6c778e5262f592a47c6d09c0117f0edfd7f70b7cd2cf808f813451861527e9236df745b1290186
7
+ data.tar.gz: 51eb712ce9a987295d99711e507b25112f31adaadf6cbc4932978f697786fbe4f92f59e2ce9ebd2414d4efb9f8e979c9c5fde5c0267c12d632e448dc6fe8b5b3
data/lib/canvas_sync.rb CHANGED
@@ -10,19 +10,20 @@ require "canvas_sync/jobs/sync_provisioning_report_job"
10
10
  require "canvas_sync/jobs/sync_terms_job"
11
11
  require "canvas_sync/jobs/sync_users_job"
12
12
  require "canvas_sync/jobs/sync_roles_job"
13
+ require "canvas_sync/jobs/sync_admins_job"
13
14
 
14
15
  Dir[File.dirname(__FILE__) + "/canvas_sync/processors/*.rb"].each {|file| require file }
15
16
  Dir[File.dirname(__FILE__) + "/canvas_sync/importers/*.rb"].each {|file| require file }
16
17
  Dir[File.dirname(__FILE__) + "/canvas_sync/generators/*.rb"].each {|file| require file }
17
18
 
18
19
  module CanvasSync
19
- SUPPORTED_MODELS = %w(users courses terms enrollments sections roles)
20
+ SUPPORTED_MODELS = %w(users courses terms enrollments sections roles admins)
20
21
  SUPPORTED_LIVE_EVENTS = %w(course enrollment submission assignment user syllabus grade)
21
22
 
22
23
  # Runs a standard provisioning sync job with no extra report types.
23
- # Terms will be synced first using the API. If you are syncing users/roles
24
- # and have also specified a Term scope, Users/Roles will by synced first, before
25
- # every other model (as Users/Roles are never scoped to Term).
24
+ # Terms will be synced first using the API. If you are syncing users/roles/admins
25
+ # and have also specified a Term scope, Users/Roles/Admins will by synced first, before
26
+ # every other model (as Users/Roles/Admins are never scoped to Term).
26
27
  #
27
28
  # @param models [Array<String>] A list of models to sync. e.g., ['users', 'courses'].
28
29
  # must be one of SUPPORTED_MODELS
@@ -65,7 +66,7 @@ module CanvasSync
65
66
  next_job_class.perform_later(duped_job_chain, next_job[:options])
66
67
  end
67
68
 
68
- # Syncs terms, users/roles if necessary, then the rest of the specified models.
69
+ # Syncs terms, users/roles/admins if necessary, then the rest of the specified models.
69
70
  #
70
71
  # @param models [Array<String>]
71
72
  # @param term_scope [String]
@@ -94,6 +95,12 @@ module CanvasSync
94
95
  models = models - ['roles']
95
96
  end
96
97
 
98
+ if models.include?('admins')
99
+ # Sync all admins first when scoping by term, because admins cannot be scoped to term
100
+ jobs.push({ job: CanvasSync::Jobs::SyncAdminsJob.to_s, options: {} })
101
+ models = models - ['admins']
102
+ end
103
+
97
104
  jobs.push({ job: CanvasSync::Jobs::SyncProvisioningReportJob.to_s, options: { term_scope: term_scope, models: models } })
98
105
 
99
106
  global_options = { legacy_support: legacy_support }
@@ -0,0 +1,20 @@
1
+ <%= autogenerated_model_warning %>
2
+
3
+ class Admin < ApplicationRecord
4
+ validates :canvas_admin_id, uniqueness: true, presence: true
5
+ belongs_to :user, primary_key: :canvas_user_id, foreign_key: :canvas_user_id, optional: true
6
+ belongs_to :role, primary_key: :canvas_role_id, foreign_key: :canvas_role_id, optional: true
7
+
8
+ def self.create_or_update(admin_params)
9
+ admin = Admin.find_or_initialize_by(canvas_admin_id: admin_params['id'])
10
+
11
+ admin.assign_attributes(role_name: admin_params['role'],
12
+ canvas_role_id: admin_params['role_id'],
13
+ user_data: admin_params['user'],
14
+ canvas_user_id: admin_params['user']['id'],
15
+ workflow_state: admin_params['workflow_state'])
16
+
17
+ admin.save! if admin.changed?
18
+ admin
19
+ end
20
+ end
@@ -0,0 +1,17 @@
1
+ <%= autogenerated_migration_warning %>
2
+
3
+ class CreateAdmins < ActiveRecord::Migration[5.1]
4
+ def change
5
+ create_table :admins do |t|
6
+ t.bigint :canvas_admin_id, null: false
7
+ t.string :role_name
8
+ t.bigint :canvas_role_id, null: false
9
+ t.json :user_data
10
+ t.bigint :canvas_user_id, null: false
11
+ t.string :workflow_state, null: false
12
+
13
+ t.timestamps
14
+ end
15
+ add_index :admins, :canvas_admin_id, unique: true
16
+ end
17
+ end
@@ -2,6 +2,7 @@
2
2
 
3
3
  class Role < ApplicationRecord
4
4
  validates :canvas_role_id, uniqueness: true, presence: true
5
+ has_many :admins, foreign_key: :canvas_role_id, primary_key: :canvas_role_id
5
6
 
6
7
  def self.create_or_update(role_params)
7
8
  role = Role.find_or_initialize_by(canvas_role_id: role_params['id'])
@@ -3,4 +3,6 @@
3
3
  class User < ApplicationRecord
4
4
  validates :canvas_user_id, uniqueness: true, presence: true
5
5
  has_many :enrollments, primary_key: :canvas_user_id, foreign_key: :canvas_user_id
6
+ has_many :admins, foreign_key: :canvas_user_id, primary_key: :canvas_user_id
7
+ has_many :admin_roles, through: :admins, source: :role
6
8
  end
@@ -0,0 +1,18 @@
1
+ module CanvasSync
2
+ module Jobs
3
+ class SyncAdminsJob < CanvasSync::Job
4
+ # Syncs Admins using the Canvas API
5
+ #
6
+ #
7
+ # @param job_chain [Hash]
8
+ # @param options [Hash]
9
+ def perform(job_chain, options)
10
+ CanvasSync.get_canvas_sync_client(job_chain[:global_options]).account_admins('self').all_pages!.each do |admin_params|
11
+ Admin.create_or_update(admin_params)
12
+ end
13
+
14
+ CanvasSync.invoke_next(job_chain)
15
+ end
16
+ end
17
+ end
18
+ end
@@ -1,3 +1,3 @@
1
1
  module CanvasSync
2
- VERSION = '0.3.6'
2
+ VERSION = '0.3.7'
3
3
  end
@@ -78,6 +78,34 @@ RSpec.describe CanvasSync do
78
78
  })
79
79
  end
80
80
  end
81
+
82
+ context 'we are syncing admins with a term scope' do
83
+ it 'syncs the admins in a separate job that runs first' do
84
+ chain = CanvasSync.default_provisioning_report_chain(['admins', 'courses'], :active)
85
+ expect(chain).to eq({
86
+ jobs: [
87
+ { job: CanvasSync::Jobs::SyncTermsJob.to_s, options: {} },
88
+ { job: CanvasSync::Jobs::SyncAdminsJob.to_s, options: {} },
89
+ { job: CanvasSync::Jobs::SyncProvisioningReportJob.to_s, options: { term_scope: 'active', models: ['courses'] } }
90
+ ],
91
+ global_options: { legacy_support: false }
92
+ })
93
+ end
94
+ end
95
+
96
+ context 'we are syncing admins without a term scope' do
97
+ it 'syncs admins separately even with no term scope' do
98
+ chain = CanvasSync.default_provisioning_report_chain(['admins', 'courses'])
99
+ expect(chain).to eq({
100
+ jobs: [
101
+ { job: CanvasSync::Jobs::SyncTermsJob.to_s, options: {} },
102
+ { job: CanvasSync::Jobs::SyncAdminsJob.to_s, options: {} },
103
+ { job: CanvasSync::Jobs::SyncProvisioningReportJob.to_s, options: { term_scope: nil, models: ['courses'] } }
104
+ ],
105
+ global_options: { legacy_support: false }
106
+ })
107
+ end
108
+ end
81
109
  end
82
110
  end
83
111
  end
@@ -0,0 +1,16 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe CanvasSync::Jobs::SyncAdminsJob do
4
+ describe '#perform' do
5
+ let(:admin_params) { open_canvas_fixture('admins') }
6
+ let(:job_chain) { { jobs: [], global_options: {}} }
7
+
8
+ it 'retrieves all terms from the Canvas API and then invokes the next job' do
9
+ expect(CanvasSync).to receive(:invoke_next).with(job_chain)
10
+
11
+ expect {
12
+ CanvasSync::Jobs::SyncAdminsJob.perform_now(job_chain, {})
13
+ }.to change { Admin.count }.by(admin_params.length)
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,46 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe Admin, type: :model do
4
+ let(:subject) { FactoryGirl.create(:admin) }
5
+
6
+ describe 'validations' do
7
+ it { should validate_presence_of(:canvas_admin_id) }
8
+ it { should validate_uniqueness_of(:canvas_admin_id) }
9
+ end
10
+
11
+ describe '.create_or_update' do
12
+ let(:admin_params) { open_canvas_fixture('admins')[0] }
13
+
14
+ context 'the admin does not already exist' do
15
+ it 'creates it' do
16
+ expect {
17
+ Admin.create_or_update(admin_params)
18
+ }.to change { Admin.count }.by(1)
19
+
20
+ admin = Admin.last
21
+ expect(admin.role_name).to eq(admin_params['role'])
22
+ expect(admin.canvas_role_id).to eq(admin_params['role_id'])
23
+ expect(admin.user_data).to eq(admin_params['user'])
24
+ expect(admin.canvas_user_id).to eq(admin_params['user']['id'])
25
+ expect(admin.workflow_state).to eq(admin_params['workflow_state'])
26
+ end
27
+ end
28
+
29
+ context 'the admin already exists' do
30
+ let!(:existing_admin) { FactoryGirl.create(:admin, canvas_admin_id: admin_params['id']) }
31
+
32
+ it 'updates it' do
33
+ expect {
34
+ Admin.create_or_update(admin_params)
35
+ }.to_not change { Admin.count }
36
+
37
+ existing_admin.reload
38
+ expect(existing_admin.role_name).to eq(admin_params['role'])
39
+ expect(existing_admin.canvas_role_id).to eq(admin_params['role_id'])
40
+ expect(existing_admin.user_data).to eq(admin_params['user'])
41
+ expect(existing_admin.canvas_user_id).to eq(admin_params['user']['id'])
42
+ expect(existing_admin.workflow_state).to eq(admin_params['workflow_state'])
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,26 @@
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 Admin < ApplicationRecord
10
+ validates :canvas_admin_id, uniqueness: true, presence: true
11
+ belongs_to :user, primary_key: :canvas_user_id, foreign_key: :canvas_user_id, optional: true
12
+ belongs_to :role, primary_key: :canvas_role_id, foreign_key: :canvas_role_id, optional: true
13
+
14
+ def self.create_or_update(admin_params)
15
+ admin = Admin.find_or_initialize_by(canvas_admin_id: admin_params['id'])
16
+
17
+ admin.assign_attributes(role_name: admin_params['role'],
18
+ canvas_role_id: admin_params['role_id'],
19
+ user_data: admin_params['user'],
20
+ canvas_user_id: admin_params['user']['id'],
21
+ workflow_state: admin_params['workflow_state'])
22
+
23
+ admin.save! if admin.changed?
24
+ admin
25
+ end
26
+ end
@@ -8,6 +8,7 @@
8
8
 
9
9
  class Role < ApplicationRecord
10
10
  validates :canvas_role_id, uniqueness: true, presence: true
11
+ has_many :admins, foreign_key: :canvas_role_id, primary_key: :canvas_role_id
11
12
 
12
13
  def self.create_or_update(role_params)
13
14
  role = Role.find_or_initialize_by(canvas_role_id: role_params['id'])
@@ -9,4 +9,6 @@
9
9
  class User < ApplicationRecord
10
10
  validates :canvas_user_id, uniqueness: true, presence: true
11
11
  has_many :enrollments, primary_key: :canvas_user_id, foreign_key: :canvas_user_id
12
+ has_many :admins, foreign_key: :canvas_user_id, primary_key: :canvas_user_id
13
+ has_many :admin_roles, through: :admins, source: :role
12
14
  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 CreateAdmins < ActiveRecord::Migration[5.1]
10
+ def change
11
+ create_table :admins do |t|
12
+ t.bigint :canvas_admin_id, null: false
13
+ t.string :role_name
14
+ t.bigint :canvas_role_id, null: false
15
+ t.json :user_data
16
+ t.bigint :canvas_user_id, null: false
17
+ t.string :workflow_state, null: false
18
+
19
+ t.timestamps
20
+ end
21
+ add_index :admins, :canvas_admin_id, unique: true
22
+ end
23
+ end
@@ -10,11 +10,23 @@
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: 20180103162102) do
13
+ ActiveRecord::Schema.define(version: 20180109210452) do
14
14
 
15
15
  # These are extensions that must be enabled in order to support this database
16
16
  enable_extension "plpgsql"
17
17
 
18
+ create_table "admins", force: :cascade do |t|
19
+ t.bigint "canvas_admin_id", null: false
20
+ t.string "role_name"
21
+ t.bigint "canvas_role_id", null: false
22
+ t.json "user_data"
23
+ t.bigint "canvas_user_id", null: false
24
+ t.string "workflow_state", null: false
25
+ t.datetime "created_at", null: false
26
+ t.datetime "updated_at", null: false
27
+ t.index ["canvas_admin_id"], name: "index_admins_on_canvas_admin_id", unique: true
28
+ end
29
+
18
30
  create_table "canvas_sync_job_logs", force: :cascade do |t|
19
31
  t.datetime "started_at"
20
32
  t.datetime "completed_at"
@@ -0,0 +1,10 @@
1
+ FactoryGirl.define do
2
+ factory :admin do
3
+ canvas_admin_id { SecureRandom.random_number(100_000_000) }
4
+ role_name 'Cool Role'
5
+ canvas_role_id { SecureRandom.random_number(100_000_000) }
6
+ user_data { "{ 'id': 1}" }
7
+ canvas_user_id 1
8
+ workflow_state 'active'
9
+ end
10
+ end
@@ -12,6 +12,10 @@ class FakeCanvas < Sinatra::Base
12
12
  json_response 200, 'roles.json'
13
13
  end
14
14
 
15
+ get '/api/v1/accounts/self/admins' do
16
+ json_response 200, 'admins.json'
17
+ end
18
+
15
19
  get '/sample_report_download' do
16
20
  json_response 200, 'terms.json'
17
21
  end
@@ -0,0 +1,50 @@
1
+ [
2
+ {
3
+ "id": 2,
4
+ "role": "AccountAdmin",
5
+ "role_id": 1,
6
+ "user": {
7
+ "id": 1,
8
+ "name": "mvalentine@instructure.com",
9
+ "sortable_name": "mvalentine@instructure.com",
10
+ "short_name": "mvalentine@instructure.com",
11
+ "sis_user_id": null,
12
+ "integration_id": null,
13
+ "sis_import_id": null,
14
+ "login_id": "mvalentine@instructure.com"
15
+ },
16
+ "workflow_state": "active"
17
+ },
18
+ {
19
+ "id": 3,
20
+ "role": "Custom Account Role",
21
+ "role_id": 11,
22
+ "user": {
23
+ "id": 11,
24
+ "name": "Test Account User",
25
+ "sortable_name": "User, Test Account",
26
+ "short_name": "Test Account User",
27
+ "sis_user_id": null,
28
+ "integration_id": null,
29
+ "sis_import_id": null,
30
+ "login_id": "testaccountuser@example.com"
31
+ },
32
+ "workflow_state": "active"
33
+ },
34
+ {
35
+ "id": 4,
36
+ "role": "Test",
37
+ "role_id": 10,
38
+ "user": {
39
+ "id": 11,
40
+ "name": "Test Account User",
41
+ "sortable_name": "User, Test Account",
42
+ "short_name": "Test Account User",
43
+ "sis_user_id": null,
44
+ "integration_id": null,
45
+ "sis_import_id": null,
46
+ "login_id": "testaccountuser@example.com"
47
+ },
48
+ "workflow_state": "active"
49
+ }
50
+ ]
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: canvas_sync
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.6
4
+ version: 0.3.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nate Collings
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-01-08 00:00:00.000000000 Z
11
+ date: 2018-01-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -293,7 +293,9 @@ files:
293
293
  - lib/canvas_sync/engine.rb
294
294
  - lib/canvas_sync/generators/install_generator.rb
295
295
  - lib/canvas_sync/generators/install_live_events_generator.rb
296
+ - lib/canvas_sync/generators/templates/models/admin.rb
296
297
  - lib/canvas_sync/generators/templates/models/course.rb
298
+ - lib/canvas_sync/generators/templates/models/create_admins.rb
297
299
  - lib/canvas_sync/generators/templates/models/create_courses.rb
298
300
  - lib/canvas_sync/generators/templates/models/create_enrollments.rb
299
301
  - lib/canvas_sync/generators/templates/models/create_roles.rb
@@ -331,6 +333,7 @@ files:
331
333
  - lib/canvas_sync/jobs/report_checker.rb
332
334
  - lib/canvas_sync/jobs/report_processor_job.rb
333
335
  - lib/canvas_sync/jobs/report_starter.rb
336
+ - lib/canvas_sync/jobs/sync_admins_job.rb
334
337
  - lib/canvas_sync/jobs/sync_provisioning_report_job.rb
335
338
  - lib/canvas_sync/jobs/sync_roles_job.rb
336
339
  - lib/canvas_sync/jobs/sync_terms_job.rb
@@ -343,10 +346,12 @@ files:
343
346
  - spec/canvas_sync/jobs/report_checker_spec.rb
344
347
  - spec/canvas_sync/jobs/report_processor_job_spec.rb
345
348
  - spec/canvas_sync/jobs/report_starter_spec.rb
349
+ - spec/canvas_sync/jobs/sync_admins_job_spec.rb
346
350
  - spec/canvas_sync/jobs/sync_provisioning_report_job_spec.rb
347
351
  - spec/canvas_sync/jobs/sync_roles_job_spec.rb
348
352
  - spec/canvas_sync/jobs/sync_terms_job_spec.rb
349
353
  - spec/canvas_sync/jobs/sync_users_job_spec.rb
354
+ - spec/canvas_sync/models/admins_spec.rb
350
355
  - spec/canvas_sync/models/course_spec.rb
351
356
  - spec/canvas_sync/models/enrollment_spec.rb
352
357
  - spec/canvas_sync/models/roles_spec.rb
@@ -356,6 +361,7 @@ files:
356
361
  - spec/canvas_sync/processors/provisioning_report_processor_spec.rb
357
362
  - spec/dummy/README.rdoc
358
363
  - spec/dummy/Rakefile
364
+ - spec/dummy/app/models/admin.rb
359
365
  - spec/dummy/app/models/application_record.rb
360
366
  - spec/dummy/app/models/course.rb
361
367
  - spec/dummy/app/models/enrollment.rb
@@ -383,10 +389,12 @@ files:
383
389
  - spec/dummy/db/migrate/20170918221413_create_users.rb
384
390
  - spec/dummy/db/migrate/20171107213207_create_sections.rb
385
391
  - spec/dummy/db/migrate/20180103162102_create_roles.rb
392
+ - spec/dummy/db/migrate/20180109210452_create_admins.rb
386
393
  - spec/dummy/db/schema.rb
387
394
  - spec/dummy/db/test.sqlite3
388
395
  - spec/dummy/log/development.log
389
396
  - spec/dummy/log/test.log
397
+ - spec/factories/admin_factory.rb
390
398
  - spec/factories/course_factory.rb
391
399
  - spec/factories/enrollment_factory.rb
392
400
  - spec/factories/role_factory.rb
@@ -395,6 +403,7 @@ files:
395
403
  - spec/factories/user_factory.rb
396
404
  - spec/spec_helper.rb
397
405
  - spec/support/fake_canvas.rb
406
+ - spec/support/fixtures/canvas_responses/admins.json
398
407
  - spec/support/fixtures/canvas_responses/roles.json
399
408
  - spec/support/fixtures/canvas_responses/terms.json
400
409
  - spec/support/fixtures/reports/courses.csv
@@ -434,10 +443,12 @@ test_files:
434
443
  - spec/canvas_sync/jobs/report_checker_spec.rb
435
444
  - spec/canvas_sync/jobs/report_processor_job_spec.rb
436
445
  - spec/canvas_sync/jobs/report_starter_spec.rb
446
+ - spec/canvas_sync/jobs/sync_admins_job_spec.rb
437
447
  - spec/canvas_sync/jobs/sync_provisioning_report_job_spec.rb
438
448
  - spec/canvas_sync/jobs/sync_roles_job_spec.rb
439
449
  - spec/canvas_sync/jobs/sync_terms_job_spec.rb
440
450
  - spec/canvas_sync/jobs/sync_users_job_spec.rb
451
+ - spec/canvas_sync/models/admins_spec.rb
441
452
  - spec/canvas_sync/models/course_spec.rb
442
453
  - spec/canvas_sync/models/enrollment_spec.rb
443
454
  - spec/canvas_sync/models/roles_spec.rb
@@ -447,6 +458,7 @@ test_files:
447
458
  - spec/canvas_sync/processors/provisioning_report_processor_spec.rb
448
459
  - spec/dummy/README.rdoc
449
460
  - spec/dummy/Rakefile
461
+ - spec/dummy/app/models/admin.rb
450
462
  - spec/dummy/app/models/application_record.rb
451
463
  - spec/dummy/app/models/course.rb
452
464
  - spec/dummy/app/models/enrollment.rb
@@ -474,10 +486,12 @@ test_files:
474
486
  - spec/dummy/db/migrate/20170918221413_create_users.rb
475
487
  - spec/dummy/db/migrate/20171107213207_create_sections.rb
476
488
  - spec/dummy/db/migrate/20180103162102_create_roles.rb
489
+ - spec/dummy/db/migrate/20180109210452_create_admins.rb
477
490
  - spec/dummy/db/schema.rb
478
491
  - spec/dummy/db/test.sqlite3
479
492
  - spec/dummy/log/development.log
480
493
  - spec/dummy/log/test.log
494
+ - spec/factories/admin_factory.rb
481
495
  - spec/factories/course_factory.rb
482
496
  - spec/factories/enrollment_factory.rb
483
497
  - spec/factories/role_factory.rb
@@ -486,6 +500,7 @@ test_files:
486
500
  - spec/factories/user_factory.rb
487
501
  - spec/spec_helper.rb
488
502
  - spec/support/fake_canvas.rb
503
+ - spec/support/fixtures/canvas_responses/admins.json
489
504
  - spec/support/fixtures/canvas_responses/roles.json
490
505
  - spec/support/fixtures/canvas_responses/terms.json
491
506
  - spec/support/fixtures/reports/courses.csv