davinci_pdex_test_kit 0.9.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (74) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +201 -0
  3. data/lib/davinci_pdex_test_kit/docs/payer_client_suite_description_v200.md +91 -0
  4. data/lib/davinci_pdex_test_kit/docs/payer_server_suite_description_v200.md +119 -0
  5. data/lib/davinci_pdex_test_kit/ext/inferno_core/record_response_route.rb +98 -0
  6. data/lib/davinci_pdex_test_kit/ext/inferno_core/request.rb +19 -0
  7. data/lib/davinci_pdex_test_kit/ext/inferno_core/runnable.rb +18 -0
  8. data/lib/davinci_pdex_test_kit/fhir_resource_navigation.rb +154 -0
  9. data/lib/davinci_pdex_test_kit/group_metadata.rb +109 -0
  10. data/lib/davinci_pdex_test_kit/metadata/mock_capability_statement.json +1052 -0
  11. data/lib/davinci_pdex_test_kit/metadata/mock_operation_outcome_resource.json +16 -0
  12. data/lib/davinci_pdex_test_kit/mock_server.rb +247 -0
  13. data/lib/davinci_pdex_test_kit/must_support_test.rb +252 -0
  14. data/lib/davinci_pdex_test_kit/pdex_payer_client/client_member_match_tests/client_member_match_submit_test.rb +24 -0
  15. data/lib/davinci_pdex_test_kit/pdex_payer_client/client_member_match_tests/client_member_match_validation_test.rb +23 -0
  16. data/lib/davinci_pdex_test_kit/pdex_payer_client/client_must_support_tests/client_member_match_must_support_submit_test.rb +26 -0
  17. data/lib/davinci_pdex_test_kit/pdex_payer_client/client_must_support_tests/client_member_match_must_support_validation_test.rb +32 -0
  18. data/lib/davinci_pdex_test_kit/pdex_payer_client/client_validation_test.rb +94 -0
  19. data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/allergyintolerance_clinical_data_request_test.rb +23 -0
  20. data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/careplan_clinical_data_request_test.rb +23 -0
  21. data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/careteam_clinical_data_request_test.rb +23 -0
  22. data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/condition_clinical_data_request_test.rb +23 -0
  23. data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/device_clinical_data_request_test.rb +23 -0
  24. data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/diagnosticreport_clinical_data_request_test.rb +23 -0
  25. data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/documentreference_clinical_data_request_test.rb +23 -0
  26. data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/encounter_clinical_data_request_test.rb +23 -0
  27. data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/explanationofbenefit_clinical_data_request_test.rb +23 -0
  28. data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/goal_clinical_data_request_test.rb +23 -0
  29. data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/immunization_clinical_data_request_test.rb +23 -0
  30. data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/initial_scratch_storing.rb +34 -0
  31. data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/initial_wait_test.rb +28 -0
  32. data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/location_clinical_data_request_test.rb +23 -0
  33. data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/medicationdispense_clinical_data_request_test.rb +23 -0
  34. data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/medicationrequest_clinical_data_request_test.rb +23 -0
  35. data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/observation_clinical_data_request_test.rb +23 -0
  36. data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/organization_clinical_data_request_test.rb +23 -0
  37. data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/patient_clinical_data_request_test.rb +23 -0
  38. data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/practitioner_clinical_data_request_test.rb +23 -0
  39. data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/practitionerrole_clinical_data_request_test.rb +23 -0
  40. data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/procedure_clinical_data_request_test.rb +23 -0
  41. data/lib/davinci_pdex_test_kit/pdex_payer_client/collection.rb +46 -0
  42. data/lib/davinci_pdex_test_kit/pdex_payer_client_suite.rb +152 -0
  43. data/lib/davinci_pdex_test_kit/pdex_payer_server/abstract_member_match_request_conformance_test.rb +33 -0
  44. data/lib/davinci_pdex_test_kit/pdex_payer_server/abstract_member_match_request_local_references_test.rb +35 -0
  45. data/lib/davinci_pdex_test_kit/pdex_payer_server/coverage_to_link_has_minimal_data_test.rb +52 -0
  46. data/lib/davinci_pdex_test_kit/pdex_payer_server/coverage_to_link_must_support_test.rb +28 -0
  47. data/lib/davinci_pdex_test_kit/pdex_payer_server/explanation_of_benefit/explanation_of_benefit_id_search_test.rb +58 -0
  48. data/lib/davinci_pdex_test_kit/pdex_payer_server/explanation_of_benefit/explanation_of_benefit_identifier_search_test.rb +58 -0
  49. data/lib/davinci_pdex_test_kit/pdex_payer_server/explanation_of_benefit/explanation_of_benefit_must_support_test.rb +40 -0
  50. data/lib/davinci_pdex_test_kit/pdex_payer_server/explanation_of_benefit/explanation_of_benefit_patient_last_updated_search_test.rb +63 -0
  51. data/lib/davinci_pdex_test_kit/pdex_payer_server/explanation_of_benefit/explanation_of_benefit_patient_service_date_search_test.rb +63 -0
  52. data/lib/davinci_pdex_test_kit/pdex_payer_server/explanation_of_benefit/explanation_of_benefit_patient_type_search_test.rb +63 -0
  53. data/lib/davinci_pdex_test_kit/pdex_payer_server/explanation_of_benefit/explanation_of_benefit_patient_use_search_test.rb +68 -0
  54. data/lib/davinci_pdex_test_kit/pdex_payer_server/explanation_of_benefit/explanation_of_benefit_provenance_revinclude_search_test.rb +52 -0
  55. data/lib/davinci_pdex_test_kit/pdex_payer_server/explanation_of_benefit/explanation_of_benefit_read_test.rb +26 -0
  56. data/lib/davinci_pdex_test_kit/pdex_payer_server/explanation_of_benefit/explanation_of_benefit_reference_resolution_test.rb +43 -0
  57. data/lib/davinci_pdex_test_kit/pdex_payer_server/explanation_of_benefit/explanation_of_benefit_validation_test.rb +40 -0
  58. data/lib/davinci_pdex_test_kit/pdex_payer_server/explanation_of_benefit_group.rb +105 -0
  59. data/lib/davinci_pdex_test_kit/pdex_payer_server/export_patient_group.rb +103 -0
  60. data/lib/davinci_pdex_test_kit/pdex_payer_server/export_validation_group.rb +59 -0
  61. data/lib/davinci_pdex_test_kit/pdex_payer_server/multiple_member_matches_group.rb +66 -0
  62. data/lib/davinci_pdex_test_kit/pdex_payer_server/no_member_matches_group.rb +69 -0
  63. data/lib/davinci_pdex_test_kit/pdex_payer_server/workflow_clinical_data.rb +66 -0
  64. data/lib/davinci_pdex_test_kit/pdex_payer_server/workflow_everything.rb +184 -0
  65. data/lib/davinci_pdex_test_kit/pdex_payer_server/workflow_export.rb +67 -0
  66. data/lib/davinci_pdex_test_kit/pdex_payer_server/workflow_member_match.rb +171 -0
  67. data/lib/davinci_pdex_test_kit/pdex_payer_server_suite.rb +158 -0
  68. data/lib/davinci_pdex_test_kit/pdex_provider_client_suite.rb +36 -0
  69. data/lib/davinci_pdex_test_kit/tags.rb +9 -0
  70. data/lib/davinci_pdex_test_kit/urls.rb +67 -0
  71. data/lib/davinci_pdex_test_kit/user_input_response.rb +32 -0
  72. data/lib/davinci_pdex_test_kit/version.rb +5 -0
  73. data/lib/davinci_pdex_test_kit.rb +8 -0
  74. metadata +218 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 53ae12fc4c0ce1813450d5b139c04b489cc9d7a8a5db03002b0cecf683986b83
