davinci_pdex_test_kit 0.11.0 → 0.12.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (111) hide show
  1. checksums.yaml +4 -4
  2. data/config/presets/pdex_payer_client_postman_preset.json.erb +67 -0
  3. data/config/presets/pdex_payer_server_fhir_foundry_ri_preset.json +2 -2
  4. data/config/presets/pdex_payer_server_inferno_ri_preset.json +2 -2
  5. data/lib/davinci_pdex_test_kit/docs/payer_client_suite_description_v200.md +124 -32
  6. data/lib/davinci_pdex_test_kit/pdex_payer_client/client_auth_smart_alca_group.rb +32 -0
  7. data/lib/davinci_pdex_test_kit/pdex_payer_client/client_auth_smart_alcs_group.rb +32 -0
  8. data/lib/davinci_pdex_test_kit/pdex_payer_client/client_auth_smart_alp_group.rb +32 -0
  9. data/lib/davinci_pdex_test_kit/pdex_payer_client/client_auth_udap_group.rb +31 -0
  10. data/lib/davinci_pdex_test_kit/pdex_payer_client/client_member_match_tests/client_member_match_validation_test.rb +7 -6
  11. data/lib/davinci_pdex_test_kit/pdex_payer_client/client_registration/configuration_display_smart_test.rb +38 -0
  12. data/lib/davinci_pdex_test_kit/pdex_payer_client/client_registration/configuration_display_udap_test.rb +38 -0
  13. data/lib/davinci_pdex_test_kit/pdex_payer_client/client_registration_group.rb +67 -0
  14. data/lib/davinci_pdex_test_kit/pdex_payer_client/client_validation_test.rb +10 -2
  15. data/lib/davinci_pdex_test_kit/pdex_payer_client/client_workflow_interaction_test.rb +43 -12
  16. data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/allergyintolerance_clinical_data_request_test.rb +0 -1
  17. data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/careplan_clinical_data_request_test.rb +0 -1
  18. data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/careteam_clinical_data_request_test.rb +0 -1
  19. data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/condition_clinical_data_request_test.rb +0 -1
  20. data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/device_clinical_data_request_test.rb +1 -2
  21. data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/diagnosticreport_clinical_data_request_test.rb +0 -1
  22. data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/documentreference_clinical_data_request_test.rb +0 -1
  23. data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/encounter_clinical_data_request_test.rb +0 -1
  24. data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/explanationofbenefit_clinical_data_request_test.rb +0 -1
  25. data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/goal_clinical_data_request_test.rb +0 -1
  26. data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/immunization_clinical_data_request_test.rb +0 -1
  27. data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/location_clinical_data_request_test.rb +0 -1
  28. data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/medicationdispense_clinical_data_request_test.rb +0 -1
  29. data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/medicationrequest_clinical_data_request_test.rb +0 -1
  30. data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/observation_clinical_data_request_test.rb +0 -1
  31. data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/organization_clinical_data_request_test.rb +0 -1
  32. data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/patient_clinical_data_request_test.rb +0 -1
  33. data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/practitioner_clinical_data_request_test.rb +0 -1
  34. data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/practitionerrole_clinical_data_request_test.rb +0 -1
  35. data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/procedure_clinical_data_request_test.rb +0 -1
  36. data/lib/davinci_pdex_test_kit/pdex_payer_client/mock_server/export_endpoint.rb +1 -1
  37. data/lib/davinci_pdex_test_kit/pdex_payer_client/mock_server/export_status_endpoint.rb +1 -1
  38. data/lib/davinci_pdex_test_kit/pdex_payer_client/mock_server/next_page_endpoint.rb +9 -2
  39. data/lib/davinci_pdex_test_kit/pdex_payer_client/mock_server/patient_endpoint.rb +1 -1
  40. data/lib/davinci_pdex_test_kit/pdex_payer_client/mock_server/proxy_endpoint.rb +15 -6
  41. data/lib/davinci_pdex_test_kit/pdex_payer_client/mock_server/resource_read_endpoint.rb +1 -1
  42. data/lib/davinci_pdex_test_kit/pdex_payer_client/mock_server/resource_search_endpoint.rb +1 -1
  43. data/lib/davinci_pdex_test_kit/pdex_payer_client/mock_server.rb +28 -2
  44. data/lib/davinci_pdex_test_kit/pdex_payer_client/mock_udap_smart_server/authorization_endpoint.rb +53 -0
  45. data/lib/davinci_pdex_test_kit/pdex_payer_client/mock_udap_smart_server/token_endpoint.rb +85 -0
  46. data/lib/davinci_pdex_test_kit/pdex_payer_client/pdex_client_options.rb +26 -0
  47. data/lib/davinci_pdex_test_kit/pdex_payer_client/tags.rb +8 -9
  48. data/lib/davinci_pdex_test_kit/pdex_payer_client/urls.rb +17 -9
  49. data/lib/davinci_pdex_test_kit/pdex_payer_client_suite.rb +57 -10
  50. data/lib/davinci_pdex_test_kit/pdex_payer_server/device/device_must_support_test.rb +50 -0
  51. data/lib/davinci_pdex_test_kit/pdex_payer_server/device/device_patient_search_test.rb +68 -0
  52. data/lib/davinci_pdex_test_kit/pdex_payer_server/device/device_patient_type_search_test.rb +54 -0
  53. data/lib/davinci_pdex_test_kit/pdex_payer_server/{explanation_of_benefit/explanation_of_benefit_provenance_revinclude_search_test.rb → device/device_provenance_revinclude_search_test.rb} +7 -7
  54. data/lib/davinci_pdex_test_kit/pdex_payer_server/device/device_read_test.rb +26 -0
  55. data/lib/davinci_pdex_test_kit/pdex_payer_server/device/device_reference_resolution_test.rb +42 -0
  56. data/lib/davinci_pdex_test_kit/pdex_payer_server/device/device_validation_test.rb +39 -0
  57. data/lib/davinci_pdex_test_kit/pdex_payer_server/device/metadata.yml +154 -0
  58. data/lib/davinci_pdex_test_kit/pdex_payer_server/device_group.rb +88 -0
  59. data/lib/davinci_pdex_test_kit/pdex_payer_server/explanation_of_benefit/explanation_of_benefit_id_search_test.rb +7 -24
  60. data/lib/davinci_pdex_test_kit/pdex_payer_server/explanation_of_benefit/explanation_of_benefit_identifier_search_test.rb +10 -24
  61. data/lib/davinci_pdex_test_kit/pdex_payer_server/explanation_of_benefit/explanation_of_benefit_must_support_test.rb +37 -5
  62. data/lib/davinci_pdex_test_kit/pdex_payer_server/explanation_of_benefit/explanation_of_benefit_patient_lastupdated_search_test.rb +48 -0
  63. data/lib/davinci_pdex_test_kit/pdex_payer_server/explanation_of_benefit/explanation_of_benefit_patient_search_test.rb +62 -0
  64. data/lib/davinci_pdex_test_kit/pdex_payer_server/explanation_of_benefit/explanation_of_benefit_patient_service_date_search_test.rb +7 -23
  65. data/lib/davinci_pdex_test_kit/pdex_payer_server/explanation_of_benefit/explanation_of_benefit_patient_type_search_test.rb +6 -23
  66. data/lib/davinci_pdex_test_kit/pdex_payer_server/explanation_of_benefit/explanation_of_benefit_reference_resolution_test.rb +7 -4
  67. data/lib/davinci_pdex_test_kit/pdex_payer_server/explanation_of_benefit/explanation_of_benefit_validation_test.rb +9 -10
  68. data/lib/davinci_pdex_test_kit/pdex_payer_server/explanation_of_benefit/metadata.yml +276 -264
  69. data/lib/davinci_pdex_test_kit/pdex_payer_server/explanation_of_benefit_group.rb +62 -64
  70. data/lib/davinci_pdex_test_kit/pdex_payer_server/export_patient_group.rb +8 -9
  71. data/lib/davinci_pdex_test_kit/pdex_payer_server/export_validation_group.rb +1 -2
  72. data/lib/davinci_pdex_test_kit/pdex_payer_server/medication_dispense/medication_dispense_must_support_test.rb +42 -0
  73. data/lib/davinci_pdex_test_kit/pdex_payer_server/medication_dispense/medication_dispense_patient_search_test.rb +64 -0
  74. data/lib/davinci_pdex_test_kit/pdex_payer_server/medication_dispense/medication_dispense_patient_status_search_test.rb +54 -0
  75. data/lib/davinci_pdex_test_kit/pdex_payer_server/medication_dispense/medication_dispense_patient_status_type_search_test.rb +55 -0
  76. data/lib/davinci_pdex_test_kit/pdex_payer_server/medication_dispense/medication_dispense_provenance_revinclude_search_test.rb +54 -0
  77. data/lib/davinci_pdex_test_kit/pdex_payer_server/medication_dispense/medication_dispense_read_test.rb +26 -0
  78. data/lib/davinci_pdex_test_kit/pdex_payer_server/medication_dispense/medication_dispense_reference_resolution_test.rb +42 -0
  79. data/lib/davinci_pdex_test_kit/pdex_payer_server/medication_dispense/medication_dispense_validation_test.rb +39 -0
  80. data/lib/davinci_pdex_test_kit/pdex_payer_server/medication_dispense/metadata.yml +206 -0
  81. data/lib/davinci_pdex_test_kit/pdex_payer_server/medication_dispense_group.rb +69 -0
  82. data/lib/davinci_pdex_test_kit/pdex_payer_server/multiple_member_matches_group.rb +36 -36
  83. data/lib/davinci_pdex_test_kit/pdex_payer_server/no_member_matches_group.rb +30 -30
  84. data/lib/davinci_pdex_test_kit/pdex_payer_server/patient_operation_in_capability_statement_validation.rb +15 -13
  85. data/lib/davinci_pdex_test_kit/pdex_payer_server/provenance/metadata.yml +173 -0
  86. data/lib/davinci_pdex_test_kit/pdex_payer_server/provenance/provenance_must_support_test.rb +51 -0
  87. data/lib/davinci_pdex_test_kit/pdex_payer_server/provenance/provenance_read_test.rb +26 -0
  88. data/lib/davinci_pdex_test_kit/pdex_payer_server/provenance/provenance_reference_resolution_test.rb +46 -0
  89. data/lib/davinci_pdex_test_kit/pdex_payer_server/provenance/provenance_validation_test.rb +39 -0
  90. data/lib/davinci_pdex_test_kit/pdex_payer_server/provenance_group.rb +59 -0
  91. data/lib/davinci_pdex_test_kit/pdex_payer_server/workflow_clinical_data_group.rb +22 -11
  92. data/lib/davinci_pdex_test_kit/pdex_payer_server/workflow_everything_group.rb +19 -6
  93. data/lib/davinci_pdex_test_kit/pdex_payer_server/workflow_export_group.rb +24 -16
  94. data/lib/davinci_pdex_test_kit/pdex_payer_server/workflow_member_match_group.rb +44 -25
  95. data/lib/davinci_pdex_test_kit/pdex_payer_server_suite.rb +123 -110
  96. data/lib/davinci_pdex_test_kit/pdex_provider_client_suite.rb +8 -8
  97. data/lib/davinci_pdex_test_kit/requirements/davinci-pdex-test-kit_out_of_scope_requirements.csv +1 -0
  98. data/lib/davinci_pdex_test_kit/requirements/davinci-pdex-test-kit_requirements.csv +66 -0
  99. data/lib/davinci_pdex_test_kit/requirements/generated/davinci-pdex-test-kit_requirements_coverage.csv +66 -0
  100. data/lib/davinci_pdex_test_kit/version.rb +2 -2
  101. data/lib/davinci_pdex_test_kit.rb +1 -0
  102. data/lib/inferno_requirements_tools/ext/inferno_core/runnable.rb +22 -0
  103. data/lib/inferno_requirements_tools/rake/rakefile_template +19 -0
  104. data/lib/inferno_requirements_tools/tasks/collect_requirements.rb +228 -0
  105. data/lib/inferno_requirements_tools/tasks/requirements_coverage.rb +284 -0
  106. data/lib/requirements_config.yaml +17 -0
  107. metadata +96 -13
  108. data/config/presets/pdex_payer_client_postman_preset.json +0 -12
  109. data/lib/davinci_pdex_test_kit/pdex_payer_client/mock_server/token_endpoint.rb +0 -27
  110. data/lib/davinci_pdex_test_kit/pdex_payer_server/explanation_of_benefit/explanation_of_benefit_patient_last_updated_search_test.rb +0 -64
  111. data/lib/davinci_pdex_test_kit/pdex_payer_server/explanation_of_benefit/explanation_of_benefit_patient_use_search_test.rb +0 -69
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 318708e3bf373fe0429d145f0bec49fe07739eea1a296dff8b6aedef2769b361
4
- data.tar.gz: d2ab19dc58bc8734324f60b6eda28350df3e999c94e15218ba614df630fc02e2
3
+ metadata.gz: a0f40793433a43053718719f614805ddda0830e0cd2d984cc59d75f1762b13e5
4
+ data.tar.gz: 842fb47429ceb04acdbcda3d90dd90b22982e1a53ea314901d7b4342e4fa0e33
5
5
  SHA512:
