panda_pal 4.1.0.beta2 → 5.0.0.beta.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/README.md +60 -71
- data/app/models/panda_pal/organization.rb +46 -17
- data/db/618eef7c0380ba654ad16f867a919e72.sqlite3 +0 -0
- data/db/9ff93d4f7e0e9dc80a43f68997caf4a1.sqlite3 +0 -0
- data/db/a3fda4044a7215bc2c9eb01a4b9e517a.sqlite3 +0 -0
- data/db/daa0e6378a5ec76fcce83b7070dad219.sqlite3 +0 -0
- data/lib/panda_pal/helpers/controller_helper.rb +38 -33
- data/lib/panda_pal/version.rb +1 -1
- data/panda_pal.gemspec +0 -3
- data/spec/dummy/config/application.rb +1 -7
- data/spec/dummy/config/environments/development.rb +14 -0
- data/spec/dummy/config/environments/production.rb +11 -0
- data/spec/dummy/config/initializers/assets.rb +11 -0
- data/spec/dummy/db/development.sqlite3 +0 -0
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/log/development.log +15058 -0
- data/spec/dummy/log/test.log +0 -0
- data/spec/models/panda_pal/organization_spec.rb +89 -0
- data/spec/spec_helper.rb +0 -8
- metadata +17 -39
- data/app/models/panda_pal/organization/settings_validation.rb +0 -115
- data/app/models/panda_pal/organization/task_scheduling.rb +0 -164
- data/app/views/panda_pal/lti/iframe_cookie_fix.html.erb +0 -12
- data/spec/models/panda_pal/organization/settings_validation_spec.rb +0 -175
- data/spec/models/panda_pal/organization/task_scheduling_spec.rb +0 -134
@@ -1,12 +0,0 @@
|
|
1
|
-
<script nonce=<%= content_security_policy_script_nonce %>>
|
2
|
-
const mainWindow = window.parent;
|
3
|
-
var url = window.location.href;
|
4
|
-
// Until PLAT-4836 is resolved, we need to make sure our url has a "?" in it.
|
5
|
-
if (!(url.indexOf("?") > -1)) {
|
6
|
-
url = url + "?dummy_param=1"
|
7
|
-
}
|
8
|
-
mainWindow.postMessage({
|
9
|
-
messageType: "requestFullWindowLaunch",
|
10
|
-
data: url
|
11
|
-
}, '*');
|
12
|
-
</script>
|
@@ -1,175 +0,0 @@
|
|
1
|
-
require 'rails_helper'
|
2
|
-
|
3
|
-
module PandaPal
|
4
|
-
PandaPal::Organization
|
5
|
-
RSpec.describe OrganizationConcerns::SettingsValidation, type: :model do
|
6
|
-
let!(:org) { create :panda_pal_organization }
|
7
|
-
|
8
|
-
def set_test_settings_structure
|
9
|
-
PandaPal.lti_options = {
|
10
|
-
title: 'Test App',
|
11
|
-
settings_structure: structure,
|
12
|
-
}
|
13
|
-
end
|
14
|
-
|
15
|
-
RSpec.shared_examples "shared stuff" do
|
16
|
-
it 'does not perform any validations if settings is not defined' do
|
17
|
-
PandaPal.lti_options = {}
|
18
|
-
expect(org.valid?).to be_truthy
|
19
|
-
end
|
20
|
-
|
21
|
-
it 'does not perform any validations if options is not defined' do
|
22
|
-
PandaPal.lti_options = nil
|
23
|
-
expect(org.valid?).to be_truthy
|
24
|
-
end
|
25
|
-
|
26
|
-
it 'does perform validations if settings_structure is defined' do
|
27
|
-
set_test_settings_structure
|
28
|
-
org.valid?
|
29
|
-
expect(org.valid?).to be_falsey
|
30
|
-
end
|
31
|
-
|
32
|
-
it 'will fail if a required setting is not present' do
|
33
|
-
set_test_settings_structure
|
34
|
-
expect(org.valid?).to be_falsey
|
35
|
-
errors = org.errors.messages[:settings]
|
36
|
-
expect(errors[0]).to eq("Entry [:canvas] is required")
|
37
|
-
end
|
38
|
-
|
39
|
-
it 'will fail if a setting is supplied but data_type is wrong' do
|
40
|
-
set_test_settings_structure
|
41
|
-
org.settings = {canvas: "Dog", reports: {}}
|
42
|
-
expect(org.valid?).to be_falsey
|
43
|
-
errors = org.errors.messages[:settings]
|
44
|
-
expect(errors[0]).to eq("Expected [:canvas] to be a Hash. Was a String")
|
45
|
-
end
|
46
|
-
|
47
|
-
it 'will fail if a required subsetting is missing' do
|
48
|
-
set_test_settings_structure
|
49
|
-
org.settings = {canvas: {base_url: 'http://'}, reports: {}}
|
50
|
-
expect(org.valid?).to be_falsey
|
51
|
-
errors = org.errors.messages[:settings]
|
52
|
-
expect(errors[0]).to eq("Entry [:canvas][:api_token] is required")
|
53
|
-
end
|
54
|
-
|
55
|
-
it 'will fail if extra options are specified' do
|
56
|
-
set_test_settings_structure
|
57
|
-
org.settings = {canvas: {base_url: 'http://', api_token: 'TEST'}, reports: {}, unknown_option: "WHAT IS THIS?"}
|
58
|
-
expect(org.valid?).to be_falsey
|
59
|
-
errors = org.errors.messages[:settings]
|
60
|
-
expect(errors[0]).to eq("Did not expect [:] to contain [unknown_option]")
|
61
|
-
end
|
62
|
-
|
63
|
-
it 'will pass if all structure is maintained' do
|
64
|
-
set_test_settings_structure
|
65
|
-
org.settings = {canvas: {base_url: 'http://', api_token: 'TEST'}, reports: {submissions_report_time_length: 30.minutes, max_recheck_time: 10.hours}}
|
66
|
-
expect(org.valid?).to be_truthy
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
context 'new settings_structure' do
|
71
|
-
let!(:properties) do
|
72
|
-
{
|
73
|
-
canvas: {
|
74
|
-
required: true,
|
75
|
-
type: 'Hash',
|
76
|
-
properties: {
|
77
|
-
api_token: { type: 'String', required: true },
|
78
|
-
base_url: { type: 'String', required: true },
|
79
|
-
},
|
80
|
-
},
|
81
|
-
reports: {
|
82
|
-
required: true,
|
83
|
-
type: 'Hash',
|
84
|
-
allow_additional: true,
|
85
|
-
}
|
86
|
-
}
|
87
|
-
end
|
88
|
-
|
89
|
-
let!(:structure) do
|
90
|
-
{
|
91
|
-
properties: properties,
|
92
|
-
}
|
93
|
-
end
|
94
|
-
|
95
|
-
it_behaves_like("shared stuff")
|
96
|
-
|
97
|
-
describe ':allow_additional' do
|
98
|
-
it 'passes extra properties if allow_additional is a matching Hash' do
|
99
|
-
structure[:allow_additional] = { type: 'String' }
|
100
|
-
set_test_settings_structure
|
101
|
-
org.settings = {canvas: {base_url: 'http://', api_token: 'TEST'}, reports: {}, unknown_option: "WHAT IS THIS?"}
|
102
|
-
expect(org).to be_valid
|
103
|
-
end
|
104
|
-
|
105
|
-
it 'fails extra properties if allow_additional is an unmatching Hash' do
|
106
|
-
structure[:allow_additional] = { type: 'Hash' }
|
107
|
-
set_test_settings_structure
|
108
|
-
org.settings = {canvas: {base_url: 'http://', api_token: 'TEST'}, reports: {}, unknown_option: "WHAT IS THIS?"}
|
109
|
-
expect(org).not_to be_valid
|
110
|
-
end
|
111
|
-
|
112
|
-
it 'passes extra properties if allow_additional is a blank Hash' do
|
113
|
-
structure[:allow_additional] = { }
|
114
|
-
set_test_settings_structure
|
115
|
-
org.settings = {canvas: {base_url: 'http://', api_token: 'TEST'}, reports: {}, unknown_option: "WHAT IS THIS?"}
|
116
|
-
expect(org).to be_valid
|
117
|
-
end
|
118
|
-
end
|
119
|
-
|
120
|
-
describe ':validate' do
|
121
|
-
let!(:properties) do
|
122
|
-
{
|
123
|
-
blah: {
|
124
|
-
type: 'String',
|
125
|
-
validate: -> (v, *args) { v == 'blah' ? nil : '<path> failed validation' },
|
126
|
-
}
|
127
|
-
}
|
128
|
-
end
|
129
|
-
|
130
|
-
it 'supports a custom validation proc' do
|
131
|
-
set_test_settings_structure
|
132
|
-
org.settings = { blah: 'blah' }
|
133
|
-
expect(org).to be_valid
|
134
|
-
end
|
135
|
-
|
136
|
-
it 'replaces <path> with the human readable path' do
|
137
|
-
set_test_settings_structure
|
138
|
-
org.settings = { blah: '' }
|
139
|
-
expect(org.valid?).to be_falsey
|
140
|
-
errors = org.errors.messages[:settings]
|
141
|
-
expect(errors[0]).to eq("[:blah] failed validation")
|
142
|
-
end
|
143
|
-
end
|
144
|
-
end
|
145
|
-
|
146
|
-
context 'old settings_structure' do
|
147
|
-
let!(:structure) do
|
148
|
-
YAML.load("
|
149
|
-
canvas:
|
150
|
-
is_required: true
|
151
|
-
data_type: Hash
|
152
|
-
api_token:
|
153
|
-
is_required: true
|
154
|
-
data_type: String
|
155
|
-
base_url:
|
156
|
-
is_required: true
|
157
|
-
data_type: String
|
158
|
-
reports:
|
159
|
-
is_required: true
|
160
|
-
data_type: Hash
|
161
|
-
active_term_allowance:
|
162
|
-
submissions_report_time_length:
|
163
|
-
is_required: false
|
164
|
-
data_type: ActiveSupport::Duration
|
165
|
-
recheck_wait:
|
166
|
-
data_type: ActiveSupport::Duration
|
167
|
-
max_recheck_time:
|
168
|
-
is_required: false
|
169
|
-
").deep_symbolize_keys
|
170
|
-
end
|
171
|
-
|
172
|
-
it_behaves_like("shared stuff")
|
173
|
-
end
|
174
|
-
end
|
175
|
-
end
|
@@ -1,134 +0,0 @@
|
|
1
|
-
require 'rails_helper'
|
2
|
-
|
3
|
-
module PandaPal
|
4
|
-
PandaPal::Organization
|
5
|
-
|
6
|
-
RSpec.describe OrganizationConcerns::TaskScheduling, type: :model do
|
7
|
-
let!(:organization) { create(:panda_pal_organization) }
|
8
|
-
let(:schedules) { {} }
|
9
|
-
|
10
|
-
before :each do
|
11
|
-
Organization.instance_variable_set(:@_schedule_descriptors, nil)
|
12
|
-
Organization.scheduled_task('0 0 0 * * *', :ident) { }
|
13
|
-
|
14
|
-
allow(Sidekiq).to receive(:remove_schedule)
|
15
|
-
allow(Sidekiq).to receive(:get_schedule) { schedules }
|
16
|
-
end
|
17
|
-
|
18
|
-
def descriptors
|
19
|
-
Organization.instance_variable_get(:@_schedule_descriptors)
|
20
|
-
end
|
21
|
-
|
22
|
-
def descriptor
|
23
|
-
descriptors[descriptors.keys[0]]
|
24
|
-
end
|
25
|
-
|
26
|
-
describe '.scheduled_task' do
|
27
|
-
it 'adds to the set of descriptors' do
|
28
|
-
expect(descriptors).to match(
|
29
|
-
'ident' => {
|
30
|
-
:key=>"ident",
|
31
|
-
:schedule=>"0 0 0 * * *",
|
32
|
-
:worker=>Proc,
|
33
|
-
:queue=>"default",
|
34
|
-
}
|
35
|
-
)
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
describe '.sync_schedules' do
|
40
|
-
it 'adds new schedules' do
|
41
|
-
expect(Sidekiq).to receive(:set_schedule).with(/org:\w+-ident/, anything)
|
42
|
-
Organization.sync_schedules
|
43
|
-
end
|
44
|
-
|
45
|
-
it 'removes schedules for deleted Orgs' do
|
46
|
-
schedules['org:deleted_org-schedule'] = {}
|
47
|
-
expect(Sidekiq).to receive(:remove_schedule).with('org:deleted_org-schedule')
|
48
|
-
Organization.sync_schedules
|
49
|
-
end
|
50
|
-
|
51
|
-
it 'keeps schedules created from other sources' do
|
52
|
-
schedules['other-schedule'] = {}
|
53
|
-
expect(Sidekiq).not_to receive(:remove_schedule).with('other-schedule')
|
54
|
-
Organization.sync_schedules
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
describe '#generate_schedule' do
|
59
|
-
it 'generates the expected schedule' do
|
60
|
-
expect(organization.generate_schedule).to eq({
|
61
|
-
"org:#{organization.name}-ident" => {
|
62
|
-
"cron"=>"0 0 0 * * *",
|
63
|
-
"queue"=>"default",
|
64
|
-
"class"=>"PandaPal::OrganizationConcerns::TaskScheduling::ScheduledTaskExecutor",
|
65
|
-
"args"=>[organization.name, "ident"],
|
66
|
-
}
|
67
|
-
})
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
describe '#schedule_task_cron_time' do
|
72
|
-
before :each do
|
73
|
-
organization.settings = { timezone: 'America/Denver' }
|
74
|
-
end
|
75
|
-
|
76
|
-
it 'includes timezone if in settings' do
|
77
|
-
expect(organization.send(:schedule_task_cron_time, descriptor)).to eq '0 0 0 * * * America/Denver'
|
78
|
-
end
|
79
|
-
|
80
|
-
it 'does not re-append timezone if already present' do
|
81
|
-
descriptor[:schedule] = '1 1 1 * * * America/Chicago'
|
82
|
-
expect(organization.send(:schedule_task_cron_time, descriptor)).to eq '1 1 1 * * * America/Chicago'
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
|
-
describe '#sync_schedule' do
|
87
|
-
it 'adds new schedules' do
|
88
|
-
expect(Sidekiq).to receive(:set_schedule).with(/org:\w+-ident/, anything)
|
89
|
-
organization.sync_schedule
|
90
|
-
end
|
91
|
-
|
92
|
-
it 'removes old jobs' do
|
93
|
-
schedules["org:#{organization.name}-old_schedule"] = {}
|
94
|
-
expect(Sidekiq).to receive(:remove_schedule).with("org:#{organization.name}-old_schedule")
|
95
|
-
organization.sync_schedule
|
96
|
-
end
|
97
|
-
end
|
98
|
-
|
99
|
-
describe 'SettingsValidation' do
|
100
|
-
before :each do
|
101
|
-
organization.settings = {}
|
102
|
-
end
|
103
|
-
|
104
|
-
it 'allows [:task_schedules] entry to be missing' do
|
105
|
-
expect(organization).to be_valid
|
106
|
-
end
|
107
|
-
|
108
|
-
it 'does not require [:task_schedules] sub-entries' do
|
109
|
-
organization.settings[:task_schedules] = {}
|
110
|
-
expect(organization).to be_valid
|
111
|
-
end
|
112
|
-
|
113
|
-
it 'allows task entry to be false' do
|
114
|
-
organization.settings[:task_schedules] = { ident: false }
|
115
|
-
expect(organization).to be_valid
|
116
|
-
end
|
117
|
-
|
118
|
-
it 'allows task entry to be a valid cron string' do
|
119
|
-
organization.settings[:task_schedules] = { ident: '0 0 0 * * * America/Denver' }
|
120
|
-
expect(organization).to be_valid
|
121
|
-
end
|
122
|
-
|
123
|
-
it 'does not allow task entry to be an invalid cron string' do
|
124
|
-
organization.settings[:task_schedules] = { ident: 'blort' }
|
125
|
-
expect(organization).not_to be_valid
|
126
|
-
end
|
127
|
-
|
128
|
-
it 'does not allow sub-entries for unknown tasks' do
|
129
|
-
organization.settings[:task_schedules] = { missing_ident: '0 0 0 * * * America/Denver' }
|
130
|
-
expect(organization).not_to be_valid
|
131
|
-
end
|
132
|
-
end
|
133
|
-
end
|
134
|
-
end
|