au_ps_inferno 0.1.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/au_ps_inferno/generator/constants.rb +61 -0
- data/lib/au_ps_inferno/generator/generator.rb +76 -0
- data/lib/au_ps_inferno/generator/generator_group_based_metadata_module.rb +113 -0
- data/lib/au_ps_inferno/generator/ig_resources_extractor.rb +149 -0
- data/lib/au_ps_inferno/generator/metadata_manager.rb +608 -0
- data/lib/au_ps_inferno/generator/naming.rb +52 -0
- data/lib/au_ps_inferno/generator/sections_validation_group_generator.rb +182 -0
- data/lib/au_ps_inferno/generator/test_file_generator.rb +77 -0
- data/lib/au_ps_inferno/suite/au_ps_bundle_instance/au_ps_bundle_instance.rb +56 -0
- data/lib/au_ps_inferno/suite/au_ps_bundle_instance/au_ps_bundle_must_support_conformance/suite_au_ps_bundle_instance_au_ps_bundle_must_support_conformance_bundle_must_support_populated.rb +21 -0
- data/lib/au_ps_inferno/suite/au_ps_bundle_instance/au_ps_bundle_must_support_conformance.rb +16 -0
- data/lib/au_ps_inferno/suite/au_ps_bundle_instance/au_ps_composition_attester/suite_au_ps_bundle_instance_au_ps_composition_attester_attester_party_ms_elements.rb +21 -0
- data/lib/au_ps_inferno/suite/au_ps_bundle_instance/au_ps_composition_attester/suite_au_ps_bundle_instance_au_ps_composition_attester_attester_party_ms_identifier_slices.rb +21 -0
- data/lib/au_ps_inferno/suite/au_ps_bundle_instance/au_ps_composition_attester/suite_au_ps_bundle_instance_au_ps_composition_attester_attester_party_ms_subelements.rb +21 -0
- data/lib/au_ps_inferno/suite/au_ps_bundle_instance/au_ps_composition_attester.rb +26 -0
- data/lib/au_ps_inferno/suite/au_ps_bundle_instance/au_ps_composition_author/suite_au_ps_bundle_instance_au_ps_composition_author_author_ms_elements.rb +21 -0
- data/lib/au_ps_inferno/suite/au_ps_bundle_instance/au_ps_composition_author/suite_au_ps_bundle_instance_au_ps_composition_author_author_ms_identifier_slices.rb +21 -0
- data/lib/au_ps_inferno/suite/au_ps_bundle_instance/au_ps_composition_author/suite_au_ps_bundle_instance_au_ps_composition_author_author_ms_subelements.rb +21 -0
- data/lib/au_ps_inferno/suite/au_ps_bundle_instance/au_ps_composition_author/suite_au_ps_bundle_instance_au_ps_composition_author_author_resource_type_is_valid.rb +21 -0
- data/lib/au_ps_inferno/suite/au_ps_bundle_instance/au_ps_composition_author.rb +28 -0
- data/lib/au_ps_inferno/suite/au_ps_bundle_instance/au_ps_composition_custodian/suite_au_ps_bundle_instance_au_ps_composition_custodian_custodian_ms_elements.rb +21 -0
- data/lib/au_ps_inferno/suite/au_ps_bundle_instance/au_ps_composition_custodian/suite_au_ps_bundle_instance_au_ps_composition_custodian_custodian_ms_identifier_slices.rb +21 -0
- data/lib/au_ps_inferno/suite/au_ps_bundle_instance/au_ps_composition_custodian/suite_au_ps_bundle_instance_au_ps_composition_custodian_custodian_ms_subelements.rb +21 -0
- data/lib/au_ps_inferno/suite/au_ps_bundle_instance/au_ps_composition_custodian.rb +26 -0
- data/lib/au_ps_inferno/suite/au_ps_bundle_instance/au_ps_composition_mandatory_sections/composition_mandatory_sections_mandatory_sections_entry_profiles.rb +21 -0
- data/lib/au_ps_inferno/suite/au_ps_bundle_instance/au_ps_composition_mandatory_sections/suite_au_ps_bundle_instance_au_ps_composition_mandatory_sections_sections_shall_populated.rb +21 -0
- data/lib/au_ps_inferno/suite/au_ps_bundle_instance/au_ps_composition_mandatory_sections.rb +20 -0
- data/lib/au_ps_inferno/suite/au_ps_bundle_instance/au_ps_composition_must_support_conformance/composition_must_support_conformance_composition_mandatory_ms_populated.rb +21 -0
- data/lib/au_ps_inferno/suite/au_ps_bundle_instance/au_ps_composition_must_support_conformance/composition_must_support_conformance_composition_ms_subelements_populated.rb +22 -0
- data/lib/au_ps_inferno/suite/au_ps_bundle_instance/au_ps_composition_must_support_conformance/composition_must_support_conformance_composition_optional_ms_populated.rb +22 -0
- data/lib/au_ps_inferno/suite/au_ps_bundle_instance/au_ps_composition_must_support_conformance/composition_must_support_conformance_composition_optional_ms_slices.rb +22 -0
- data/lib/au_ps_inferno/suite/au_ps_bundle_instance/au_ps_composition_must_support_conformance.rb +28 -0
- data/lib/au_ps_inferno/suite/au_ps_bundle_instance/au_ps_composition_optional_sections/suite_au_ps_bundle_instance_au_ps_composition_optional_sections_optional_sections_entry_profiles.rb +22 -0
- data/lib/au_ps_inferno/suite/au_ps_bundle_instance/au_ps_composition_optional_sections/suite_au_ps_bundle_instance_au_ps_composition_optional_sections_sections_may_populated.rb +24 -0
- data/lib/au_ps_inferno/suite/au_ps_bundle_instance/au_ps_composition_optional_sections.rb +20 -0
- data/lib/au_ps_inferno/suite/au_ps_bundle_instance/au_ps_composition_recommended_sections/composition_recommended_sections_recommended_sections_entry_profiles.rb +21 -0
- data/lib/au_ps_inferno/suite/au_ps_bundle_instance/au_ps_composition_recommended_sections/suite_au_ps_bundle_instance_au_ps_composition_recommended_sections_sections_should_populated.rb +22 -0
- data/lib/au_ps_inferno/suite/au_ps_bundle_instance/au_ps_composition_recommended_sections.rb +20 -0
- data/lib/au_ps_inferno/suite/au_ps_bundle_instance/au_ps_composition_subject/suite_au_ps_bundle_instance_au_ps_composition_subject_subject_ms_elements.rb +21 -0
- data/lib/au_ps_inferno/suite/au_ps_bundle_instance/au_ps_composition_subject/suite_au_ps_bundle_instance_au_ps_composition_subject_subject_ms_identifier_slices.rb +21 -0
- data/lib/au_ps_inferno/suite/au_ps_bundle_instance/au_ps_composition_subject/suite_au_ps_bundle_instance_au_ps_composition_subject_subject_ms_subelements_populated.rb +21 -0
- data/lib/au_ps_inferno/suite/au_ps_bundle_instance/au_ps_composition_subject/suite_au_ps_bundle_instance_au_ps_composition_subject_subject_resource_type_is_valid.rb +21 -0
- data/lib/au_ps_inferno/suite/au_ps_bundle_instance/au_ps_composition_subject.rb +28 -0
- data/lib/au_ps_inferno/suite/au_ps_bundle_instance/au_ps_composition_undefined_sections/suite_au_ps_bundle_instance_au_ps_composition_undefined_sections_sections_may_undefined.rb +24 -0
- data/lib/au_ps_inferno/suite/au_ps_bundle_instance/au_ps_composition_undefined_sections.rb +18 -0
- data/lib/au_ps_inferno/suite/au_ps_bundle_instance/bundle_validation/suite_au_ps_bundle_instance_bundle_validation_bundle_valid.rb +21 -0
- data/lib/au_ps_inferno/suite/au_ps_bundle_instance/bundle_validation/suite_au_ps_bundle_instance_bundle_validation_bundle_valid_ips.rb +21 -0
- data/lib/au_ps_inferno/suite/au_ps_bundle_instance/bundle_validation.rb +20 -0
- data/lib/au_ps_inferno/suite/au_ps_retrieve_cs_group/au_ps_cs_is_valid_test.rb +21 -0
- data/lib/au_ps_inferno/suite/au_ps_retrieve_cs_group/au_ps_cs_supports_au_ps_profiles.rb +40 -0
- data/lib/au_ps_inferno/suite/au_ps_retrieve_cs_group/au_ps_cs_supports_ips_recommended_ops.rb +19 -0
- data/lib/au_ps_inferno/suite/au_ps_retrieve_cs_group/au_ps_retrieve_cs_group.rb +47 -0
- data/lib/au_ps_inferno/suite/au_ps_v100.rb +39 -0
- data/lib/au_ps_inferno/suite/generate_au_ps_using_ips_summary_validation_tests/au_ps_bundle_must_support_conformance/bundle_must_support_conformance_bundle_must_support_populated.rb +21 -0
- data/lib/au_ps_inferno/suite/generate_au_ps_using_ips_summary_validation_tests/au_ps_bundle_must_support_conformance.rb +16 -0
- data/lib/au_ps_inferno/suite/generate_au_ps_using_ips_summary_validation_tests/au_ps_composition_attester/composition_attester_attester_party_ms_elements.rb +21 -0
- data/lib/au_ps_inferno/suite/generate_au_ps_using_ips_summary_validation_tests/au_ps_composition_attester/composition_attester_attester_party_ms_identifier_slices.rb +21 -0
- data/lib/au_ps_inferno/suite/generate_au_ps_using_ips_summary_validation_tests/au_ps_composition_attester/composition_attester_attester_party_ms_subelements.rb +21 -0
- data/lib/au_ps_inferno/suite/generate_au_ps_using_ips_summary_validation_tests/au_ps_composition_attester.rb +26 -0
- data/lib/au_ps_inferno/suite/generate_au_ps_using_ips_summary_validation_tests/au_ps_composition_author/composition_author_author_ms_elements.rb +21 -0
- data/lib/au_ps_inferno/suite/generate_au_ps_using_ips_summary_validation_tests/au_ps_composition_author/composition_author_author_ms_identifier_slices.rb +21 -0
- data/lib/au_ps_inferno/suite/generate_au_ps_using_ips_summary_validation_tests/au_ps_composition_author/composition_author_author_ms_subelements.rb +21 -0
- data/lib/au_ps_inferno/suite/generate_au_ps_using_ips_summary_validation_tests/au_ps_composition_author/composition_author_author_resource_type_is_valid.rb +21 -0
- data/lib/au_ps_inferno/suite/generate_au_ps_using_ips_summary_validation_tests/au_ps_composition_author.rb +28 -0
- data/lib/au_ps_inferno/suite/generate_au_ps_using_ips_summary_validation_tests/au_ps_composition_custodian/composition_custodian_custodian_ms_elements.rb +21 -0
- data/lib/au_ps_inferno/suite/generate_au_ps_using_ips_summary_validation_tests/au_ps_composition_custodian/composition_custodian_custodian_ms_identifier_slices.rb +21 -0
- data/lib/au_ps_inferno/suite/generate_au_ps_using_ips_summary_validation_tests/au_ps_composition_custodian/composition_custodian_custodian_ms_subelements.rb +21 -0
- data/lib/au_ps_inferno/suite/generate_au_ps_using_ips_summary_validation_tests/au_ps_composition_custodian.rb +26 -0
- data/lib/au_ps_inferno/suite/generate_au_ps_using_ips_summary_validation_tests/au_ps_composition_mandatory_sections/composition_mandatory_sections_mandatory_sections_entry_profiles.rb +21 -0
- data/lib/au_ps_inferno/suite/generate_au_ps_using_ips_summary_validation_tests/au_ps_composition_mandatory_sections/composition_mandatory_sections_sections_shall_populated.rb +21 -0
- data/lib/au_ps_inferno/suite/generate_au_ps_using_ips_summary_validation_tests/au_ps_composition_mandatory_sections.rb +20 -0
- data/lib/au_ps_inferno/suite/generate_au_ps_using_ips_summary_validation_tests/au_ps_composition_must_support_conformance/composition_must_support_conformance_composition_mandatory_ms_populated.rb +21 -0
- data/lib/au_ps_inferno/suite/generate_au_ps_using_ips_summary_validation_tests/au_ps_composition_must_support_conformance/composition_must_support_conformance_composition_ms_subelements_populated.rb +22 -0
- data/lib/au_ps_inferno/suite/generate_au_ps_using_ips_summary_validation_tests/au_ps_composition_must_support_conformance/composition_must_support_conformance_composition_optional_ms_populated.rb +22 -0
- data/lib/au_ps_inferno/suite/generate_au_ps_using_ips_summary_validation_tests/au_ps_composition_must_support_conformance/composition_must_support_conformance_composition_optional_ms_slices.rb +22 -0
- data/lib/au_ps_inferno/suite/generate_au_ps_using_ips_summary_validation_tests/au_ps_composition_must_support_conformance.rb +28 -0
- data/lib/au_ps_inferno/suite/generate_au_ps_using_ips_summary_validation_tests/au_ps_composition_optional_sections/composition_optional_sections_optional_sections_entry_profiles.rb +22 -0
- data/lib/au_ps_inferno/suite/generate_au_ps_using_ips_summary_validation_tests/au_ps_composition_optional_sections/composition_optional_sections_sections_may_populated.rb +24 -0
- data/lib/au_ps_inferno/suite/generate_au_ps_using_ips_summary_validation_tests/au_ps_composition_optional_sections.rb +20 -0
- data/lib/au_ps_inferno/suite/generate_au_ps_using_ips_summary_validation_tests/au_ps_composition_recommended_sections/composition_recommended_sections_recommended_sections_entry_profiles.rb +21 -0
- data/lib/au_ps_inferno/suite/generate_au_ps_using_ips_summary_validation_tests/au_ps_composition_recommended_sections/composition_recommended_sections_sections_should_populated.rb +22 -0
- data/lib/au_ps_inferno/suite/generate_au_ps_using_ips_summary_validation_tests/au_ps_composition_recommended_sections.rb +20 -0
- data/lib/au_ps_inferno/suite/generate_au_ps_using_ips_summary_validation_tests/au_ps_composition_subject/composition_subject_subject_ms_elements.rb +21 -0
- data/lib/au_ps_inferno/suite/generate_au_ps_using_ips_summary_validation_tests/au_ps_composition_subject/composition_subject_subject_ms_identifier_slices.rb +21 -0
- data/lib/au_ps_inferno/suite/generate_au_ps_using_ips_summary_validation_tests/au_ps_composition_subject/composition_subject_subject_ms_subelements_populated.rb +21 -0
- data/lib/au_ps_inferno/suite/generate_au_ps_using_ips_summary_validation_tests/au_ps_composition_subject/composition_subject_subject_resource_type_is_valid.rb +21 -0
- data/lib/au_ps_inferno/suite/generate_au_ps_using_ips_summary_validation_tests/au_ps_composition_subject.rb +28 -0
- data/lib/au_ps_inferno/suite/generate_au_ps_using_ips_summary_validation_tests/au_ps_composition_undefined_sections/composition_undefined_sections_sections_may_undefined.rb +24 -0
- data/lib/au_ps_inferno/suite/generate_au_ps_using_ips_summary_validation_tests/au_ps_composition_undefined_sections.rb +18 -0
- data/lib/au_ps_inferno/suite/generate_au_ps_using_ips_summary_validation_tests/bundle_validation/suite_generate_au_ps_using_ips_summary_validation_tests_bundle_validation_bundle_valid.rb +21 -0
- data/lib/au_ps_inferno/suite/generate_au_ps_using_ips_summary_validation_tests/bundle_validation/suite_generate_au_ps_using_ips_summary_validation_tests_bundle_validation_bundle_valid_ips.rb +21 -0
- data/lib/au_ps_inferno/suite/generate_au_ps_using_ips_summary_validation_tests/bundle_validation.rb +20 -0
- data/lib/au_ps_inferno/suite/generate_au_ps_using_ips_summary_validation_tests/generate_au_ps_using_ips_summary_validation_tests.rb +56 -0
- data/lib/au_ps_inferno/suite/retrieve_au_ps_bundle_validation_tests/au_ps_bundle_must_support_conformance/bundle_must_support_conformance_bundle_must_support_populated.rb +21 -0
- data/lib/au_ps_inferno/suite/retrieve_au_ps_bundle_validation_tests/au_ps_bundle_must_support_conformance.rb +16 -0
- data/lib/au_ps_inferno/suite/retrieve_au_ps_bundle_validation_tests/au_ps_composition_attester/composition_attester_attester_party_ms_elements.rb +21 -0
- data/lib/au_ps_inferno/suite/retrieve_au_ps_bundle_validation_tests/au_ps_composition_attester/composition_attester_attester_party_ms_identifier_slices.rb +21 -0
- data/lib/au_ps_inferno/suite/retrieve_au_ps_bundle_validation_tests/au_ps_composition_attester/composition_attester_attester_party_ms_subelements.rb +21 -0
- data/lib/au_ps_inferno/suite/retrieve_au_ps_bundle_validation_tests/au_ps_composition_attester.rb +26 -0
- data/lib/au_ps_inferno/suite/retrieve_au_ps_bundle_validation_tests/au_ps_composition_author/composition_author_author_ms_identifier_slices.rb +21 -0
- data/lib/au_ps_inferno/suite/retrieve_au_ps_bundle_validation_tests/au_ps_composition_author/composition_author_author_resource_type_is_valid.rb +21 -0
- data/lib/au_ps_inferno/suite/retrieve_au_ps_bundle_validation_tests/au_ps_composition_author/suite_retrieve_au_ps_bundle_validation_tests_au_ps_composition_author_author_ms_elements.rb +21 -0
- data/lib/au_ps_inferno/suite/retrieve_au_ps_bundle_validation_tests/au_ps_composition_author/suite_retrieve_au_ps_bundle_validation_tests_au_ps_composition_author_author_ms_subelements.rb +21 -0
- data/lib/au_ps_inferno/suite/retrieve_au_ps_bundle_validation_tests/au_ps_composition_author.rb +28 -0
- data/lib/au_ps_inferno/suite/retrieve_au_ps_bundle_validation_tests/au_ps_composition_custodian/composition_custodian_custodian_ms_identifier_slices.rb +21 -0
- data/lib/au_ps_inferno/suite/retrieve_au_ps_bundle_validation_tests/au_ps_composition_custodian/composition_custodian_custodian_ms_subelements.rb +21 -0
- data/lib/au_ps_inferno/suite/retrieve_au_ps_bundle_validation_tests/au_ps_composition_custodian/suite_retrieve_au_ps_bundle_validation_tests_au_ps_composition_custodian_custodian_ms_elements.rb +21 -0
- data/lib/au_ps_inferno/suite/retrieve_au_ps_bundle_validation_tests/au_ps_composition_custodian.rb +26 -0
- data/lib/au_ps_inferno/suite/retrieve_au_ps_bundle_validation_tests/au_ps_composition_mandatory_sections/composition_mandatory_sections_mandatory_sections_entry_profiles.rb +21 -0
- data/lib/au_ps_inferno/suite/retrieve_au_ps_bundle_validation_tests/au_ps_composition_mandatory_sections/composition_mandatory_sections_sections_shall_populated.rb +21 -0
- data/lib/au_ps_inferno/suite/retrieve_au_ps_bundle_validation_tests/au_ps_composition_mandatory_sections.rb +20 -0
- data/lib/au_ps_inferno/suite/retrieve_au_ps_bundle_validation_tests/au_ps_composition_must_support_conformance/composition_must_support_conformance_composition_mandatory_ms_populated.rb +21 -0
- data/lib/au_ps_inferno/suite/retrieve_au_ps_bundle_validation_tests/au_ps_composition_must_support_conformance/composition_must_support_conformance_composition_ms_subelements_populated.rb +22 -0
- data/lib/au_ps_inferno/suite/retrieve_au_ps_bundle_validation_tests/au_ps_composition_must_support_conformance/composition_must_support_conformance_composition_optional_ms_populated.rb +22 -0
- data/lib/au_ps_inferno/suite/retrieve_au_ps_bundle_validation_tests/au_ps_composition_must_support_conformance/composition_must_support_conformance_composition_optional_ms_slices.rb +22 -0
- data/lib/au_ps_inferno/suite/retrieve_au_ps_bundle_validation_tests/au_ps_composition_must_support_conformance.rb +28 -0
- data/lib/au_ps_inferno/suite/retrieve_au_ps_bundle_validation_tests/au_ps_composition_optional_sections/composition_optional_sections_optional_sections_entry_profiles.rb +22 -0
- data/lib/au_ps_inferno/suite/retrieve_au_ps_bundle_validation_tests/au_ps_composition_optional_sections/composition_optional_sections_sections_may_populated.rb +24 -0
- data/lib/au_ps_inferno/suite/retrieve_au_ps_bundle_validation_tests/au_ps_composition_optional_sections.rb +20 -0
- data/lib/au_ps_inferno/suite/retrieve_au_ps_bundle_validation_tests/au_ps_composition_recommended_sections/composition_recommended_sections_recommended_sections_entry_profiles.rb +21 -0
- data/lib/au_ps_inferno/suite/retrieve_au_ps_bundle_validation_tests/au_ps_composition_recommended_sections/composition_recommended_sections_sections_should_populated.rb +22 -0
- data/lib/au_ps_inferno/suite/retrieve_au_ps_bundle_validation_tests/au_ps_composition_recommended_sections.rb +20 -0
- data/lib/au_ps_inferno/suite/retrieve_au_ps_bundle_validation_tests/au_ps_composition_subject/composition_subject_subject_ms_identifier_slices.rb +21 -0
- data/lib/au_ps_inferno/suite/retrieve_au_ps_bundle_validation_tests/au_ps_composition_subject/composition_subject_subject_ms_subelements_populated.rb +21 -0
- data/lib/au_ps_inferno/suite/retrieve_au_ps_bundle_validation_tests/au_ps_composition_subject/composition_subject_subject_resource_type_is_valid.rb +21 -0
- data/lib/au_ps_inferno/suite/retrieve_au_ps_bundle_validation_tests/au_ps_composition_subject/suite_retrieve_au_ps_bundle_validation_tests_au_ps_composition_subject_subject_ms_elements.rb +21 -0
- data/lib/au_ps_inferno/suite/retrieve_au_ps_bundle_validation_tests/au_ps_composition_subject.rb +28 -0
- data/lib/au_ps_inferno/suite/retrieve_au_ps_bundle_validation_tests/au_ps_composition_undefined_sections/composition_undefined_sections_sections_may_undefined.rb +24 -0
- data/lib/au_ps_inferno/suite/retrieve_au_ps_bundle_validation_tests/au_ps_composition_undefined_sections.rb +18 -0
- data/lib/au_ps_inferno/suite/retrieve_au_ps_bundle_validation_tests/bundle_validation/suite_retrieve_au_ps_bundle_validation_tests_bundle_validation_bundle_valid.rb +21 -0
- data/lib/au_ps_inferno/suite/retrieve_au_ps_bundle_validation_tests/bundle_validation/suite_retrieve_au_ps_bundle_validation_tests_bundle_validation_bundle_valid_ips.rb +21 -0
- data/lib/au_ps_inferno/suite/retrieve_au_ps_bundle_validation_tests/bundle_validation.rb +20 -0
- data/lib/au_ps_inferno/suite/retrieve_au_ps_bundle_validation_tests/retrieve_au_ps_bundle_validation_tests.rb +56 -0
- data/lib/au_ps_inferno/utils/attester/basic_test_attester_identifier_slices.rb +74 -0
- data/lib/au_ps_inferno/utils/attester/basic_test_attester_message_helpers.rb +16 -0
- data/lib/au_ps_inferno/utils/attester/basic_test_attester_module.rb +14 -0
- data/lib/au_ps_inferno/utils/attester/basic_test_attester_resource.rb +54 -0
- data/lib/au_ps_inferno/utils/author/basic_test_author_module.rb +12 -0
- data/lib/au_ps_inferno/utils/author/basic_test_author_resource.rb +32 -0
- data/lib/au_ps_inferno/utils/author/basic_test_author_tests.rb +24 -0
- data/lib/au_ps_inferno/utils/basic_test/bundle_module.rb +87 -0
- data/lib/au_ps_inferno/utils/basic_test/capability_operations_module.rb +37 -0
- data/lib/au_ps_inferno/utils/basic_test/composition_elements_and_slices_module.rb +98 -0
- data/lib/au_ps_inferno/utils/basic_test/composition_section_check_resources_ms_elements_module.rb +197 -0
- data/lib/au_ps_inferno/utils/basic_test/composition_section_read_issues_helpers_module.rb +66 -0
- data/lib/au_ps_inferno/utils/basic_test/composition_section_read_module.rb +127 -0
- data/lib/au_ps_inferno/utils/basic_test/composition_subelements_module.rb +84 -0
- data/lib/au_ps_inferno/utils/basic_test/ms_elements_populated_helpers_module.rb +38 -0
- data/lib/au_ps_inferno/utils/basic_test/ms_elements_populated_module.rb +71 -0
- data/lib/au_ps_inferno/utils/basic_test/ms_identifier_slices_module.rb +61 -0
- data/lib/au_ps_inferno/utils/basic_test/ms_sub_elements_populated_module.rb +128 -0
- data/lib/au_ps_inferno/utils/basic_test/paths_module.rb +26 -0
- data/lib/au_ps_inferno/utils/basic_test/resolve_path_debug_module.rb +45 -0
- data/lib/au_ps_inferno/utils/basic_test/resolve_resource_type_module.rb +52 -0
- data/lib/au_ps_inferno/utils/basic_test/resource_helpers_module.rb +129 -0
- data/lib/au_ps_inferno/utils/basic_test/scratch_bundle_entries_module.rb +30 -0
- data/lib/au_ps_inferno/utils/basic_test/section_bundle_validation_module.rb +70 -0
- data/lib/au_ps_inferno/utils/basic_test_class.rb +56 -0
- data/lib/au_ps_inferno/utils/basic_test_contants_module.rb +32 -0
- data/lib/au_ps_inferno/utils/basic_test_with_url.rb +8 -0
- data/lib/au_ps_inferno/utils/basic_validate_bundle_test.rb +43 -0
- data/lib/au_ps_inferno/utils/bundle_decorator.rb +81 -0
- data/lib/au_ps_inferno/utils/bundle_entry_decorator.rb +19 -0
- data/lib/au_ps_inferno/utils/bundle_is_valid_class.rb +31 -0
- data/lib/au_ps_inferno/utils/capability_statement_decorator.rb +20 -0
- data/lib/au_ps_inferno/utils/composition_decorator.rb +56 -0
- data/lib/au_ps_inferno/utils/composition_utils/boolean_and_stats.rb +28 -0
- data/lib/au_ps_inferno/utils/composition_utils.rb +29 -0
- data/lib/au_ps_inferno/utils/custodian/basic_test_custodian_identifier_slices.rb +47 -0
- data/lib/au_ps_inferno/utils/custodian/basic_test_custodian_module.rb +14 -0
- data/lib/au_ps_inferno/utils/custodian/basic_test_custodian_resource.rb +32 -0
- data/lib/au_ps_inferno/utils/custodian/basic_test_custodian_tests.rb +19 -0
- data/lib/au_ps_inferno/utils/inferno_suite_generator_compat.rb +7 -0
- data/lib/au_ps_inferno/utils/ips_bundle_is_valid_class.rb +15 -0
- data/lib/au_ps_inferno/utils/ips_retrieve_bundle_test_class.rb +17 -0
- data/lib/au_ps_inferno/utils/ips_summary_valid_bundle_class.rb +15 -0
- data/lib/au_ps_inferno/utils/metadata_manager.rb +58 -0
- data/lib/au_ps_inferno/utils/retrieve_bundle_test_class.rb +81 -0
- data/lib/au_ps_inferno/utils/rich_message_class.rb +23 -0
- data/lib/au_ps_inferno/utils/rich_validation_message.rb +42 -0
- data/lib/au_ps_inferno/utils/section_decorator.rb +23 -0
- data/lib/au_ps_inferno/utils/section_names_mapping.rb +31 -0
- data/lib/au_ps_inferno/utils/section_test_class.rb +18 -0
- data/lib/au_ps_inferno/utils/section_test_module.rb +16 -0
- data/lib/au_ps_inferno/utils/structure_definition_decorator.rb +28 -0
- data/lib/au_ps_inferno/utils/subject/basic_test_subject_module.rb +12 -0
- data/lib/au_ps_inferno/utils/subject/basic_test_subject_patient_ms_other_tests.rb +15 -0
- data/lib/au_ps_inferno/utils/subject/basic_test_subject_resource.rb +21 -0
- data/lib/au_ps_inferno/utils/summary_valid_bundle_class.rb +84 -0
- data/lib/au_ps_inferno/utils/validator_helpers.rb +92 -0
- data/lib/au_ps_inferno/version.rb +6 -0
- data/lib/au_ps_inferno.rb +3 -0
- metadata +310 -0
data/lib/au_ps_inferno/utils/basic_test/composition_section_check_resources_ms_elements_module.rb
ADDED
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative '../inferno_suite_generator_compat'
|
|
4
|
+
require 'inferno_suite_generator/test_utils/ms_checker'
|
|
5
|
+
module AUPSTestKit
|
|
6
|
+
module BasicTestCompositionSectionReadModule
|
|
7
|
+
# Composition Must Support elements in sections.
|
|
8
|
+
module BasicTestCompositionSectionCheckResourcesMSElementsModule # rubocop:disable Metrics/ModuleLength
|
|
9
|
+
AU_PS_PROFILE_BASE_URL = 'http://hl7.org.au/fhir/ps/StructureDefinition/'
|
|
10
|
+
|
|
11
|
+
def check_ms_elements_populated(profile_url, resources, all_present: false)
|
|
12
|
+
profile_metadata = group_metadata_for(profile_url)
|
|
13
|
+
collapsed_elements_statuses(ms_checker_for(profile_metadata).elements_present_statuses(resources, all_present:))
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
private
|
|
17
|
+
|
|
18
|
+
def collapsed_elements_statuses(elements_statuses)
|
|
19
|
+
to_collapse = parent_paths_to_collapse(elements_statuses)
|
|
20
|
+
elements_statuses.filter do |element|
|
|
21
|
+
next true unless element[:path].include?('.')
|
|
22
|
+
|
|
23
|
+
to_collapse.none? do |to_collapse_path|
|
|
24
|
+
element[:path].start_with?("#{to_collapse_path}.")
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def parent_paths_to_collapse(elements_statuses)
|
|
30
|
+
optional_missing_parent_elements(elements_statuses).map { |element| element[:path] }.uniq
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def complex_elements(elements_statuses)
|
|
34
|
+
elements_statuses.filter { |element| element[:path].include?('.') }.map { |element| element[:path] }
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def optional_missing_parent_elements(elements_statuses)
|
|
38
|
+
complex_elements_paths = complex_elements(elements_statuses)
|
|
39
|
+
elements_statuses.filter do |element|
|
|
40
|
+
element[:present] == false &&
|
|
41
|
+
element[:mandatory] == false &&
|
|
42
|
+
!element[:path].include?('.') &&
|
|
43
|
+
complex_elements_paths.any? { |complex_element| complex_element.start_with?(element[:path]) }
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def raw_sections_profiles(sections_codes)
|
|
48
|
+
sections_metadata = metadata_manager.sections_metadata_by_codes(sections_codes)
|
|
49
|
+
sections_metadata.flat_map do |section_metadata|
|
|
50
|
+
section_short = section_metadata[:short]
|
|
51
|
+
section_code = section_metadata[:code]
|
|
52
|
+
section_metadata[:entries].flat_map do |entry_metadata|
|
|
53
|
+
entry_metadata[:profiles].map do |profile|
|
|
54
|
+
{
|
|
55
|
+
profile: profile,
|
|
56
|
+
section_short: section_short,
|
|
57
|
+
section_code: section_code
|
|
58
|
+
}
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def sections_profiles(sections_codes)
|
|
65
|
+
uniq_profiles = Set.new
|
|
66
|
+
raw_sections_profiles(sections_codes).filter do |profile|
|
|
67
|
+
_, profile_url = profile[:profile].split('|', 2)
|
|
68
|
+
next false unless profile_url.present? && profile_url.start_with?(AU_PS_PROFILE_BASE_URL)
|
|
69
|
+
next false if uniq_profiles.include?(profile_url)
|
|
70
|
+
|
|
71
|
+
uniq_profiles.add(profile_url)
|
|
72
|
+
true
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def resources_to_check_ms(sections_codes:, bundle_resource:)
|
|
77
|
+
composition_resource = bundle_resource.composition_resource
|
|
78
|
+
|
|
79
|
+
entry_references = composition_resource.entry_references_by_codes(sections_codes)
|
|
80
|
+
bundle_resource.resources_by_references(entry_references)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def result_has?(results, result_type)
|
|
84
|
+
results.any? { |result| result == result_type }
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def results_error?(results)
|
|
88
|
+
result_has?(results, 'error')
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def check_ms_elements_populated_against_profiles(sections_profiles, resources_to_check_ms, all_present: false)
|
|
92
|
+
sections_profiles.map { |profile| process_profile(profile, resources_to_check_ms, all_present:) }
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def normalize_resource_type_and_profile(profile)
|
|
96
|
+
parts = profile.split('|')
|
|
97
|
+
raise StandardError, 'Profile is not in the correct format' if parts.length < 2
|
|
98
|
+
|
|
99
|
+
{
|
|
100
|
+
resource_type: parts[0],
|
|
101
|
+
profile_url: parts[1]
|
|
102
|
+
}
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def msg_line(title, text)
|
|
106
|
+
"**#{title}**: #{text}"
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def ms_checker_for(profile_metadata, section_context = nil)
|
|
110
|
+
InfernoSuiteGenerator::MSChecker.new(profile_metadata, ms_checker_message_config(section_context))
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def build_ms_outcome(profile_metadata, resources, section_context = nil, all_present: false)
|
|
114
|
+
ms_helper = ms_checker_for(profile_metadata, section_context)
|
|
115
|
+
ms_checks_results = check_ms_elements_populated(profile_metadata.profile_url, resources, all_present:)
|
|
116
|
+
|
|
117
|
+
{
|
|
118
|
+
status: ms_helper.calculate_elements_status_message_level(ms_checks_results),
|
|
119
|
+
message: ms_helper.build_report_message(profile_metadata, ms_checks_results)
|
|
120
|
+
}
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def process_profile(section_profile, resources_to_check_ms, all_present: false)
|
|
124
|
+
profile_info_str, filtered_resources, _, profile_url =
|
|
125
|
+
build_profile_context(section_profile, resources_to_check_ms)
|
|
126
|
+
return report_missing_resources(profile_info_str) if filtered_resources.blank?
|
|
127
|
+
|
|
128
|
+
profile_metadata = group_metadata_for(profile_url)
|
|
129
|
+
outcome = build_ms_outcome(profile_metadata, filtered_resources, section_profile, all_present:)
|
|
130
|
+
add_message(outcome[:status], outcome[:message].join("\n\n"))
|
|
131
|
+
|
|
132
|
+
outcome[:status]
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def build_profile_context(section_profile, resources_to_check_ms)
|
|
136
|
+
resource_type_and_profile = normalize_resource_type_and_profile(section_profile[:profile])
|
|
137
|
+
resource_type, profile_url = resource_type_and_profile.values_at(:resource_type, :profile_url)
|
|
138
|
+
profile_info_str = msg_line('Profile', "#{resource_type} — #{profile_url}")
|
|
139
|
+
filtered_resources = resources_by_type(resources_to_check_ms, resource_type)
|
|
140
|
+
|
|
141
|
+
[profile_info_str, filtered_resources, resource_type, profile_url]
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def resources_by_type(resources, resource_type)
|
|
145
|
+
resources.filter { |resource| resource.resourceType == resource_type }
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
def group_metadata_for(profile_url)
|
|
149
|
+
resource_metadata_raw = metadata_manager.group_metadata_by_profile_url(profile_url)
|
|
150
|
+
InfernoSuiteGenerator::Generator::GroupMetadata.new(resource_metadata_raw)
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
def report_missing_resources(profile_info_str)
|
|
154
|
+
full_message_data = [
|
|
155
|
+
'No resources found',
|
|
156
|
+
profile_info_str
|
|
157
|
+
]
|
|
158
|
+
add_message('warning', full_message_data.join("\n\n"))
|
|
159
|
+
nil
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
def section_context_label(section_context)
|
|
163
|
+
short = section_context[:section_short]
|
|
164
|
+
code = section_context[:section_code]
|
|
165
|
+
short.present? ? "#{short} (#{code})" : code.to_s
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
def ms_checker_message_config(section_context)
|
|
169
|
+
return {} if section_context.blank?
|
|
170
|
+
|
|
171
|
+
section_label = section_context_label(section_context)
|
|
172
|
+
|
|
173
|
+
{
|
|
174
|
+
'mandatory_error_message' =>
|
|
175
|
+
inject_section_into_ms_message(InfernoSuiteGenerator::MSChecker::MANDATORY_ERROR_MS_MESSAGE, section_label),
|
|
176
|
+
'optional_warning_message' =>
|
|
177
|
+
inject_section_into_ms_message(InfernoSuiteGenerator::MSChecker::OPTIONAL_MS_WARNING_MESSAGE,
|
|
178
|
+
section_label),
|
|
179
|
+
'okay_message' =>
|
|
180
|
+
inject_section_into_ms_message(InfernoSuiteGenerator::MSChecker::MS_OKAY_MESSAGE, section_label)
|
|
181
|
+
}
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
def inject_section_into_ms_message(message, section_label)
|
|
185
|
+
message.sub('.', " in the #{section_label} section.")
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
def composition_section_check_ms_pass?(sections_codes:, bundle_resource:, all_present: false)
|
|
189
|
+
results = check_ms_elements_populated_against_profiles(sections_profiles(sections_codes),
|
|
190
|
+
resources_to_check_ms(sections_codes: sections_codes,
|
|
191
|
+
bundle_resource: bundle_resource),
|
|
192
|
+
all_present:)
|
|
193
|
+
!results_error?(results)
|
|
194
|
+
end
|
|
195
|
+
end
|
|
196
|
+
end
|
|
197
|
+
end
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module AUPSTestKit
|
|
4
|
+
# Helpers for reading composition section issues.
|
|
5
|
+
module BasicTestCompositionSectionReadIssuesHelpersModule
|
|
6
|
+
def references_resolution_report(section_metadata, bundle_resource)
|
|
7
|
+
section_code = section_metadata[:code]
|
|
8
|
+
composition_resource = bundle_resource.composition_resource
|
|
9
|
+
section = composition_resource.section_by_code(section_code)
|
|
10
|
+
entries_resource_types = permitted_resource_types(section_metadata)
|
|
11
|
+
|
|
12
|
+
section.entry_references.map do |ref|
|
|
13
|
+
issues = composition_section_ref_read_issues(ref, bundle_resource, entries_resource_types)
|
|
14
|
+
build_reference_resolution_report(ref, issues)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
private
|
|
19
|
+
|
|
20
|
+
def read_composition_section_issues(section_metadata, bundle_resource)
|
|
21
|
+
section_code = section_metadata[:code]
|
|
22
|
+
if bundle_resource.composition_resource.section_by_code(section_code).blank?
|
|
23
|
+
return ["No composition section found for code: #{section_code}"]
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
references_resolution_report(section_metadata, bundle_resource).map do |ref_report|
|
|
27
|
+
ref_report[:issues]
|
|
28
|
+
end.flatten.compact
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def build_reference_resolution_report(ref, issues)
|
|
32
|
+
{
|
|
33
|
+
reference: ref,
|
|
34
|
+
resolved: issues.empty?,
|
|
35
|
+
issues: issues
|
|
36
|
+
}
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def composition_section_ref_read_issues(ref, bundle_resource, entries_resource_types)
|
|
40
|
+
resource = bundle_resource.resource_by_reference(ref)
|
|
41
|
+
issues = []
|
|
42
|
+
issues << "Resource not found for reference: #{ref}" if resource.blank?
|
|
43
|
+
if resource.present? && !entries_resource_types.include?(resource.resourceType)
|
|
44
|
+
issues << "Resource type: #{resource.resourceType} is not in the list " \
|
|
45
|
+
"of expected resource types: #{entries_resource_types}"
|
|
46
|
+
end
|
|
47
|
+
issues
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def permitted_resource_types(section_metadata)
|
|
51
|
+
section_metadata[:entries].map do |entry|
|
|
52
|
+
entry[:profiles].map do |profile|
|
|
53
|
+
profile.split('|').first
|
|
54
|
+
end
|
|
55
|
+
end.flatten.uniq
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def empty_section_entry_reason_line(section)
|
|
59
|
+
if section.empty_reason_str.present?
|
|
60
|
+
"emptyReason: #{section.empty_reason_str}"
|
|
61
|
+
else
|
|
62
|
+
'No entries; no emptyReason.'
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative '../inferno_suite_generator_compat'
|
|
4
|
+
require_relative 'composition_section_check_resources_ms_elements_module'
|
|
5
|
+
require_relative 'composition_section_read_issues_helpers_module'
|
|
6
|
+
module AUPSTestKit
|
|
7
|
+
# Reading composition section rows: profile/entry matching and list outcomes.
|
|
8
|
+
module BasicTestCompositionSectionReadModule
|
|
9
|
+
# !!!!!!!!!!
|
|
10
|
+
# TODO: Remove generator and replace with runtime
|
|
11
|
+
MANDATORY_SECTIONS_CODES = %w[11450-4 48765-2 10160-0].freeze
|
|
12
|
+
RECOMMENDED_SECTIONS_CODES = %w[11369-6 30954-2 47519-4 46264-8].freeze
|
|
13
|
+
OPTIONAL_SECTIONS_CODES = %w[42348-3 104605-1 47420-5 11348-0 10162-6 81338-6 18776-5 29762-2 8716-3].freeze
|
|
14
|
+
|
|
15
|
+
include BasicTestCompositionSectionCheckResourcesMSElementsModule
|
|
16
|
+
include BasicTestCompositionSectionReadIssuesHelpersModule
|
|
17
|
+
|
|
18
|
+
private
|
|
19
|
+
|
|
20
|
+
def test_composition_mandatory_sections
|
|
21
|
+
check_bundle_exists_in_scratch
|
|
22
|
+
test_composition_sections_data(sections_codes: MANDATORY_SECTIONS_CODES, bundle_data: scratch_bundle,
|
|
23
|
+
mandatory: true)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def test_composition_recommended_sections
|
|
27
|
+
check_bundle_exists_in_scratch
|
|
28
|
+
test_composition_sections_data(sections_codes: RECOMMENDED_SECTIONS_CODES, bundle_data: scratch_bundle)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def test_composition_optional_sections
|
|
32
|
+
check_bundle_exists_in_scratch
|
|
33
|
+
test_composition_sections_data(sections_codes: OPTIONAL_SECTIONS_CODES, bundle_data: scratch_bundle)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def test_composition_sections_data(sections_codes:, bundle_data:, mandatory: false)
|
|
37
|
+
# Mandatory: true - FN should fail if any mandatory section is not populated correctly.
|
|
38
|
+
# Unresolved references always fail regardless of mandatory status.
|
|
39
|
+
bundle_resource = BundleDecorator.new(bundle_data)
|
|
40
|
+
refs_test_pass = composition_sections_references_resolution_pass?(sections_codes: sections_codes,
|
|
41
|
+
bundle_resource: bundle_resource,
|
|
42
|
+
mandatory: mandatory)
|
|
43
|
+
ms_test_pass = composition_section_check_ms_pass?(sections_codes: sections_codes,
|
|
44
|
+
bundle_resource: bundle_resource,
|
|
45
|
+
all_present: true)
|
|
46
|
+
|
|
47
|
+
assert refs_test_pass, 'Some section entry references cannot be resolved.'
|
|
48
|
+
assert ms_test_pass,
|
|
49
|
+
'Some of the sections are not populated with the correct Must Support elements.'
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def composition_sections_references_resolution_pass?(sections_codes:, bundle_resource:, mandatory: false)
|
|
53
|
+
composition_resource = bundle_resource.composition_resource
|
|
54
|
+
sections_metadata = metadata_manager.sections_metadata_by_codes(sections_codes)
|
|
55
|
+
sections_metadata.map do |section_metadata|
|
|
56
|
+
composition_section_references_resolution_issues?(section_metadata: section_metadata,
|
|
57
|
+
composition_resource: composition_resource,
|
|
58
|
+
bundle_resource: bundle_resource,
|
|
59
|
+
mandatory: mandatory)
|
|
60
|
+
end.all?
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def section_reference_message_level(mandatory:, has_unresolved:)
|
|
64
|
+
mandatory || has_unresolved ? 'error' : 'warning'
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def composition_section_references_resolution_issues?(section_metadata:, composition_resource:, bundle_resource:,
|
|
68
|
+
mandatory:)
|
|
69
|
+
section_code = section_metadata[:code]
|
|
70
|
+
section = composition_resource.section_by_code(section_code)
|
|
71
|
+
issues = read_composition_section_issues(section_metadata, bundle_resource)
|
|
72
|
+
text = composition_section_read_report_message(section_metadata, section, bundle_resource, section_code)
|
|
73
|
+
has_unresolved = issues.any? { |issue| issue.start_with?('Resource not found for reference:') }
|
|
74
|
+
level = section_reference_message_level(mandatory:, has_unresolved:)
|
|
75
|
+
add_message(issues.empty? ? 'info' : level, text)
|
|
76
|
+
issues.empty? || (!mandatory && !has_unresolved)
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def composition_section_read_report_message(section_metadata, section, bundle_resource, section_code)
|
|
80
|
+
short = section_metadata[:short]
|
|
81
|
+
header = short.present? ? "#{short} (#{section_code})" : section_code.to_s
|
|
82
|
+
body = composition_section_read_list_body(section, bundle_resource, section_code, section_metadata)
|
|
83
|
+
"#{header}\n\n#{body}"
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def composition_section_read_list_body(section, bundle_resource, section_code, section_metadata)
|
|
87
|
+
return "No composition section found for code: #{section_code}" if section.blank?
|
|
88
|
+
return empty_section_entry_reason_line(section) if section.entry_references.empty?
|
|
89
|
+
|
|
90
|
+
section.entry_references.each.map do |ref|
|
|
91
|
+
format_composition_section_entry_line(ref, bundle_resource, section_metadata)
|
|
92
|
+
end.join("\n\n")
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def format_composition_section_entry_line(ref, bundle_resource, section_metadata)
|
|
96
|
+
resource = bundle_resource.resource_by_reference(ref)
|
|
97
|
+
index = get_section_entry_index(section_metadata, bundle_resource, ref)
|
|
98
|
+
return composition_section_entry_line_unresolved(ref) if resource.blank?
|
|
99
|
+
unless permitted_resource_types(section_metadata).include?(resource.resourceType)
|
|
100
|
+
return composition_section_entry_line_bad_type(index, ref, resource.resourceType)
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
composition_section_entry_line_resolved(index, ref, resource)
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def get_section_entry_index(section_metadata, bundle_resource, ref)
|
|
107
|
+
section = bundle_resource.composition_resource.section_by_code(section_metadata[:code])
|
|
108
|
+
return nil if section.blank?
|
|
109
|
+
|
|
110
|
+
section.get_entry_index_by_reference(ref)
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def composition_section_entry_line_unresolved(ref)
|
|
114
|
+
"**#{ref}** -> ❌ Reference does not resolve"
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def composition_section_entry_line_bad_type(index, ref, resource_type)
|
|
118
|
+
"entry[#{index}]: **#{ref}** -> ❌ Invalid resource type: #{resource_type}"
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def composition_section_entry_line_resolved(index, ref, resource)
|
|
122
|
+
profiles = resource.meta&.profile || []
|
|
123
|
+
suffix = profiles.any? ? "(meta.profile: #{profiles.join(', ')})" : '(no meta.profile)'
|
|
124
|
+
"entry[#{index}]: **#{ref}** -> #{resource.resourceType} #{suffix}"
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
end
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module AUPSTestKit
|
|
4
|
+
# Composition Must Support sub-elements (grouped paths) and parent-group validation on arbitrary resources.
|
|
5
|
+
module BasicTestCompositionSubelementsModule
|
|
6
|
+
private
|
|
7
|
+
|
|
8
|
+
def validate_populated_sub_elements_in_composition(mandatory_ms, optional_ms)
|
|
9
|
+
composition_resource = composition_resource_from_scratch
|
|
10
|
+
return false unless composition_resource.present?
|
|
11
|
+
|
|
12
|
+
grouped_elements = (mandatory_ms + optional_ms).group_by { |element| element.split('.').first }
|
|
13
|
+
run_composition_subelements_assertions(composition_resource, grouped_elements, mandatory_ms)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def composition_resource_from_scratch
|
|
17
|
+
return nil unless scratch_bundle.present?
|
|
18
|
+
|
|
19
|
+
BundleDecorator.new(scratch_bundle).composition_resource
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def run_composition_subelements_assertions(composition_resource, grouped_elements, mandatory_ms)
|
|
23
|
+
any_parent = composition_any_subelement_parent_populated?(composition_resource, grouped_elements)
|
|
24
|
+
mandatory_ok = composition_mandatory_subelements_ok?(composition_resource, grouped_elements, mandatory_ms)
|
|
25
|
+
|
|
26
|
+
# Error: when any mandatory Must Support sub-elements are missing (i.e. subject.reference and attester.mode).
|
|
27
|
+
# Warning: when any optional Must Support sub-elements are missing (i.e. attester.time and attester.party)
|
|
28
|
+
# Info: when all optional Must Support sub-elements are populated
|
|
29
|
+
# One message for each complex element with Must Support sub-elements, i.e. subject and attester
|
|
30
|
+
# Include list of Must Support sub-elements populated and missing.
|
|
31
|
+
|
|
32
|
+
grouped_elements.each do |parent_path, sub_elements|
|
|
33
|
+
add_composition_subelements_messages(composition_resource, parent_path, sub_elements, mandatory_ms)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
skip_if !any_parent, 'No complex element with Must Support sub-elements is populated'
|
|
37
|
+
msg = 'Some of the mandatory Must Support sub-elements are not populated. ' \
|
|
38
|
+
'See the list of populated sub-elements in messages tab.'
|
|
39
|
+
assert mandatory_ok, msg
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def composition_any_subelement_parent_populated?(composition_resource, grouped_elements)
|
|
43
|
+
grouped_elements.any? do |parent_path, _|
|
|
44
|
+
resolve_path_with_dar(composition_resource, parent_path).first.present?
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def composition_mandatory_subelements_ok?(composition_resource, grouped_elements, mandatory_ms)
|
|
49
|
+
grouped_elements.all? do |parent_path, sub_elements|
|
|
50
|
+
next true unless resolve_path_with_dar(composition_resource, parent_path).first.present?
|
|
51
|
+
|
|
52
|
+
(mandatory_ms & sub_elements).all? { |el| resolve_path_with_dar(composition_resource, el).first.present? }
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def add_composition_subelements_messages(composition_resource, parent_path, sub_elements, mandatory_ms)
|
|
57
|
+
unless resolve_path_with_dar(composition_resource, parent_path).first.present?
|
|
58
|
+
add_message('warning', composition_subelement_parent_unpopulated_message(parent_path, sub_elements))
|
|
59
|
+
return
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
level = composition_subelements_worst_level(composition_resource, sub_elements, mandatory_ms)
|
|
63
|
+
add_message(level, populated_paths_info(composition_resource, sub_elements, mandatory_array: mandatory_ms))
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def composition_subelement_parent_unpopulated_message(parent_path, sub_elements)
|
|
67
|
+
detail = "**Complex element #{parent_path}** is not populated. " \
|
|
68
|
+
"Must Support sub-elements that would be validated: #{sub_elements.join(', ')}."
|
|
69
|
+
['Must Support sub-elements correctly populated', 'Composition', detail].join("\n\n")
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def composition_subelements_worst_level(composition_resource, sub_elements, mandatory_ms)
|
|
73
|
+
levels = sub_elements.map do |sub_element|
|
|
74
|
+
present = resolve_path_with_dar(composition_resource, sub_element).first.present?
|
|
75
|
+
next 'info' if present
|
|
76
|
+
|
|
77
|
+
mandatory_ms.include?(sub_element) ? 'error' : 'warning'
|
|
78
|
+
end
|
|
79
|
+
return 'error' if levels.include?('error')
|
|
80
|
+
|
|
81
|
+
levels.include?('warning') ? 'warning' : 'info'
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module AUPSTestKit
|
|
4
|
+
# Internal helpers to keep the populated-message module concise.
|
|
5
|
+
module BasicTestMsElementsPopulatedHelpersModule
|
|
6
|
+
private
|
|
7
|
+
|
|
8
|
+
def assert_message
|
|
9
|
+
'When any mandatory Must Support element is missing. See the list in messages tab.'
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def get_target_metadata_by_container_type(container_type)
|
|
13
|
+
case container_type
|
|
14
|
+
when 'subject'
|
|
15
|
+
metadata_manager.subject_metadata
|
|
16
|
+
when 'author'
|
|
17
|
+
metadata_manager.author_metadata
|
|
18
|
+
when 'custodian'
|
|
19
|
+
metadata_manager.custodian_metadata
|
|
20
|
+
when 'attester'
|
|
21
|
+
metadata_manager.attester_metadata
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def get_resource_by_container_type(container_type)
|
|
26
|
+
case container_type
|
|
27
|
+
when 'subject'
|
|
28
|
+
subject_resource
|
|
29
|
+
when 'author'
|
|
30
|
+
author_resource
|
|
31
|
+
when 'custodian'
|
|
32
|
+
custodian_resource
|
|
33
|
+
when 'attester'
|
|
34
|
+
attester_party_resource
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'ms_elements_populated_helpers_module'
|
|
4
|
+
|
|
5
|
+
module AUPSTestKit
|
|
6
|
+
# Must Support elements populated or missing message.
|
|
7
|
+
module BasicTestMsElementsPopulatedModule
|
|
8
|
+
include BasicTestMsElementsPopulatedHelpersModule
|
|
9
|
+
|
|
10
|
+
def ms_elements_populated_message(container_type)
|
|
11
|
+
guard_populated_resource(container_type)
|
|
12
|
+
|
|
13
|
+
resource = get_resource_by_container_type(container_type)
|
|
14
|
+
|
|
15
|
+
author_and_device_resource?(container_type, resource)
|
|
16
|
+
|
|
17
|
+
resource_metadata_raw = metadata_manager.group_metadata_by_resource_type(resource.resourceType)
|
|
18
|
+
return unless resource_metadata_raw.present?
|
|
19
|
+
|
|
20
|
+
profile_metadata = InfernoSuiteGenerator::Generator::GroupMetadata.new(resource_metadata_raw)
|
|
21
|
+
|
|
22
|
+
assert all_ms_mandatory_elements_populated?(resource, profile_metadata), assert_message
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
private
|
|
26
|
+
|
|
27
|
+
def all_ms_mandatory_elements_populated?(resource, profile_metadata)
|
|
28
|
+
ms_checker = InfernoSuiteGenerator::MSChecker.new(profile_metadata)
|
|
29
|
+
ms_checks_results = elements(ms_checker, [resource])
|
|
30
|
+
ms_slices_results = slices(ms_checker, [resource])
|
|
31
|
+
ms_extension_results = extensions(ms_checker, [resource])
|
|
32
|
+
all_check_results = [*ms_checks_results, *ms_slices_results, *ms_extension_results]
|
|
33
|
+
|
|
34
|
+
status = ms_checker.calculate_elements_status_message_level(all_check_results)
|
|
35
|
+
message = ms_checker.build_report_message(profile_metadata, all_check_results)
|
|
36
|
+
add_message(status, message.join("\n\n"))
|
|
37
|
+
|
|
38
|
+
all_check_results.none? { |result| !result[:present] && result[:mandatory] }
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def elements(checker, resources)
|
|
42
|
+
elements_statuses = checker.elements_present_statuses(resources, all_present: false)
|
|
43
|
+
elements_statuses.filter { |result| element_simple?(result[:path]) }
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def slices(checker, resources)
|
|
47
|
+
slices_statuses = checker.slices_present_statuses(resources, all_present: false)
|
|
48
|
+
slices_statuses.filter { |result| element_simple?(result[:path]) }
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def extensions(checker, resources)
|
|
52
|
+
ms_extension_results = checker.extensions_present_statuses(resources, all_present: false)
|
|
53
|
+
normalized_ms_extension_results(ms_extension_results)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def normalized_ms_extension_results(ms_extension_results)
|
|
57
|
+
ms_extension_results.map do |result|
|
|
58
|
+
{
|
|
59
|
+
definition: result[:definition],
|
|
60
|
+
path: result[:definition][:id].split(':')[-1],
|
|
61
|
+
present: result[:present],
|
|
62
|
+
mandatory: false
|
|
63
|
+
}
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def element_simple?(path)
|
|
68
|
+
!path.include?('.')
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module AUPSTestKit
|
|
4
|
+
# Must Support identifier slices (IHI, DVA, Medicare) on a resource (e.g. Patient).
|
|
5
|
+
module BasicTestMsIdentifierSlicesModule
|
|
6
|
+
private
|
|
7
|
+
|
|
8
|
+
# Validates Must Support identifier slices (IHI, DVA, Medicare) on a resource (e.g. Patient).
|
|
9
|
+
# Two messages: (1) Must support identifier slices correctly populated; (2) At least one slice populated.
|
|
10
|
+
# Pass: all messages info or warning. No error level used.
|
|
11
|
+
#
|
|
12
|
+
# @param resource [Hash, FHIR::Model] The resource with identifier array (e.g. Patient)
|
|
13
|
+
# @param slices [Array<Hash>] Each hash has :name (String) and :system (String URL)
|
|
14
|
+
def validate_ms_identifier_slices_in_resource(resource, slices)
|
|
15
|
+
return unless resource.present?
|
|
16
|
+
|
|
17
|
+
slice_results = build_ms_identifier_slice_results(identifiers_from_resource(resource) || [], slices)
|
|
18
|
+
add_ms_identifier_slices_populated_message(slice_results)
|
|
19
|
+
add_ms_identifier_slices_at_least_one_message(slice_results)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def add_ms_identifier_slices_populated_message(slice_results)
|
|
23
|
+
lines = slice_results.map { |r| ms_identifier_slice_line_with_type(r) }
|
|
24
|
+
heading = '## List of Must Support identifier slices populated or missing'
|
|
25
|
+
body = ['Must support identifier slices correctly populated', heading, lines.join("\n\n")].join("\n\n")
|
|
26
|
+
add_message(slice_results.all? { |r| r[:identifier].present? } ? 'info' : 'warning', body)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def add_ms_identifier_slices_at_least_one_message(slice_results)
|
|
30
|
+
lines = slice_results.map { |r| ms_identifier_slice_line_system_only(r) }
|
|
31
|
+
heading = '## List of Must Support identifier slices populated or missing (system when populated)'
|
|
32
|
+
intro = 'At least one Must Support identifier slices is populated'
|
|
33
|
+
body = [intro, heading, lines.join("\n\n")].join("\n\n")
|
|
34
|
+
add_message(slice_results.any? { |r| r[:identifier].present? } ? 'info' : 'warning', body)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def build_ms_identifier_slice_results(identifiers, slices)
|
|
38
|
+
slices.map do |slice|
|
|
39
|
+
ident = find_identifier_by_system(identifiers, slice[:system])
|
|
40
|
+
{ slice: slice, identifier: ident }
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def ms_identifier_slice_line_with_type(result)
|
|
45
|
+
if result[:identifier].present?
|
|
46
|
+
type_str = identifier_type_display(result[:identifier])
|
|
47
|
+
"✅ Populated: **#{result[:slice][:name]}** — system: #{result[:slice][:system]}#{type_str}"
|
|
48
|
+
else
|
|
49
|
+
"⚠️ Missing: **#{result[:slice][:name]}**"
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def ms_identifier_slice_line_system_only(result)
|
|
54
|
+
if result[:identifier].present?
|
|
55
|
+
"✅ Populated: **#{result[:slice][:name]}** — system: #{result[:slice][:system]}"
|
|
56
|
+
else
|
|
57
|
+
"⚠️ Missing: **#{result[:slice][:name]}**"
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|