panda_pal 3.0.1 → 3.0.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5d38f3ee39fd2a646758d9c6e47e9c0fdb496ed5
4
- data.tar.gz: d15a3f38b606c3705ee397e1e8ff7446c518006b
3
+ metadata.gz: 142d69b7f513a07ebace023bd229a780b099f17d
4
+ data.tar.gz: 60bd6a9784c2e2a9265b2e7c6582759560892c66
5
5
  SHA512:
6
- metadata.gz: c0524f269d6725c879f19bb6b304f8e83fe94d551935b7e6d7b424e8f1aac2dd1b2022ee06607d73180f6017f43a9c55dfa160f8c77613e97d06062d1bd9be57
7
- data.tar.gz: 7d8437a68bdb6611df7375b1f4a2fd8e7e17eb03075bf4af379fb7222293e7d9ffd7195525aa38ccde8fdab9032348b6bbdb1d65743594f98d7b59a520c9a3e2
6
+ metadata.gz: c95b68006a09db2e5cb559bc653f93219d6fc3f2aff350e5c2daa942a2d85c6a4490c1a10020cd0b8b8901f91ce3d299977d9334b677014c8c1c5bda14389083
7
+ data.tar.gz: d7ddd1733b129b550d69b736f9201115e0667f06cb1b8e116115b890e108963597fecb05d9b962fe2926e030e4557682cdd49b09d4106bfd4239d66b90bdedab
data/Rakefile CHANGED
@@ -14,7 +14,7 @@ RDoc::Task.new(:rdoc) do |rdoc|
14
14
  rdoc.rdoc_files.include('lib/**/*.rb')
15
15
  end
16
16
 
17
- APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
17
+ APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)
18
18
  load 'rails/tasks/engine.rake'
19
19
 
20
20
 
@@ -1,4 +1,5 @@
1
1
  module PandaPal
2
+
2
3
  class Organization < ActiveRecord::Base
3
4
  attribute :settings
4
5
  attr_encrypted :settings, marshal: true, key: :encryption_key
@@ -8,7 +9,7 @@ module PandaPal
8
9
  validates :name, uniqueness: { case_sensitive: false }, presence: true, format: { with: /\A[a-z0-9_]+\z/i }
9
10
  validates :canvas_account_id, presence: true
10
11
  validates :salesforce_id, presence: true, uniqueness: true
11
-
12
+ validate :validate_settings
12
13
  after_create :create_schema
13
14
  after_commit :destroy_schema, on: :destroy
14
15
 
@@ -37,5 +38,48 @@ module PandaPal
37
38
  def destroy_schema
38
39
  Apartment::Tenant.drop name
39
40
  end