6
- metadata.gz: 57c7352a6207c74197bf2511a7e1305fca155c2d0135456aa725cc209f89cedb5ef8733daffa2f546042a12b6c2f91f94bb1fe9f58c4f3aa6a3253c051d58896
7
- data.tar.gz: 7cbb1b8afee0ddc8e04fe6e19853b0a13f82981feff200d3197b92597fd248104c49cb3570a3ce0e0b4a183350a8c78a8d0c3a7feca16cf42ab8f201edbe08e6
6
+ metadata.gz: 40ce4e887659579ea541da03e3567f35bcb7abe5fa2ddb09d47dd26a777733c43ce538ea315dfdf6c06f47871713a2adaf49b02e9c09ce43852400e1b8463c19
7
+ data.tar.gz: 2f6584ff86cf25ab1de0019bc5f80bd0abb362d1ae5ad8f608391215b960f1b6d0366ee87bdb3a625e7dadc3ecc465948ab92fc1c80ca49ba05a52f48dd23517
@@ -0,0 +1,67 @@
1
+ {
2
+ "title": "Demo: Submit PDex Payer Client Requests With Postman",
3
+ "id": "pdex_payer_client_postman_demo_preset",
4
+ "test_suite_id": "pdex_payer_client",
5
+ "inputs": [
6
+ {
7
+ "name": "udap_client_uri",
8
+ "description": "The UDAP Client URI that will be used to register with Inferno's simulated UDAP server.",
9
+ "title": "UDAP Client URI",
10
+ "type": "text",
11
+ "value": "<%= Inferno::Application['base_url'] %>/custom/udap_security/fhir"
12
+ },
13
+ {
14
+ "name": "client_id",
15
+ "description": "Testers may provide a specific value for Inferno to assign as the client id. If no value is provided, the Inferno session id will be used.",
16
+ "optional": true,
17
+ "title": "Client Id",
18
+ "type": "text",
19
+ "value": "smart_client_test_demo"
20
+ },
21
+ {
22
+ "name": "smart_launch_urls",
23
+ "description": "If the client app supports EHR launch, a comma-delimited list of one or more URLs that Inferno can use to launch the app.",
24
+ "optional": true,
25
+ "title": "SMART App Launch URL(s)",
26
+ "type": "textarea",
27
+ "value": ""
28
+ },
29
+ {
30
+ "name": "smart_redirect_uris",
31
+ "description": "A comma-separated list of one or more URIs that the app will sepcify as the target of the redirect for Inferno to use when providing the authorization code.",
32
+ "title": "SMART App Launch Redirect URI(s)",
33
+ "type": "textarea",
34
+ "value": "<%= Inferno::Application['base_url'] %>/custom/smart_stu2_2/redirect"
35
+ },
36
+ {
37
+ "name": "smart_client_secret",
38
+ "description": "Provide the client secret that the confidential symmetric client will send with token requests to authenticate the client to Inferno.",
39
+ "title": "SMART Confidential Symmetric Client Secret",
40
+ "type": "text",
41
+ "value": "SAMPLE_SECRET"
42
+ },
43
+ {
44
+ "name": "smart_jwk_set",
45
+ "description": "The SMART client's JSON Web Key Set including the key(s) Inferno will need to verify signatures on token requests made by the client. May be provided as either a publicly accessible url containing the JWKS, or the raw JWKS JSON.",
46
+ "title": "SMART Confidential Asymmetric JSON Web Key Set (JWKS)",
47
+ "type": "textarea",
48
+ "value": "<%= Inferno::Application['base_url'] %>/custom/smart_stu2_2/.well-known/jwks.json"
49
+ },
50
+ {
51
+ "name": "launch_context",
52
+ "description": "Launch context details to be included in access token responses, specified as a JSON array. If provided, the contents will be merged into Inferno's token responses.",
53
+ "optional": true,
54
+ "title": "Launch Context",
55
+ "type": "textarea",
56
+ "value": ""
57
+ },
58
+ {
59
+ "name": "fhir_user_relative_reference",
60
+ "description": "A FHIR relative reference (<resource type>/<id>) for the FHIR user record to return when the openid and fhirUser scopes are requested. Include this resource in the **Available Resources** input so that it can be accessed via FHIR read.",
61
+ "optional": true,
62
+ "title": "FHIR User Relative Reference",
63
+ "type": "text",
64
+ "value": "Patient/999"
65
+ }
66
+ ]
67
+ }
@@ -10,10 +10,10 @@
10
10
  "_type": "text"
