inferno_core 0.6.17 → 1.0.1
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/inferno/apps/cli/execute.rb +1 -1
- data/lib/inferno/apps/cli/templates/.rubocop.yml +2 -2
- data/lib/inferno/apps/cli/templates/lib/%library_name%/example_suite.rb.tt +0 -1
- data/lib/inferno/apps/cli/templates/spec/%library_name%/patient_group_spec.rb.tt +11 -10
- data/lib/inferno/apps/web/controllers/test_runs/create.rb +1 -1
- data/lib/inferno/apps/web/controllers/test_session_form_post_controller.rb +32 -1
- data/lib/inferno/apps/web/controllers/test_sessions/client_show.rb +1 -1
- data/lib/inferno/apps/web/router.rb +30 -3
- data/lib/inferno/apps/web/serializers/requirements_filtering_extractor.rb +17 -0
- data/lib/inferno/apps/web/serializers/test.rb +2 -1
- data/lib/inferno/apps/web/serializers/test_group.rb +7 -3
- data/lib/inferno/apps/web/serializers/test_session.rb +12 -2
- data/lib/inferno/apps/web/serializers/test_suite.rb +9 -6
- data/lib/inferno/apps/web/templates/test_kit.html.erb +316 -0
- data/lib/inferno/entities/test_kit.rb +4 -0
- data/lib/inferno/public/bundle.js +34 -34
- data/lib/inferno/public/bundle.js.LICENSE.txt +1 -1
- data/lib/inferno/public/common.js +48 -0
- data/lib/inferno/public/session.js +35 -0
- data/lib/inferno/public/test_kits.js +59 -0
- data/lib/inferno/repositories/test_kits.rb +11 -0
- data/lib/inferno/utils/persist_inputs.rb +4 -4
- data/lib/inferno/version.rb +1 -1
- metadata +36 -3
- /data/lib/inferno/apps/web/{index.html.erb → templates/client_index.html.erb} +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d8f8cb64cc07cf0ea3225a930fa47c6e54619da91d739912452cf0b8c8e27568
|
4
|
+
data.tar.gz: fcc3c0d0b6f20a0cb34021f26a79f32a8abff955333a105a4b7cc94de0307db7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 749b0cc95ead3ef3a7c200918f314aae140c789f98d10199f26b65d973c23b269115cfdbe45e19358e0a13cc71f284c7366f7c8b90c29277b52eaed95215afc3
|
7
|
+
data.tar.gz: 593752aa7a14ec8c04b921403eae863e72d84e2de4f452ea656d2a56bf102597e5a88c444447cb02ea0bf93918039cf51ac88dce58338686da1d7cf8f861f5d1
|
@@ -115,7 +115,7 @@ module Inferno
|
|
115
115
|
test_session.suite_options
|
116
116
|
)
|
117
117
|
|
118
|
-
persist_inputs(session_data_repo, create_params(test_session, suite),
|
118
|
+
persist_inputs(session_data_repo, create_params(test_session, suite), runnable)
|
119
119
|
|
120
120
|
dispatch_job(test_run)
|
121
121
|
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# @note includes RSpec shared context 'when testing a runnable'
|
1
2
|
RSpec.describe <%= module_name %>::PatientGroup do
|
2
3
|
let(:suite_id) { '<%= test_suite_id %>' }
|
3
4
|
let(:group) { suite.groups[1] }
|
@@ -7,7 +8,7 @@ RSpec.describe <%= module_name %>::PatientGroup do
|
|
7
8
|
outcomes: [{
|
8
9
|
issues: []
|
9
10
|
}],
|
10
|
-
sessionId:
|
11
|
+
sessionId: test_session.id
|
11
12
|
}
|
12
13
|
end
|
13
14
|
let(:error_outcome) do
|
@@ -19,7 +20,7 @@ RSpec.describe <%= module_name %>::PatientGroup do
|
|
19
20
|
level: 'ERROR'
|
20
21
|
}]
|
21
22
|
}],
|
22
|
-
sessionId:
|
23
|
+
sessionId: test_session.id
|
23
24
|
}
|
24
25
|
end
|
25
26
|
|
@@ -34,7 +35,7 @@ RSpec.describe <%= module_name %>::PatientGroup do
|
|
34
35
|
|
35
36
|
result = run(test, url: url, patient_id: patient_id)
|
36
37
|
|
37
|
-
expect(result.result).to eq('pass')
|
38
|
+
expect(result.result).to eq('pass'), result.result_message
|
38
39
|
end
|
39
40
|
|
40
41
|
it 'fails if a 200 is not received' do
|
@@ -44,7 +45,7 @@ RSpec.describe <%= module_name %>::PatientGroup do
|
|
44
45
|
|
45
46
|
result = run(test, url: url, patient_id: patient_id)
|
46
47
|
|
47
|
-
expect(result.result).to eq('fail')
|
48
|
+
expect(result.result).to eq('fail'), result.result_message
|
48
49
|
expect(result.result_message).to match(/200/)
|
49
50
|
end
|
50
51
|
|
@@ -55,7 +56,7 @@ RSpec.describe <%= module_name %>::PatientGroup do
|
|
55
56
|
|
56
57
|
result = run(test, url: url, patient_id: patient_id)
|
57
58
|
|
58
|
-
expect(result.result).to eq('fail')
|
59
|
+
expect(result.result).to eq('fail'), result.result_message
|
59
60
|
expect(result.result_message).to match(/Patient/)
|
60
61
|
end
|
61
62
|
|
@@ -66,7 +67,7 @@ RSpec.describe <%= module_name %>::PatientGroup do
|
|
66
67
|
|
67
68
|
result = run(test, url: url, patient_id: patient_id)
|
68
69
|
|
69
|
-
expect(result.result).to eq('fail')
|
70
|
+
expect(result.result).to eq('fail'), result.result_message
|
70
71
|
expect(result.result_message).to match(/resource with id/)
|
71
72
|
end
|
72
73
|
end
|
@@ -75,7 +76,7 @@ RSpec.describe <%= module_name %>::PatientGroup do
|
|
75
76
|
let(:test) { group.tests.last }
|
76
77
|
|
77
78
|
it 'passes if the resource is valid' do
|
78
|
-
stub_request(:post,
|
79
|
+
stub_request(:post, validation_url)
|
79
80
|
.with(query: hash_including({}))
|
80
81
|
.to_return(status: 200, body: success_outcome.to_json)
|
81
82
|
|
@@ -89,11 +90,11 @@ RSpec.describe <%= module_name %>::PatientGroup do
|
|
89
90
|
|
90
91
|
result = run(test, url: url)
|
91
92
|
|
92
|
-
expect(result.result).to eq('pass')
|
93
|
+
expect(result.result).to eq('pass'), result.result_message
|
93
94
|
end
|
94
95
|
|
95
96
|
it 'fails if the resource is not valid' do
|
96
|
-
stub_request(:post,
|
97
|
+
stub_request(:post, validation_url)
|
97
98
|
.with(query: hash_including({}))
|
98
99
|
.to_return(status: 200, body: error_outcome.to_json)
|
99
100
|
|
@@ -107,7 +108,7 @@ RSpec.describe <%= module_name %>::PatientGroup do
|
|
107
108
|
|
108
109
|
result = run(test, url: url)
|
109
110
|
|
110
|
-
expect(result.result).to eq('fail')
|
111
|
+
expect(result.result).to eq('fail'), result.result_message
|
111
112
|
end
|
112
113
|
end
|
113
114
|
end
|
@@ -35,7 +35,7 @@ module Inferno
|
|
35
35
|
|
36
36
|
res.body = serialize(test_run, suite_options: test_session.suite_options)
|
37
37
|
|
38
|
-
persist_inputs(session_data_repo, req.params, test_run)
|
38
|
+
persist_inputs(session_data_repo, req.params, test_run.runnable)
|
39
39
|
|
40
40
|
Jobs.perform(Jobs::ExecuteTestRun, test_run.id)
|
41
41
|
rescue Sequel::ValidationFailed, Sequel::ForeignKeyConstraintViolation,
|
@@ -1,12 +1,18 @@
|
|
1
|
+
require_relative '../../../utils/verify_runnable'
|
2
|
+
require_relative '../../../utils/persist_inputs'
|
3
|
+
|
1
4
|
module Inferno
|
2
5
|
module Web
|
3
6
|
module Controllers
|
4
7
|
class TestSessionFormPostController < Hanami::Action
|
8
|
+
include ::Inferno::Utils::VerifyRunnable
|
9
|
+
include ::Inferno::Utils::PersistInputs
|
10
|
+
|
5
11
|
def self.call(...)
|
6
12
|
new.call(...)
|
7
13
|
end
|
8
14
|
|
9
|
-
def handle(req, res)
|
15
|
+
def handle(req, res) # rubocop:disable Metrics/CyclomaticComplexity
|
10
16
|
test_suite_id = req.params[:test_suite_id]
|
11
17
|
|
12
18
|
test_suite = Inferno::Repositories::TestSuites.new.find(test_suite_id)
|
@@ -31,7 +37,32 @@ module Inferno
|
|
31
37
|
repo.apply_preset(session, preset_id)
|
32
38
|
end
|
33
39
|
|
40
|
+
inputs = req.params[:inputs]
|
41
|
+
|
42
|
+
if inputs.present?
|
43
|
+
begin
|
44
|
+
verify_runnable(
|
45
|
+
test_suite,
|
46
|
+
inputs,
|
47
|
+
session.suite_options
|
48
|
+
)
|
49
|
+
rescue Inferno::Exceptions::RequiredInputsNotFound => e
|
50
|
+
Application['logger'].info("#{e.message}. Can be added later at test run creation.")
|
51
|
+
end
|
52
|
+
|
53
|
+
params.merge!(inputs:, test_session_id: session.id)
|
54
|
+
|
55
|
+
session_data_repo = Inferno::Repositories::SessionData.new
|
56
|
+
persist_inputs(session_data_repo, params, test_suite)
|
57
|
+
|
58
|
+
end
|
59
|
+
|
34
60
|
res.redirect_to "#{Inferno::Application['base_url']}/#{test_suite_id}/#{session.id}"
|
61
|
+
rescue Inferno::Exceptions::NotUserRunnableException => e
|
62
|
+
halt 422, { errors: e.message }.to_json
|
63
|
+
rescue StandardError => e
|
64
|
+
Application['logger'].error(e.full_message)
|
65
|
+
halt 500, { errors: e.message }.to_json
|
35
66
|
end
|
36
67
|
end
|
37
68
|
end
|
@@ -1,5 +1,8 @@
|
|
1
1
|
require 'erb'
|
2
|
+
require 'kramdown'
|
3
|
+
require 'kramdown-parser-gfm'
|
2
4
|
require_relative '../../feature'
|
5
|
+
require_relative '../../repositories/test_kits'
|
3
6
|
|
4
7
|
Dir.glob(File.join(__dir__, 'controllers', '**', '*.rb')).each { |path| require_relative path }
|
5
8
|
|
@@ -7,9 +10,11 @@ module Inferno
|
|
7
10
|
module Web
|
8
11
|
client_page = ERB.new(
|
9
12
|
File.read(
|
10
|
-
File.join(Inferno::Application.root, 'lib', 'inferno', 'apps', 'web', '
|
13
|
+
File.join(Inferno::Application.root, 'lib', 'inferno', 'apps', 'web', 'templates', 'client_index.html.erb')
|
11
14
|
)
|
12
15
|
).result
|
16
|
+
|
17
|
+
test_kit_template = ERB.new(File.read(File.join(__dir__, 'templates', 'test_kit.html.erb')))
|
13
18
|
CLIENT_PAGE_RESPONSE = ->(_env) { [200, { 'Content-Type' => 'text/html' }, [client_page]] }
|
14
19
|
|
15
20
|
base_path = Application['base_path']&.delete_prefix('/')
|
@@ -69,7 +74,16 @@ module Inferno
|
|
69
74
|
|
70
75
|
# Should not need Content-Type header but GitHub Codespaces will not work without them.
|
71
76
|
# This could be investigated and likely removed if addressed properly elsewhere.
|
72
|
-
get '/',
|
77
|
+
get '/',
|
78
|
+
to: lambda { |env|
|
79
|
+
local_test_kit = Inferno::Repositories::TestKits.new.local_test_kit
|
80
|
+
if local_test_kit.present?
|
81
|
+
base = Inferno::Application['base_path'].present? ? "/#{Inferno::Application['base_path']}" : ''
|
82
|
+
[301, { 'Location' => "#{base}/#{local_test_kit.url_fragment}" }, []]
|
83
|
+
else
|
84
|
+
CLIENT_PAGE_RESPONSE.call(env)
|
85
|
+
end
|
86
|
+
}
|
73
87
|
get '/jwks.json', to: lambda { |_env|
|
74
88
|
[200, { 'Content-Type' => 'application/json' }, [Inferno::JWKS.jwks_json]]
|
75
89
|
}, as: :jwks
|
@@ -87,7 +101,20 @@ module Inferno
|
|
87
101
|
|
88
102
|
Inferno::Repositories::TestSuites.all.map { |suite| "/#{suite.id}" }.each do |suite_path|
|
89
103
|
Application['logger'].info("Registering suite route: #{suite_path}")
|
90
|
-
get suite_path, to:
|
104
|
+
get suite_path, to: lambda { |env|
|
105
|
+
test_kit = Inferno::Repositories::TestKits.new.test_kit_for_suite(suite_path.delete_prefix('/'))
|
106
|
+
if test_kit.present?
|
107
|
+
[200, { 'Content-Type' => 'text/html' }, [test_kit_template.result_with_hash(test_kit:)]]
|
108
|
+
else
|
109
|
+
CLIENT_PAGE_RESPONSE.call(env)
|
110
|
+
end
|
111
|
+
}
|
112
|
+
end
|
113
|
+
|
114
|
+
Inferno::Repositories::TestKits.all.each do |test_kit|
|
115
|
+
Application['logger'].info("Registering test kit route: /#{test_kit.url_fragment}")
|
116
|
+
get "/#{test_kit.url_fragment}",
|
117
|
+
to: ->(_env) { [200, { 'Content-Type' => 'text/html' }, [test_kit_template.result_with_hash(test_kit:)]] }
|
91
118
|
end
|
92
119
|
|
93
120
|
get '/test_sessions/:id', to: Inferno::Web::Controllers::TestSessions::ClientShow, as: :client_session_show
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Inferno
|
2
|
+
module Web
|
3
|
+
module Serializers
|
4
|
+
class RequirementsFilteringExtractor < Blueprinter::Extractor
|
5
|
+
def extract(_field_name, runnable, local_options, _options)
|
6
|
+
if local_options[:suite_requirement_ids].blank?
|
7
|
+
runnable.verifies_requirements
|
8
|
+
else
|
9
|
+
runnable.verifies_requirements.select do |requirement_id|
|
10
|
+
local_options[:suite_requirement_ids].include? requirement_id
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require_relative 'hash_value_extractor'
|
2
2
|
require_relative 'input'
|
3
|
+
require_relative 'requirements_filtering_extractor'
|
3
4
|
|
4
5
|
module Inferno
|
5
6
|
module Web
|
@@ -20,7 +21,7 @@ module Inferno
|
|
20
21
|
field :input_instructions
|
21
22
|
field :user_runnable?, name: :user_runnable
|
22
23
|
field :optional?, name: :optional
|
23
|
-
field :verifies_requirements, if: :field_present
|
24
|
+
field :verifies_requirements, if: :field_present?, extractor: RequirementsFilteringExtractor
|
24
25
|
end
|
25
26
|
end
|
26
27
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require_relative 'hash_value_extractor'
|
2
|
+
require_relative 'requirements_filtering_extractor'
|
1
3
|
require_relative 'test'
|
2
4
|
|
3
5
|
module Inferno
|
@@ -21,18 +23,20 @@ module Inferno
|
|
21
23
|
end
|
22
24
|
field :test_groups do |group, options|
|
23
25
|
suite_options = options[:suite_options]
|
24
|
-
|
26
|
+
suite_requirement_ids = options[:suite_requirement_ids]
|
27
|
+
TestGroup.render_as_hash(group.groups(suite_options), suite_options:, suite_requirement_ids:)
|
25
28
|
end
|
26
29
|
field :tests do |group, options|
|
27
30
|
suite_options = options[:suite_options]
|
28
|
-
|
31
|
+
suite_requirement_ids = options[:suite_requirement_ids]
|
32
|
+
Test.render_as_hash(group.tests(suite_options), suite_options:, suite_requirement_ids:)
|
29
33
|
end
|
30
34
|
field :inputs do |group, options|
|
31
35
|
suite_options = options[:suite_options]
|
32
36
|
Input.render_as_hash(group.available_inputs(suite_options).values)
|
33
37
|
end
|
34
38
|
field :output_definitions, name: :outputs, extractor: HashValueExtractor
|
35
|
-
field :verifies_requirements, if: :field_present
|
39
|
+
field :verifies_requirements, if: :field_present?, extractor: RequirementsFilteringExtractor
|
36
40
|
end
|
37
41
|
end
|
38
42
|
end
|
@@ -10,8 +10,18 @@ module Inferno
|
|
10
10
|
field :test_suite_id
|
11
11
|
association :suite_options, blueprint: SuiteOption
|
12
12
|
|
13
|
-
field :test_suite do |
|
14
|
-
|
13
|
+
field :test_suite do |test_session, _options|
|
14
|
+
suite_requirement_ids =
|
15
|
+
Inferno::Repositories::Requirements.new
|
16
|
+
.requirements_for_suite(test_session.test_suite_id, test_session.id)
|
17
|
+
.map(&:id)
|
18
|
+
|
19
|
+
TestSuite.render_as_hash(
|
20
|
+
test_session.test_suite,
|
21
|
+
view: :full,
|
22
|
+
suite_options: test_session.suite_options,
|
23
|
+
suite_requirement_ids:
|
24
|
+
)
|
15
25
|
end
|
16
26
|
end
|
17
27
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require_relative 'preset'
|
2
|
+
require_relative 'requirements_filtering_extractor'
|
2
3
|
require_relative 'requirement_set'
|
3
4
|
require_relative 'suite_option'
|
4
5
|
require_relative 'test_group'
|
@@ -22,6 +23,11 @@ module Inferno
|
|
22
23
|
suite.test_count(options[:suite_options])
|
23
24
|
end
|
24
25
|
|
26
|
+
field :inputs do |suite, options|
|
27
|
+
suite_options = options[:suite_options]
|
28
|
+
Input.render_as_hash(suite.available_inputs(suite_options).values)
|
29
|
+
end
|
30
|
+
|
25
31
|
association :suite_options, blueprint: SuiteOption
|
26
32
|
association :presets, view: :summary, blueprint: Preset
|
27
33
|
end
|
@@ -31,13 +37,10 @@ module Inferno
|
|
31
37
|
|
32
38
|
field :test_groups do |suite, options|
|
33
39
|
suite_options = options[:suite_options]
|
34
|
-
|
40
|
+
suite_requirement_ids = options[:suite_requirement_ids]
|
41
|
+
TestGroup.render_as_hash(suite.groups(suite_options), suite_options:, suite_requirement_ids:)
|
35
42
|
end
|
36
43
|
field :configuration_messages
|
37
|
-
field :inputs do |suite, options|
|
38
|
-
suite_options = options[:suite_options]
|
39
|
-
Input.render_as_hash(suite.available_inputs(suite_options).values)
|
40
|
-
end
|
41
44
|
field :requirement_sets, if: :field_present? do |suite, options|
|
42
45
|
selected_options = options[:suite_options] || []
|
43
46
|
requirement_sets = suite.requirement_sets.select do |requirement_set|
|
@@ -46,7 +49,7 @@ module Inferno
|
|
46
49
|
|
47
50
|
RequirementSet.render_as_hash(requirement_sets)
|
48
51
|
end
|
49
|
-
field :verifies_requirements, if: :field_present
|
52
|
+
field :verifies_requirements, if: :field_present?, extractor: RequirementsFilteringExtractor
|
50
53
|
end
|
51
54
|
end
|
52
55
|
end
|