davinci_pas_test_kit 0.12.1 → 0.13.0
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/config/presets/pas_server_subscription_creation_against_pas_client.json +32 -0
- data/lib/davinci_pas_test_kit/certs/InfernoCA.key +52 -0
- data/lib/davinci_pas_test_kit/certs/InfernoCA.pem +35 -0
- data/lib/davinci_pas_test_kit/certs/TestKit.pem +32 -0
- data/lib/davinci_pas_test_kit/certs/TestKitPrivateKey.key +28 -0
- data/lib/davinci_pas_test_kit/client_suite.rb +141 -100
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/client_registration/configuration_other_display_test.rb +46 -0
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/client_registration/configuration_smart_display_test.rb +37 -0
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/client_registration/configuration_udap_display_test.rb +37 -0
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/client_registration/other_auth_attest_test.rb +36 -0
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/client_tests/pas_client_approval_submit_test.rb +24 -10
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/client_tests/pas_client_denial_submit_test.rb +23 -10
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/client_tests/pas_client_inquire_must_support_test.rb +21 -9
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/client_tests/pas_client_inquire_request_bundle_validation_test.rb +4 -0
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/client_tests/pas_client_pended_submit_test.rb +30 -14
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/client_tests/pas_client_request_bundle_validation_test.rb +6 -0
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/client_tests/pas_client_response_attest.rb +4 -9
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/client_tests/pas_client_submit_must_support_test.rb +24 -9
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/client_tests/pas_client_subscription_create_test.rb +26 -13
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/client_tests/pas_client_subscription_pas_conformance_test.rb +6 -24
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/error_tests/pas_inquiry_error_test.rb +1 -0
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/error_tests/pas_submission_error_test.rb +3 -0
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/notification/pas_subscription_notification_test.rb +24 -20
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/pas_client_approval_group.rb +6 -4
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/pas_client_auth_smart_group.rb +32 -0
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/pas_client_auth_udap_group.rb +31 -0
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/pas_client_denial_group.rb +10 -4
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/pas_client_must_support_group.rb +29 -0
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/pas_client_options.rb +25 -0
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/pas_client_pended_group.rb +11 -4
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/pas_client_registration_group.rb +63 -0
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/pas_client_subscription_setup_group.rb +23 -0
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/pas_client_workflows_group.rb +21 -0
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/pas_server_subscription_input_conformance.rb +35 -0
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/pas_server_subscription_setup.rb +43 -0
- data/lib/davinci_pas_test_kit/descriptions.rb +10 -0
- data/lib/davinci_pas_test_kit/docs/client_suite_description_v201.md +203 -79
- data/lib/davinci_pas_test_kit/docs/demo/PAS Client Suite Demonstration.postman_collection.json +246 -0
- data/lib/davinci_pas_test_kit/docs/server_suite_description_v201.md +21 -10
- data/lib/davinci_pas_test_kit/endpoints/claim_endpoint.rb +13 -1
- data/lib/davinci_pas_test_kit/endpoints/subscription_create_endpoint.rb +13 -1
- data/lib/davinci_pas_test_kit/endpoints/subscription_status_endpoint.rb +10 -1
- data/lib/davinci_pas_test_kit/endpoints/token_endpoint.rb +29 -15
- data/lib/davinci_pas_test_kit/generated/v2.0.1/beneficiary/metadata.yml +2 -1
- data/lib/davinci_pas_test_kit/generated/v2.0.1/claim/claim_operation_test.rb +1 -1
- data/lib/davinci_pas_test_kit/generated/v2.0.1/claim/metadata.yml +28 -17
- data/lib/davinci_pas_test_kit/generated/v2.0.1/claim_inquiry/claim_inquiry_operation_test.rb +1 -2
- data/lib/davinci_pas_test_kit/generated/v2.0.1/claim_inquiry/client_inquire_request_claim_inquiry_must_support_test.rb +4 -1
- data/lib/davinci_pas_test_kit/generated/v2.0.1/claim_inquiry/metadata.yml +7 -1
- data/lib/davinci_pas_test_kit/generated/v2.0.1/claim_inquiry/server_inquire_request_claim_inquiry_must_support_test.rb +3 -1
- data/lib/davinci_pas_test_kit/generated/v2.0.1/claim_update/client_submit_request_claim_update_must_support_test.rb +9 -3
- data/lib/davinci_pas_test_kit/generated/v2.0.1/claim_update/metadata.yml +28 -17
- data/lib/davinci_pas_test_kit/generated/v2.0.1/claim_update/server_submit_request_claim_update_must_support_test.rb +9 -3
- data/lib/davinci_pas_test_kit/generated/v2.0.1/claiminquiryresponse/metadata.yml +6 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/claiminquiryresponse/server_inquire_response_claiminquiryresponse_must_support_test.rb +1 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/claimresponse/metadata.yml +8 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/claimresponse/server_submit_response_claimresponse_must_support_test.rb +1 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/communication_request/metadata.yml +4 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/coverage/metadata.yml +11 -5
- data/lib/davinci_pas_test_kit/generated/v2.0.1/device_request/metadata.yml +2 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/encounter/metadata.yml +6 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/insurer/metadata.yml +4 -2
- data/lib/davinci_pas_test_kit/generated/v2.0.1/medication_request/metadata.yml +2 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/metadata.yml +153 -53
- data/lib/davinci_pas_test_kit/generated/v2.0.1/nutrition_order/metadata.yml +2 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/pas_inquiry_request_bundle/metadata.yml +2 -1
- data/lib/davinci_pas_test_kit/generated/v2.0.1/pas_inquiry_request_bundle/server_pas_inquiry_request_bundle_validation_test.rb +0 -2
- data/lib/davinci_pas_test_kit/generated/v2.0.1/pas_inquiry_response_bundle/metadata.yml +2 -1
- data/lib/davinci_pas_test_kit/generated/v2.0.1/pas_inquiry_response_bundle/server_pas_inquiry_response_bundle_validation_test.rb +2 -3
- data/lib/davinci_pas_test_kit/generated/v2.0.1/pas_request_bundle/metadata.yml +2 -1
- data/lib/davinci_pas_test_kit/generated/v2.0.1/pas_request_bundle/server_pas_request_bundle_validation_test.rb +0 -2
- data/lib/davinci_pas_test_kit/generated/v2.0.1/pas_response_bundle/metadata.yml +2 -1
- data/lib/davinci_pas_test_kit/generated/v2.0.1/pas_response_bundle/server_pas_response_bundle_validation_test.rb +2 -3
- data/lib/davinci_pas_test_kit/generated/v2.0.1/pas_server_approval_use_case_group.rb +0 -1
- data/lib/davinci_pas_test_kit/generated/v2.0.1/pas_server_denial_use_case_group.rb +0 -1
- data/lib/davinci_pas_test_kit/generated/v2.0.1/pas_server_must_support_use_case_group.rb +3 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/pas_server_pended_use_case_group.rb +10 -3
- data/lib/davinci_pas_test_kit/generated/v2.0.1/practitioner/metadata.yml +2 -1
- data/lib/davinci_pas_test_kit/generated/v2.0.1/practitioner_role/metadata.yml +4 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/requestor/metadata.yml +4 -2
- data/lib/davinci_pas_test_kit/generated/v2.0.1/server_suite.rb +8 -5
- data/lib/davinci_pas_test_kit/generated/v2.0.1/service_request/metadata.yml +2 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/task/metadata.yml +4 -0
- data/lib/davinci_pas_test_kit/generator/group_generator.rb +20 -4
- data/lib/davinci_pas_test_kit/generator/group_metadata_extractor.rb +2 -2
- data/lib/davinci_pas_test_kit/generator/ig_resources.rb +4 -0
- data/lib/davinci_pas_test_kit/generator/must_support_test_generator.rb +14 -3
- data/lib/davinci_pas_test_kit/generator/operation_test_generator.rb +16 -3
- data/lib/davinci_pas_test_kit/generator/templates/group.rb.erb +10 -3
- data/lib/davinci_pas_test_kit/generator/templates/must_support.rb.erb +3 -0
- data/lib/davinci_pas_test_kit/generator/templates/operation.rb.erb +4 -1
- data/lib/davinci_pas_test_kit/generator/templates/suite.rb.erb +8 -5
- data/lib/davinci_pas_test_kit/generator/templates/validation.rb.erb +5 -4
- data/lib/davinci_pas_test_kit/generator/validation_test_generator.rb +12 -1
- data/lib/davinci_pas_test_kit/must_support_test.rb +2 -202
- data/lib/davinci_pas_test_kit/pas_bundle_validation.rb +4 -4
- data/lib/davinci_pas_test_kit/pas_subscription_verification.rb +30 -0
- data/lib/davinci_pas_test_kit/requirements/davinci-pas-test-kit_out_of_scope_requirements.csv +11 -0
- data/lib/davinci_pas_test_kit/requirements/davinci-pas-test-kit_requirements.csv +214 -0
- data/lib/davinci_pas_test_kit/requirements/generated/davinci-pas-test-kit_requirements_coverage.csv +214 -0
- data/lib/davinci_pas_test_kit/session_identification.rb +45 -0
- data/lib/davinci_pas_test_kit/tags.rb +1 -0
- data/lib/davinci_pas_test_kit/urls.rb +61 -9
- data/lib/davinci_pas_test_kit/version.rb +2 -2
- data/lib/davinci_pas_test_kit.rb +1 -0
- data/lib/inferno_requirements_tools/ext/inferno_core/runnable.rb +22 -0
- data/lib/inferno_requirements_tools/tasks/requirements_coverage.rb +284 -0
- data/lib/requirements_config.yaml +17 -0
- metadata +62 -10
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/client_tests/pas_client_token_request_test.rb +0 -31
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/client_tests/pas_client_token_validation_test.rb +0 -18
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/pas_client_authentication_group.rb +0 -49
- data/lib/davinci_pas_test_kit/generator/must_support_metadata_extractor.rb +0 -327
@@ -0,0 +1,22 @@
|
|
1
|
+
module Inferno
|
2
|
+
module DSL
|
3
|
+
# This module contains the DSL for defining child entities in the test
|
4
|
+
# definition framework.
|
5
|
+
module Runnable
|
6
|
+
# Set/Get the IDs of requirements verifed by this runnable
|
7
|
+
# Set with [] to clear the list
|
8
|
+
#
|
9
|
+
# @param requirements [Array<String>]
|
10
|
+
# @return [Array<String>] the requirement IDs
|
11
|
+
def verifies_requirements(*requirement_ids)
|
12
|
+
if requirement_ids.empty?
|
13
|
+
@requirement_ids || []
|
14
|
+
elsif requirement_ids == [[]]
|
15
|
+
@requirement_ids = []
|
16
|
+
else
|
17
|
+
@requirement_ids = requirement_ids
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,284 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'csv'
|
4
|
+
require 'yaml'
|
5
|
+
require_relative '../ext/inferno_core/runnable'
|
6
|
+
|
7
|
+
module InfernoRequirementsTools
|
8
|
+
module Tasks
|
9
|
+
# This class manages the mapping of test kit tests to requirements that they verify
|
10
|
+
# and creates a CSV file with the tests that cover each requirement.
|
11
|
+
# It expects a CSV file in the repo at `lib/[test kit id]/requirements/[test kit id]_requirements.csv`
|
12
|
+
# that serves as the source of the requirement set for the test kit. The requirements in
|
13
|
+
# this files are identified by a requirement set and an id and tests, groups, and suites
|
14
|
+
# within in the test kit can claim that they verify a requirement by including a reference
|
15
|
+
# to that requirementin the form <requirement set>@<id> in their `verifies_requirements` field.
|
16
|
+
# Requirements that are out of scope can be listed in a companion file
|
17
|
+
# `lib/[test kit id]/requirements/[test kit id]_out_of_scope_requirements.csv`.
|
18
|
+
#
|
19
|
+
# The `run` method generates a CSV file at
|
20
|
+
# `lib/[test kit id]/requirements/generated/[test kit id]_requirements_coverage.csv``.
|
21
|
+
# This file will be identical to the input spreadsheet, plus an additional column which holds a comma separated
|
22
|
+
# list of inferno test IDs that test each requirement. These test IDs are Inferno short form IDs that represent the
|
23
|
+
# position of the test within its group and suite. For example, the fifth test in the second group will have an ID
|
24
|
+
# of 2.05. This ID is also shown in the Inferno web UI.
|
25
|
+
#
|
26
|
+
# The `run_check` method will check whether the previously generated file is up-to-date.
|
27
|
+
class RequirementsCoverage
|
28
|
+
VERSION = '0.2.0' # update when making meaningful changes to this method for tracking used versions
|
29
|
+
CONFIG = YAML.load_file(File.join('lib', 'requirements_config.yaml'))
|
30
|
+
|
31
|
+
TEST_KIT_ID = CONFIG['test_kit_id']
|
32
|
+
TEST_SUITES = CONFIG['suites'].map do |test_suite|
|
33
|
+
Object.const_get(test_suite['class_name'])
|
34
|
+
end
|
35
|
+
|
36
|
+
SUITE_ID_TO_ACTOR_MAP = CONFIG['suites'].each_with_object({}) do |test_suite, hash|
|
37
|
+
hash[test_suite['id']] = test_suite['suite_actor']
|
38
|
+
end
|
39
|
+
|
40
|
+
# Derivative constants
|
41
|
+
TEST_KIT_CODE_FOLDER = TEST_KIT_ID
|
42
|
+
DASHERIZED_TEST_KIT_ID = TEST_KIT_ID.gsub('_', '-')
|
43
|
+
INPUT_HEADERS = [
|
44
|
+
'Req Set',
|
45
|
+
'ID',
|
46
|
+
'URL',
|
47
|
+
'Requirement',
|
48
|
+
'Conformance',
|
49
|
+
'Actor',
|
50
|
+
'Sub-Requirement(s)',
|
51
|
+
'Conditionality'
|
52
|
+
].freeze
|
53
|
+
SHORT_ID_HEADER = 'Short ID(s)'
|
54
|
+
FULL_ID_HEADER = 'Full ID(s)'
|
55
|
+
INPUT_FILE_NAME = "#{DASHERIZED_TEST_KIT_ID}_requirements.csv".freeze
|
56
|
+
INPUT_FILE = File.join('lib', TEST_KIT_CODE_FOLDER, 'requirements', INPUT_FILE_NAME).freeze
|
57
|
+
NOT_TESTED_FILE_NAME = "#{DASHERIZED_TEST_KIT_ID}_out_of_scope_requirements.csv".freeze
|
58
|
+
NOT_TESTED_FILE = File.join('lib', TEST_KIT_CODE_FOLDER, 'requirements', NOT_TESTED_FILE_NAME).freeze
|
59
|
+
OUTPUT_HEADERS = INPUT_HEADERS + TEST_SUITES.flat_map do |suite|
|
60
|
+
["#{suite.title} #{SHORT_ID_HEADER}", "#{suite.title} #{FULL_ID_HEADER}"]
|
61
|
+
end
|
62
|
+
OUTPUT_FILE_NAME = "#{DASHERIZED_TEST_KIT_ID}_requirements_coverage.csv".freeze
|
63
|
+
OUTPUT_FILE_DIRECTORY = File.join('lib', TEST_KIT_CODE_FOLDER, 'requirements', 'generated')
|
64
|
+
OUTPUT_FILE = File.join(OUTPUT_FILE_DIRECTORY, OUTPUT_FILE_NAME).freeze
|
65
|
+
|
66
|
+
def input_rows
|
67
|
+
@input_rows ||=
|
68
|
+
CSV.parse(File.open(INPUT_FILE, 'r:bom|utf-8'), headers: true).map do |row|
|
69
|
+
row.to_h.slice(*INPUT_HEADERS)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def not_tested_requirements_map
|
74
|
+
@not_tested_requirements_map ||= load_not_tested_requirements
|
75
|
+
end
|
76
|
+
|
77
|
+
def load_not_tested_requirements
|
78
|
+
return {} unless File.exist?(NOT_TESTED_FILE)
|
79
|
+
|
80
|
+
not_tested_requirements = {}
|
81
|
+
CSV.parse(File.open(NOT_TESTED_FILE, 'r:bom|utf-8'), headers: true).each do |row|
|
82
|
+
row_hash = row.to_h
|
83
|
+
not_tested_requirements["#{row_hash['Req Set']}@#{row_hash['ID']}"] = row_hash
|
84
|
+
end
|
85
|
+
|
86
|
+
not_tested_requirements
|
87
|
+
end
|
88
|
+
|
89
|
+
# Of the form:
|
90
|
+
# {
|
91
|
+
# 'req-id-1': [
|
92
|
+
# { short_id: 'short-id-1', full_id: 'long-id-1', suite_id: 'suite-id-1' },
|
93
|
+
# { short_id: 'short-id-2', full_id: 'long-id-2', suite_id: 'suite-id-2' }
|
94
|
+
# ],
|
95
|
+
# 'req-id-2': [{ short_id: 'short-id-3', full_id: 'long-id-3', suite_id: 'suite-id-3' }],
|
96
|
+
# ...
|
97
|
+
# }
|
98
|
+
def inferno_requirements_map
|
99
|
+
@inferno_requirements_map ||= TEST_SUITES.each_with_object({}) do |suite, requirements_map|
|
100
|
+
serialize_requirements(suite, 'suite', suite.id, requirements_map)
|
101
|
+
suite.groups.each do |group|
|
102
|
+
map_group_requirements(group, suite.id, requirements_map)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def new_csv
|
108
|
+
@new_csv ||=
|
109
|
+
CSV.generate(+"\xEF\xBB\xBF") do |csv|
|
110
|
+
csv << OUTPUT_HEADERS
|
111
|
+
input_rows.each do |row| # NOTE: use row order from source file
|
112
|
+
next if row['Conformance'] == 'DEPRECATED' # filter out deprecated rows
|
113
|
+
|
114
|
+
TEST_SUITES.each do |suite|
|
115
|
+
suite_actor = SUITE_ID_TO_ACTOR_MAP[suite.id]
|
116
|
+
if row['Actor']&.include?(suite_actor)
|
117
|
+
add_suite_tests_for_row(row, suite)
|
118
|
+
else
|
119
|
+
row["#{suite.title} #{SHORT_ID_HEADER}"] = 'NA'
|
120
|
+
row["#{suite.title} #{FULL_ID_HEADER}"] = 'NA'
|
121
|
+
end
|
122
|
+
end
|
123
|
+
csv << row.values
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def add_suite_tests_for_row(row, suite)
|
129
|
+
set_and_req_id = "#{row['Req Set']}@#{row['ID']}"
|
130
|
+
items = get_items_for_requirement(set_and_req_id, suite)
|
131
|
+
short_ids = items[0]
|
132
|
+
full_ids = items[1]
|
133
|
+
if short_ids.blank? && not_tested_requirements_map.key?(set_and_req_id)
|
134
|
+
row["#{suite.title} #{SHORT_ID_HEADER}"] = 'Not Tested'
|
135
|
+
row["#{suite.title} #{FULL_ID_HEADER}"] = 'Not Tested'
|
136
|
+
else
|
137
|
+
row["#{suite.title} #{SHORT_ID_HEADER}"] = short_ids&.join(', ')
|
138
|
+
row["#{suite.title} #{FULL_ID_HEADER}"] = full_ids&.join(', ')
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
def get_items_for_requirement(set_and_req_id, suite)
|
143
|
+
suite_requirement_items = inferno_requirements_map[set_and_req_id]&.filter do |item|
|
144
|
+
item[:suite_id] == suite.id
|
145
|
+
end
|
146
|
+
[
|
147
|
+
suite_requirement_items&.map { |item| item[:short_id] },
|
148
|
+
suite_requirement_items&.map { |item| item[:full_id] }
|
149
|
+
]
|
150
|
+
end
|
151
|
+
|
152
|
+
def input_requirement_ids
|
153
|
+
@input_requirement_ids ||= input_rows.map { |row| "#{row['Req Set']}@#{row['ID']}" }
|
154
|
+
end
|
155
|
+
|
156
|
+
# The requirements present in Inferno that aren't in the input spreadsheet
|
157
|
+
def unmatched_requirements_map
|
158
|
+
@unmatched_requirements_map ||= inferno_requirements_map.except(*input_requirement_ids)
|
159
|
+
end
|
160
|
+
|
161
|
+
def old_csv
|
162
|
+
@old_csv ||= File.read(OUTPUT_FILE)
|
163
|
+
end
|
164
|
+
|
165
|
+
def run
|
166
|
+
unless File.exist?(INPUT_FILE)
|
167
|
+
puts "Could not find input file: #{INPUT_FILE}. Aborting requirements coverage generation..."
|
168
|
+
exit(1)
|
169
|
+
end
|
170
|
+
|
171
|
+
if unmatched_requirements_map.any?
|
172
|
+
puts "WARNING: The following requirements indicated in the test kit are not present in #{INPUT_FILE_NAME}"
|
173
|
+
output_requirements_map_table(unmatched_requirements_map)
|
174
|
+
end
|
175
|
+
|
176
|
+
if File.exist?(OUTPUT_FILE)
|
177
|
+
if old_csv == new_csv
|
178
|
+
puts "'#{OUTPUT_FILE_NAME}' file is up to date."
|
179
|
+
return
|
180
|
+
else
|
181
|
+
puts 'Requirements coverage has changed.'
|
182
|
+
end
|
183
|
+
else
|
184
|
+
puts "No existing #{OUTPUT_FILE_NAME}."
|
185
|
+
end
|
186
|
+
|
187
|
+
puts "Writing to file #{OUTPUT_FILE}..."
|
188
|
+
FileUtils.mkdir_p(OUTPUT_FILE_DIRECTORY)
|
189
|
+
File.write(OUTPUT_FILE, new_csv)
|
190
|
+
puts 'Done.'
|
191
|
+
end
|
192
|
+
|
193
|
+
def run_check
|
194
|
+
unless File.exist?(INPUT_FILE)
|
195
|
+
puts "Could not find input file: #{INPUT_FILE}. Aborting requirements coverage check..."
|
196
|
+
exit(1)
|
197
|
+
end
|
198
|
+
|
199
|
+
if unmatched_requirements_map.any?
|
200
|
+
puts "The following requirements indicated in the test kit are not present in #{INPUT_FILE_NAME}"
|
201
|
+
output_requirements_map_table(unmatched_requirements_map)
|
202
|
+
end
|
203
|
+
|
204
|
+
if File.exist?(OUTPUT_FILE)
|
205
|
+
if old_csv == new_csv
|
206
|
+
puts "'#{OUTPUT_FILE_NAME}' file is up to date."
|
207
|
+
return unless unmatched_requirements_map.any?
|
208
|
+
else
|
209
|
+
puts <<~MESSAGE
|
210
|
+
#{OUTPUT_FILE_NAME} file is out of date.
|
211
|
+
To regenerate the file, run:
|
212
|
+
|
213
|
+
bundle exec rake requirements:generate_coverage
|
214
|
+
|
215
|
+
MESSAGE
|
216
|
+
end
|
217
|
+
else
|
218
|
+
puts <<~MESSAGE
|
219
|
+
No existing #{OUTPUT_FILE_NAME} file.
|
220
|
+
To generate the file, run:
|
221
|
+
|
222
|
+
bundle exec rake requirements:generate_coverage
|
223
|
+
|
224
|
+
MESSAGE
|
225
|
+
end
|
226
|
+
|
227
|
+
puts 'Check failed.'
|
228
|
+
exit(1)
|
229
|
+
end
|
230
|
+
|
231
|
+
def map_group_requirements(group, suite_id, requirements_map)
|
232
|
+
serialize_requirements(group, group.short_id, suite_id, requirements_map)
|
233
|
+
group.tests&.each { |test| serialize_requirements(test, test.short_id, suite_id, requirements_map) }
|
234
|
+
group.groups&.each { |subgroup| map_group_requirements(subgroup, suite_id, requirements_map) }
|
235
|
+
end
|
236
|
+
|
237
|
+
def serialize_requirements(runnable, short_id, suite_id, requirements_map)
|
238
|
+
runnable.verifies_requirements&.each do |requirement_id|
|
239
|
+
requirement_id_string = requirement_id.to_s
|
240
|
+
|
241
|
+
requirements_map[requirement_id_string] ||= []
|
242
|
+
requirements_map[requirement_id_string] << { short_id:, full_id: runnable.id, suite_id: }
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
246
|
+
# Output the requirements in the map like so:
|
247
|
+
#
|
248
|
+
# requirement_id | short_id | full_id
|
249
|
+
# ---------------+------------+----------
|
250
|
+
# req-id-1 | short-id-1 | full-id-1
|
251
|
+
# req-id-2 | short-id-2 | full-id-2
|
252
|
+
#
|
253
|
+
def output_requirements_map_table(requirements_map)
|
254
|
+
headers = %w[requirement_id short_id full_id]
|
255
|
+
col_widths = headers.map(&:length)
|
256
|
+
col_widths[0] = [col_widths[0], requirements_map.keys.map(&:length).max].max
|
257
|
+
col_widths[1] = ([col_widths[1]] + requirements_map.values.flatten.map { |item| item[:short_id].length }).max
|
258
|
+
col_widths[2] = ([col_widths[2]] + requirements_map.values.flatten.map { |item| item[:full_id].length }).max
|
259
|
+
col_widths.map { |width| width + 3 }
|
260
|
+
|
261
|
+
puts [
|
262
|
+
headers[0].ljust(col_widths[0]),
|
263
|
+
headers[1].ljust(col_widths[1]),
|
264
|
+
headers[2].ljust(col_widths[2])
|
265
|
+
].join(' | ')
|
266
|
+
puts col_widths.map { |width| '-' * width }.join('-+-')
|
267
|
+
output_requirements_map_table_contents(requirements_map, col_widths)
|
268
|
+
puts
|
269
|
+
end
|
270
|
+
|
271
|
+
def output_requirements_map_table_contents(requirements_map, col_widths)
|
272
|
+
requirements_map.each do |requirement_id, runnables|
|
273
|
+
runnables.each do |runnable|
|
274
|
+
puts [
|
275
|
+
requirement_id.ljust(col_widths[0]),
|
276
|
+
runnable[:short_id].ljust(col_widths[1]),
|
277
|
+
runnable[:full_id].ljust(col_widths[2])
|
278
|
+
].join(' | ')
|
279
|
+
end
|
280
|
+
end
|
281
|
+
end
|
282
|
+
end
|
283
|
+
end
|
284
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
test_kit_id: davinci_pas_test_kit
|
2
|
+
|
3
|
+
suites:
|
4
|
+
- id: davinci_pas_client_suite_v201
|
5
|
+
class_name: DaVinciPASTestKit::DaVinciPASV201::ClientSuite
|
6
|
+
suite_actor: Client
|
7
|
+
- id: davinci_pas_server_suite_v201
|
8
|
+
class_name: DaVinciPASTestKit::DaVinciPASV201::ServerSuite
|
9
|
+
suite_actor: Server
|
10
|
+
|
11
|
+
requirement_sets:
|
12
|
+
- id: hl7.fhir.us.davinci-pas_2.0.1
|
13
|
+
folder: Prior Auth Support (PAS)
|
14
|
+
requirements: All
|
15
|
+
actor_map:
|
16
|
+
- {spec: Client, test_kit: Client}
|
17
|
+
- {spec: Server, test_kit: Server}
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: davinci_pas_test_kit
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.13.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Inferno Team
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-
|
11
|
+
date: 2025-05-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: inferno_core
|
@@ -16,28 +16,56 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 0.6.
|
19
|
+
version: 0.6.8
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 0.6.
|
26
|
+
version: 0.6.8
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: smart_app_launch_test_kit
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.6.2
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 0.6.2
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
42
|
name: subscriptions_test_kit
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
30
44
|
requirements:
|
31
45
|
- - "~>"
|
32
46
|
- !ruby/object:Gem::Version
|
33
|
-
version: 0.
|
47
|
+
version: 0.11.0
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 0.11.0
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: udap_security_test_kit
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 0.11.4
|
34
62
|
type: :runtime
|
35
63
|
prerelease: false
|
36
64
|
version_requirements: !ruby/object:Gem::Requirement
|
37
65
|
requirements:
|
38
66
|
- - "~>"
|
39
67
|
- !ruby/object:Gem::Version
|
40
|
-
version: 0.
|
68
|
+
version: 0.11.4
|
41
69
|
- !ruby/object:Gem::Dependency
|
42
70
|
name: database_cleaner-sequel
|
43
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -104,9 +132,18 @@ files:
|
|
104
132
|
- LICENSE
|
105
133
|
- config/presets/pas_client_example.json
|
106
134
|
- config/presets/pas_ri.json
|
135
|
+
- config/presets/pas_server_subscription_creation_against_pas_client.json
|
107
136
|
- lib/davinci_pas_test_kit.rb
|
137
|
+
- lib/davinci_pas_test_kit/certs/InfernoCA.key
|
138
|
+
- lib/davinci_pas_test_kit/certs/InfernoCA.pem
|
139
|
+
- lib/davinci_pas_test_kit/certs/TestKit.pem
|
140
|
+
- lib/davinci_pas_test_kit/certs/TestKitPrivateKey.key
|
108
141
|
- lib/davinci_pas_test_kit/client_suite.rb
|
109
142
|
- lib/davinci_pas_test_kit/custom_groups/v2.0.1/claim_response_decision/pas_claim_response_decision_test.rb
|
143
|
+
- lib/davinci_pas_test_kit/custom_groups/v2.0.1/client_registration/configuration_other_display_test.rb
|
144
|
+
- lib/davinci_pas_test_kit/custom_groups/v2.0.1/client_registration/configuration_smart_display_test.rb
|
145
|
+
- lib/davinci_pas_test_kit/custom_groups/v2.0.1/client_registration/configuration_udap_display_test.rb
|
146
|
+
- lib/davinci_pas_test_kit/custom_groups/v2.0.1/client_registration/other_auth_attest_test.rb
|
110
147
|
- lib/davinci_pas_test_kit/custom_groups/v2.0.1/client_tests/pas_client_approval_submit_test.rb
|
111
148
|
- lib/davinci_pas_test_kit/custom_groups/v2.0.1/client_tests/pas_client_denial_submit_test.rb
|
112
149
|
- lib/davinci_pas_test_kit/custom_groups/v2.0.1/client_tests/pas_client_inquire_must_support_test.rb
|
@@ -119,8 +156,6 @@ files:
|
|
119
156
|
- lib/davinci_pas_test_kit/custom_groups/v2.0.1/client_tests/pas_client_submit_must_support_test.rb
|
120
157
|
- lib/davinci_pas_test_kit/custom_groups/v2.0.1/client_tests/pas_client_subscription_create_test.rb
|
121
158
|
- lib/davinci_pas_test_kit/custom_groups/v2.0.1/client_tests/pas_client_subscription_pas_conformance_test.rb
|
122
|
-
- lib/davinci_pas_test_kit/custom_groups/v2.0.1/client_tests/pas_client_token_request_test.rb
|
123
|
-
- lib/davinci_pas_test_kit/custom_groups/v2.0.1/client_tests/pas_client_token_validation_test.rb
|
124
159
|
- lib/davinci_pas_test_kit/custom_groups/v2.0.1/error_tests/nonconformant_pas_bundle.json
|
125
160
|
- lib/davinci_pas_test_kit/custom_groups/v2.0.1/error_tests/pas_inquiry_error_test.rb
|
126
161
|
- lib/davinci_pas_test_kit/custom_groups/v2.0.1/error_tests/pas_submission_error_test.rb
|
@@ -132,12 +167,22 @@ files:
|
|
132
167
|
- lib/davinci_pas_test_kit/custom_groups/v2.0.1/must_support/service_request_metadata.yml
|
133
168
|
- lib/davinci_pas_test_kit/custom_groups/v2.0.1/notification/pas_subscription_notification_test.rb
|
134
169
|
- lib/davinci_pas_test_kit/custom_groups/v2.0.1/pas_client_approval_group.rb
|
135
|
-
- lib/davinci_pas_test_kit/custom_groups/v2.0.1/
|
170
|
+
- lib/davinci_pas_test_kit/custom_groups/v2.0.1/pas_client_auth_smart_group.rb
|
171
|
+
- lib/davinci_pas_test_kit/custom_groups/v2.0.1/pas_client_auth_udap_group.rb
|
136
172
|
- lib/davinci_pas_test_kit/custom_groups/v2.0.1/pas_client_denial_group.rb
|
173
|
+
- lib/davinci_pas_test_kit/custom_groups/v2.0.1/pas_client_must_support_group.rb
|
174
|
+
- lib/davinci_pas_test_kit/custom_groups/v2.0.1/pas_client_options.rb
|
137
175
|
- lib/davinci_pas_test_kit/custom_groups/v2.0.1/pas_client_pended_group.rb
|
176
|
+
- lib/davinci_pas_test_kit/custom_groups/v2.0.1/pas_client_registration_group.rb
|
177
|
+
- lib/davinci_pas_test_kit/custom_groups/v2.0.1/pas_client_subscription_setup_group.rb
|
178
|
+
- lib/davinci_pas_test_kit/custom_groups/v2.0.1/pas_client_workflows_group.rb
|
138
179
|
- lib/davinci_pas_test_kit/custom_groups/v2.0.1/pas_error_group.rb
|
180
|
+
- lib/davinci_pas_test_kit/custom_groups/v2.0.1/pas_server_subscription_input_conformance.rb
|
181
|
+
- lib/davinci_pas_test_kit/custom_groups/v2.0.1/pas_server_subscription_setup.rb
|
182
|
+
- lib/davinci_pas_test_kit/descriptions.rb
|
139
183
|
- lib/davinci_pas_test_kit/docs/PAS Requirements Interpretation.xlsx
|
140
184
|
- lib/davinci_pas_test_kit/docs/client_suite_description_v201.md
|
185
|
+
- lib/davinci_pas_test_kit/docs/demo/PAS Client Suite Demonstration.postman_collection.json
|
141
186
|
- lib/davinci_pas_test_kit/docs/server_suite_description_v201.md
|
142
187
|
- lib/davinci_pas_test_kit/endpoints/claim_endpoint.rb
|
143
188
|
- lib/davinci_pas_test_kit/endpoints/subscription_create_endpoint.rb
|
@@ -254,7 +299,6 @@ files:
|
|
254
299
|
- lib/davinci_pas_test_kit/generator/ig_metadata_extractor.rb
|
255
300
|
- lib/davinci_pas_test_kit/generator/ig_resources.rb
|
256
301
|
- lib/davinci_pas_test_kit/generator/must_support_check_profiles.rb
|
257
|
-
- lib/davinci_pas_test_kit/generator/must_support_metadata_extractor.rb
|
258
302
|
- lib/davinci_pas_test_kit/generator/must_support_test_generator.rb
|
259
303
|
- lib/davinci_pas_test_kit/generator/naming.rb
|
260
304
|
- lib/davinci_pas_test_kit/generator/operation_test_generator.rb
|
@@ -276,13 +320,21 @@ files:
|
|
276
320
|
- lib/davinci_pas_test_kit/metadata.rb
|
277
321
|
- lib/davinci_pas_test_kit/must_support_test.rb
|
278
322
|
- lib/davinci_pas_test_kit/pas_bundle_validation.rb
|
323
|
+
- lib/davinci_pas_test_kit/pas_subscription_verification.rb
|
324
|
+
- lib/davinci_pas_test_kit/requirements/davinci-pas-test-kit_out_of_scope_requirements.csv
|
325
|
+
- lib/davinci_pas_test_kit/requirements/davinci-pas-test-kit_requirements.csv
|
326
|
+
- lib/davinci_pas_test_kit/requirements/generated/davinci-pas-test-kit_requirements_coverage.csv
|
279
327
|
- lib/davinci_pas_test_kit/response_generator.rb
|
328
|
+
- lib/davinci_pas_test_kit/session_identification.rb
|
280
329
|
- lib/davinci_pas_test_kit/tags.rb
|
281
330
|
- lib/davinci_pas_test_kit/urls.rb
|
282
331
|
- lib/davinci_pas_test_kit/user_input_response.rb
|
283
332
|
- lib/davinci_pas_test_kit/validation_test.rb
|
284
333
|
- lib/davinci_pas_test_kit/validator_suppressions.rb
|
285
334
|
- lib/davinci_pas_test_kit/version.rb
|
335
|
+
- lib/inferno_requirements_tools/ext/inferno_core/runnable.rb
|
336
|
+
- lib/inferno_requirements_tools/tasks/requirements_coverage.rb
|
337
|
+
- lib/requirements_config.yaml
|
286
338
|
homepage: https://github.com/inferno-framework/davinci-pas-test-kit
|
287
339
|
licenses:
|
288
340
|
- Apache-2.0
|
data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/client_tests/pas_client_token_request_test.rb
DELETED
@@ -1,31 +0,0 @@
|
|
1
|
-
require_relative '../../../urls'
|
2
|
-
|
3
|
-
module DaVinciPASTestKit
|
4
|
-
module DaVinciPASV201
|
5
|
-
class PASClientTokenRequestTest < Inferno::Test
|
6
|
-
include URLs
|
7
|
-
|
8
|
-
id :pas_client_v201_token_request_test
|
9
|
-
title 'Client makes token request'
|
10
|
-
description %(
|
11
|
-
Inferno will wait for the client to make a token request.
|
12
|
-
)
|
13
|
-
input :client_id,
|
14
|
-
title: 'Client ID',
|
15
|
-
description: %(
|
16
|
-
Client ID that the client will use to request an access token.
|
17
|
-
)
|
18
|
-
|
19
|
-
run do
|
20
|
-
wait(
|
21
|
-
identifier: client_id,
|
22
|
-
message: %(
|
23
|
-
Submit your token request with client id `#{client_id}` to
|
24
|
-
|
25
|
-
`#{token_url}`
|
26
|
-
)
|
27
|
-
)
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/client_tests/pas_client_token_validation_test.rb
DELETED
@@ -1,18 +0,0 @@
|
|
1
|
-
require_relative '../../../tags'
|
2
|
-
|
3
|
-
module DaVinciPASTestKit
|
4
|
-
module DaVinciPASV201
|
5
|
-
class PASClientTokentRequestTest < Inferno::Test
|
6
|
-
id :pas_client_v201_token_validation_test
|
7
|
-
title 'Client token request is valid'
|
8
|
-
description 'Inferno will verify that an access token was successfully returned to the client under test.'
|
9
|
-
output :access_token
|
10
|
-
|
11
|
-
run do
|
12
|
-
load_tagged_requests(AUTH_TAG)
|
13
|
-
skip_if requests.empty?, 'No token requests were received'
|
14
|
-
output access_token: JSON.parse(requests.last.response_body)['access_token']
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
@@ -1,49 +0,0 @@
|
|
1
|
-
require_relative 'client_tests/pas_client_token_request_test'
|
2
|
-
require_relative 'client_tests/pas_client_token_validation_test'
|
3
|
-
|
4
|
-
module DaVinciPASTestKit
|
5
|
-
module DaVinciPASV201
|
6
|
-
class PASClientAuthenticationGroup < Inferno::TestGroup
|
7
|
-
id :pas_client_v201_authentication_group
|
8
|
-
title 'Demonstrate Authorization'
|
9
|
-
description %(
|
10
|
-
This group of tests allows Inferno to act as a OAuth server
|
11
|
-
and provide access tokens for the client under test to use
|
12
|
-
when making further requests.
|
13
|
-
|
14
|
-
The tests assume that the authentication workflow starts
|
15
|
-
after client registration. Upon clicking the "Run Tests" button
|
16
|
-
in the upper right, Inferno will ask for an input for the `client_id`
|
17
|
-
that was used for client registration, or manually configured in the
|
18
|
-
client.
|
19
|
-
|
20
|
-
Before submitting a token request, click the "Submit" button at the
|
21
|
-
bottom of the dialog to confirm the `client_id` that Inferno will
|
22
|
-
watch for.
|
23
|
-
|
24
|
-
Finally, make a valid token request that includes the specified `client_id`
|
25
|
-
to indicated token endpoint. This should be a POST of an `x-www-form-encoded`
|
26
|
-
body containing keys for `grant_type` with a value of `client_credentials` and
|
27
|
-
`client_id` with a value of the configured `client_id` value. For example, if
|
28
|
-
the `client_id` value was `123`, then the body of the request would be:
|
29
|
-
|
30
|
-
```grant_type=client_credentials&client_id=123```
|
31
|
-
|
32
|
-
The response json object will include an `access_token` key, for example:
|
33
|
-
|
34
|
-
```{"access_token":"97e792038d922bc3cf388b608e45c318","token_type":"bearer","expires_in":300}```
|
35
|
-
|
36
|
-
The value of the `access_token` key (`97e792038d922bc3cf388b608e45c318` in the example)
|
37
|
-
must be sent with every subsequent request to Inferno during this session in
|
38
|
-
the "Authorization" HTTP header with prefix "Bearer: ". In this example, the
|
39
|
-
Authorization HTTP header would have value:
|
40
|
-
|
41
|
-
```Bearer 97e792038d922bc3cf388b608e45c318```
|
42
|
-
)
|
43
|
-
run_as_group
|
44
|
-
|
45
|
-
test from: :pas_client_v201_token_request_test
|
46
|
-
test from: :pas_client_v201_token_validation_test
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|