11
11
  },
12
12
  {
13
- "name": "credentials",
13
+ "name": "smart_auth_info",
14
14
  "value": null,
15
15
  "_title": "OAuth Credentials",
16
- "_type": "oauth_credentials",
16
+ "_type": "auth_info",
17
17
  "_optional": true
18
18
  },
19
19
  {
@@ -10,10 +10,10 @@
10
10
  "_type": "text"
11
11
  },
12
12
  {
13
- "name": "credentials",
13
+ "name": "smart_auth_info",
14
14
  "value": null,
15
15
  "_title": "OAuth Credentials",
16
- "_type": "oauth_credentials",
16
+ "_type": "auth_info",
17
17
  "_optional": true
18
18
  },
19
19
  {
@@ -59,43 +59,59 @@ validated with the Java validator using `tx.fhir.org` as the terminology server.
59
59
 
60
60
  ### Quick Start
61
61
 
62
- For Inferno to simulate a server that returns a matching patient and responds to requests
63
- for that patient's data using FHIR read and search APIs, Inferno only needs to be able to
64
- identify when requests come from the client under test. Inferno piggybacks on the request
65
- authentication for this purpose. Testers must provide a bearer access token that will be
66
- provided within the `Authorization` header (`Bearer <token>`) on all requests made to
67
- Inferno endpoints during the test. Inferno uses this information to associate the message
68
- with the test session and determine how to respond. How the token provided to Inferno is
69
- generated is up to the tester.
70
-
71
- Note: auth options for these tests have not been finalized and are subject to change
72
- as the requirements in the PDex IG evolve. If the implemented approach prevents you from using
73
- these tests, please
74
- [provide feedback](https://github.com/inferno-framework/davinci-pdex-test-kit/issues) so the
75
- limitations can be addressed.
76
-
77
- Using the bearer token, the client under test will then demonstrate its ability to find
78
- a patient using `$member-match` and retrieve corresponding clinical data using read and search
79
- requests, the `$everything` operation, or the `$export` operation.
62
+ Inferno's simulated payer endpoints require authentication using the OAuth flows
63
+ conforming either to the
64
+ - SMART [App Launch flow](https://hl7.org/fhir/smart-app-launch/STU2.2/app-launch.html), or
65
+ - UDAP [Consumer-Facing flow](https://hl7.org/fhir/us/udap-security/STU1/consumer.html).
66
+
67
+ When creating a test session, select the Client Security Type corresponding to an
68
+ authentication approach supported by the client. Then, start by running the "Client Registration"
69
+ group which will guide you through the registration process, including what inputs to provide. See the
70
+ *Auth Configuration Details* section below for details. If the client is not able to use the SMART or
71
+ UDAP protocols to obtain an access token, see the *Demonstration* section below for how to use the SMART
72
+ or UDAP server tests to obtain an access token that the client can use.
73
+
74
+ Once registration is complete, run the "Verify PDex Data Access" group and Inferno will
75
+ wait for the client to make PDex resource and search requests from the client, return the requested PDex
76
+ resources to the client, and verify the interactions. The demographics of the target
77
+ patient are listed in the *Test Methodology* section above.
80
78
 
81
79
  ### Postman-based Demo
82
80
 
83
81
  If you do not have a PDex client but would like to try the tests out, you can use
82
+ the Inferno SMART App Launch test kit to request an access token and
84
83
  [this postman collection](https://github.com/inferno-framework/davinci-pdex-test-kit/blob/main/PDEX.postman_collection.json)
85
- to make requests against Inferno for these tests. To use the Postman demo on this test session
84
+ to make requests against Inferno. To execute the Postman-based demo:
86
85
 
86
+ 1. Create a PDex Payer Client session, selecting one of the SMART options for the "Client Security Type"
87
+ 1. In the PDex Payer Client session, select the "Demo: Submit PDex Payer Client Requests With Postman" preset
88
+ from the dropdown in the upper left.
89
+ 1. Click the `RUN ALL TESTS` button in the upper right and then click the `SUBMIT` button in the input dialog
90
+ that appears.
91
+ 1. Register and obtain and access token:
92
+ 1. In a separate tab, create a SMART App Launch STU2.2 test session.
93
+ 1. Select the "Demo: Run Against the SMART Client Suite" preset corresponding
94
+ to the authentication approach (public, confidential symmetric, or confidential asymmetric) chosen for
95
+ the PDex Payer Client session from the dropdown in the upper left.
96
+ 1. Select the "Standalone Launch" group from the list at the left and click the "RUN TESTS" button in the upper right.
97
+ 1. In the input dialog the follows, replace the **FHIR Endpoint** input with the FHIR endpoint displayed
98
+ in the wait dialog on the PDex Payer Client session.
99
+ 1. Click "SUBMIT" and when the "User Action Required" dialog appears, click the link to authorize and complete the tests.
100
+ 1. Find the `standalone_access_token` output in test **1.2.06** "Token exchange response body contains required information
101
+ encoded in JSON", and copy the value, which will be a ~100 character string of letters and numbers (e.g.,
102
+ eyJjbGllbnRfaWQiOiJzbWFydF9jbGllbnRfdGVzdF9kZW1vIiwiZXhwaXJhdGlvbiI6MTc0MzUxNDk4Mywibm9uY2UiOiJlZDI5MWIwNmZhMTE4OTc4In0).
103
+ 1. In the "User Action Required" dialog in the PDex Payer Client session, click to confirm client configuration. Another
104
+ "User Action Required" dialog will appear asking for the client to make PDex requests.
87
105
  1. Download the [collection](https://github.com/inferno-framework/davinci-pdex-test-kit/blob/main/PDEX.postman_collection.json)
88
- and import it into [Postman](https://www.postman.com/downloads/).
89
- 2. Select the `PDex Payer Client Postman Demo` from the preset dropdown in the upper left.
90
- 3. Click `Run All Tests` button in the upper right and click the `Submit` button in the dialog
91
- that appears.
92
- 4. When a `User Action Required` dialog appears, use Postman to first send a `$member-match` request
93
- found in the "$member-match Requests" folder (the `missing CoverageToMatch` entry will return
94
- a result, but will fail request validation).
95
- 5. Next, use the "Patient GET by identifier" request in the "Patient id Search" folder to turn the
106
+ and import it into [Postman](https://www.postman.com/downloads/) if not already done.
107
+ 1. Open the "Variables" tab of the `PDEX` collection, paste the access value obtained in the previous step into the "Current value"
108
+ column for the "access_token" variable, and save the collection.
109
+ 1. Use Postman to send a `$member-match` request found in the "$member-match Requests" folder
110
+ (the `missing CoverageToMatch` entry will return a result, but will fail request validation).
111
+ 1. Next, use the "Patient GET by identifier" request in the "Patient id Search" folder to turn the
96
112
  returned Patient identifier (`99999` in system
97
113
  `http://github.com/inferno-framework/target-payer/identifiers/member`) into a Patient resource id (`999`).
98
- 6. Now, make clinical data requests found in the other
114
+ 1. Now, make clinical data requests found in the other
99
115
  folders representing the three data access approaches: "Read and Search Requests",
100
116
  "Patient $everything Requests", or "$export Requests". Specific paths that will completely pass
101
117
  the tests include:
@@ -112,8 +128,84 @@ to make requests against Inferno for these tests. To use the Postman demo on thi
112
128
  `output` entry, copy the `url` into the URL of the "ndjson retrieval" request and make it to
113
129
  get the data. Finally, make the "Read and Search Requests" to Read the Location
114
130
  and PractitionerRole instances since those aren't returned by the `$export` operation.
115
- 7. After making all the requests you want, click the "Click here" link to finish the tests
116
- and make the results available for review.
131
+ 1. After making all the requests you want, click the "Click here" link in the PDex Payer Client tests
132
+ to finish execution. Review the results.
133
+
134
+ #### Optional Demo Modification: Tester-provided Client Id
135
+
136
+ NOTE: Inferno uses **Client Id** input and the generated bearer tokens sent in the `Authorization` HTTP header
137
+ to associate requests with sessions. If multiple concurrent sessions are configured
138
+ to use the same token, they may interfere with each other. To prevent concurrent executors
139
+ of these sample executions from disrupting your session it is recommended, but not required, to:
140
+ 1. When running the Client Registration test group, leave the **Client Id** input blank or provide your own unique or
141
+ random value.
142
+ 2. When the wait dialog appears for confirmation of client registration, note the indicated `Client Id` value and copy it
143
+ into the **Client ID** input of the SMART tests.
144
+
145
+ #### Optional Demo Modification: UDAP Authentication
146
+
147
+ To run the demonstration using UDAP authentication to obtain an access token, replace step 4. "Register and obtain and access token"
148
+ with the following:
149
+
150
+ 1. In another tab, start an Inferno session for the UDAP Security Server test suite. Select the "Demo: Run Against the UDAP Security
151
+ Client Suite" preset
152
+ 1. Select the "UDAP Authorization Code Flow" group, click the "RUN TESTS" button, and update the **FHIR Server Base URL**
153
+ input with the FHIR server URL displayed in the wait dialog of the PDex Payer Client test session.
154
+ 1. Click the "SUBMIT" button and click to authorize in the "User Action Required" dialog that appears, which will complete
155
+ the tests.
156
+ 1. Find the `udap_auth_code_flow_access_token` output in test **1.3.04** "Token exchange response body contains required information
157
+ encoded in JSON", and copy the value, which will be a ~100 character string of letters and numbers (e.g.,
158
+ eyJjbGllbnRfaWQiOiJzbWFydF9jbGllbnRfdGVzdF9kZW1vIiwiZXhwaXJhdGlvbiI6MTc0MzUxNDk4Mywibm9uY2UiOiJlZDI5MWIwNmZhMTE4OTc4In0).
159
+ 1. Return to the PDex Payer Client test session and confirm that UDAP registration has been completed in the current
160
+ "User Action Required" dialog.
161
+
162
+ The PDex Client Registration tests will pass with the possible exception of some UDAP registration details.
163
+
164
+ ## Input Details
165
+
166
+ ### Auth Configuration Details
167
+
168
+ When running these tests there are 4 options for authentication, which also allows
169
+ Inferno to identify which session the requests are for. The choice is made when the
170
+ session is created with the selected Client Security Type option, which determines
171
+ what details the tester needs to provide during the Client Registration tests:
172
+
173
+ - **SMART App Launch Client**: the system under test will manually register
174
+ with Inferno and request access tokens to use when accessing FHIR endpoints
175
+ as per the SMART App Launch specification, which includes providing one or more
176
+ redirect URI(s) in the **SMART App Launch Redirect URI(s)** input, and optionally,
177
+ launch URL(s) in the **SMART App Launch URL(s)** input. Additionally, testers may provide
178
+ a **Client Id** if they want their client assigned a specific one. Depending on the
179
+ specific SMART flavor chosen, additional inputs for authentication may be needed:
180
+ - **SMART App Launch Public Client**: no additional authentication inputs
181
+ - **SMART App Launch Confidential Symmetric Client**: provide a secret using the
182
+ **SMART Confidential Symmetric Client Secret** input.
183
+ - **SMART App Launch Confidential Asymmetric Client**: provide a URL that resolves
184
+ to a JWKS or a raw JWKS in JSON format using the **SMART JSON Web Key Set (JWKS)** input.
185
+ - **UDAP Authorization Code Client**: the system under test will dynamically register
186
+ with Inferno and request access tokens used to access FHIR endpoints
187
+ as per the UDAP specification. It requires the **UDAP Client URI** input
188
+ to be populated with the URI that the client will use when dynamically
189
+ registering with Inferno. This will be used to generate a client id (each
190
+ unique UDAP Client URI will always get the same client id). All other details
191
+ that Inferno needs will be provided as a part of the dynamic registration.
192
+
193
+ ### Inputs Controlling Token Responses
194
+
195
+ Inferno's SMART simulation does not include the details needed to populate
196
+ the token response [context data](https://hl7.org/fhir/smart-app-launch/STU2.2/scopes-and-launch-context.html)
197
+ when requested by apps using scopes during the *SMART App Launch* flow. If the tested app
198
+ needs and will request these details, the tester must provide them for Inferno
199
+ to respond with using the following inputs:
200
+ - **Launch Context**: Testers can provide a JSON
201
+ array for Inferno to use as the base for building a token response on. This can include
202
+ keys like `"patient"` when the `launch/patient` scope will be requested. Note that when keys that Inferno
203
+ also populates (e.g. `access_token` or `id_token`) are included, the Inferno value will be returned.
204
+ - **FHIR User Relative Reference**: Testers
205
+ can provide a FHIR relative reference (`<resource type>/<id>`) for the FHIR user record
206
+ to return with the `id_token` when the `openid` and `fhirUser` scopes are requested.
207
+ If populated, ensure that the referenced resource is available in Inferno's simulated
208
+ FHIR server so that it can be accessed.
117
209
 
118
210
  ## Testing Limitations
119
211
 
@@ -129,7 +221,7 @@ likely to change in future versions of the PDex specification.
129
221
 
130
222
  At this time, coverage of additional scenarios beyond the happy path payer to payer workflow
131
223
  are not validated. These scenarios, such as a failed member match, will be tested in future
132
- versions of the tests.
224
+ versions of these tests.
133
225
 
134
226
  ### Demographic Matching
135
227
 
@@ -165,7 +257,7 @@ includes two auth steps, one for obtaining a token that allows `$member-match` i
165
257
  that gets access for a specific member Patient. Inferno requires that clients choose and send a single
166
258
  bearer token for the duration of the tests.
167
259
 
168
- ### Requireed Patient id Search
260
+ ### Required Patient id Search
169
261
 
170
262
  The [HRex 1.0.0 $member-match
171
263
  operation](https://hl7.org/fhir/us/davinci-hrex/STU1/OperationDefinition-member-match.html#membermatch)
@@ -0,0 +1,32 @@
1
+ require 'smart_app_launch_test_kit'
2
+
3
+ module DaVinciPDexTestKit
4
+ module PDexPayerClient
5
+ class PDexClientAuthSMARTConfidentialAsymmetricGroup < Inferno::TestGroup
6
+ id :pdex_client_auth_smart_alca
7
+ title 'Review Authentication Interactions'
8
+ description %(
9
+ During these tests, Inferno will verify that the client interacted with Inferno's
10
+ simulated SMART authorization server in a conformant manner when requesting access tokens
11
+ and that the client under test was able to use provided access tokens to make PDex
12
+ requests.
13
+
14
+ Before running these tests, perform the Data Access group so that the client
15
+ will request an access token and use it on a data access request.
16
+ )
17
+ run_as_group
18
+
19
+ # smart auth verification
20
+ test from: :smart_client_authorization_request_verification,
21
+ id: :pdex_client_authorization_smart_alca_verification,
22
+ config: { options: { endpoint_suite_id: :pdex_payer_client } }
23
+ test from: :smart_client_token_request_alca_verification,
24
+ id: :pdex_client_token_smart_alca_verification,
25
+ config: { options: { endpoint_suite_id: :pdex_payer_client } }
26
+ test from: :smart_client_token_use_verification,
27
+ config: {
28
+ options: { access_request_tags: [RESOURCE_ID_TAG, RESOURCE_API_TAG] }
29
+ }
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,32 @@
1
+ require 'smart_app_launch_test_kit'
2
+
3
+ module DaVinciPDexTestKit
4
+ module PDexPayerClient
5
+ class PDexClientAuthSMARTConfidentialSymmetricGroup < Inferno::TestGroup
6
+ id :pdex_client_auth_smart_alcs
7
+ title 'Review Authentication Interactions'
8
+ description %(
9
+ During these tests, Inferno will verify that the client interacted with Inferno's
10
+ simulated SMART authorization server in a conformant manner when requesting access tokens
11
+ and that the client under test was able to use provided access tokens to make PDex
12
+ requests.
13
+
14
+ Before running these tests, perform the Data Access group so that the client
15
+ will request an access token and use it on a data access request.
16
+ )
17
+ run_as_group
18
+
19
+ # smart auth verification
20
+ test from: :smart_client_authorization_request_verification,
21
+ id: :pdex_client_authorization_smart_alcs_verification,
22
+ config: { options: { endpoint_suite_id: :pdex_payer_client } }
23
+ test from: :smart_client_token_request_alcs_verification,
24
+ id: :pdex_client_token_smart_alcs_verification,
25
+ config: { options: { endpoint_suite_id: :pdex_payer_client } }
26
+ test from: :smart_client_token_use_verification,
27
+ config: {
28
+ options: { access_request_tags: [RESOURCE_ID_TAG, RESOURCE_API_TAG] }
29
+ }
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,32 @@
1
+ require 'smart_app_launch_test_kit'
2
+
3
+ module DaVinciPDexTestKit
4
+ module PDexPayerClient
5
+ class PDexClientAuthSMARTPublicGroup < Inferno::TestGroup
6
+ id :pdex_client_auth_smart_alp
7
+ title 'Review Authentication Interactions'
8
+ description %(
9
+ During these tests, Inferno will verify that the client interacted with Inferno's
10
+ simulated SMART authorization server in a conformant manner when requesting access tokens
11
+ and that the client under test was able to use provided access tokens to make PDex
12
+ requests.
13
+
14
+ Before running these tests, perform the Data Access group so that the client
15
+ will request an access token and use it on a data access request.
16
+ )
17
+ run_as_group
18
+
19
+ # smart auth verification
20
+ test from: :smart_client_authorization_request_verification,
21
+ id: :pdex_client_authorization_smart_alp_verification,
22
+ config: { options: { endpoint_suite_id: :pdex_payer_client } }
23
+ test from: :smart_client_token_request_alp_verification,
24
+ id: :pdex_client_token_smart_alp_verification,
25
+ config: { options: { endpoint_suite_id: :pdex_payer_client } }
26
+ test from: :smart_client_token_use_verification,
27
+ config: {
28
+ options: { access_request_tags: [RESOURCE_ID_TAG, RESOURCE_API_TAG] }
29
+ }
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,31 @@
1
+ require 'udap_security_test_kit'
2
+
3
+ module DaVinciPDexTestKit
4
+ module PDexPayerClient
5
+ class PDexClientAuthUDAPGroup < Inferno::TestGroup
6
+ id :pdex_client_auth_udap
7
+ title 'Review UDAP Authentication Interactions'
8
+ description %(
9
+ During these tests, Inferno will verify that the client interacted with Inferno's
10
+ simulated UDAP authorization server in a conformant manner when requesting access tokens
11
+ and that the client under test was able to use provided access tokens to make PDex
12
+ requests.
13
+
14
+ Before running these tests, perform the Data Access group so that the client
15
+ will request an access token and use it on a data access request.
16
+ )
17
+ run_as_group
18
+
19
+ test from: :udap_client_authorization_request_verification,
20
+ id: :pdex_client_authorization_udap_verification,
21
+ config: { options: { endpoint_suite_id: :pdex_payer_client } }
22
+ test from: :udap_client_token_request_ac_verification,
23
+ id: :pdex_client_token_udap_verification,
24
+ config: { options: { endpoint_suite_id: :pdex_payer_client } }
25
+ test from: :udap_client_token_use_verification,
26
+ config: {
27
+ options: { access_request_tags: [RESOURCE_ID_TAG, RESOURCE_API_TAG] }
28
+ }
29
+ end
30
+ end
31
+ end
@@ -1,21 +1,22 @@
1
- require_relative '../client_validation_test.rb'
1
+ require_relative '../client_validation_test'
2
2
 
3
3
  module DaVinciPDexTestKit
4
4
  module PDexPayerClient
5
5
  class PDexInitialMemberMatchValidationTest < Inferno::Test
6
6
  include ClientValidationTest
7
-
7
+
8
8
  id :pdex_initial_member_match_validation
9
9
  title 'Client provides a valid $member-match request'
10
10
  description %(
11
11
  This test will validate the received $member-match-request input, ensuring it corresponds to the
12
12
  [HRex member-match-in profile](http://hl7.org/fhir/us/davinci-hrex/StructureDefinition/hrex-parameters-member-match-in).
13
13
  )
14
- input :access_token
15
-
14
+
15
+ verifies_requirements 'hl7.fhir.us.davinci-pdex_2.0.0@29'
16
+
16
17
  run do
17
- skip_if !member_match_request.present?, "No previous $member-match request received"
18
-
18
+ skip_if !member_match_request.present?, 'No previous $member-match request received'
19
+
19
20
  parameters = FHIR.from_contents(member_match_request.request_body)
20
21
  assert_resource_type(:parameters, resource: parameters)
21
22
  assert_valid_resource(resource: parameters, profile_url: 'http://hl7.org/fhir/us/davinci-hrex/StructureDefinition/hrex-parameters-member-match-in')
@@ -0,0 +1,38 @@
1
+ require_relative '../urls'
2
+
3
+ module DaVinciPDexTestKit
4
+ module PDexPayerClient
5
+ class PDexlientRegistrationConfigurationSMARTDisplay < Inferno::Test
6
+ include URLs
7
+
8
+ id :pdex_client_reg_config_smart_display
9
+ title 'Confirm client configuration'
10
+ description %(
11
+ This test provides all the information needed for testers to configure
12
+ the client under test to communicate with Inferno's simulated PDex server
13
+ including SMART endpoints to obtain access tokens using the SMART App Launch flow.
14
+ )
15
+
16
+ input :client_id
17
+
18
+ run do
19
+ wait(
20
+ identifier: client_id,
21
+ message: %(
22
+ **Inferno Simulated Server Details**:
23
+
24
+ FHIR Base URL: `#{fhir_base_url}`
25
+
26
+ Authentication Details:
27
+ - SMART Client Id: `#{client_id}`
28
+ - Authorization endpoint: `#{authorization_url}`
29
+ - Token endpoint: `#{token_url}`
30
+
31
+ [Click here](#{resume_pass_url}?token=#{client_id}) once you have configured
32
+ the client to connect to Inferno at the above endpoints.
33
+ )
34
+ )
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,38 @@
1
+ require_relative '../urls'
2
+
3
+ module DaVinciPDexTestKit
4
+ module PDexPayerClient
5
+ class PDexClientRegistrationConfigurationUDAPDisplay < Inferno::Test
6
+ include URLs
7
+
8
+ id :pdex_client_reg_config_udap_display
9
+ title 'Confirm client configuration'
10
+ description %(
11
+ This test provides all the information needed for testers to configure
12
+ the client under test to communicate with Inferno's simulated PDex server
13
+ including UDAP endpoints to obtain access tokens using the authorization_code flow.
14
+ )
15
+
16
+ input :client_id
17
+
18
+ run do
19
+ wait(
20
+ identifier: client_id,
21
+ message: %(
22
+ **Inferno Simulated Server Details**:
23
+
24
+ FHIR Base URL: `#{fhir_base_url}`
25
+
26
+ Authentication Details:
27
+ - UDAP Client Id: `#{client_id}`
28
+ - Authorization endpoint: `#{authorization_url}`
29
+ - Token endpoint: `#{token_url}`
30
+
31
+ [Click here](#{resume_pass_url}?token=#{client_id}) once you have configured
32
+ the client to connect to Inferno at the above endpoints.
33
+ )
34
+ )
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,67 @@
1
+ require 'udap_security_test_kit'
2
+ require 'smart_app_launch_test_kit'
3
+ require_relative 'pdex_client_options'
4
+ require_relative 'client_registration/configuration_display_smart_test'
5
+ require_relative 'client_registration/configuration_display_udap_test'
6
+
7
+ module DaVinciPDexTestKit
8
+ module PDexPayerClient
9
+ class PDexClientRegistrationGroup < Inferno::TestGroup
10
+ id :pdex_client_registration
11
+ title 'Client Registration'
12
+ description %(
13
+ Register the client under test with Inferno's simulated PDex Server,
14
+ including configuration of the system under test to hit the correct endpoints and
15
+ enable authentication and authorization of PDex requests.
16
+ )
17
+ run_as_group
18
+
19
+ # smart registration tests
20
+ test from: :smart_client_registration_alca_verification,
21
+ required_suite_options: {
22
+ client_type: PDexClientOptions::SMART_APP_LAUNCH_CONFIDENTIAL_ASYMMETRIC
23
+ }
24
+ test from: :smart_client_registration_alcs_verification,
25
+ required_suite_options: {
26
+ client_type: PDexClientOptions::SMART_APP_LAUNCH_CONFIDENTIAL_SYMMETRIC
27
+ }
28
+ test from: :smart_client_registration_alp_verification,
29
+ required_suite_options: {
30
+ client_type: PDexClientOptions::SMART_APP_LAUNCH_PUBLIC
31
+ }
32
+ test from: :pdex_client_reg_config_smart_display,
33
+ id: :pdex_client_reg_config_smart_alca_display,
34
+ required_suite_options: {
35
+ client_type: PDexClientOptions::SMART_APP_LAUNCH_CONFIDENTIAL_ASYMMETRIC
36
+ }
37
+ test from: :pdex_client_reg_config_smart_display,
38
+ id: :pdex_client_reg_config_smart_alcs_display,
39
+ required_suite_options: {
40
+ client_type: PDexClientOptions::SMART_APP_LAUNCH_CONFIDENTIAL_SYMMETRIC
41
+ }
42
+ test from: :pdex_client_reg_config_smart_display,
43
+ id: :pdex_client_reg_config_smart_alp_display,
44
+ required_suite_options: {
45
+ client_type: PDexClientOptions::SMART_APP_LAUNCH_PUBLIC
46
+ }
47
+
48
+ # udap registration tests
49
+ test from: :udap_client_registration_interaction,
50
+ id: :pdex_client_reg_udap_interaction,
51
+ config: { options: { endpoint_suite_id: :pdex_payer_client } },
52
+ required_suite_options: {
53
+ client_type: PDexClientOptions::UDAP_AUTHORIZATION_CODE
54
+ }
55
+ test from: :udap_client_registration_ac_verification,
56
+ id: :pdex_client_reg_udap_verification,
57
+ config: { options: { endpoint_suite_id: :pdex_payer_client } },
58
+ required_suite_options: {
59
+ client_type: PDexClientOptions::UDAP_AUTHORIZATION_CODE
60
+ }
61
+ test from: :pdex_client_reg_config_udap_display,
62
+ required_suite_options: {
63
+ client_type: PDexClientOptions::UDAP_AUTHORIZATION_CODE
64
+ }
65
+ end
66
+ end
67
+ end
@@ -62,7 +62,9 @@ module DaVinciPDexTestKit
62
62
 
63
63
  # @return [Array<Inferno::Entities::Request>]
64
64
  def previous_clinical_data_requests
65
- [] + load_tagged_requests(RESOURCE_REQUEST_TAG) + load_tagged_requests(EVERYTHING_TAG) # TODO add export request
65
+ [] + load_tagged_requests(RESOURCE_API_TAG) +
66
+ load_tagged_requests(RESOURCE_ID_TAG) +
67
+ load_tagged_requests(EVERYTHING_TAG) # TODO add export request
66
68
  end
67
69
 
68
70
  def everything_request
@@ -86,7 +88,13 @@ module DaVinciPDexTestKit
86
88
  end
87
89
 
88
90
  def export_resources
89
- @export_resources ||= (load_tagged_requests(BINARY_TAG).map { |binary_read| binary_read.response_body.split("\n") }.flatten).map { |resource_in_binary| FHIR.from_contents(resource_in_binary) }
91
+ @export_resources ||=
92
+ (
93
+ load_tagged_requests(BINARY_TAG)
94
+ .select { |binary_read| binary_read.status == 200 }
95
+ .map { |binary_read| binary_read.response_body.split("\n") }
96
+ .flatten
97
+ ).map { |resource_in_binary| FHIR.from_contents(resource_in_binary) }
90
98
  end
91
99
 
92
100
  # def patient_id_from_match_request