onc_certification_g31_test_kit 1.0.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.
Files changed (23) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +201 -0
  3. data/config/presets/g31_against_inferno_crd_server_suite.json.erb +24 -0
  4. data/config/presets/g31_against_ri_br_provider.json.erb +38 -0
  5. data/execution_scripts/README.md +16 -0
  6. data/lib/onc_certification_g31_test_kit/documentation_attestation_test.rb +55 -0
  7. data/lib/onc_certification_g31_test_kit/endpoints/g31_cds_services_discovery_handler.rb +30 -0
  8. data/lib/onc_certification_g31_test_kit/endpoints/g31_hook_request_endpoint.rb +12 -0
  9. data/lib/onc_certification_g31_test_kit/g31_certification_suite.rb +358 -0
  10. data/lib/onc_certification_g31_test_kit/g31_certification_suite_short_id_map.yml +1971 -0
  11. data/lib/onc_certification_g31_test_kit/g31_crd_import.rb +96 -0
  12. data/lib/onc_certification_g31_test_kit/g31_options.rb +33 -0
  13. data/lib/onc_certification_g31_test_kit/g31_requirements.rb +96 -0
  14. data/lib/onc_certification_g31_test_kit/igs/.keep +0 -0
  15. data/lib/onc_certification_g31_test_kit/igs/README.md +21 -0
  16. data/lib/onc_certification_g31_test_kit/metadata.rb +71 -0
  17. data/lib/onc_certification_g31_test_kit/requirements/(g)(31)_HTI-4_requirements.xlsx +0 -0
  18. data/lib/onc_certification_g31_test_kit/requirements/(j)(20)_HTI-4_requirements.xlsx +0 -0
  19. data/lib/onc_certification_g31_test_kit/requirements/generated/g31_certification_requirements_coverage.csv +1296 -0
  20. data/lib/onc_certification_g31_test_kit/requirements/onc_certification_g31_test_kit_requirements.csv +17 -0
  21. data/lib/onc_certification_g31_test_kit/version.rb +4 -0
  22. data/lib/onc_certification_g31_test_kit.rb +1 -0
  23. metadata +114 -0
