davinci_pas_test_kit 0.9.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 +7 -0
- data/LICENSE +201 -0
- data/lib/davinci_pas_test_kit/client_suite.rb +289 -0
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/claim_status/pas_claim_status_test.rb +109 -0
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/client_tests/pas_client_approval_submit_response_attest.rb +39 -0
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/client_tests/pas_client_approval_submit_test.rb +38 -0
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/client_tests/pas_client_denial_submit_response_attest.rb +38 -0
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/client_tests/pas_client_denial_submit_test.rb +43 -0
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/client_tests/pas_client_inquire_must_support_test.rb +51 -0
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/client_tests/pas_client_pended_inquire_response_attest.rb +39 -0
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/client_tests/pas_client_pended_inquire_test.rb +35 -0
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/client_tests/pas_client_pended_submit_response_attest.rb +39 -0
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/client_tests/pas_client_pended_submit_test.rb +43 -0
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/client_tests/pas_client_submit_must_support_test.rb +57 -0
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/client_tests/pas_client_token_request_test.rb +31 -0
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/client_tests/pas_client_token_validation_test.rb +18 -0
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/error_tests/nonconformant_pas_bundle.json +16 -0
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/error_tests/pas_inquiry_error_test.rb +38 -0
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/error_tests/pas_submission_error_test.rb +56 -0
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/must_support/device_request_metadata.yml +112 -0
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/must_support/medication_request_metadata.yml +183 -0
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/must_support/nutrition_order_metadata.yml +109 -0
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/must_support/pas_client_must_support_requirement_test.rb +117 -0
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/must_support/pas_server_must_support_requirement_test.rb +116 -0
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/must_support/service_request_metadata.yml +148 -0
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/pas_client_approval_group.rb +26 -0
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/pas_client_authentication_group.rb +49 -0
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/pas_client_denial_group.rb +41 -0
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/pas_client_pended_group.rb +56 -0
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/pas_error_group.rb +20 -0
- data/lib/davinci_pas_test_kit/ext/inferno_core/record_response_route.rb +98 -0
- data/lib/davinci_pas_test_kit/ext/inferno_core/request.rb +19 -0
- data/lib/davinci_pas_test_kit/ext/inferno_core/runnable.rb +18 -0
- data/lib/davinci_pas_test_kit/fhir_resource_navigation.rb +72 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/beneficiary/client_inquiry_request_beneficiary_must_support_test.rb +75 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/beneficiary/client_submit_request_beneficiary_must_support_test.rb +75 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/beneficiary/metadata.yml +162 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/beneficiary/server_inquiry_request_beneficiary_must_support_test.rb +75 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/beneficiary/server_inquiry_response_beneficiary_must_support_test.rb +75 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/beneficiary/server_submit_request_beneficiary_must_support_test.rb +75 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/beneficiary/server_submit_response_beneficiary_must_support_test.rb +75 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/claim/claim_operation_test.rb +67 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/claim/metadata.yml +577 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/claim_inquiry/claim_inquiry_operation_test.rb +57 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/claim_inquiry/client_inquiry_request_claim_inquiry_must_support_test.rb +95 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/claim_inquiry/metadata.yml +516 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/claim_inquiry/server_inquiry_request_claim_inquiry_must_support_test.rb +95 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/claim_update/client_submit_request_claim_update_must_support_test.rb +102 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/claim_update/metadata.yml +591 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/claim_update/server_submit_request_claim_update_must_support_test.rb +102 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/claiminquiryresponse/metadata.yml +311 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/claiminquiryresponse/server_inquiry_response_claiminquiryresponse_must_support_test.rb +73 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/claimresponse/metadata.yml +318 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/claimresponse/server_submit_response_claimresponse_must_support_test.rb +75 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/client_tests/client_denial_pas_response_bundle_validation_test.rb +53 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/client_tests/client_pas_request_bundle_validation_test.rb +55 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/client_tests/client_pended_pas_inquiry_request_bundle_validation_test.rb +55 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/client_tests/client_pended_pas_response_bundle_validation_test.rb +53 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/communication_request/metadata.yml +130 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/communication_request/server_submit_response_communication_request_must_support_test.rb +58 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/coverage/client_inquiry_request_coverage_must_support_test.rb +55 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/coverage/client_submit_request_coverage_must_support_test.rb +55 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/coverage/metadata.yml +111 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/coverage/server_inquiry_request_coverage_must_support_test.rb +55 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/coverage/server_submit_request_coverage_must_support_test.rb +55 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/device_request/client_submit_request_device_request_must_support_test.rb +51 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/device_request/metadata.yml +112 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/device_request/server_submit_request_device_request_must_support_test.rb +51 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/encounter/client_submit_request_encounter_must_support_test.rb +67 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/encounter/metadata.yml +213 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/encounter/server_submit_request_encounter_must_support_test.rb +67 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/insurer/client_inquiry_request_insurer_must_support_test.rb +60 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/insurer/client_submit_request_insurer_must_support_test.rb +60 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/insurer/metadata.yml +104 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/insurer/server_inquiry_request_insurer_must_support_test.rb +60 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/insurer/server_inquiry_response_insurer_must_support_test.rb +60 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/insurer/server_submit_request_insurer_must_support_test.rb +60 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/insurer/server_submit_response_insurer_must_support_test.rb +60 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/medication_request/client_submit_request_medication_request_must_support_test.rb +61 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/medication_request/metadata.yml +183 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/medication_request/server_submit_request_medication_request_must_support_test.rb +61 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/metadata.yml +5253 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/nutrition_order/client_submit_request_nutrition_order_must_support_test.rb +53 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/nutrition_order/metadata.yml +109 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/nutrition_order/server_submit_request_nutrition_order_must_support_test.rb +53 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/pas_client_inquiry_must_support_use_case_group.rb +51 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/pas_client_submit_must_support_use_case_group.rb +61 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/pas_inquiry_request_bundle/client_inquiry_request_pas_inquiry_request_bundle_must_support_test.rb +53 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/pas_inquiry_request_bundle/metadata.yml +77 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/pas_inquiry_request_bundle/server_inquiry_request_pas_inquiry_request_bundle_must_support_test.rb +53 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/pas_inquiry_request_bundle/server_pas_inquiry_request_bundle_validation_test.rb +83 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/pas_inquiry_response_bundle/metadata.yml +67 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/pas_inquiry_response_bundle/server_inquiry_response_pas_inquiry_response_bundle_must_support_test.rb +52 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/pas_inquiry_response_bundle/server_pas_inquiry_response_bundle_validation_test.rb +80 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/pas_request_bundle/client_submit_request_pas_request_bundle_must_support_test.rb +53 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/pas_request_bundle/metadata.yml +77 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/pas_request_bundle/server_pas_request_bundle_validation_test.rb +83 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/pas_request_bundle/server_submit_request_pas_request_bundle_must_support_test.rb +53 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/pas_response_bundle/metadata.yml +71 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/pas_response_bundle/server_pas_response_bundle_validation_test.rb +80 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/pas_response_bundle/server_submit_response_pas_response_bundle_must_support_test.rb +52 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/pas_server_approval_use_case_group.rb +59 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/pas_server_denial_use_case_group.rb +59 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/pas_server_must_support_use_case_group.rb +265 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/pas_server_pended_use_case_group.rb +84 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/practitioner/client_inquiry_request_practitioner_must_support_test.rb +53 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/practitioner/client_submit_request_practitioner_must_support_test.rb +53 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/practitioner/metadata.yml +74 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/practitioner/server_inquiry_request_practitioner_must_support_test.rb +53 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/practitioner/server_inquiry_response_practitioner_must_support_test.rb +53 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/practitioner/server_submit_request_practitioner_must_support_test.rb +53 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/practitioner/server_submit_response_practitioner_must_support_test.rb +53 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/practitioner_role/client_inquiry_request_practitioner_role_must_support_test.rb +49 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/practitioner_role/client_submit_request_practitioner_role_must_support_test.rb +49 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/practitioner_role/metadata.yml +81 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/practitioner_role/server_inquiry_request_practitioner_role_must_support_test.rb +49 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/practitioner_role/server_inquiry_response_practitioner_role_must_support_test.rb +49 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/practitioner_role/server_submit_request_practitioner_role_must_support_test.rb +49 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/practitioner_role/server_submit_response_practitioner_role_must_support_test.rb +49 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/requestor/client_inquiry_request_requestor_must_support_test.rb +63 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/requestor/client_submit_request_requestor_must_support_test.rb +63 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/requestor/metadata.yml +107 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/requestor/server_inquiry_request_requestor_must_support_test.rb +63 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/requestor/server_inquiry_response_requestor_must_support_test.rb +63 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/requestor/server_submit_request_requestor_must_support_test.rb +63 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/requestor/server_submit_response_requestor_must_support_test.rb +63 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/resource_list.rb +54 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/server_suite.rb +236 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/service_request/client_submit_request_service_request_must_support_test.rb +53 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/service_request/metadata.yml +148 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/service_request/server_submit_request_service_request_must_support_test.rb +53 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/subscriber/client_inquiry_request_subscriber_must_support_test.rb +74 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/subscriber/client_submit_request_subscriber_must_support_test.rb +74 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/subscriber/metadata.yml +159 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/subscriber/server_inquiry_request_subscriber_must_support_test.rb +74 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/subscriber/server_submit_request_subscriber_must_support_test.rb +74 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/task/metadata.yml +192 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/task/server_inquiry_response_task_must_support_test.rb +61 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/task/server_submit_response_task_must_support_test.rb +61 -0
- data/lib/davinci_pas_test_kit/generator/group_generator.rb +440 -0
- data/lib/davinci_pas_test_kit/generator/group_metadata.rb +73 -0
- data/lib/davinci_pas_test_kit/generator/group_metadata_extractor.rb +244 -0
- data/lib/davinci_pas_test_kit/generator/ig_loader.rb +78 -0
- data/lib/davinci_pas_test_kit/generator/ig_metadata.rb +66 -0
- data/lib/davinci_pas_test_kit/generator/ig_metadata_extractor.rb +54 -0
- data/lib/davinci_pas_test_kit/generator/ig_resources.rb +74 -0
- data/lib/davinci_pas_test_kit/generator/must_support_check_profiles.rb +86 -0
- data/lib/davinci_pas_test_kit/generator/must_support_metadata_extractor.rb +327 -0
- data/lib/davinci_pas_test_kit/generator/must_support_test_generator.rb +155 -0
- data/lib/davinci_pas_test_kit/generator/naming.rb +50 -0
- data/lib/davinci_pas_test_kit/generator/operation_test_generator.rb +136 -0
- data/lib/davinci_pas_test_kit/generator/resource_list_generator.rb +59 -0
- data/lib/davinci_pas_test_kit/generator/suite_generator.rb +94 -0
- data/lib/davinci_pas_test_kit/generator/terminology_binding_metadata_extractor.rb +108 -0
- data/lib/davinci_pas_test_kit/generator/validation_test_generator.rb +181 -0
- data/lib/davinci_pas_test_kit/generator/value_extractor.rb +48 -0
- data/lib/davinci_pas_test_kit/generator.rb +80 -0
- data/lib/davinci_pas_test_kit/mock_server.rb +189 -0
- data/lib/davinci_pas_test_kit/must_support_test.rb +267 -0
- data/lib/davinci_pas_test_kit/pas_bundle_validation.rb +568 -0
- data/lib/davinci_pas_test_kit/tags.rb +7 -0
- data/lib/davinci_pas_test_kit/urls.rb +39 -0
- data/lib/davinci_pas_test_kit/user_input_response.rb +32 -0
- data/lib/davinci_pas_test_kit/validation_test.rb +58 -0
- data/lib/davinci_pas_test_kit/validator_suppressions.rb +143 -0
- data/lib/davinci_pas_test_kit/version.rb +5 -0
- data/lib/davinci_pas_test_kit.rb +2 -0
- metadata +281 -0
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
module DaVinciPASTestKit
|
|
2
|
+
class Generator
|
|
3
|
+
class ResourceListGenerator
|
|
4
|
+
class << self
|
|
5
|
+
def generate(ig_metadata, base_output_dir)
|
|
6
|
+
@ig_metadata = ig_metadata
|
|
7
|
+
|
|
8
|
+
FileUtils.mkdir_p(base_output_dir)
|
|
9
|
+
File.write(File.join(base_output_dir, base_output_file_name), output)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def resource_list
|
|
13
|
+
@ig_metadata.groups.map(&:title).uniq
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def resource_supported_profiles
|
|
17
|
+
dict = {}
|
|
18
|
+
@ig_metadata.groups.each do |group|
|
|
19
|
+
dict[group.resource] ||= []
|
|
20
|
+
dict[group.resource] << group.profile_url
|
|
21
|
+
end
|
|
22
|
+
dict
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def resource_list_string
|
|
26
|
+
resource_list.map { |resource| " '#{resource}'" }.join(",\n")
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def module_name
|
|
30
|
+
"PAS#{@ig_metadata.reformatted_version.upcase}"
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def read_interaction(group_metadata)
|
|
34
|
+
group_metadata.interactions.find { |interaction| interaction[:code] == 'read' } || {}
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def submit_operation(group_metadata)
|
|
38
|
+
group_metadata.operations.find { |operation| operation[:code] == '$submit' } || {}
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def inquiry_operation(group_metadata)
|
|
42
|
+
group_metadata.operations.find { |operation| operation[:code] == '$inquire' } || {}
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def template
|
|
46
|
+
@template ||= File.read(File.join(__dir__, 'templates', 'resource_list.rb.erb'))
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def output
|
|
50
|
+
ERB.new(template).result(binding)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def base_output_file_name
|
|
54
|
+
'resource_list.rb'
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
require_relative 'naming'
|
|
2
|
+
|
|
3
|
+
module DaVinciPASTestKit
|
|
4
|
+
class Generator
|
|
5
|
+
class SuiteGenerator
|
|
6
|
+
class << self
|
|
7
|
+
def generate(ig_metadata, base_output_dir)
|
|
8
|
+
new(ig_metadata, base_output_dir).generate
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
attr_accessor :ig_metadata, :base_output_dir
|
|
13
|
+
|
|
14
|
+
def initialize(ig_metadata, base_output_dir)
|
|
15
|
+
self.ig_metadata = ig_metadata
|
|
16
|
+
self.base_output_dir = base_output_dir
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def template
|
|
20
|
+
@template ||= File.read(File.join(__dir__, 'templates', 'suite.rb.erb'))
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def output
|
|
24
|
+
@output ||= ERB.new(template).result(binding)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def base_output_file_name
|
|
28
|
+
'server_suite.rb'
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def class_name
|
|
32
|
+
'ServerSuite'
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def module_name
|
|
36
|
+
"DaVinciPAS#{ig_metadata.reformatted_version.upcase}"
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def output_file_name
|
|
40
|
+
File.join(base_output_dir, base_output_file_name)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def suite_id
|
|
44
|
+
"davinci_pas_server_suite_#{ig_metadata.reformatted_version}"
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def title
|
|
48
|
+
"Da Vinci PAS Server Suite #{ig_metadata.ig_version}"
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def ig_link
|
|
52
|
+
case ig_metadata.ig_version
|
|
53
|
+
when 'v2.0.1'
|
|
54
|
+
'https://hl7.org/fhir/us/davinci-pas/STU2/'
|
|
55
|
+
else
|
|
56
|
+
'https://hl7.org/fhir/us/davinci-pas/history.html'
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def generate
|
|
61
|
+
File.write(output_file_name, output)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def groups
|
|
65
|
+
ig_metadata.use_case_groups
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def group_id_list
|
|
69
|
+
@group_id_list ||= groups.map { |group| group[:id] }
|
|
70
|
+
.reject { |id| id.include?('client') }
|
|
71
|
+
.reject { |id| id.include?('must_support') }
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def group_file_list
|
|
75
|
+
@group_file_list ||= groups.map { |group| group[:file_name].delete_suffix('.rb') }
|
|
76
|
+
.reject { |name| name.include?('client') }
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def error_group_file_name
|
|
80
|
+
"../../custom_groups/#{ig_metadata.ig_version}/pas_error_group"
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def error_group_id
|
|
84
|
+
"pas_#{ig_metadata.reformatted_version}_error_group"
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def must_support_group_id
|
|
88
|
+
@must_support_group_id ||= groups.map { |group| group[:id] }
|
|
89
|
+
.reject { |id| id.include?('client') }
|
|
90
|
+
.find { |id| id.include?('must_support') }
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
module DaVinciPASTestKit
|
|
2
|
+
class Generator
|
|
3
|
+
class TerminologyBindingMetadataExtractor
|
|
4
|
+
attr_accessor :profile_elements, :ig_resources, :resource
|
|
5
|
+
|
|
6
|
+
def initialize(profile_elements, ig_resources, resource)
|
|
7
|
+
self.profile_elements = profile_elements
|
|
8
|
+
self.ig_resources = ig_resources
|
|
9
|
+
self.resource = resource
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def terminology_bindings
|
|
13
|
+
(element_terminology_bindings + extension_terminology_bindings).compact
|
|
14
|
+
# add_terminology_bindings_from_extensions
|
|
15
|
+
# profile_elements.select { |element| element.type&.first&.code == 'Extension' }
|
|
16
|
+
# .each { |extension| add_terminology_bindings_from_extension(extension) }
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def element_has_fixed_value?(element)
|
|
20
|
+
case element.type.first.code
|
|
21
|
+
when 'Quantity'
|
|
22
|
+
code = profile_elements.find { |e| e.path == "#{element.path}.code" }
|
|
23
|
+
system = profile_elements.find { |e| e.path == "#{element.path}.system" }
|
|
24
|
+
code&.fixedCode || system&.fixedUri
|
|
25
|
+
when 'code'
|
|
26
|
+
element.fixedCode.present?
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def profile_elements_with_bindings
|
|
31
|
+
profile_elements
|
|
32
|
+
.select { |element| element.binding.present? }
|
|
33
|
+
.reject { |element| element_has_fixed_value? element }
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def element_terminology_bindings
|
|
37
|
+
profile_elements_with_bindings.map do |element|
|
|
38
|
+
{
|
|
39
|
+
type: element.type.first.code,
|
|
40
|
+
strength: element.binding.strength,
|
|
41
|
+
# Goal.target.detail has an unbound binding
|
|
42
|
+
system: element.binding.valueSet&.split('|')&.first,
|
|
43
|
+
path: element.path.gsub('[x]', '').gsub("#{resource}.", '')
|
|
44
|
+
}
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def extension_profile_elements
|
|
49
|
+
profile_elements
|
|
50
|
+
.select { |element| element.type&.first&.code == 'Extension' }
|
|
51
|
+
.select { |element| extension_profile_url(element).present? }
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def extension_profile_url(extension)
|
|
55
|
+
extension.type.first.profile&.first
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def extension_terminology_bindings
|
|
59
|
+
extension_profile_elements
|
|
60
|
+
.flat_map do |extension_profile_element|
|
|
61
|
+
url = extension_profile_url(extension_profile_element)
|
|
62
|
+
extension = ig_resources.profile_by_url(url)
|
|
63
|
+
|
|
64
|
+
# TODO: Temporaray fix for extension defined out of US Core. FI-1623
|
|
65
|
+
next if extension.nil?
|
|
66
|
+
|
|
67
|
+
elements = extension.snapshot.element
|
|
68
|
+
elements_with_bindings = elements.select do |element|
|
|
69
|
+
element.binding.present? && !element.id.include?('Extension.extension')
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
elements_with_bindings.map do |element|
|
|
73
|
+
{
|
|
74
|
+
type: element.type.first.code,
|
|
75
|
+
strength: element.binding.strength,
|
|
76
|
+
system: element.binding.valueSet&.split('|')&.first,
|
|
77
|
+
path: element.path.gsub('[x]', '').gsub('Extension.', ''),
|
|
78
|
+
extensions: [url]
|
|
79
|
+
}
|
|
80
|
+
end + nested_extension_terminology_bindings(elements, url)
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def nested_extension_terminology_bindings(elements, extension_url)
|
|
85
|
+
nested_extensions = elements.select { |element| element.path == 'Extension.extension' }
|
|
86
|
+
nested_extensions.flat_map do |nested_extension|
|
|
87
|
+
nested_extension_element = elements.find { |element| element.id == "#{nested_extension.id}.url" }
|
|
88
|
+
next unless nested_extension_element.present?
|
|
89
|
+
|
|
90
|
+
nested_extension_url = nested_extension_element.fixedUri
|
|
91
|
+
nested_elements_with_bindings = elements.select do |element|
|
|
92
|
+
element.id.include?(nested_extension.id) && element.binding.present?
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
nested_elements_with_bindings.map do |element|
|
|
96
|
+
{
|
|
97
|
+
type: element.type.first.code,
|
|
98
|
+
strength: element.binding.strength,
|
|
99
|
+
system: element.binding.valueSet&.split('|')&.first,
|
|
100
|
+
path: element.path.gsub('[x]', '').gsub('Extension.extension.', ''),
|
|
101
|
+
extensions: [extension_url, nested_extension_url]
|
|
102
|
+
}
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
require 'pry'
|
|
2
|
+
require_relative 'naming'
|
|
3
|
+
|
|
4
|
+
module DaVinciPASTestKit
|
|
5
|
+
class Generator
|
|
6
|
+
class ValidationTestGenerator
|
|
7
|
+
class << self
|
|
8
|
+
def generate(ig_metadata, base_output_dir)
|
|
9
|
+
['server', 'client'].each do |system|
|
|
10
|
+
if system == 'server'
|
|
11
|
+
ig_metadata.bundle_groups.each do |group|
|
|
12
|
+
new(group, system, base_output_dir:).generate
|
|
13
|
+
end
|
|
14
|
+
else
|
|
15
|
+
ig_metadata.bundle_groups.each do |group|
|
|
16
|
+
case group.profile_name
|
|
17
|
+
when 'PAS Request Bundle'
|
|
18
|
+
new(group, system, base_output_dir:).generate
|
|
19
|
+
when 'PAS Inquiry Request Bundle'
|
|
20
|
+
new(group, system, 'pended_inquiry', base_output_dir:).generate
|
|
21
|
+
when 'PAS Response Bundle'
|
|
22
|
+
['denial', 'pended'].each do |workflow|
|
|
23
|
+
new(group, system, workflow, base_output_dir:).generate
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
attr_accessor :group_metadata, :medication_request_metadata, :base_output_dir, :system, :workflow
|
|
33
|
+
|
|
34
|
+
def initialize(group_metadata, system, workflow = nil, medication_request_metadata = nil, base_output_dir:)
|
|
35
|
+
self.group_metadata = group_metadata
|
|
36
|
+
self.system = system
|
|
37
|
+
self.workflow = workflow
|
|
38
|
+
self.medication_request_metadata = medication_request_metadata
|
|
39
|
+
self.base_output_dir = base_output_dir
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def template
|
|
43
|
+
temp = system == 'server' ? 'validation.rb.erb' : 'validation_client.rb.erb'
|
|
44
|
+
@template ||= File.read(File.join(__dir__, 'templates', temp))
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def output
|
|
48
|
+
@output ||= ERB.new(template).result(binding)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def base_output_file_name
|
|
52
|
+
"#{class_name.underscore}.rb"
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def output_file_directory
|
|
56
|
+
File.join(base_output_dir, directory_name)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def output_file_name
|
|
60
|
+
File.join(output_file_directory, base_output_file_name)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def directory_name
|
|
64
|
+
return 'client_tests' if system == 'client'
|
|
65
|
+
|
|
66
|
+
Naming.snake_case_for_profile(medication_request_metadata || group_metadata)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def profile_identifier
|
|
70
|
+
Naming.snake_case_for_profile(group_metadata)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def profile_url
|
|
74
|
+
group_metadata.profile_url
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def profile_name
|
|
78
|
+
group_metadata.profile_name
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def profile_version
|
|
82
|
+
group_metadata.profile_version
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def formatted_workflow
|
|
86
|
+
workflow.to_s.split('_').first.to_s
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def test_id
|
|
90
|
+
pref = "pas_#{system}_#{group_metadata.reformatted_version}_#{formatted_workflow}".delete_suffix('_')
|
|
91
|
+
"#{pref}_#{profile_identifier}_validation_test"
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def class_name
|
|
95
|
+
pref = "#{system.capitalize}#{formatted_workflow.camelize}"
|
|
96
|
+
"#{pref}#{Naming.upper_camel_case_for_profile(group_metadata)}ValidationTest"
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def module_name
|
|
100
|
+
"DaVinciPAS#{group_metadata.reformatted_version.upcase}"
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def resource_type
|
|
104
|
+
group_metadata.resource
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def conformance_expectation
|
|
108
|
+
read_interaction[:expectation]
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def skip_if_empty
|
|
112
|
+
# Return true if a system must demonstrate at least one example of the resource type.
|
|
113
|
+
# This drives omit vs. skip result statuses in this test.
|
|
114
|
+
resource_type != 'Medication'
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def request_type
|
|
118
|
+
Naming.request_type_for_bundle_or_claim[profile_name]
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def generate
|
|
122
|
+
FileUtils.mkdir_p(output_file_directory)
|
|
123
|
+
File.write(output_file_name, output)
|
|
124
|
+
|
|
125
|
+
test_metadata = {
|
|
126
|
+
id: test_id,
|
|
127
|
+
file_name: base_output_file_name
|
|
128
|
+
}
|
|
129
|
+
group_metadata.add_test(**test_metadata)
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def title
|
|
133
|
+
pref = user_input? ? '[USER INPUT VALIDATION] ' : ''
|
|
134
|
+
"#{pref}#{group_metadata.title} is valid"
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def user_input?
|
|
138
|
+
(system == 'server' && request_type.include?('request')) ||
|
|
139
|
+
(system == 'client' && request_type.include?('response'))
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
def description
|
|
143
|
+
<<~DESCRIPTION
|
|
144
|
+
#{system == 'server' ? description_intro_server : description_intro_client}
|
|
145
|
+
It verifies the presence of mandatory elements and that elements with
|
|
146
|
+
required bindings contain appropriate values. CodeableConcept element
|
|
147
|
+
bindings will fail if none of their codings have a code/system belonging
|
|
148
|
+
to the bound ValueSet. Quantity, Coding, and code element bindings will
|
|
149
|
+
fail if their code/system are not found in the valueset.
|
|
150
|
+
|
|
151
|
+
Note that because X12 value sets are not public, elements bound to value
|
|
152
|
+
sets containing X12 codes are not validated.
|
|
153
|
+
DESCRIPTION
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
def description_intro_server
|
|
157
|
+
<<~GENERIC_INTRO
|
|
158
|
+
This test validates the conformity of the
|
|
159
|
+
#{request_type.include?('request') ? 'user input' : "server's response"} to the
|
|
160
|
+
[#{profile_name}](#{profile_url}) structure#{request_type.include?('request') ? ', ensuring subsequent tests can accurately simulate content.' : '.'}
|
|
161
|
+
It also checks that other conformance requirements defined in the [PAS Formal
|
|
162
|
+
Specification](https://hl7.org/fhir/us/davinci-pas/STU2/specification.html),
|
|
163
|
+
such as the presence of all referenced instances within the bundle and the
|
|
164
|
+
conformance of those instances to the appropriate profiles, are met.
|
|
165
|
+
GENERIC_INTRO
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
def description_intro_client
|
|
169
|
+
<<~GENERIC_INTRO
|
|
170
|
+
This test validates the conformity of the
|
|
171
|
+
#{request_type.include?('response') ? 'user input' : "client's request"} to the
|
|
172
|
+
[#{profile_name}](#{profile_url}) structure.
|
|
173
|
+
It also checks that other conformance requirements defined in the [PAS Formal
|
|
174
|
+
Specification](https://hl7.org/fhir/us/davinci-pas/STU2/specification.html),
|
|
175
|
+
such as the presence of all referenced instances within the bundle and the
|
|
176
|
+
conformance of those instances to the appropriate profiles, are met.
|
|
177
|
+
GENERIC_INTRO
|
|
178
|
+
end
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
module DaVinciPASTestKit
|
|
2
|
+
class Generator
|
|
3
|
+
class ValueExactor
|
|
4
|
+
attr_accessor :ig_resources, :resource
|
|
5
|
+
|
|
6
|
+
def initialize(ig_resources, resource)
|
|
7
|
+
self.ig_resources = ig_resources
|
|
8
|
+
self.resource = resource
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def value_set_binding(the_element)
|
|
12
|
+
the_element&.binding
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def value_set(the_element)
|
|
16
|
+
ig_resources.value_set_by_url(value_set_binding(the_element)&.valueSet)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def bound_systems(the_element)
|
|
20
|
+
value_set(the_element)&.compose&.include&.reject { |code| code.concept.nil? }
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def values_from_value_set_binding(the_element)
|
|
24
|
+
bound_systems = bound_systems(the_element)
|
|
25
|
+
|
|
26
|
+
return [] if bound_systems.blank?
|
|
27
|
+
|
|
28
|
+
bound_systems.flat_map { |system| system.concept.map(&:code) }.uniq
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def fhir_metadata(current_path)
|
|
32
|
+
FHIR.const_get(resource)::METADATA[current_path]
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def values_from_resource_metadata(paths)
|
|
36
|
+
values = []
|
|
37
|
+
|
|
38
|
+
paths.each do |current_path|
|
|
39
|
+
current_metadata = fhir_metadata(current_path)
|
|
40
|
+
|
|
41
|
+
values += current_metadata['valid_codes'].values.flatten if current_metadata&.dig('valid_codes').present?
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
values
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
require 'inferno/ext/fhir_models'
|
|
2
|
+
|
|
3
|
+
require_relative 'generator/ig_loader'
|
|
4
|
+
require_relative 'generator/ig_metadata_extractor'
|
|
5
|
+
require_relative 'generator/resource_list_generator'
|
|
6
|
+
require_relative 'generator/validation_test_generator'
|
|
7
|
+
require_relative 'generator/operation_test_generator'
|
|
8
|
+
require_relative 'generator/group_generator'
|
|
9
|
+
require_relative 'generator/suite_generator'
|
|
10
|
+
require_relative 'generator/must_support_test_generator'
|
|
11
|
+
|
|
12
|
+
module DaVinciPASTestKit
|
|
13
|
+
class Generator
|
|
14
|
+
def self.generate
|
|
15
|
+
ig_packages = Dir.glob(File.join(Dir.pwd, 'lib', 'davinci_pas_test_kit', 'igs', '*.tgz'))
|
|
16
|
+
|
|
17
|
+
ig_packages.each do |ig_package|
|
|
18
|
+
new(ig_package).generate
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
attr_accessor :ig_resources, :ig_metadata, :ig_file_name
|
|
23
|
+
|
|
24
|
+
def initialize(ig_file_name)
|
|
25
|
+
self.ig_file_name = ig_file_name
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def generate
|
|
29
|
+
puts "Generating tests for IG #{File.basename(ig_file_name)}"
|
|
30
|
+
load_ig_package
|
|
31
|
+
extract_metadata
|
|
32
|
+
generate_resource_list
|
|
33
|
+
generate_validation_tests
|
|
34
|
+
generate_operation_tests
|
|
35
|
+
generate_must_support_tests
|
|
36
|
+
generate_groups
|
|
37
|
+
generate_suites
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def load_ig_package
|
|
41
|
+
FHIR.logger = Logger.new('/dev/null')
|
|
42
|
+
self.ig_resources = IGLoader.new(ig_file_name).load
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def extract_metadata
|
|
46
|
+
self.ig_metadata = IGMetadataExtractor.new(ig_resources).extract
|
|
47
|
+
|
|
48
|
+
FileUtils.mkdir_p(base_output_dir)
|
|
49
|
+
File.write(File.join(base_output_dir, 'metadata.yml'), YAML.dump(ig_metadata.to_hash))
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def base_output_dir
|
|
53
|
+
File.join(__dir__, 'generated', ig_metadata.ig_version)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def generate_resource_list
|
|
57
|
+
ResourceListGenerator.generate(ig_metadata, base_output_dir)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def generate_validation_tests
|
|
61
|
+
ValidationTestGenerator.generate(ig_metadata, base_output_dir)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def generate_operation_tests
|
|
65
|
+
OperationTestGenerator.generate(ig_metadata, base_output_dir)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def generate_groups
|
|
69
|
+
GroupGenerator.generate(ig_metadata, base_output_dir)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def generate_suites
|
|
73
|
+
SuiteGenerator.generate(ig_metadata, base_output_dir)
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def generate_must_support_tests
|
|
77
|
+
MustSupportTestGenerator.generate(ig_metadata, base_output_dir)
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|