4
+ data.tar.gz: 03fdbb64fa1da8eb461087db829f9965e4a60a582aa285ce08835ffbe0151f5c
5
+ SHA512:
6
+ metadata.gz: c435c9cf7ef61a2b12122a7c3dc1f75c2cd9c6c2e703ec572e5bba161232f529d4338538e4b5dfc93fcb095ed99b81d6ef9f2f8c6a2e8eb8371af58a7632b012
7
+ data.tar.gz: 2ee7697f2c9e875ce880282fe1c6da4d4e34028c3113bba0c16e4053d8d846d1d0d2b2844681231580814ad1296dd7315ec671f50ab2d1649d9ef1272da320a1
data/LICENSE ADDED
@@ -0,0 +1,201 @@
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6
+
7
+ 1. Definitions.
8
+
9
+ "License" shall mean the terms and conditions for use, reproduction,
10
+ and distribution as defined by Sections 1 through 9 of this document.
11
+
12
+ "Licensor" shall mean the copyright owner or entity authorized by
13
+ the copyright owner that is granting the License.
14
+
15
+ "Legal Entity" shall mean the union of the acting entity and all
16
+ other entities that control, are controlled by, or are under common
17
+ control with that entity. For the purposes of this definition,
18
+ "control" means (i) the power, direct or indirect, to cause the
19
+ direction or management of such entity, whether by contract or
20
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
21
+ outstanding shares, or (iii) beneficial ownership of such entity.
22
+
23
+ "You" (or "Your") shall mean an individual or Legal Entity
24
+ exercising permissions granted by this License.
25
+
26
+ "Source" form shall mean the preferred form for making modifications,
27
+ including but not limited to software source code, documentation
28
+ source, and configuration files.
29
+
30
+ "Object" form shall mean any form resulting from mechanical
31
+ transformation or translation of a Source form, including but
32
+ not limited to compiled object code, generated documentation,
33
+ and conversions to other media types.
34
+
35
+ "Work" shall mean the work of authorship, whether in Source or
36
+ Object form, made available under the License, as indicated by a
37
+ copyright notice that is included in or attached to the work
38
+ (an example is provided in the Appendix below).
39
+
40
+ "Derivative Works" shall mean any work, whether in Source or Object
41
+ form, that is based on (or derived from) the Work and for which the
42
+ editorial revisions, annotations, elaborations, or other modifications
43
+ represent, as a whole, an original work of authorship. For the purposes
44
+ of this License, Derivative Works shall not include works that remain
45
+ separable from, or merely link (or bind by name) to the interfaces of,
46
+ the Work and Derivative Works thereof.
47
+
48
+ "Contribution" shall mean any work of authorship, including
49
+ the original version of the Work and any modifications or additions
50
+ to that Work or Derivative Works thereof, that is intentionally
51
+ submitted to Licensor for inclusion in the Work by the copyright owner
52
+ or by an individual or Legal Entity authorized to submit on behalf of
53
+ the copyright owner. For the purposes of this definition, "submitted"
54
+ means any form of electronic, verbal, or written communication sent
55
+ to the Licensor or its representatives, including but not limited to
56
+ communication on electronic mailing lists, source code control systems,
57
+ and issue tracking systems that are managed by, or on behalf of, the
58
+ Licensor for the purpose of discussing and improving the Work, but
59
+ excluding communication that is conspicuously marked or otherwise
60
+ designated in writing by the copyright owner as "Not a Contribution."
61
+
62
+ "Contributor" shall mean Licensor and any individual or Legal Entity
63
+ on behalf of whom a Contribution has been received by Licensor and
64
+ subsequently incorporated within the Work.
65
+
66
+ 2. Grant of Copyright License. Subject to the terms and conditions of
67
+ this License, each Contributor hereby grants to You a perpetual,
68
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69
+ copyright license to reproduce, prepare Derivative Works of,
70
+ publicly display, publicly perform, sublicense, and distribute the
71
+ Work and such Derivative Works in Source or Object form.
72
+
73
+ 3. Grant of Patent License. Subject to the terms and conditions of
74
+ this License, each Contributor hereby grants to You a perpetual,
75
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76
+ (except as stated in this section) patent license to make, have made,
77
+ use, offer to sell, sell, import, and otherwise transfer the Work,
78
+ where such license applies only to those patent claims licensable
79
+ by such Contributor that are necessarily infringed by their
80
+ Contribution(s) alone or by combination of their Contribution(s)
81
+ with the Work to which such Contribution(s) was submitted. If You
82
+ institute patent litigation against any entity (including a
83
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
84
+ or a Contribution incorporated within the Work constitutes direct
85
+ or contributory patent infringement, then any patent licenses
86
+ granted to You under this License for that Work shall terminate
87
+ as of the date such litigation is filed.
88
+
89
+ 4. Redistribution. You may reproduce and distribute copies of the
90
+ Work or Derivative Works thereof in any medium, with or without
91
+ modifications, and in Source or Object form, provided that You
92
+ meet the following conditions:
93
+
94
+ (a) You must give any other recipients of the Work or
95
+ Derivative Works a copy of this License; and
96
+
97
+ (b) You must cause any modified files to carry prominent notices
98
+ stating that You changed the files; and
99
+
100
+ (c) You must retain, in the Source form of any Derivative Works
101
+ that You distribute, all copyright, patent, trademark, and
102
+ attribution notices from the Source form of the Work,
103
+ excluding those notices that do not pertain to any part of
104
+ the Derivative Works; and
105
+
106
+ (d) If the Work includes a "NOTICE" text file as part of its
107
+ distribution, then any Derivative Works that You distribute must
108
+ include a readable copy of the attribution notices contained
109
+ within such NOTICE file, excluding those notices that do not
110
+ pertain to any part of the Derivative Works, in at least one
111
+ of the following places: within a NOTICE text file distributed
112
+ as part of the Derivative Works; within the Source form or
113
+ documentation, if provided along with the Derivative Works; or,
114
+ within a display generated by the Derivative Works, if and
115
+ wherever such third-party notices normally appear. The contents
116
+ of the NOTICE file are for informational purposes only and
117
+ do not modify the License. You may add Your own attribution
118
+ notices within Derivative Works that You distribute, alongside
119
+ or as an addendum to the NOTICE text from the Work, provided
120
+ that such additional attribution notices cannot be construed
121
+ as modifying the License.
122
+
123
+ You may add Your own copyright statement to Your modifications and
124
+ may provide additional or different license terms and conditions
125
+ for use, reproduction, or distribution of Your modifications, or
126
+ for any such Derivative Works as a whole, provided Your use,
127
+ reproduction, and distribution of the Work otherwise complies with
128
+ the conditions stated in this License.
129
+
130
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
131
+ any Contribution intentionally submitted for inclusion in the Work
132
+ by You to the Licensor shall be under the terms and conditions of
133
+ this License, without any additional terms or conditions.
134
+ Notwithstanding the above, nothing herein shall supersede or modify
135
+ the terms of any separate license agreement you may have executed
136
+ with Licensor regarding such Contributions.
137
+
138
+ 6. Trademarks. This License does not grant permission to use the trade
139
+ names, trademarks, service marks, or product names of the Licensor,
140
+ except as required for reasonable and customary use in describing the
141
+ origin of the Work and reproducing the content of the NOTICE file.
142
+
143
+ 7. Disclaimer of Warranty. Unless required by applicable law or
144
+ agreed to in writing, Licensor provides the Work (and each
145
+ Contributor provides its Contributions) on an "AS IS" BASIS,
146
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147
+ implied, including, without limitation, any warranties or conditions
148
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149
+ PARTICULAR PURPOSE. You are solely responsible for determining the
150
+ appropriateness of using or redistributing the Work and assume any
151
+ risks associated with Your exercise of permissions under this License.
152
+
153
+ 8. Limitation of Liability. In no event and under no legal theory,
154
+ whether in tort (including negligence), contract, or otherwise,
155
+ unless required by applicable law (such as deliberate and grossly
156
+ negligent acts) or agreed to in writing, shall any Contributor be
157
+ liable to You for damages, including any direct, indirect, special,
158
+ incidental, or consequential damages of any character arising as a
159
+ result of this License or out of the use or inability to use the
160
+ Work (including but not limited to damages for loss of goodwill,
161
+ work stoppage, computer failure or malfunction, or any and all
162
+ other commercial damages or losses), even if such Contributor
163
+ has been advised of the possibility of such damages.
164
+
165
+ 9. Accepting Warranty or Additional Liability. While redistributing
166
+ the Work or Derivative Works thereof, You may choose to offer,
167
+ and charge a fee for, acceptance of support, warranty, indemnity,
168
+ or other liability obligations and/or rights consistent with this
169
+ License. However, in accepting such obligations, You may act only
170
+ on Your own behalf and on Your sole responsibility, not on behalf
171
+ of any other Contributor, and only if You agree to indemnify,
172
+ defend, and hold each Contributor harmless for any liability
173
+ incurred by, or claims asserted against, such Contributor by reason
174
+ of your accepting any such warranty or additional liability.
175
+
176
+ END OF TERMS AND CONDITIONS
177
+
178
+ APPENDIX: How to apply the Apache License to your work.
179
+
180
+ To apply the Apache License to your work, attach the following
181
+ boilerplate notice, with the fields enclosed by brackets "{}"
182
+ replaced with your own identifying information. (Don't include
183
+ the brackets!) The text should be enclosed in the appropriate
184
+ comment syntax for the file format. We also recommend that a
185
+ file or class name and description of purpose be included on the
186
+ same "printed page" as the copyright notice for easier
187
+ identification within third-party archives.
188
+
189
+ Copyright {yyyy} {name of copyright owner}
190
+
191
+ Licensed under the Apache License, Version 2.0 (the "License");
192
+ you may not use this file except in compliance with the License.
193
+ You may obtain a copy of the License at
194
+
195
+ http://www.apache.org/licenses/LICENSE-2.0
196
+
197
+ Unless required by applicable law or agreed to in writing, software
198
+ distributed under the License is distributed on an "AS IS" BASIS,
199
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200
+ See the License for the specific language governing permissions and
201
+ limitations under the License.
@@ -0,0 +1,91 @@
1
+ The Da Vinci PDex Test Kit Payer Client Suite validates the conformance of payer client
2
+ systems to the STU 2 version of the HL7® FHIR®
3
+ [Da Vinci Payer Data Exchange (PDex) Implementation Guide](https://hl7.org/fhir/us/davinci-pdex/STU2/).
4
+
5
+ ## Scope
6
+
7
+ These tests are a **DRAFT** intended to allow payer implementers to perform
8
+ preliminary checks of their systems against PDex IG requirements and [provide
9
+ feedback](https://github.com/inferno-framework/davinci-pdex-test-kit/issues)
10
+ on the tests. Future versions of these tests may validate other
11
+ requirements and may change the test validation logic.
12
+
13
+ ## Test Methodology
14
+
15
+ Inferno will simulate a PDex payer server for the client under test to interact with. The client
16
+ will be expected to initiate requests to the server and demonstrate its ability to react
17
+ to the returned responses. Over the course of these interactions,
18
+ Inferno will seek to observe conformant handling of PDex requirements around
19
+ [single member payer-to-payer data exchange](https://hl7.org/fhir/us/davinci-pdex/STU2/payertopayerexchange.html)
20
+ the transfer of member data from an old payer (represented by Infero) to a new payer
21
+ (represented by the client under test). This includes
22
+ - The ability of the client to complete the payer to payer data exchange workflow by
23
+ - Initiating the request by invoking the `$member-match` operation.
24
+ - Fetching all clinical data available from the old payer (Inferno) on the returned member.
25
+
26
+ Because the process by which
27
+ [payer servers identify each other and establish trust](https://hl7.org/fhir/us/davinci-pdex/STU2/payertopayerexchange.html#mtls-endpoint-discovery)
28
+ is [still under active development](https://hl7.org/fhir/us/davinci-pdex/STU2/payertopayerexchange.html#future-direction-for-discovery-and-registration),
29
+ Inferno does not currently facilitate or validate this part of the workflow.
30
+ See the *Quick Start* section below for the specifics of how this test suite approaches authentication.
31
+
32
+ For further details on limitations of these tests, see the *Testing Limitations* section below.
33
+
34
+ All requests made by the client will be checked for conformance to the PDex
35
+ IG requirements individually and used in aggregate to determine whether
36
+ required features and functionality are present. HL7® FHIR® resources are
37
+ validated with the Java validator using `tx.fhir.org` as the terminology server.
38
+
39
+ ## Running the Tests
40
+
41
+ ### Quick Start
42
+
43
+ For Inferno to simulate a server that returns a matching patient and responds to requests
44
+ for that patient's data using FHIR read and search APIs, Inferno only needs to be able to
45
+ identify when requests come from the client under test. Inferno piggybacks on the request
46
+ authentication for this purpose. Testers must provide a bearer access token that will be
47
+ provided within the `Authentication` header (`Bearer <token>`) on all requests made to
48
+ Inferno endpoints during the test. Inferno uses this information to associate the message
49
+ with the test session and determine how to respond. How the token provided to Inferno is
50
+ generated is up to the tester.
51
+
52
+ Note: authentication options for these tests have not been finalized and are subject to change
53
+ as the requirements in the PDex IG evolve. If the implemented approach prevents you from using
54
+ these tests, please
55
+ [provide feedback](https://github.com/inferno-framework/davinci-pdex-test-kit/issues) so the
56
+ limitations can be addressed.
57
+
58
+ ### Postman-based Demo
59
+
60
+ If you do not have a PDex client but would like to try the tests out, you can use
61
+ [this postman collection](https://github.com/inferno-framework/davinci-pdex-test-kit/blob/main/PDEX.postman_collection.json)
62
+ to make requests against Inferno for these tests. To use the Postman demo on this test session
63
+
64
+ 1. Download the [collection](https://github.com/inferno-framework/davinci-pdex-test-kit/blob/main/PDEX.postman_collection.json) and import it into [Postman](https://www.postman.com/downloads/).
65
+ 2. Select the `PDex Payer Client Postman Demo` from the preset dropdown in the upper left.
66
+ 3. Click `Run All Tests` button in the upper right and click the `Submit` button in the dialog
67
+ that appears.
68
+ 4. When a `User Action Required` dialog will appear requesting a `$member-match` request be made,
69
+ use Postman to send the `$member-match` request found in the `$member-match Requests` folder.
70
+ 5. When a new `User Action Required` dialog will appear requesting clinical data requests be made,
71
+ use Postman to send some or all of the requests in the `Clinical Data Requests` folder and click
72
+ on the link in the dialog when done. If not all the requests are made, the test will not pass
73
+ because the test requires that all available data be accessed.
74
+ 6. When a third `User Action Required` requesting additional `$member-match` requests be made
75
+ demonstrating coverage of all must support elements on `$member-match` submissions, use Postman to send any or all of the requests found in the `$member-match Requests` folder. If only the
76
+ `$member-match missing CoverageToMatch` is sent, then the test will fail due to missing examples.
77
+
78
+ The tests will complete and the results made available for review.
79
+
80
+ ## Testing Limitations
81
+
82
+ The PDex IG is under active development and the IG authors intend to change the approach to the
83
+ workflows included within future versions of the IG. In particular the payer to payer workflow
84
+ will move from a single-patient workflow to a multi-patient workflow. This test suite focuses on
85
+ validating the high-level payer to payer workflow and the ability of clients to use the current
86
+ specification to access member data, without doing detailed validation of the mechanisms,
87
+ including authentication and trust establishment, because those details are likely to change
88
+ in future versions of the PDex specification.
89
+
90
+ At this time, coverage of additional scenarios beyond the happy path payer to payer workflow
91
+ are not validated. These scenarios will be tested in future versions of the tests.
@@ -0,0 +1,119 @@
1
+ The Da Vinci PDex Test Kit Payer Server Suite validates the conformance of payer server
2
+ systems to the STU 2 version of the HL7® FHIR®
3
+ [Da Vinci Payer Data Exchange (PDex) Implementation Guide](https://hl7.org/fhir/us/davinci-pdex/STU2/).
4
+
5
+ ## Scope
6
+
7
+ These tests are a **DRAFT** intended to allow payer implementers to perform
8
+ preliminary checks of their systems against PDex IG requirements and [provide
9
+ feedback](https://github.com/inferno-framework/davinci-pdex-test-kit/issues)
10
+ on the tests. Future versions of these tests may validate other
11
+ requirements and may change the test validation logic.
12
+
13
+ ## Test Methodology
14
+
15
+ Inferno will simulate a PDex payer client for the server under test to interact with. The server
16
+ will be expected to respond to requests made by Inferno. Over the course of these interactions,
17
+ Inferno will seek to observe conformant handling of PDex requirements around
18
+ [single member payer-to-payer data exchange](https://hl7.org/fhir/us/davinci-pdex/STU2/payertopayerexchange.html)
19
+ the transfer of member data from an old payer (represented by the server under test) to a new payer
20
+ (represented by Inferno). This includes
21
+ - The ability of the server to complete the payer to payer data exchange workflow by
22
+ - Responding successfully to invocations of the `$member-match` operation.
23
+ - Returning requested clinical data for the matched member.
24
+ - The ability of the server to handle the full scope of the PDex IG, such as
25
+ - Support PDex and US Core 3.1.1 search and read APIs, profile, and must support requirements
26
+ - Produce failure responses to `$member-match` requests
27
+
28
+ Because the process by which
29
+ [payer servers identify each other and establish trust](https://hl7.org/fhir/us/davinci-pdex/STU2/payertopayerexchange.html#mtls-endpoint-discovery)
30
+ is [still under active development](https://hl7.org/fhir/us/davinci-pdex/STU2/payertopayerexchange.html#future-direction-for-discovery-and-registration),
31
+ Inferno does not currently facilitate or validate this part of the workflow.
32
+ See the *Authentication* section below for the specifics of how this test suite approaches authentication.
33
+
34
+ Note additionally that because the member matching logic is not specified within the implementation
35
+ guide and Inferno will not know ahead of time the contents of server under test, testers are required
36
+ to provide request bodies for `$member-match` invocations that they know will return the outcome
37
+ expected by the test. Inferno will validate that these request bodies conform to the [`$member-match`
38
+ input parameter requirements](https://hl7.org/fhir/us/davinci-hrex/StructureDefinition-hrex-parameters-member-match-in.html).
39
+
40
+ For further details on limitations of these tests, see the *Testing Limitations* section below.
41
+
42
+ All tester-provided requests and responses returned by the server will be checked
43
+ for conformance to the PDex IG requirements individually and used in aggregate to determine whether
44
+ required features and functionality are present. HL7® FHIR® resources are
45
+ validated with the Java validator using `tx.fhir.org` as the terminology server.
46
+
47
+ ## Running the Tests
48
+
49
+ ### Quick Start
50
+
51
+ Execution of these tests require a significant amount of tester input in the
52
+ form of requests that Inferno will make against the server under test.
53
+
54
+ If you would like to try out the tests using examples from the IG against the
55
+ [PDex reference server hosted on FHIR Foundry](https://pdex-server.davinci.hl7.org/fhir), you can do so by
56
+ 1. Selecting the *PDex Payer Server Preset for FHIR Foundry RI* option from the Preset dropdown in the upper left
57
+ 2. Clicking the *Run All Tests* button in the upper right
58
+ 3. Clicking the *Submit* button at the bottom of the input dialog
59
+
60
+ Note that the reference implementation is not expected to pass the tests at this time.
61
+
62
+ You can run these tests using your own server by updating the "FHIR Server Endpoint URL" and
63
+ "OAuth Credentials" inputs. Additional inputs to update to values specific to your implementation
64
+ include:
65
+ - "Member Match Request for one match"
66
+ - "Member Match Request for no matches"
67
+ - "Member Match Request for multiple matches"
68
+ - "Patient IDs"
69
+
70
+ Details on these inputs can be found below.
71
+
72
+ ## Test Configuration Details
73
+
74
+ The details provided here supplement the documentation of individual fields in the input dialog
75
+ that appears when initiating a test run.
76
+
77
+ ### Server identification
78
+
79
+ Requests will be made to the `/Patient/$member-match` and clinical data access endpoints under
80
+ the url provided in the "FHIR Server Endpoint URL" field.
81
+
82
+ ### Authentication
83
+
84
+ The PDex payer to payer workflow contains a
85
+ [detailed approach to endpoint discovery](https://hl7.org/fhir/us/davinci-pdex/STU2/payertopayerexchange.html#mtls-endpoint-discovery),
86
+ [trust](https://hl7.org/fhir/us/davinci-pdex/STU2/payertopayerexchange.html#trust-framework), and
87
+ [scoped data access](https://hl7.org/fhir/us/davinci-pdex/STU2/payertopayerexchange.html#data-retrieval-methods).
88
+ However, the IG also states that significant parts of the IGs that are [expected to change](https://hl7.org/fhir/us/davinci-pdex/STU2/payertopayerexchange.html#future-direction-for-discovery-and-registration).
89
+ Therefore, the tests currently assume that the server under test can provide a bearer token that Inferno
90
+ will submit with all requests. If this simplified approach prevents you from using these tests, please
91
+ [provide feedback](https://github.com/inferno-framework/davinci-pdex-test-kit/issues) so the
92
+ limitations can be addressed.
93
+
94
+ ### $member-match Request Bodies
95
+
96
+ Three inputs for the test suite ask the tester to provide bodies for `$member-match` submissions:
97
+ - "Member Match Request for one match"
98
+ - "Member Match Request for no matches"
99
+ - "Member Match Request for multiple matches"
100
+
101
+ In each case, provide the raw json for the body that Inferno will use to invoke the server's
102
+ `$member-match` operation that will elicit an appropriate response.
103
+
104
+ ### Complete Patients
105
+
106
+ Inferno will test that the server's FHIR API allows for access to all clinical data covered by
107
+ the PDex IG and the US Core IG that it inherits from. In order to do so, it needs the id of
108
+ one or more patients in the "Patient IDs" input. It will use the patient id or ids provided
109
+ to fetch clinical data and check that the required profiles and must support elements are represented.
110
+
111
+ ## Testing Limitations
112
+
113
+ The PDex IG is under active development and the IG authors intend to change the approach to the
114
+ workflows included within future versions of the IG. In particular the payer to payer workflow
115
+ will move from a single-patient workflow to a multi-patient workflow. This test suite focuses on
116
+ validating the high-level payer to payer workflow and the ability of servers to use the current
117
+ specification to make member data available, without doing detailed validation of the mechanisms,
118
+ including authentication and trust establishment, because those details are likely to change
119
+ in future versions of the PDex specification.
@@ -0,0 +1,98 @@
1
+ require 'hanami/controller'
2
+
3
+ module Inferno
4
+ module DSL
5
+ # A base class for creating routes with custom response logic. Requests and responses are tagged and saved.
6
+ # @private
7
+ # @see Inferno::DSL::Runnable#resume_test_route
8
+ class RecordResponseRoute < Hanami::Action
9
+ include Import[
10
+ requests_repo: 'inferno.repositories.requests',
11
+ results_repo: 'inferno.repositories.results',
12
+ test_runs_repo: 'inferno.repositories.test_runs',
13
+ tests_repo: 'inferno.repositories.tests'
14
+ ]
15
+
16
+ def self.call(...)
17
+ new.call(...)
18
+ end
19
+
20
+ # @private
21
+ def test_run_identifier_block
22
+ self.class.singleton_class.instance_variable_get(:@test_run_identifier_block)
23
+ end
24
+
25
+ # @private
26
+ def build_response_block
27
+ self.class.singleton_class.instance_variable_get(:@build_response_block)
28
+ end
29
+
30
+ # @private
31
+ def tags
32
+ self.class.singleton_class.instance_variable_get(:@tags)
33
+ end
34
+
35
+ # @private
36
+ def resumes?(test)
37
+ instance_exec(test, &self.class.singleton_class.instance_variable_get(:@resumes))
38
+ end
39
+
40
+ # @private
41
+ def find_test_run(test_run_identifier)
42
+ test_runs_repo.find_latest_waiting_by_identifier(test_run_identifier)
43
+ end
44
+
45
+ # @private
46
+ def find_waiting_result(test_run)
47
+ results_repo.find_waiting_result(test_run_id: test_run.id)
48
+ end
49
+
50
+ # @private
51
+ def update_result(waiting_result)
52
+ results_repo.update_result(waiting_result.id, 'pass')
53
+ end
54
+
55
+ # @private
56
+ def persist_request(request, test_run, waiting_result, test)
57
+ requests_repo.create(
58
+ request.to_hash.merge(
59
+ test_session_id: test_run.test_session_id,
60
+ result_id: waiting_result.id,
61
+ name: test.config.request_name(test.incoming_request_name),
62
+ tags:
63
+ )
64
+ )
65
+ end
66
+
67
+ # @private
68
+ def find_test(waiting_result)
69
+ tests_repo.find(waiting_result.test_id)
70
+ end
71
+
72
+ # @private
73
+ def handle(req, res)
74
+ request = Inferno::Entities::Request.from_hanami_request(req)
75
+
76
+ test_run_identifier = instance_exec(request, &test_run_identifier_block)
77
+
78
+ test_run = find_test_run(test_run_identifier)
79
+
80
+ halt 500, "Unable to find test run with identifier '#{test_run_identifier}'." if test_run.nil?
81
+
82
+ waiting_result = find_waiting_result(test_run)
83
+ test = find_test(waiting_result)
84
+
85
+ test_runs_repo.mark_as_no_longer_waiting(test_run.id) if resumes? test
86
+
87
+ update_result(waiting_result) if resumes? test
88
+
89
+ instance_exec(request, test, waiting_result, &build_response_block)
90
+
91
+ Inferno::Entities::Request.to_hanami_response(request, res)
92
+ persist_request(request, test_run, waiting_result, test)
93
+
94
+ Jobs.perform(Jobs::ResumeTestRun, test_run.id) if resumes? test
95
+ end
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,19 @@
1
+ module Inferno
2
+ module Entities
3
+ class Request
4
+ def self.to_hanami_response(request, response)
5
+ response.status = request.status
6
+ response.body = request.response_body
7
+ request.response_headers.each do |header|
8
+ response.headers[header.name] = header.value
9
+ end
10
+
11
+ response
12
+ end
13
+
14
+ def response_headers=(headers_hash)
15
+ headers.concat(headers_hash.map { |key, value| Header.new(name: key.to_s, value:, type: 'response') })
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,18 @@
1
+ require_relative 'record_response_route'
2
+
3
+ module Inferno
4
+ module DSL
5
+ module Runnable
6
+ def record_response_route(method, path, tags, build_response, resumes: ->(_) { true }, &block)
7
+ route_class = Class.new(Inferno::DSL::RecordResponseRoute) do |klass|
8
+ klass.singleton_class.instance_variable_set(:@build_response_block, build_response)
9
+ klass.singleton_class.instance_variable_set(:@test_run_identifier_block, block)
10
+ klass.singleton_class.instance_variable_set(:@tags, Array.wrap(tags))
11
+ klass.singleton_class.instance_variable_set(:@resumes, resumes)
12
+ end
13
+
14
+ route(method, path, route_class)
15
+ end
16
+ end
17
+ end
18
+ end