41
+
42
+ def validate_settings
43
+ record = self
44
+ if PandaPal.lti_options && PandaPal.lti_options[:settings_structure]
45
+ validate_level(record, PandaPal.lti_options[:settings_structure], record.settings, [])
46
+ end
47
+ end
48
+ def validate_level(record, expectation, reality, previous_keys)
49
+ # Verify that the data elements at this level conform to requirements.
50
+ if expectation
51
+ expectation.each do |key, value|
52
+ is_required = expectation[key].try(:delete, :is_required)
53
+ data_type = expectation[key].try(:delete, :data_type)
54
+ value = reality.is_a?(Hash) ? reality.dig(key) : reality
55
+
56
+ if is_required && !value
57
+ record.errors[:settings] << "PandaPal::Organization.settings requires key [:#{previous_keys.push(key).join("][:")}]. It was not found."
58
+ end
59
+ if data_type && value
60
+ if value.class.to_s != data_type
61
+ record.errors[:settings] << "PandaPal::Organization.settings expected key [:#{previous_keys.push(key).join("][:")}] to be #{data_type} but it was instead #{value.class}."
62
+ end
63
+ end
64
+ end
65
+ end
66
+ # Verify that anything that is in the real settings has an expectation.
67
+ if reality
68
+ if reality.is_a? Hash
69
+ reality.each do |key, value|
70
+ was_expected = expectation.has_key?(key)
71
+ if !was_expected
72
+ record.errors[:settings] << "PandaPal::Organization.settings had unexpected key: #{key}. If settings have expanded please update your lti_options accordingly."
73
+ end
74
+ end
75
+ end
76
+ end
77
+ # Recursively check out any children settings as well.
78
+ if expectation
79
+ expectation.each do |key, value|
80
+ validate_level(record, expectation[key], (reality.is_a?(Hash) ? reality.dig(key) : nil), previous_keys.deep_dup.push(key))
81
+ end
82
+ end
83
+ end
40
84
  end
41
85
  end
@@ -1,4 +1,8 @@
1
1
  class RemoveOldOrganizationSettings < ActiveRecord::Migration[5.1]
2
+ def current_tenant
3
+ @current_tenant ||= PandaPal::Organization.find_by_name(Apartment::Tenant.current)
4
+ end
5
+
2
6
  def up
3
7
  # migrations run for public and local tenants. However, PandaPal::Organization
4
8
  # is going to always go to public tenant. So don't do this active record
@@ -1,3 +1,3 @@
1
1
  module PandaPal
2
- VERSION = "3.0.1"
2
+ VERSION = "3.0.3"
3
3
  end
data/panda_pal.gemspec CHANGED
@@ -21,8 +21,6 @@ Gem::Specification.new do |s|
21
21
  s.add_dependency 'ims-lti', '~> 2.1.0'
22
22
  s.add_dependency 'browser', '2.5.0'
23
23
  s.add_dependency 'attr_encrypted', '~> 3.0.0'
24
-
25
24
  s.add_development_dependency 'rspec-rails'
26
25
  s.add_development_dependency 'factory_girl_rails'
27
- s.add_development_dependency 'test_after_commit'
28
26
  end
@@ -19,8 +19,5 @@ module Dummy
19
19
  # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
20
20
  # config.i18n.default_locale = :de
21
21
 
22
- # Do not swallow errors in after_commit/after_rollback callbacks.
23
- config.active_record.raise_in_transactional_callbacks = true
24
22
  end
25
23
  end
26
-
@@ -5,20 +5,20 @@
5
5
  # gem 'sqlite3'
6
6
  #
7
7
  default: &default
8
- adapter: sqlite3
8
+ adapter: postgresql
9
9
  pool: 5
10
10
  timeout: 5000
11
11
 
12
12
  development:
13
13
  <<: *default
14
- database: db/development.sqlite3
14
+ database: panda_pal_development
15
15
 
16
16
  # Warning: The database defined as "test" will be erased and
17
17
  # re-generated from your development database when you run "rake".
18
18
  # Do not set this db to the same as development or production.
19
19
  test:
20
20
  <<: *default
21
- database: db/test.sqlite3
21
+ database: panda_pal_test
22
22
 
23
23
  production:
24
24
  <<: *default
@@ -1,4 +1,3 @@
1
- # encoding: UTF-8
2
1
  # This file is auto-generated from the current state of the database. Instead
3
2
  # of editing this file, please use the migrations feature of Active Record to
4
3
  # incrementally modify your database, and then regenerate this schema definition.
@@ -11,45 +10,30 @@
11
10
  #
12
11
  # It's strongly recommended that you check this file into your version control system.
13
12
 
14
- ActiveRecord::Schema.define(version: 20160415162154) do
15
-
16
- create_table "delayed_jobs", force: :cascade do |t|
17
- t.integer "priority", default: 0, null: false
18
- t.integer "attempts", default: 0, null: false
19
- t.text "handler", null: false
20
- t.text "last_error"
21
- t.datetime "run_at"
22
- t.datetime "locked_at"
23
- t.datetime "failed_at"
24
- t.string "locked_by"
25
- t.string "queue"
26
- t.string "tenant"
27
- t.datetime "created_at"
28
- t.datetime "updated_at"
29
- end
30
-
31
- add_index "delayed_jobs", ["priority", "run_at"], name: "delayed_jobs_priority"
13
+ ActiveRecord::Schema.define(version: 30171205194657) do
32
14
 
33
15
  create_table "panda_pal_organizations", force: :cascade do |t|
34
- t.string "name"
35
- t.string "key"
36
- t.string "secret"
37
- t.string "canvas_account_id"
38
- t.text "settings"
39
- t.datetime "created_at", null: false
40
- t.datetime "updated_at", null: false
16
+ t.string "name"
17
+ t.string "key"
18
+ t.string "secret"
19
+ t.string "canvas_account_id"
20
+ t.datetime "created_at", null: false
21
+ t.datetime "updated_at", null: false
22
+ t.string "salesforce_id"
23
+ t.text "encrypted_settings"
24
+ t.string "encrypted_settings_iv"
25
+ t.index ["key"], name: "index_panda_pal_organizations_on_key", unique: true
26
+ t.index ["name"], name: "index_panda_pal_organizations_on_name", unique: true
41
27
  end
42
28
 
43
- add_index "panda_pal_organizations", ["key"], name: "index_panda_pal_organizations_on_key", unique: true
44
- add_index "panda_pal_organizations", ["name"], name: "index_panda_pal_organizations_on_name", unique: true
45
-
46
29
  create_table "panda_pal_sessions", force: :cascade do |t|
47
- t.string "session_key"
48
- t.text "data"
49
- t.datetime "created_at", null: false
50
- t.datetime "updated_at", null: false
30
+ t.string "session_key"
31
+ t.text "data"
32
+ t.datetime "created_at", null: false
33
+ t.datetime "updated_at", null: false
34
+ t.integer "panda_pal_organization_id"
35
+ t.index ["panda_pal_organization_id"], name: "index_panda_pal_sessions_on_panda_pal_organization_id"
36
+ t.index ["session_key"], name: "index_panda_pal_sessions_on_session_key", unique: true
51
37
  end
52
38
 
53
- add_index "panda_pal_sessions", ["session_key"], name: "index_panda_pal_sessions_on_session_key", unique: true
54
-
55
39
  end
@@ -3,18 +3,44 @@ require 'rails_helper'
3
3
  module PandaPal
4
4
  RSpec.describe Organization, type: :model do
5
5
 
6
+ def set_test_settings_structure
7
+ PandaPal.lti_options = {
8
+ title: 'Test App',
9
+ settings_structure: YAML.load("
10
+ canvas:
11
+ is_required: true
12
+ data_type: Hash
13
+ api_token:
14
+ is_required: true
15
+ data_type: String
16
+ base_url:
17
+ is_required: true
18
+ data_type: String
19
+ reports:
20
+ is_required: true
21
+ data_type: Hash
22
+ active_term_allowance:
23
+ submissions_report_time_length:
24
+ is_required: true
25
+ data_type: ActiveSupport::Duration
26
+ recheck_wait:
27
+ data_type: ActiveSupport::Duration
28
+ max_recheck_time:
29
+ is_required: true
30
+ ").deep_symbolize_keys
31
+ }
32
+ end
33
+
6
34
  it 'creates a schema upon creation' do
7
35
  expect(Apartment::Tenant).to receive(:create)
8
36
  create :panda_pal_organization
9
37
  end
10
38
 
11
39
  it 'deletes a schema upon deletion' do
12
- TestAfterCommit.with_commits(true) do
13
- expect(Apartment::Tenant).to receive(:create)
14
- expect(Apartment::Tenant).to receive(:drop)
15
- org = create :panda_pal_organization
16
- org.destroy
17
- end
40
+ expect(Apartment::Tenant).to receive(:create)
41
+ expect(Apartment::Tenant).to receive(:drop)
42
+ org = create :panda_pal_organization
43
+ org.destroy
18
44
  end
19
45
 
20
46
  it 'does not allow the name to be changed after creation' do
@@ -33,5 +59,65 @@ module PandaPal
33
59
  org2 = build :panda_pal_organization, salesforce_id: 'salesforce'
34
60
  expect(org2.valid?).to be_falsey
35
61
  end
62
+
63
+ context 'settings validation' do
64
+ let!(:org) { create :panda_pal_organization }
65
+
66
+ it 'does not perform any validations if settings is not defined' do
67
+ PandaPal.lti_options = {}
68
+ expect_any_instance_of(PandaPal::Organization).not_to receive(:validate_level)
69
+ expect(org.valid?).to be_truthy
70
+ end
71
+
72
+ it 'does not perform any validations if options is not defined' do
73
+ PandaPal.lti_options = nil
74
+ expect_any_instance_of(PandaPal::Organization).not_to receive(:validate_level)
75
+ expect(org.valid?).to be_truthy
76
+ end
77
+
78
+ it 'does perform validations if settings_structure is defined' do
79
+ set_test_settings_structure
80
+ org.valid?
81
+ expect(org.valid?).to be_falsey
82
+ end
83
+
84
+ it 'will fail if a required setting is not present' do
85
+ set_test_settings_structure
86
+ expect(org.valid?).to be_falsey
87
+ errors = org.errors.messages[:settings]
88
+ expect(errors[0]).to eq("PandaPal::Organization.settings requires key [:canvas]. It was not found.")
89
+ end
90
+
91
+ it 'will fail if a setting is supplied but data_type is wrong' do
92
+ set_test_settings_structure
93
+ org.settings = {canvas: "Dog"}
94
+ expect(org.valid?).to be_falsey
95
+ errors = org.errors.messages[:settings]
96
+ expect(errors[0]).to eq("PandaPal::Organization.settings expected key [:canvas] to be Hash but it was instead String.")
97
+ end
98
+
99
+ it 'will fail if a required subsetting is missing' do
100
+ set_test_settings_structure
101
+ org.settings = {canvas: {base_url: 'http://'}, reports: {}}
102
+ expect(org.valid?).to be_falsey
103
+ errors = org.errors.messages[:settings]
104
+ expect(errors[0]).to eq("PandaPal::Organization.settings requires key [:canvas][:api_token]. It was not found.")
105
+ end
106
+
107
+ it 'will fail if extra options are specified' do
108
+ set_test_settings_structure
109
+ org.settings = {canvas: {base_url: 'http://'}, reports: {}, unknown_option: "WHAT IS THIS?"}
110
+ expect(org.valid?).to be_falsey
111
+ errors = org.errors.messages[:settings]
112
+ expect(errors[0]).to eq("PandaPal::Organization.settings had unexpected key: unknown_option. If settings have expanded please update your lti_options accordingly.")
113
+ end
114
+
115
+ it 'will pass if all structure is maintained' do
116
+ set_test_settings_structure
117
+ org.settings = {canvas: {base_url: 'http://', api_token: 'TEST'}, reports: {submissions_report_time_length: 30.minutes, max_recheck_time: 10.hours}}
118
+ expect(org.valid?).to be_truthy
119
+ end
120
+
121
+ end
36
122
  end
37
123
  end
data/spec/spec_helper.rb CHANGED
@@ -3,13 +3,17 @@ require File.expand_path("../dummy/config/environment.rb", __FILE__)
3
3
  require 'rspec/rails'
4
4
  require 'rspec/autorun'
5
5
  require 'nokogiri'
6
- require 'delayed_job_active_record'
7
6
  require 'factory_girl_rails'
8
- require 'test_after_commit'
9
7
 
10
- Delayed::Worker.delay_jobs = false
8
+ ActiveRecord::Migration.maintain_test_schema!
9
+ ActiveRecord::Schema.verbose = false
10
+ load 'dummy/db/schema.rb' # db agnostic
11
+
11
12
  RSpec.configure do |config|
12
13
  config.include FactoryGirl::Syntax::Methods
14
+ FactoryGirl.definition_file_paths = [File.expand_path('../factories', __FILE__)]
15
+ FactoryGirl.find_definitions
16
+
13
17
  # rspec-expectations config goes here. You can use an alternate
14
18
  # assertion/expectation library such as wrong or the stdlib/minitest
15
19
  # assertions if you prefer.
@@ -33,6 +37,13 @@ RSpec.configure do |config|
33
37
  mocks.verify_partial_doubles = true
34
38
  end
35
39
 
40
+ config.before(:each) do
41
+ PandaPal.lti_options = {
42
+ title: 'Test App',
43
+ settings_structure: {}
44
+ }
45
+ end
46
+
36
47
  # The settings below are suggested to provide a good initial experience
37
48
  # with RSpec, but feel free to customize to your heart's content.
38
49
  =begin
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: panda_pal
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.1
4
+ version: 3.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ben Young
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2017-12-21 00:00:00.000000000 Z
12
+ date: 2018-01-04 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
@@ -123,20 +123,6 @@ dependencies:
123
123
  - - ">="
124
124
  - !ruby/object:Gem::Version
125
125
  version: '0'
126
- - !ruby/object:Gem::Dependency
127
- name: test_after_commit
128
- requirement: !ruby/object:Gem::Requirement
129
- requirements:
130
- - - ">="
131
- - !ruby/object:Gem::Version
132
- version: '0'
133
- type: :development
134
- prerelease: false
135
- version_requirements: !ruby/object:Gem::Requirement
136
- requirements:
137
- - - ">="
138
- - !ruby/object:Gem::Version
139
- version: '0'
140
126
  description:
141
127
  email:
142
128
  - byoung@instructure.com
@@ -206,9 +192,6 @@ files:
206
192
  - spec/dummy/config/locales/en.yml
207
193
  - spec/dummy/config/routes.rb
208
194
  - spec/dummy/config/secrets.yml
209
- - spec/dummy/db/migrate/20160415162152_create_panda_pal_organizations.panda_pal.rb
210
- - spec/dummy/db/migrate/20160415162153_create_delayed_jobs.panda_pal.rb
211
- - spec/dummy/db/migrate/20160415162154_create_panda_pal_sessions.panda_pal.rb
212
195
  - spec/dummy/db/schema.rb
213
196
  - spec/dummy/public/404.html
214
197
  - spec/dummy/public/422.html
@@ -240,7 +223,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
240
223
  version: '0'
241
224
  requirements: []
242
225
  rubyforge_project:
243
- rubygems_version: 2.5.2
226
+ rubygems_version: 2.2.2
244
227
  signing_key:
245
228
  specification_version: 4
246
229
  summary: LTI mountable engine
@@ -273,9 +256,6 @@ test_files:
273
256
  - spec/dummy/config/routes.rb
274
257
  - spec/dummy/config/secrets.yml
275
258
  - spec/dummy/config.ru
276
- - spec/dummy/db/migrate/20160415162152_create_panda_pal_organizations.panda_pal.rb
277
- - spec/dummy/db/migrate/20160415162153_create_delayed_jobs.panda_pal.rb
278
- - spec/dummy/db/migrate/20160415162154_create_panda_pal_sessions.panda_pal.rb
279
259
  - spec/dummy/db/schema.rb
280
260
  - spec/dummy/public/404.html
281
261
  - spec/dummy/public/422.html
@@ -289,3 +269,4 @@ test_files:
289
269
  - spec/models/panda_pal/session_spec.rb
290
270
  - spec/rails_helper.rb
291
271
  - spec/spec_helper.rb
272
+ has_rdoc:
@@ -1,16 +0,0 @@
1
- # This migration comes from panda_pal (originally 20160412205931)
2
- class CreatePandaPalOrganizations < ActiveRecord::Migration
3
- def change
4
- create_table :panda_pal_organizations do |t|
5
- t.string :name
6
- t.string :key
7
- t.string :secret
8
- t.string :canvas_account_id
9
- t.text :settings
10
-
11
- t.timestamps null: false
12
- end
13
- add_index :panda_pal_organizations, :name, unique: true
14
- add_index :panda_pal_organizations, :key, unique: true
15
- end
16
- end
@@ -1,24 +0,0 @@
1
- # This migration comes from panda_pal (originally 20160413132229)
2
- class CreateDelayedJobs < ActiveRecord::Migration
3
- def self.up
4
- create_table :delayed_jobs, force: true do |table|
5
- table.integer :priority, default: 0, null: false # Allows some jobs to jump to the front of the queue
6
- table.integer :attempts, default: 0, null: false # Provides for retries, but still fail eventually.
7
- table.text :handler, null: false # YAML-encoded string of the object that will do work
8
- table.text :last_error # reason for last failure (See Note below)
9
- table.datetime :run_at # When to run. Could be Time.zone.now for immediately, or sometime in the future.
10
- table.datetime :locked_at # Set when a client is working on this object
11
- table.datetime :failed_at # Set when all retries have failed (actually, by default, the record is deleted instead)
12
- table.string :locked_by # Who is working on this object (if locked)
13
- table.string :queue # The name of the queue this job is in
14
- table.string :tenant
15
- table.timestamps null: true
16
- end
17
-
18
- add_index :delayed_jobs, [:priority, :run_at], name: "delayed_jobs_priority"
19
- end
20
-
21
- def self.down
22
- drop_table :delayed_jobs
23
- end
24
- end
@@ -1,12 +0,0 @@
1
- # This migration comes from panda_pal (originally 20160413135653)
2
- class CreatePandaPalSessions < ActiveRecord::Migration
3
- def change
4
- create_table :panda_pal_sessions do |t|
5
- t.string :session_key
6
- t.text :data
7
-
8
- t.timestamps null: false
9
- end
10
- add_index :panda_pal_sessions, :session_key, unique: true
11
- end
12
- end