canvas_sync 0.10.0 → 0.10.2
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/lib/canvas_sync/api_syncable.rb +20 -1
- data/lib/canvas_sync/generators/templates/migrations/create_roles.rb +2 -0
- data/lib/canvas_sync/generators/templates/models/admin.rb +16 -10
- data/lib/canvas_sync/generators/templates/models/assignment_group.rb +2 -1
- data/lib/canvas_sync/generators/templates/models/role.rb +12 -10
- data/lib/canvas_sync/generators/templates/models/term.rb +19 -14
- data/lib/canvas_sync/version.rb +1 -1
- data/spec/dummy/app/models/admin.rb +16 -10
- data/spec/dummy/app/models/role.rb +12 -10
- data/spec/dummy/app/models/term.rb +19 -14
- data/spec/dummy/db/migrate/{20190521003448_create_roles.rb → 20190606161037_create_roles.rb} +2 -0
- data/spec/dummy/db/schema.rb +3 -1
- data/spec/support/fixtures/canvas_responses/admins.json +49 -49
- data/spec/support/fixtures/canvas_responses/roles.json +743 -743
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 50ea86e0116f11f92019daae4edd22aa3a402355e1d910947e391a0f3b6ac000
|
4
|
+
data.tar.gz: 5712f275605f93eefc0f0ab5f1711b31e20dbc29d9a5e2b56d39853745610a49
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f914d9934b0b7c7c31fc3e3188d9884a07aeb104a4b89b9815f2455ada59bf74f6f43b3eb8fdc3fbd994dcca48166fd108dc45ae415f8715197ac96f33b3a2df
|
7
|
+
data.tar.gz: b56ddedc9b422d64bf319f2f425cb209b1889fbfd4a5992eb403ab1901efd2b3aaeaa7463c3ca9b4d32924e6b44fc0b8479084c6462796ea547a8d6e5fd516b9
|
@@ -1,7 +1,26 @@
|
|
1
1
|
module CanvasSync::ApiSyncable
|
2
2
|
extend ActiveSupport::Concern
|
3
|
+
NON_EXISTANT_ERRORS = [Faraday::Error::ResourceNotFound, Footrest::HttpError::NotFound]
|
3
4
|
|
4
5
|
class_methods do
|
6
|
+
def find_or_fetch(canvas_id, save: false, retries: 1)
|
7
|
+
inst = find_by(canvas_id: canvas_id)
|
8
|
+
return inst if inst.present?
|
9
|
+
inst = new(canvas_id: canvas_id)
|
10
|
+
api_response = inst.request_from_api(retries: retries)
|
11
|
+
inst.update_from_api_params(api_response)
|
12
|
+
inst.save! if save
|
13
|
+
inst
|
14
|
+
rescue *NON_EXISTANT_ERRORS
|
15
|
+
nil
|
16
|
+
end
|
17
|
+
|
18
|
+
def find_or_fetch!(*args)
|
19
|
+
inst = find_or_fetch(*args)
|
20
|
+
raise ActiveRecord::RecordNotFound unless inst.present?
|
21
|
+
inst
|
22
|
+
end
|
23
|
+
|
5
24
|
def api_sync_options=(opts)
|
6
25
|
@api_sync_options = opts
|
7
26
|
end
|
@@ -42,7 +61,7 @@ module CanvasSync::ApiSyncable
|
|
42
61
|
api_response = request_from_api(retries: retries)
|
43
62
|
update_from_api_params!(api_response)
|
44
63
|
api_response
|
45
|
-
rescue
|
64
|
+
rescue *NON_EXISTANT_ERRORS
|
46
65
|
api_mark_deleted
|
47
66
|
save! if changed?
|
48
67
|
nil
|
@@ -7,11 +7,13 @@ class CreateRoles < ActiveRecord::Migration[5.1]
|
|
7
7
|
t.string :label, null: false
|
8
8
|
t.string :base_role_type, null: false
|
9
9
|
t.json :account
|
10
|
+
t.integer :canvas_account_id
|
10
11
|
t.string :workflow_state, null: false
|
11
12
|
t.json :permissions
|
12
13
|
|
13
14
|
t.timestamps
|
14
15
|
end
|
15
16
|
add_index :roles, :canvas_id, unique: true
|
17
|
+
add_index :roles, :canvas_account_id
|
16
18
|
end
|
17
19
|
end
|
@@ -1,20 +1,26 @@
|
|
1
1
|
<%= autogenerated_model_warning %>
|
2
2
|
|
3
3
|
class Admin < ApplicationRecord
|
4
|
+
include CanvasSync::ApiSyncable
|
5
|
+
|
4
6
|
validates :canvas_id, uniqueness: true, presence: true
|
5
7
|
belongs_to :user, primary_key: :canvas_id, foreign_key: :canvas_user_id, optional: true
|
6
8
|
belongs_to :role, primary_key: :canvas_id, foreign_key: :canvas_role_id, optional: true
|
7
9
|
|
8
|
-
|
9
|
-
|
10
|
+
api_syncable({
|
11
|
+
canvas_id: :id,
|
12
|
+
role_name: :role,
|
13
|
+
canvas_role_id: :role_id,
|
14
|
+
user_data: :user,
|
15
|
+
canvas_user_id: ->(r) { r['user']['id'] },
|
16
|
+
workflow_state: :workflow_state,
|
17
|
+
}, -> (api) {
|
18
|
+
admins = api.account_admins('self').all_pages!
|
19
|
+
admin_data = admins.find{|admin| admin['id'] == canvas_id }
|
20
|
+
raise Footrest::HttpError::NotFound unless admin_data.present?
|
21
|
+
admin_data
|
22
|
+
})
|
10
23
|
|
11
|
-
|
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'])
|
24
|
+
def self.create_or_update(params); find_or_initialize_by(canvas_id: params['id']).update_from_api_params!(params); end
|
16
25
|
|
17
|
-
admin.save! if admin.changed?
|
18
|
-
admin
|
19
|
-
end
|
20
26
|
end
|
@@ -15,5 +15,6 @@ class AssignmentGroup < ApplicationRecord
|
|
15
15
|
position: :position,
|
16
16
|
rules: :rules,
|
17
17
|
group_weight: :group_weight,
|
18
|
-
|
18
|
+
workflow_state: ->(p) { 'available' },
|
19
|
+
}, -> (api) { api.assignment_group(canvas_course_id, canvas_id) })
|
19
20
|
end
|
@@ -1,19 +1,21 @@
|
|
1
1
|
<%= autogenerated_model_warning %>
|
2
2
|
|
3
3
|
class Role < ApplicationRecord
|
4
|
+
include CanvasSync::ApiSyncable
|
5
|
+
|
4
6
|
validates :canvas_id, uniqueness: true, presence: true
|
5
7
|
has_many :admins, foreign_key: :canvas_role_id, primary_key: :canvas_id
|
6
8
|
|
7
|
-
|
8
|
-
|
9
|
+
api_syncable({
|
10
|
+
canvas_id: :id,
|
11
|
+
label: :label,
|
12
|
+
base_role_type: :base_role_type,
|
13
|
+
account: :account,
|
14
|
+
canvas_account_id: ->(r) { r.dig('account', 'id') },
|
15
|
+
permissions: :permissions,
|
16
|
+
workflow_state: :workflow_state,
|
17
|
+
}, -> (api) { api.get("/api/v1/accounts/#{canvas_account_id}/roles/#{canvas_id}") })
|
9
18
|
|
10
|
-
|
11
|
-
base_role_type: role_params['base_role_type'],
|
12
|
-
account: role_params['account'],
|
13
|
-
permissions: role_params['permissions'],
|
14
|
-
workflow_state: role_params['workflow_state'])
|
19
|
+
def self.create_or_update(params); find_or_initialize_by(canvas_id: params['id']).update_from_api_params!(params); end
|
15
20
|
|
16
|
-
role.save! if role.changed?
|
17
|
-
role
|
18
|
-
end
|
19
21
|
end
|
@@ -1,9 +1,28 @@
|
|
1
1
|
<%= autogenerated_model_warning %>
|
2
2
|
|
3
3
|
class Term < ApplicationRecord
|
4
|
+
include CanvasSync::ApiSyncable
|
5
|
+
|
4
6
|
validates :canvas_id, uniqueness: true, presence: true
|
5
7
|
has_many :courses, foreign_key: :canvas_term_id, primary_key: :canvas_id
|
6
8
|
|
9
|
+
api_syncable({
|
10
|
+
canvas_id: :id,
|
11
|
+
name: :name,
|
12
|
+
sis_id: :sis_term_id,
|
13
|
+
start_at: :start_at,
|
14
|
+
end_at: :end_at,
|
15
|
+
workflow_state: :workflow_state,
|
16
|
+
grading_period_group_id: :grading_period_group_id,
|
17
|
+
}, -> (api) {
|
18
|
+
terms = api.terms('self').all_pages!
|
19
|
+
term_data = terms.find{|term| term['id'] == canvas_id }
|
20
|
+
raise Footrest::HttpError::NotFound unless term_data.present?
|
21
|
+
term_data
|
22
|
+
})
|
23
|
+
|
24
|
+
def self.create_or_update(params); find_or_initialize_by(canvas_id: params['id']).update_from_api_params!(params); end
|
25
|
+
|
7
26
|
# This is a sample scope created by the CanvasSync gem; feel
|
8
27
|
# free to customize it for your tool's requirements.
|
9
28
|
scope :active, -> {
|
@@ -12,18 +31,4 @@ class Term < ApplicationRecord
|
|
12
31
|
.where("end_at >= ? OR end_at IS NULL", 15.days.ago)
|
13
32
|
}
|
14
33
|
|
15
|
-
def self.create_or_update(term_params)
|
16
|
-
term = Term.find_or_initialize_by(canvas_id: term_params['id'])
|
17
|
-
|
18
|
-
term.assign_attributes(name: term_params['name'],
|
19
|
-
start_at: term_params['start_at'],
|
20
|
-
end_at: term_params['end_at'],
|
21
|
-
workflow_state: term_params['workflow_state'],
|
22
|
-
grading_period_group_id: term_params['grading_period_group_id'],
|
23
|
-
sis_id: term_params['sis_term_id'])
|
24
|
-
|
25
|
-
term.save! if term.changed?
|
26
|
-
term
|
27
|
-
end
|
28
|
-
|
29
34
|
end
|
data/lib/canvas_sync/version.rb
CHANGED
@@ -7,20 +7,26 @@
|
|
7
7
|
|
8
8
|
|
9
9
|
class Admin < ApplicationRecord
|
10
|
+
include CanvasSync::ApiSyncable
|
11
|
+
|
10
12
|
validates :canvas_id, uniqueness: true, presence: true
|
11
13
|
belongs_to :user, primary_key: :canvas_id, foreign_key: :canvas_user_id, optional: true
|
12
14
|
belongs_to :role, primary_key: :canvas_id, foreign_key: :canvas_role_id, optional: true
|
13
15
|
|
14
|
-
|
15
|
-
|
16
|
+
api_syncable({
|
17
|
+
canvas_id: :id,
|
18
|
+
role_name: :role,
|
19
|
+
canvas_role_id: :role_id,
|
20
|
+
user_data: :user,
|
21
|
+
canvas_user_id: ->(r) { r['user']['id'] },
|
22
|
+
workflow_state: :workflow_state,
|
23
|
+
}, -> (api) {
|
24
|
+
admins = api.account_admins('self').all_pages!
|
25
|
+
admin_data = admins.find{|admin| admin['id'] == canvas_id }
|
26
|
+
raise Footrest::HttpError::NotFound unless admin_data.present?
|
27
|
+
admin_data
|
28
|
+
})
|
16
29
|
|
17
|
-
|
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'])
|
30
|
+
def self.create_or_update(params); find_or_initialize_by(canvas_id: params['id']).update_from_api_params!(params); end
|
22
31
|
|
23
|
-
admin.save! if admin.changed?
|
24
|
-
admin
|
25
|
-
end
|
26
32
|
end
|
@@ -7,19 +7,21 @@
|
|
7
7
|
|
8
8
|
|
9
9
|
class Role < ApplicationRecord
|
10
|
+
include CanvasSync::ApiSyncable
|
11
|
+
|
10
12
|
validates :canvas_id, uniqueness: true, presence: true
|
11
13
|
has_many :admins, foreign_key: :canvas_role_id, primary_key: :canvas_id
|
12
14
|
|
13
|
-
|
14
|
-
|
15
|
+
api_syncable({
|
16
|
+
canvas_id: :id,
|
17
|
+
label: :label,
|
18
|
+
base_role_type: :base_role_type,
|
19
|
+
account: :account,
|
20
|
+
canvas_account_id: ->(r) { r.dig('account', 'id') },
|
21
|
+
permissions: :permissions,
|
22
|
+
workflow_state: :workflow_state,
|
23
|
+
}, -> (api) { api.get("/api/v1/accounts/#{canvas_account_id}/roles/#{canvas_id}") })
|
15
24
|
|
16
|
-
|
17
|
-
base_role_type: role_params['base_role_type'],
|
18
|
-
account: role_params['account'],
|
19
|
-
permissions: role_params['permissions'],
|
20
|
-
workflow_state: role_params['workflow_state'])
|
25
|
+
def self.create_or_update(params); find_or_initialize_by(canvas_id: params['id']).update_from_api_params!(params); end
|
21
26
|
|
22
|
-
role.save! if role.changed?
|
23
|
-
role
|
24
|
-
end
|
25
27
|
end
|
@@ -7,9 +7,28 @@
|
|
7
7
|
|
8
8
|
|
9
9
|
class Term < ApplicationRecord
|
10
|
+
include CanvasSync::ApiSyncable
|
11
|
+
|
10
12
|
validates :canvas_id, uniqueness: true, presence: true
|
11
13
|
has_many :courses, foreign_key: :canvas_term_id, primary_key: :canvas_id
|
12
14
|
|
15
|
+
api_syncable({
|
16
|
+
canvas_id: :id,
|
17
|
+
name: :name,
|
18
|
+
sis_id: :sis_term_id,
|
19
|
+
start_at: :start_at,
|
20
|
+
end_at: :end_at,
|
21
|
+
workflow_state: :workflow_state,
|
22
|
+
grading_period_group_id: :grading_period_group_id,
|
23
|
+
}, -> (api) {
|
24
|
+
terms = api.terms('self').all_pages!
|
25
|
+
term_data = terms.find{|term| term['id'] == canvas_id }
|
26
|
+
raise Footrest::HttpError::NotFound unless term_data.present?
|
27
|
+
term_data
|
28
|
+
})
|
29
|
+
|
30
|
+
def self.create_or_update(params); find_or_initialize_by(canvas_id: params['id']).update_from_api_params!(params); end
|
31
|
+
|
13
32
|
# This is a sample scope created by the CanvasSync gem; feel
|
14
33
|
# free to customize it for your tool's requirements.
|
15
34
|
scope :active, -> {
|
@@ -18,18 +37,4 @@ class Term < ApplicationRecord
|
|
18
37
|
.where("end_at >= ? OR end_at IS NULL", 15.days.ago)
|
19
38
|
}
|
20
39
|
|
21
|
-
def self.create_or_update(term_params)
|
22
|
-
term = Term.find_or_initialize_by(canvas_id: term_params['id'])
|
23
|
-
|
24
|
-
term.assign_attributes(name: term_params['name'],
|
25
|
-
start_at: term_params['start_at'],
|
26
|
-
end_at: term_params['end_at'],
|
27
|
-
workflow_state: term_params['workflow_state'],
|
28
|
-
grading_period_group_id: term_params['grading_period_group_id'],
|
29
|
-
sis_id: term_params['sis_term_id'])
|
30
|
-
|
31
|
-
term.save! if term.changed?
|
32
|
-
term
|
33
|
-
end
|
34
|
-
|
35
40
|
end
|
data/spec/dummy/db/migrate/{20190521003448_create_roles.rb → 20190606161037_create_roles.rb}
RENAMED
@@ -13,11 +13,13 @@ class CreateRoles < ActiveRecord::Migration[5.1]
|
|
13
13
|
t.string :label, null: false
|
14
14
|
t.string :base_role_type, null: false
|
15
15
|
t.json :account
|
16
|
+
t.integer :canvas_account_id
|
16
17
|
t.string :workflow_state, null: false
|
17
18
|
t.json :permissions
|
18
19
|
|
19
20
|
t.timestamps
|
20
21
|
end
|
21
22
|
add_index :roles, :canvas_id, unique: true
|
23
|
+
add_index :roles, :canvas_account_id
|
22
24
|
end
|
23
25
|
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: 20190606161037) do
|
14
14
|
|
15
15
|
# These are extensions that must be enabled in order to support this database
|
16
16
|
enable_extension "plpgsql"
|
@@ -162,10 +162,12 @@ ActiveRecord::Schema.define(version: 20190604193942) do
|
|
162
162
|
t.string "label", null: false
|
163
163
|
t.string "base_role_type", null: false
|
164
164
|
t.json "account"
|
165
|
+
t.integer "canvas_account_id"
|
165
166
|
t.string "workflow_state", null: false
|
166
167
|
t.json "permissions"
|
167
168
|
t.datetime "created_at", null: false
|
168
169
|
t.datetime "updated_at", null: false
|
170
|
+
t.index ["canvas_account_id"], name: "index_roles_on_canvas_account_id"
|
169
171
|
t.index ["canvas_id"], name: "index_roles_on_canvas_id", unique: true
|
170
172
|
end
|
171
173
|
|
@@ -1,50 +1,50 @@
|
|
1
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
|
-
]
|
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
|
+
]
|