@@ -0,0 +1,96 @@
1
+ require 'davinci_crd_test_kit/client/v2.2.1/client_urls'
2
+ require_relative 'g31_options'
3
+
4
+ module ONCCertificationG31TestKit
5
+ module G31ClientURLs
6
+ SUITE_ID = 'g31_certification'.freeze
7
+
8
+ def inferno_base_url
9
+ @inferno_base_url ||= G31CRDImport.base_url
10
+ end
11
+ end
12
+
13
+ module G31CRDImport
14
+ STALE_CACHE_IVARS = [:@test_count, :@available_inputs, :@children_available_inputs].freeze
15
+ RUNNABLE_TEXT_FIELDS = [:title, :short_title, :description, :input_instructions].freeze
16
+ INPUT_TEXT_FIELDS = [:title, :description].freeze
17
+
18
+ # Singular references only: statements about "CRD clients" in general are left as is.
19
+ # NOTE: this pattern gets replaced within static text in the suite (descriptions,
20
+ # titles for runnables and inputs). It does not update the same strings within
21
+ # dynamic messages associated with the runnable during testing. This is expected
22
+ # and documented in docs/Technical-Overview.md.
23
+ CRD_CLIENT_PATTERN = /CRD client(?!s)/
24
+ HEALTH_IT_MODULE = 'Health IT Module'.freeze
25
+
26
+ def self.import!(runnable)
27
+ exclude_optional!(runnable)
28
+ rewrite_crd_references!(runnable)
29
+
30
+ runnable
31
+ end
32
+
33
+ def self.exclude_optional!(runnable)
34
+ runnable.all_children.reject(&:required?).each(&:remove_self_from_repository)
35
+ runnable.all_children.select!(&:required?)
36
+ STALE_CACHE_IVARS.each do |ivar|
37
+ runnable.remove_instance_variable(ivar) if runnable.instance_variable_defined?(ivar)
38
+ end
39
+
40
+ runnable.all_children.each { |child| exclude_optional!(child) }
41
+ end
42
+ private_class_method :exclude_optional!
43
+
44
+ def self.rewrite_crd_references!(runnable)
45
+ runnable.include(G31ClientURLs) if runnable.include?(DaVinciCRDTestKit::V221::ClientURLs)
46
+ rewrite_runnable_text!(runnable)
47
+ rewrite_input_text!(runnable)
48
+
49
+ runnable.all_children.each { |child| rewrite_crd_references!(child) }
50
+ end
51
+ private_class_method :rewrite_crd_references!
52
+
53
+ def self.rewrite_runnable_text!(runnable)
54
+ RUNNABLE_TEXT_FIELDS.each do |field|
55
+ text = runnable.send(field)
56
+ next if text.nil?
57
+
58
+ rewritten = rewrite_text(text)
59
+ runnable.send(field, rewritten) unless rewritten == text
60
+ end
61
+ end
62
+ private_class_method :rewrite_runnable_text!
63
+
64
+ def self.rewrite_input_text!(runnable)
65
+ updates = runnable.config.inputs.each_with_object({}) do |(identifier, input), acc|
66
+ input_updates = INPUT_TEXT_FIELDS.each_with_object({}) do |field, field_acc|
67
+ text = input.send(field)
68
+ next if text.nil?
69
+
70
+ rewritten = rewrite_text(text)
71
+ field_acc[field] = rewritten unless rewritten == text
72
+ end
73
+
74
+ acc[identifier] = input_updates if input_updates.any?
75
+ end
76
+
77
+ runnable.config(inputs: updates) if updates.any?
78
+ end
79
+ private_class_method :rewrite_input_text!
80
+
81
+ def self.rewrite_text(text)
82
+ text.to_s.gsub(crd_base_url, base_url).gsub(CRD_CLIENT_PATTERN, HEALTH_IT_MODULE)
83
+ end
84
+ private_class_method :rewrite_text
85
+
86
+ # Includes the CRD version prefix, so imported tests point at this suite's v2.2.1 endpoints
87
+ # rather than at the suite root.
88
+ def self.base_url
89
+ "#{Inferno::Application['base_url']}/custom/#{G31ClientURLs::SUITE_ID}#{G31Options::CRD_V221_PREFIX}"
90
+ end
91
+
92
+ def self.crd_base_url
93
+ "#{Inferno::Application['base_url']}/custom/#{DaVinciCRDTestKit::V221::ClientURLs::SUITE_ID}"
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,33 @@
1
+ module ONCCertificationG31TestKit
2
+ module G31Options
3
+ CRD_V221 = '2.2.1'.freeze
4
+ CRD_V221_COMPACT = "v#{CRD_V221.delete('.')}".freeze # v221
5
+ CRD_V221_DOTTED = "v#{CRD_V221}".freeze # v2.2.1
6
+ CRD_V221_PREFIX = "/crd_#{CRD_V221_COMPACT}".freeze # /crd_v221
7
+ CRD_V221_IG_PACKAGE = "hl7.fhir.us.davinci-crd##{CRD_V221}".freeze
8
+
9
+ US_CORE_3 = 'us_core_3'.freeze
10
+ US_CORE_4 = 'us_core_4'.freeze
11
+ US_CORE_5 = 'us_core_5'.freeze
12
+ US_CORE_6 = 'us_core_6'.freeze
13
+ US_CORE_7 = 'us_core_7'.freeze
14
+
15
+ US_CORE_VERSION_NUMBERS = {
16
+ US_CORE_3 => '3.1.1',
17
+ US_CORE_4 => '4.0.0',
18
+ US_CORE_5 => '5.0.1',
19
+ US_CORE_6 => '6.1.0',
20
+ US_CORE_7 => '7.0.0'
21
+ }.freeze
22
+
23
+ US_CORE_3_REQUIREMENT = { us_core_version: US_CORE_3 }.freeze
24
+ US_CORE_4_REQUIREMENT = { us_core_version: US_CORE_4 }.freeze
25
+ US_CORE_5_REQUIREMENT = { us_core_version: US_CORE_5 }.freeze
26
+ US_CORE_6_REQUIREMENT = { us_core_version: US_CORE_6 }.freeze
27
+ US_CORE_7_REQUIREMENT = { us_core_version: US_CORE_7 }.freeze
28
+
29
+ def us_core_version
30
+ suite_options[:us_core_version]
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,96 @@
1
+ module ONCCertificationG31TestKit
2
+ # Maps the § 170.315(g)(31) and § 170.315(j)(20) certification requirements onto the runnables
3
+ # imported from the Da Vinci CRD client suite.
4
+ #
5
+ # The imported runnables already declare the IG-level requirements that they verify, so these
6
+ # regulatory requirements are added to what each one declares rather than replacing it.
7
+ #
8
+ # Regulatory requirements are written at the level of a whole capability, so they are attached to
9
+ # the group that exercises that capability when no single test demonstrates it, and to individual
10
+ # tests when one does.
11
+ module G31Requirements
12
+ G31_SET = '170.315(g)(31)_HTI-4'.freeze
13
+ J20_SET = '170.315(j)(20)_HTI-4'.freeze
14
+
15
+ # Requirement id => the runnables that verify it, identified by the trailing portion of their id
16
+ # within this suite. Keys are the shortest suffix that identifies a single runnable; ids that
17
+ # are reused across groups (e.g., the response attestation) are qualified by their parent.
18
+ REQUIREMENT_MAP = {
19
+ "#{G31_SET}@3" => [
20
+ 'crd_v221_client_registration'
21
+ ],
22
+ "#{G31_SET}@4" => [
23
+ 'g31_hook_invocation'
24
+ ],
25
+ "#{G31_SET}@5" => [
26
+ 'crd_v221_client_order_sign'
27
+ ],
28
+ "#{J20_SET}@1" => [
29
+ 'g31_hook_invocation'
30
+ ],
31
+ "#{J20_SET}@2" => [
32
+ 'crd_v221_client_registration'
33
+ ],
34
+ "#{J20_SET}@3" => [
35
+ 'crd_v221_order_sign_auth',
36
+ 'crd_v221_cross_hook_auth'
37
+ ],
38
+ "#{J20_SET}@4" => [
39
+ 'crd_v221_order_sign_auth',
40
+ 'crd_v221_cross_hook_auth'
41
+ ],
42
+ "#{J20_SET}@5" => [
43
+ 'crd_v221_order_sign_requests-crd_v221_hook_data_fetch_verification',
44
+ 'crd_v221_cross_hook_requests-crd_v221_hook_data_fetch_verification'
45
+ ],
46
+ "#{J20_SET}@6" => [
47
+ 'crd_v221_client_order_sign',
48
+ 'crd_v221_client_cross_hook_interaction'
49
+ ],
50
+ "#{J20_SET}@7" => [
51
+ 'crd_v221_client_order_sign',
52
+ 'crd_v221_client_cross_hook_interaction'
53
+ ],
54
+ "#{J20_SET}@8" => [
55
+ 'crd_v221_order_sign_requests-crd_v221_hook_data_fetch_verification',
56
+ 'crd_v221_cross_hook_requests-crd_v221_hook_data_fetch_verification'
57
+ ],
58
+ "#{J20_SET}@9" => [
59
+ 'crd_v221_order_sign_responses-crd_v221_card_display_attest_test',
60
+ 'crd_v221_cross_hook_responses-crd_v221_card_display_attest_test'
61
+ ]
62
+ }.freeze
63
+
64
+ # Adds the requirements above to the runnables that verify them. Raises if a key no longer
65
+ # identifies exactly one runnable, so that a change to the imported suite is caught here rather
66
+ # than silently dropping coverage.
67
+ def self.apply!(suite)
68
+ runnables = [suite, *suite.all_descendants]
69
+
70
+ REQUIREMENT_MAP.each do |requirement_id, runnable_keys|
71
+ runnable_keys.each do |runnable_key|
72
+ add_requirement!(find_runnable!(runnables, runnable_key), requirement_id)
73
+ end
74
+ end
75
+ end
76
+
77
+ def self.find_runnable!(runnables, runnable_key)
78
+ matches = runnables.select { |runnable| runnable.id.to_s.end_with?("-#{runnable_key}") }
79
+
80
+ raise "No runnable found for requirement mapping key '#{runnable_key}'" if matches.empty?
81
+
82
+ if matches.length > 1
83
+ raise "Requirement mapping key '#{runnable_key}' matches multiple runnables: " \
84
+ "#{matches.map(&:id).join(', ')}"
85
+ end
86
+
87
+ matches.first
88
+ end
89
+ private_class_method :find_runnable!
90
+
91
+ def self.add_requirement!(runnable, requirement_id)
92
+ runnable.verifies_requirements(*(runnable.verifies_requirements + [requirement_id]).uniq)
93
+ end
94
+ private_class_method :add_requirement!
95
+ end
96
+ end
File without changes
@@ -0,0 +1,21 @@
1
+ # Note on this IGs folder
2
+
3
+ There are three reasons why it would be necessary to put an IG package.tgz in this folder. If none of these apply, you do not need to put any files here, or can consider removing any existing files to make it clear they are unused.
4
+
5
+ ## 1. Generated Test Suites
6
+ Some test kits use a "generator" to automatically generate the contents of a test suite for an IG. The IG files are required every time the test suites need to be regenerated. Examples of test kits that use this approach are the US Core Test Kit and CARIN IG for Blue Button® Test Kit.
7
+
8
+
9
+ ## 2. Non-published IG
10
+ If your IG, or the specific version of the IG you want to test against, is not published, then the validator service needs to load the IG from file in order to be able to validate resources with it. The IG must be referenced in the `fhir_resource_validator` block in the test suite definition by filename, ie:
11
+
12
+ ```ruby
13
+ fhir_resource_validator do
14
+ igs 'igs/filename.tgz'
15
+
16
+ ...
17
+ end
18
+ ```
19
+
20
+ ## 3. Inferno Validator UI
21
+ The Inferno Validator UI is configured to auto-load any IGs present in the igs folder and include them in all validations. In general, the Inferno team is currently leaving IGs in this folder even if not otherwise necessary to make it easy to re-enable the validator UI.
@@ -0,0 +1,71 @@
1
+ require_relative 'version'
2
+
3
+ module ONCCertificationG31TestKit
4
+ class Metadata < Inferno::TestKit
5
+ id :onc_certification_g31_test_kit
6
+ title 'ONC Certification (g)(31) Coverage Requirements Discovery API Test Kit'
7
+ description <<~DESCRIPTION
8
+ The ONC Certification (g)(31) Coverage Requirements Discovery API Test Kit is a
9
+ testing tool for Health IT Modules seeking to meet the requirements of the
10
+ Coverage Requirements Discovery criterion § 170.315(g)(31) in the ONC Health
11
+ IT Certification Program.
12
+ <!-- break -->
13
+
14
+ The CRD standard allows clients to support one of several US Core versions. To begin testing,
15
+ select a US Core version for Inferno to verify against, and click 'Create Test Session'.
16
+
17
+ ## Status
18
+
19
+ The ONC Certification (g)(31) Coverage Requirements Discovery API Test Kit is actively
20
+ developed and updates are released monthly.
21
+
22
+ The test kit currently tests requirements for the [Coverage Requirements
23
+ Discovery criterion §
24
+ 170.315(g)(31)](https://healthit.gov/test-method/provider-prior-authorization-api-coverage-requirements-discovery).
25
+ This includes:
26
+ - Registration
27
+ - CDS Hooks support for the order-sign hook
28
+ - CRD Client capabilities, including support for specific scenarios and must support elements
29
+ - FHIR API
30
+ - Documentation
31
+
32
+ See the test descriptions within the test kit for detail on the specific
33
+ validations performed as part of testing these requirements. These descriptions
34
+ also contain a "View Specification Requirements" link that can be used to see
35
+ the specific requirements verified. Testers seeking help in using these tests
36
+ can find additional details within the [Walkthrough](https://github.com/onc-healthit/onc-certification-g31-test-kit/wiki/Walkthrough)
37
+ on the (g)(31) Test Kit wiki.
38
+
39
+ ## Repository and Resources
40
+
41
+ The ONC Certification (g)(31) Coverage Requirements Discovery API Test Kit can be
42
+ [downloaded from its GitHub repository](https://github.com/onc-healthit/onc-certification-g31-test-kit),
43
+ where additional resources and documentation are also available to help users
44
+ get started with the testing process. The
45
+ [Releases](https://github.com/onc-healthit/onc-certification-g31-test-kit/releases)
46
+ page provides information about each new release.
47
+
48
+ ## Providing Feedback and Reporting Issues
49
+
50
+ We welcome feedback on the tests, including but not limited to the following areas:
51
+
52
+ - Validation logic, such as potential bugs, lax checks, and unexpected failures.
53
+ - Requirements coverage, such as requirements that have been missed, tests that
54
+ necessitate features that the IG does not require, or other issues with the
55
+ interpretation of the IG's requirements.
56
+ - User experience, such as confusing or missing information in the test UI.
57
+
58
+ Please report any issues with this set of tests in the [issues
59
+ section](https://github.com/onc-healthit/onc-certification-g31-test-kit/issues)
60
+ of the repository.
61
+ DESCRIPTION
62
+
63
+ suite_ids [:g31_certification]
64
+ tags ['Da Vinci', 'CRD', 'US Core']
65
+ last_updated LAST_UPDATED
66
+ version VERSION
67
+ maturity 'Certification'
68
+ authors ['Inferno Team']
69
+ repo 'https://github.com/onc-healthit/onc-certification-g31-test-kit'
70
+ end
71
+ end