ipa_test_kit 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (270) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +201 -0
  3. data/lib/ipa_test_kit/custom_groups/capability_statement/conformance_support_test.rb +41 -0
  4. data/lib/ipa_test_kit/custom_groups/capability_statement/fhir_version_test.rb +15 -0
  5. data/lib/ipa_test_kit/custom_groups/capability_statement/json_support_test.rb +39 -0
  6. data/lib/ipa_test_kit/custom_groups/capability_statement/profile_support_test.rb +76 -0
  7. data/lib/ipa_test_kit/custom_groups/capability_statement_group.rb +64 -0
  8. data/lib/ipa_test_kit/date_search_validation.rb +101 -0
  9. data/lib/ipa_test_kit/ext/fhir_models.rb +59 -0
  10. data/lib/ipa_test_kit/fhir_resource_navigation.rb +63 -0
  11. data/lib/ipa_test_kit/generated/allergy_intolerance/allergy_intolerance_must_support_test.rb +40 -0
  12. data/lib/ipa_test_kit/generated/allergy_intolerance/allergy_intolerance_patient_clinical_status_search_test.rb +46 -0
  13. data/lib/ipa_test_kit/generated/allergy_intolerance/allergy_intolerance_patient_search_test.rb +60 -0
  14. data/lib/ipa_test_kit/generated/allergy_intolerance/allergy_intolerance_provenance_revinclude_search_test.rb +49 -0
  15. data/lib/ipa_test_kit/generated/allergy_intolerance/allergy_intolerance_read_test.rb +24 -0
  16. data/lib/ipa_test_kit/generated/allergy_intolerance/allergy_intolerance_reference_resolution_test.rb +28 -0
  17. data/lib/ipa_test_kit/generated/allergy_intolerance/allergy_intolerance_validation_test.rb +34 -0
  18. data/lib/ipa_test_kit/generated/allergy_intolerance/metadata.yml +165 -0
  19. data/lib/ipa_test_kit/generated/allergy_intolerance_group.rb +85 -0
  20. data/lib/ipa_test_kit/generated/bmi/bmi_must_support_test.rb +49 -0
  21. data/lib/ipa_test_kit/generated/bmi/bmi_patient_category_date_search_test.rb +46 -0
  22. data/lib/ipa_test_kit/generated/bmi/bmi_patient_category_search_test.rb +45 -0
  23. data/lib/ipa_test_kit/generated/bmi/bmi_patient_category_status_search_test.rb +47 -0
  24. data/lib/ipa_test_kit/generated/bmi/bmi_patient_code_date_search_test.rb +48 -0
  25. data/lib/ipa_test_kit/generated/bmi/bmi_patient_code_search_test.rb +62 -0
  26. data/lib/ipa_test_kit/generated/bmi/bmi_provenance_revinclude_search_test.rb +51 -0
  27. data/lib/ipa_test_kit/generated/bmi/bmi_read_test.rb +24 -0
  28. data/lib/ipa_test_kit/generated/bmi/bmi_reference_resolution_test.rb +28 -0
  29. data/lib/ipa_test_kit/generated/bmi/bmi_validation_test.rb +34 -0
  30. data/lib/ipa_test_kit/generated/bmi/metadata.yml +322 -0
  31. data/lib/ipa_test_kit/generated/bmi_group.rb +93 -0
  32. data/lib/ipa_test_kit/generated/bodyheight/bodyheight_must_support_test.rb +49 -0
  33. data/lib/ipa_test_kit/generated/bodyheight/bodyheight_patient_category_date_search_test.rb +46 -0
  34. data/lib/ipa_test_kit/generated/bodyheight/bodyheight_patient_category_search_test.rb +45 -0
  35. data/lib/ipa_test_kit/generated/bodyheight/bodyheight_patient_category_status_search_test.rb +47 -0
  36. data/lib/ipa_test_kit/generated/bodyheight/bodyheight_patient_code_date_search_test.rb +48 -0
  37. data/lib/ipa_test_kit/generated/bodyheight/bodyheight_patient_code_search_test.rb +62 -0
  38. data/lib/ipa_test_kit/generated/bodyheight/bodyheight_provenance_revinclude_search_test.rb +51 -0
  39. data/lib/ipa_test_kit/generated/bodyheight/bodyheight_read_test.rb +24 -0
  40. data/lib/ipa_test_kit/generated/bodyheight/bodyheight_reference_resolution_test.rb +28 -0
  41. data/lib/ipa_test_kit/generated/bodyheight/bodyheight_validation_test.rb +34 -0
  42. data/lib/ipa_test_kit/generated/bodyheight/metadata.yml +328 -0
  43. data/lib/ipa_test_kit/generated/bodyheight_group.rb +93 -0
  44. data/lib/ipa_test_kit/generated/bodytemp/bodytemp_must_support_test.rb +49 -0
  45. data/lib/ipa_test_kit/generated/bodytemp/bodytemp_patient_category_date_search_test.rb +46 -0
  46. data/lib/ipa_test_kit/generated/bodytemp/bodytemp_patient_category_search_test.rb +45 -0
  47. data/lib/ipa_test_kit/generated/bodytemp/bodytemp_patient_category_status_search_test.rb +47 -0
  48. data/lib/ipa_test_kit/generated/bodytemp/bodytemp_patient_code_date_search_test.rb +48 -0
  49. data/lib/ipa_test_kit/generated/bodytemp/bodytemp_patient_code_search_test.rb +62 -0
  50. data/lib/ipa_test_kit/generated/bodytemp/bodytemp_provenance_revinclude_search_test.rb +51 -0
  51. data/lib/ipa_test_kit/generated/bodytemp/bodytemp_read_test.rb +24 -0
  52. data/lib/ipa_test_kit/generated/bodytemp/bodytemp_reference_resolution_test.rb +28 -0
  53. data/lib/ipa_test_kit/generated/bodytemp/bodytemp_validation_test.rb +34 -0
  54. data/lib/ipa_test_kit/generated/bodytemp/metadata.yml +328 -0
  55. data/lib/ipa_test_kit/generated/bodytemp_group.rb +93 -0
  56. data/lib/ipa_test_kit/generated/bodyweight/bodyweight_must_support_test.rb +49 -0
  57. data/lib/ipa_test_kit/generated/bodyweight/bodyweight_patient_category_date_search_test.rb +46 -0
  58. data/lib/ipa_test_kit/generated/bodyweight/bodyweight_patient_category_search_test.rb +45 -0
  59. data/lib/ipa_test_kit/generated/bodyweight/bodyweight_patient_category_status_search_test.rb +47 -0
  60. data/lib/ipa_test_kit/generated/bodyweight/bodyweight_patient_code_date_search_test.rb +48 -0
  61. data/lib/ipa_test_kit/generated/bodyweight/bodyweight_patient_code_search_test.rb +62 -0
  62. data/lib/ipa_test_kit/generated/bodyweight/bodyweight_provenance_revinclude_search_test.rb +51 -0
  63. data/lib/ipa_test_kit/generated/bodyweight/bodyweight_read_test.rb +24 -0
  64. data/lib/ipa_test_kit/generated/bodyweight/bodyweight_reference_resolution_test.rb +28 -0
  65. data/lib/ipa_test_kit/generated/bodyweight/bodyweight_validation_test.rb +34 -0
  66. data/lib/ipa_test_kit/generated/bodyweight/metadata.yml +328 -0
  67. data/lib/ipa_test_kit/generated/bodyweight_group.rb +93 -0
  68. data/lib/ipa_test_kit/generated/bp/bp_must_support_test.rb +52 -0
  69. data/lib/ipa_test_kit/generated/bp/bp_patient_category_date_search_test.rb +46 -0
  70. data/lib/ipa_test_kit/generated/bp/bp_patient_category_search_test.rb +45 -0
  71. data/lib/ipa_test_kit/generated/bp/bp_patient_category_status_search_test.rb +47 -0
  72. data/lib/ipa_test_kit/generated/bp/bp_patient_code_date_search_test.rb +48 -0
  73. data/lib/ipa_test_kit/generated/bp/bp_patient_code_search_test.rb +62 -0
  74. data/lib/ipa_test_kit/generated/bp/bp_provenance_revinclude_search_test.rb +51 -0
  75. data/lib/ipa_test_kit/generated/bp/bp_read_test.rb +24 -0
  76. data/lib/ipa_test_kit/generated/bp/bp_reference_resolution_test.rb +28 -0
  77. data/lib/ipa_test_kit/generated/bp/bp_validation_test.rb +34 -0
  78. data/lib/ipa_test_kit/generated/bp/metadata.yml +379 -0
  79. data/lib/ipa_test_kit/generated/bp_group.rb +93 -0
  80. data/lib/ipa_test_kit/generated/condition/condition_must_support_test.rb +39 -0
  81. data/lib/ipa_test_kit/generated/condition/condition_patient_category_search_test.rb +47 -0
  82. data/lib/ipa_test_kit/generated/condition/condition_patient_clinical_status_search_test.rb +46 -0
  83. data/lib/ipa_test_kit/generated/condition/condition_patient_code_search_test.rb +47 -0
  84. data/lib/ipa_test_kit/generated/condition/condition_patient_onset_date_search_test.rb +47 -0
  85. data/lib/ipa_test_kit/generated/condition/condition_patient_search_test.rb +60 -0
  86. data/lib/ipa_test_kit/generated/condition/condition_provenance_revinclude_search_test.rb +49 -0
  87. data/lib/ipa_test_kit/generated/condition/condition_read_test.rb +24 -0
  88. data/lib/ipa_test_kit/generated/condition/condition_reference_resolution_test.rb +28 -0
  89. data/lib/ipa_test_kit/generated/condition/condition_validation_test.rb +34 -0
  90. data/lib/ipa_test_kit/generated/condition/metadata.yml +231 -0
  91. data/lib/ipa_test_kit/generated/condition_group.rb +91 -0
  92. data/lib/ipa_test_kit/generated/document_reference/document_reference_id_search_test.rb +40 -0
  93. data/lib/ipa_test_kit/generated/document_reference/document_reference_must_support_test.rb +49 -0
  94. data/lib/ipa_test_kit/generated/document_reference/document_reference_patient_category_date_search_test.rb +46 -0
  95. data/lib/ipa_test_kit/generated/document_reference/document_reference_patient_category_search_test.rb +45 -0
  96. data/lib/ipa_test_kit/generated/document_reference/document_reference_patient_search_test.rb +61 -0
  97. data/lib/ipa_test_kit/generated/document_reference/document_reference_patient_status_search_test.rb +46 -0
  98. data/lib/ipa_test_kit/generated/document_reference/document_reference_patient_type_period_search_test.rb +48 -0
  99. data/lib/ipa_test_kit/generated/document_reference/document_reference_patient_type_search_test.rb +45 -0
  100. data/lib/ipa_test_kit/generated/document_reference/document_reference_provenance_revinclude_search_test.rb +50 -0
  101. data/lib/ipa_test_kit/generated/document_reference/document_reference_read_test.rb +24 -0
  102. data/lib/ipa_test_kit/generated/document_reference/document_reference_reference_resolution_test.rb +28 -0
  103. data/lib/ipa_test_kit/generated/document_reference/document_reference_validation_test.rb +34 -0
  104. data/lib/ipa_test_kit/generated/document_reference/metadata.yml +356 -0
  105. data/lib/ipa_test_kit/generated/document_reference_group.rb +99 -0
  106. data/lib/ipa_test_kit/generated/head_circumference/head_circumference_must_support_test.rb +49 -0
  107. data/lib/ipa_test_kit/generated/head_circumference/head_circumference_patient_category_date_search_test.rb +46 -0
  108. data/lib/ipa_test_kit/generated/head_circumference/head_circumference_patient_category_search_test.rb +45 -0
  109. data/lib/ipa_test_kit/generated/head_circumference/head_circumference_patient_category_status_search_test.rb +47 -0
  110. data/lib/ipa_test_kit/generated/head_circumference/head_circumference_patient_code_date_search_test.rb +48 -0
  111. data/lib/ipa_test_kit/generated/head_circumference/head_circumference_patient_code_search_test.rb +62 -0
  112. data/lib/ipa_test_kit/generated/head_circumference/head_circumference_provenance_revinclude_search_test.rb +51 -0
  113. data/lib/ipa_test_kit/generated/head_circumference/head_circumference_read_test.rb +24 -0
  114. data/lib/ipa_test_kit/generated/head_circumference/head_circumference_reference_resolution_test.rb +28 -0
  115. data/lib/ipa_test_kit/generated/head_circumference/head_circumference_validation_test.rb +34 -0
  116. data/lib/ipa_test_kit/generated/head_circumference/metadata.yml +324 -0
  117. data/lib/ipa_test_kit/generated/head_circumference_group.rb +93 -0
  118. data/lib/ipa_test_kit/generated/heartrate/heartrate_must_support_test.rb +49 -0
  119. data/lib/ipa_test_kit/generated/heartrate/heartrate_patient_category_date_search_test.rb +46 -0
  120. data/lib/ipa_test_kit/generated/heartrate/heartrate_patient_category_search_test.rb +45 -0
  121. data/lib/ipa_test_kit/generated/heartrate/heartrate_patient_category_status_search_test.rb +47 -0
  122. data/lib/ipa_test_kit/generated/heartrate/heartrate_patient_code_date_search_test.rb +48 -0
  123. data/lib/ipa_test_kit/generated/heartrate/heartrate_patient_code_search_test.rb +62 -0
  124. data/lib/ipa_test_kit/generated/heartrate/heartrate_provenance_revinclude_search_test.rb +51 -0
  125. data/lib/ipa_test_kit/generated/heartrate/heartrate_read_test.rb +24 -0
  126. data/lib/ipa_test_kit/generated/heartrate/heartrate_reference_resolution_test.rb +28 -0
  127. data/lib/ipa_test_kit/generated/heartrate/heartrate_validation_test.rb +34 -0
  128. data/lib/ipa_test_kit/generated/heartrate/metadata.yml +325 -0
  129. data/lib/ipa_test_kit/generated/heartrate_group.rb +93 -0
  130. data/lib/ipa_test_kit/generated/immunization/immunization_must_support_test.rb +40 -0
  131. data/lib/ipa_test_kit/generated/immunization/immunization_patient_date_search_test.rb +47 -0
  132. data/lib/ipa_test_kit/generated/immunization/immunization_patient_search_test.rb +60 -0
  133. data/lib/ipa_test_kit/generated/immunization/immunization_patient_status_search_test.rb +45 -0
  134. data/lib/ipa_test_kit/generated/immunization/immunization_provenance_revinclude_search_test.rb +50 -0
  135. data/lib/ipa_test_kit/generated/immunization/immunization_read_test.rb +24 -0
  136. data/lib/ipa_test_kit/generated/immunization/immunization_reference_resolution_test.rb +28 -0
  137. data/lib/ipa_test_kit/generated/immunization/immunization_validation_test.rb +34 -0
  138. data/lib/ipa_test_kit/generated/immunization/metadata.yml +210 -0
  139. data/lib/ipa_test_kit/generated/immunization_group.rb +87 -0
  140. data/lib/ipa_test_kit/generated/ipa_test_suite.rb +88 -0
  141. data/lib/ipa_test_kit/generated/medication_request/medication_request_must_support_test.rb +44 -0
  142. data/lib/ipa_test_kit/generated/medication_request/medication_request_patient_intent_authoredon_search_test.rb +53 -0
  143. data/lib/ipa_test_kit/generated/medication_request/medication_request_patient_intent_encounter_search_test.rb +52 -0
  144. data/lib/ipa_test_kit/generated/medication_request/medication_request_patient_intent_search_test.rb +68 -0
  145. data/lib/ipa_test_kit/generated/medication_request/medication_request_patient_intent_status_search_test.rb +49 -0
  146. data/lib/ipa_test_kit/generated/medication_request/medication_request_provenance_revinclude_search_test.rb +51 -0
  147. data/lib/ipa_test_kit/generated/medication_request/medication_request_read_test.rb +24 -0
  148. data/lib/ipa_test_kit/generated/medication_request/medication_request_reference_resolution_test.rb +28 -0
  149. data/lib/ipa_test_kit/generated/medication_request/medication_request_validation_test.rb +34 -0
  150. data/lib/ipa_test_kit/generated/medication_request/medication_validation_test.rb +34 -0
  151. data/lib/ipa_test_kit/generated/medication_request/metadata.yml +307 -0
  152. data/lib/ipa_test_kit/generated/medication_request_group.rb +92 -0
  153. data/lib/ipa_test_kit/generated/medication_statement/medication_statement_must_support_test.rb +43 -0
  154. data/lib/ipa_test_kit/generated/medication_statement/medication_statement_patient_context_search_test.rb +51 -0
  155. data/lib/ipa_test_kit/generated/medication_statement/medication_statement_patient_effective_search_test.rb +52 -0
  156. data/lib/ipa_test_kit/generated/medication_statement/medication_statement_patient_search_test.rb +68 -0
  157. data/lib/ipa_test_kit/generated/medication_statement/medication_statement_patient_status_search_test.rb +49 -0
  158. data/lib/ipa_test_kit/generated/medication_statement/medication_statement_provenance_revinclude_search_test.rb +51 -0
  159. data/lib/ipa_test_kit/generated/medication_statement/medication_statement_read_test.rb +24 -0
  160. data/lib/ipa_test_kit/generated/medication_statement/medication_statement_reference_resolution_test.rb +28 -0
  161. data/lib/ipa_test_kit/generated/medication_statement/medication_statement_validation_test.rb +34 -0
  162. data/lib/ipa_test_kit/generated/medication_statement/medication_validation_test.rb +34 -0
  163. data/lib/ipa_test_kit/generated/medication_statement/metadata.yml +230 -0
  164. data/lib/ipa_test_kit/generated/medication_statement_group.rb +92 -0
  165. data/lib/ipa_test_kit/generated/metadata.yml +6230 -0
  166. data/lib/ipa_test_kit/generated/observation/metadata.yml +1280 -0
  167. data/lib/ipa_test_kit/generated/observation/observation_must_support_test.rb +41 -0
  168. data/lib/ipa_test_kit/generated/observation/observation_patient_category_date_search_test.rb +46 -0
  169. data/lib/ipa_test_kit/generated/observation/observation_patient_category_search_test.rb +62 -0
  170. data/lib/ipa_test_kit/generated/observation/observation_patient_category_status_search_test.rb +47 -0
  171. data/lib/ipa_test_kit/generated/observation/observation_patient_code_date_search_test.rb +48 -0
  172. data/lib/ipa_test_kit/generated/observation/observation_patient_code_search_test.rb +45 -0
  173. data/lib/ipa_test_kit/generated/observation/observation_provenance_revinclude_search_test.rb +51 -0
  174. data/lib/ipa_test_kit/generated/observation/observation_read_test.rb +24 -0
  175. data/lib/ipa_test_kit/generated/observation/observation_reference_resolution_test.rb +28 -0
  176. data/lib/ipa_test_kit/generated/observation/observation_validation_test.rb +34 -0
  177. data/lib/ipa_test_kit/generated/observation_group.rb +93 -0
  178. data/lib/ipa_test_kit/generated/oxygensat/metadata.yml +366 -0
  179. data/lib/ipa_test_kit/generated/oxygensat/oxygensat_must_support_test.rb +65 -0
  180. data/lib/ipa_test_kit/generated/oxygensat/oxygensat_patient_category_date_search_test.rb +46 -0
  181. data/lib/ipa_test_kit/generated/oxygensat/oxygensat_patient_category_search_test.rb +45 -0
  182. data/lib/ipa_test_kit/generated/oxygensat/oxygensat_patient_category_status_search_test.rb +47 -0
  183. data/lib/ipa_test_kit/generated/oxygensat/oxygensat_patient_code_date_search_test.rb +48 -0
  184. data/lib/ipa_test_kit/generated/oxygensat/oxygensat_patient_code_search_test.rb +62 -0
  185. data/lib/ipa_test_kit/generated/oxygensat/oxygensat_provenance_revinclude_search_test.rb +51 -0
  186. data/lib/ipa_test_kit/generated/oxygensat/oxygensat_read_test.rb +24 -0
  187. data/lib/ipa_test_kit/generated/oxygensat/oxygensat_reference_resolution_test.rb +28 -0
  188. data/lib/ipa_test_kit/generated/oxygensat/oxygensat_validation_test.rb +34 -0
  189. data/lib/ipa_test_kit/generated/oxygensat_group.rb +93 -0
  190. data/lib/ipa_test_kit/generated/patient/metadata.yml +320 -0
  191. data/lib/ipa_test_kit/generated/patient/patient_birthdate_family_search_test.rb +41 -0
  192. data/lib/ipa_test_kit/generated/patient/patient_birthdate_name_search_test.rb +39 -0
  193. data/lib/ipa_test_kit/generated/patient/patient_family_gender_search_test.rb +41 -0
  194. data/lib/ipa_test_kit/generated/patient/patient_gender_name_search_test.rb +39 -0
  195. data/lib/ipa_test_kit/generated/patient/patient_id_search_test.rb +53 -0
  196. data/lib/ipa_test_kit/generated/patient/patient_identifier_search_test.rb +40 -0
  197. data/lib/ipa_test_kit/generated/patient/patient_must_support_test.rb +57 -0
  198. data/lib/ipa_test_kit/generated/patient/patient_name_search_test.rb +39 -0
  199. data/lib/ipa_test_kit/generated/patient/patient_provenance_revinclude_search_test.rb +49 -0
  200. data/lib/ipa_test_kit/generated/patient/patient_read_test.rb +24 -0
  201. data/lib/ipa_test_kit/generated/patient/patient_reference_resolution_test.rb +28 -0
  202. data/lib/ipa_test_kit/generated/patient/patient_validation_test.rb +34 -0
  203. data/lib/ipa_test_kit/generated/patient_group.rb +99 -0
  204. data/lib/ipa_test_kit/generated/practitioner/metadata.yml +124 -0
  205. data/lib/ipa_test_kit/generated/practitioner/practitioner_identifier_search_test.rb +40 -0
  206. data/lib/ipa_test_kit/generated/practitioner/practitioner_must_support_test.rb +40 -0
  207. data/lib/ipa_test_kit/generated/practitioner/practitioner_name_search_test.rb +49 -0
  208. data/lib/ipa_test_kit/generated/practitioner/practitioner_read_test.rb +24 -0
  209. data/lib/ipa_test_kit/generated/practitioner/practitioner_reference_resolution_test.rb +28 -0
  210. data/lib/ipa_test_kit/generated/practitioner/practitioner_validation_test.rb +34 -0
  211. data/lib/ipa_test_kit/generated/practitioner_group.rb +84 -0
  212. data/lib/ipa_test_kit/generated/practitioner_role/metadata.yml +141 -0
  213. data/lib/ipa_test_kit/generated/practitioner_role/practitioner_role_identifier_search_test.rb +40 -0
  214. data/lib/ipa_test_kit/generated/practitioner_role/practitioner_role_must_support_test.rb +40 -0
  215. data/lib/ipa_test_kit/generated/practitioner_role/practitioner_role_practitioner_search_test.rb +51 -0
  216. data/lib/ipa_test_kit/generated/practitioner_role/practitioner_role_read_test.rb +24 -0
  217. data/lib/ipa_test_kit/generated/practitioner_role/practitioner_role_reference_resolution_test.rb +28 -0
  218. data/lib/ipa_test_kit/generated/practitioner_role/practitioner_role_validation_test.rb +34 -0
  219. data/lib/ipa_test_kit/generated/practitioner_role_group.rb +84 -0
  220. data/lib/ipa_test_kit/generated/provenance/metadata.yml +114 -0
  221. data/lib/ipa_test_kit/generated/provenance/provenance_read_test.rb +24 -0
  222. data/lib/ipa_test_kit/generated/provenance/provenance_reference_resolution_test.rb +28 -0
  223. data/lib/ipa_test_kit/generated/provenance/provenance_validation_test.rb +34 -0
  224. data/lib/ipa_test_kit/generated/provenance_group.rb +53 -0
  225. data/lib/ipa_test_kit/generated/resource_list.rb +18 -0
  226. data/lib/ipa_test_kit/generated/resprate/metadata.yml +325 -0
  227. data/lib/ipa_test_kit/generated/resprate/resprate_must_support_test.rb +49 -0
  228. data/lib/ipa_test_kit/generated/resprate/resprate_patient_category_date_search_test.rb +46 -0
  229. data/lib/ipa_test_kit/generated/resprate/resprate_patient_category_search_test.rb +45 -0
  230. data/lib/ipa_test_kit/generated/resprate/resprate_patient_category_status_search_test.rb +47 -0
  231. data/lib/ipa_test_kit/generated/resprate/resprate_patient_code_date_search_test.rb +48 -0
  232. data/lib/ipa_test_kit/generated/resprate/resprate_patient_code_search_test.rb +62 -0
  233. data/lib/ipa_test_kit/generated/resprate/resprate_provenance_revinclude_search_test.rb +51 -0
  234. data/lib/ipa_test_kit/generated/resprate/resprate_read_test.rb +24 -0
  235. data/lib/ipa_test_kit/generated/resprate/resprate_reference_resolution_test.rb +28 -0
  236. data/lib/ipa_test_kit/generated/resprate/resprate_validation_test.rb +34 -0
  237. data/lib/ipa_test_kit/generated/resprate_group.rb +93 -0
  238. data/lib/ipa_test_kit/generator/group_generator.rb +171 -0
  239. data/lib/ipa_test_kit/generator/group_metadata.rb +98 -0
  240. data/lib/ipa_test_kit/generator/group_metadata_extractor.rb +278 -0
  241. data/lib/ipa_test_kit/generator/ig_loader.rb +63 -0
  242. data/lib/ipa_test_kit/generator/ig_metadata.rb +49 -0
  243. data/lib/ipa_test_kit/generator/ig_metadata_extractor.rb +56 -0
  244. data/lib/ipa_test_kit/generator/ig_resources.rb +48 -0
  245. data/lib/ipa_test_kit/generator/must_support_metadata_extractor.rb +221 -0
  246. data/lib/ipa_test_kit/generator/must_support_test_generator.rb +86 -0
  247. data/lib/ipa_test_kit/generator/naming.rb +46 -0
  248. data/lib/ipa_test_kit/generator/provenance_revinclude_search_test_generator.rb +186 -0
  249. data/lib/ipa_test_kit/generator/read_test_generator.rb +89 -0
  250. data/lib/ipa_test_kit/generator/reference_resolution_test_generator.rb +72 -0
  251. data/lib/ipa_test_kit/generator/resource_list_generator.rb +46 -0
  252. data/lib/ipa_test_kit/generator/search_definition_metadata_extractor.rb +181 -0
  253. data/lib/ipa_test_kit/generator/search_metadata_extractor.rb +74 -0
  254. data/lib/ipa_test_kit/generator/search_test_generator.rb +295 -0
  255. data/lib/ipa_test_kit/generator/special_cases.rb +16 -0
  256. data/lib/ipa_test_kit/generator/suite_generator.rb +67 -0
  257. data/lib/ipa_test_kit/generator/terminology_binding_metadata_extractor.rb +105 -0
  258. data/lib/ipa_test_kit/generator/validation_test_generator.rb +124 -0
  259. data/lib/ipa_test_kit/generator.rb +86 -0
  260. data/lib/ipa_test_kit/igs/package.tgz +0 -0
  261. data/lib/ipa_test_kit/must_support_test.rb +146 -0
  262. data/lib/ipa_test_kit/read_test.rb +62 -0
  263. data/lib/ipa_test_kit/reference_resolution_test.rb +111 -0
  264. data/lib/ipa_test_kit/request_logger.rb +46 -0
  265. data/lib/ipa_test_kit/search_test.rb +728 -0
  266. data/lib/ipa_test_kit/search_test_properties.rb +61 -0
  267. data/lib/ipa_test_kit/validation_test.rb +48 -0
  268. data/lib/ipa_test_kit/version.rb +3 -0
  269. data/lib/ipa_test_kit.rb +2 -0
  270. metadata +397 -0
@@ -0,0 +1,105 @@
1
+ module IpaTestKit
2
+ class Generator
3
+ class TerminologyBindingMetadataExtractor
4
+ attr_accessor :profile_elements, :ig_resources, :resource
5
+
6
+ def initialize(profile_elements, ig_resources, resource)
7
+ self.profile_elements = profile_elements
8
+ self.ig_resources = ig_resources
9
+ self.resource = resource
10
+ end
11
+
12
+ def terminology_bindings
13
+ (element_terminology_bindings + extension_terminology_bindings).compact
14
+ # add_terminology_bindings_from_extensions
15
+ # profile_elements.select { |element| element.type&.first&.code == 'Extension' }
16
+ # .each { |extension| add_terminology_bindings_from_extension(extension) }
17
+ end
18
+
19
+ def element_has_fixed_value?(element)
20
+ case element.type.first.code
21
+ when 'Quantity'
22
+ code = profile_elements.find { |e| e.path == "#{element.path}.code" }
23
+ system = profile_elements.find { |e| e.path == "#{element.path}.system" }
24
+ code&.fixedCode || system&.fixedUri
25
+ when 'code'
26
+ element.fixedCode.present?
27
+ end
28
+ end
29
+
30
+ def profile_elements_with_bindings
31
+ profile_elements
32
+ .select { |element| element.binding.present? }
33
+ .reject { |element| element_has_fixed_value? element }
34
+ end
35
+
36
+ def element_terminology_bindings
37
+ profile_elements_with_bindings.map do |element|
38
+ {
39
+ type: element.type.first.code,
40
+ strength: element.binding.strength,
41
+ # Goal.target.detail has an unbound binding
42
+ system: element.binding.valueSet&.split('|')&.first,
43
+ path: element.path.gsub('[x]', '').gsub("#{resource}.", '')
44
+ }
45
+ end
46
+ end
47
+
48
+ def extension_profile_elements
49
+ profile_elements
50
+ .select { |element| element.type&.first&.code == 'Extension' }
51
+ .select { |element| extension_profile_url(element).present? }
52
+ end
53
+
54
+ def extension_profile_url(extension)
55
+ extension.type.first.profile&.first
56
+ end
57
+
58
+ def extension_terminology_bindings
59
+ extension_profile_elements
60
+ .flat_map do |extension_profile_element|
61
+ url = extension_profile_url(extension_profile_element)
62
+ extension = ig_resources.profile_by_url(url)
63
+
64
+ elements = extension.snapshot.element
65
+ elements_with_bindings = elements.select do |element|
66
+ element.binding.present? && !element.id.include?('Extension.extension')
67
+ end
68
+
69
+ elements_with_bindings.map do |element|
70
+ {
71
+ type: element.type.first.code,
72
+ strength: element.binding.strength,
73
+ system: element.binding.valueSet&.split('|')&.first,
74
+ path: element.path.gsub('[x]', '').gsub('Extension.', ''),
75
+ extensions: [url]
76
+ }
77
+ end + nested_extension_terminology_bindings(elements, url)
78
+ end
79
+ end
80
+
81
+ def nested_extension_terminology_bindings(elements, extension_url)
82
+ nested_extensions = elements.select { |element| element.path == 'Extension.extension' }
83
+ nested_extensions.flat_map do |nested_extension|
84
+ nested_extension_element = elements.find { |element| element.id == "#{nested_extension.id}.url" }
85
+ next unless nested_extension_element.present?
86
+
87
+ nested_extension_url = nested_extension_element.fixedUri
88
+ nested_elements_with_bindings = elements.select do |element|
89
+ element.id.include?(nested_extension.id) && element.binding.present?
90
+ end
91
+
92
+ nested_elements_with_bindings.map do |element|
93
+ {
94
+ type: element.type.first.code,
95
+ strength: element.binding.strength,
96
+ system: element.binding.valueSet&.split('|')&.first,
97
+ path: element.path.gsub('[x]', '').gsub('Extension.extension.', ''),
98
+ extensions: [extension_url, nested_extension_url]
99
+ }
100
+ end
101
+ end
102
+ end
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,124 @@
1
+ require_relative 'naming'
2
+ require_relative 'special_cases'
3
+
4
+ module IpaTestKit
5
+ class Generator
6
+ class ValidationTestGenerator
7
+ class << self
8
+ def generate(ig_metadata)
9
+ ig_metadata.groups
10
+ .reject { |group| SpecialCases.exclude_resource? group.resource }
11
+ .each do |group|
12
+ new(group).generate
13
+ next unless group.resource == 'MedicationRequest'
14
+
15
+ # The Medication validation test lives in the MedicationRequest
16
+ # group, so we need to pass in that group's metadata
17
+ medication_group_metadata = ig_metadata.groups.find { |group| group.resource == 'Medication' }
18
+ new(medication_group_metadata, group).generate
19
+ end
20
+ end
21
+ end
22
+
23
+ attr_accessor :group_metadata, :medication_request_metadata
24
+
25
+ def initialize(group_metadata, medication_request_metadata = nil)
26
+ self.group_metadata = group_metadata
27
+ self.medication_request_metadata = medication_request_metadata
28
+ end
29
+
30
+ def template
31
+ @template ||= File.read(File.join(__dir__, 'templates', 'validation.rb.erb'))
32
+ end
33
+
34
+ def output
35
+ @output ||= ERB.new(template).result(binding)
36
+ end
37
+
38
+ def base_output_file_name
39
+ "#{class_name.underscore}.rb"
40
+ end
41
+
42
+ def output_file_directory
43
+ File.join(__dir__, '..', 'generated', directory_name)
44
+ end
45
+
46
+ def output_file_name
47
+ File.join(output_file_directory, base_output_file_name)
48
+ end
49
+
50
+ def directory_name
51
+ Naming.snake_case_for_profile(medication_request_metadata || group_metadata)
52
+ end
53
+
54
+ def profile_identifier
55
+ Naming.snake_case_for_profile(group_metadata)
56
+ end
57
+
58
+ def profile_url
59
+ group_metadata.profile_url
60
+ end
61
+
62
+ def profile_name
63
+ group_metadata.profile_name
64
+ end
65
+
66
+ def test_id
67
+ "ipa_010_#{profile_identifier}_validation_test"
68
+ end
69
+
70
+ def class_name
71
+ "#{Naming.upper_camel_case_for_profile(group_metadata)}ValidationTest"
72
+ end
73
+
74
+ def resource_type
75
+ group_metadata.resource
76
+ end
77
+
78
+ def conformance_expectation
79
+ read_interaction[:expectation]
80
+ end
81
+
82
+ def generate
83
+ FileUtils.mkdir_p(output_file_directory)
84
+ File.open(output_file_name, 'w') { |f| f.write(output) }
85
+
86
+ test_metadata = {
87
+ id: test_id,
88
+ file_name: base_output_file_name
89
+ }
90
+
91
+ if resource_type == 'Medication'
92
+ medication_request_metadata.add_test(test_metadata)
93
+ else
94
+ group_metadata.add_test(test_metadata)
95
+ end
96
+ end
97
+
98
+ def description
99
+ <<~DESCRIPTION
100
+ #{description_intro}
101
+ It verifies the presence of mandatory elements and that elements with
102
+ required bindings contain appropriate values. CodeableConcept element
103
+ bindings will fail if none of their codings have a code/system belonging
104
+ to the bound ValueSet. Quantity, Coding, and code element bindings will
105
+ fail if their code/system are not found in the valueset.
106
+ DESCRIPTION
107
+ end
108
+
109
+ def description_intro
110
+ if resource_type == 'Medication'
111
+ <<~MEDICATION_INTRO
112
+ This test verifies resources returned from previous tests conform to
113
+ the [#{profile_name}](#{profile_url}).
114
+ MEDICATION_INTRO
115
+ else
116
+ <<~GENERIC_INTRO
117
+ This test verifies resources returned from the first search conform to
118
+ the [#{profile_name}](#{profile_url}).
119
+ GENERIC_INTRO
120
+ end
121
+ end
122
+ end
123
+ end
124
+ end
@@ -0,0 +1,86 @@
1
+ require 'fhir_models'
2
+
3
+ require_relative 'ext/fhir_models'
4
+ require_relative 'generator/ig_loader'
5
+ require_relative 'generator/ig_metadata_extractor'
6
+ require_relative 'generator/group_generator'
7
+ require_relative 'generator/must_support_test_generator'
8
+ require_relative 'generator/provenance_revinclude_search_test_generator'
9
+ require_relative 'generator/read_test_generator'
10
+ require_relative 'generator/reference_resolution_test_generator'
11
+ require_relative 'generator/resource_list_generator'
12
+ require_relative 'generator/search_test_generator'
13
+ require_relative 'generator/suite_generator'
14
+ require_relative 'generator/validation_test_generator'
15
+
16
+ module IpaTestKit
17
+ class Generator
18
+ attr_accessor :ig_resources, :ig_metadata
19
+
20
+ def generate
21
+ load_ig_package
22
+ extract_metadata
23
+ generate_resource_list
24
+ generate_search_tests
25
+ generate_read_tests
26
+ # TODO: generate_vread_tests
27
+ # TODO: generate_history_tests
28
+ generate_provenance_revinclude_search_tests
29
+ generate_validation_tests
30
+ generate_must_support_tests
31
+ generate_reference_resolution_tests
32
+
33
+ generate_groups
34
+
35
+ generate_suites
36
+ end
37
+
38
+ def extract_metadata
39
+ self.ig_metadata = IGMetadataExtractor.new(ig_resources).extract
40
+ File.open(File.join(__dir__, 'generated', 'metadata.yml'), 'w') do |file|
41
+ file.write(YAML.dump(ig_metadata.to_hash))
42
+ end
43
+ end
44
+
45
+ def load_ig_package
46
+ FHIR.logger = Logger.new('/dev/null')
47
+ self.ig_resources = IGLoader.new.load
48
+ end
49
+
50
+ def generate_resource_list
51
+ ResourceListGenerator.generate(ig_metadata)
52
+ end
53
+
54
+ def generate_reference_resolution_tests
55
+ ReferenceResolutionTestGenerator.generate(ig_metadata)
56
+ end
57
+
58
+ def generate_must_support_tests
59
+ MustSupportTestGenerator.generate(ig_metadata)
60
+ end
61
+
62
+ def generate_validation_tests
63
+ ValidationTestGenerator.generate(ig_metadata)
64
+ end
65
+
66
+ def generate_read_tests
67
+ ReadTestGenerator.generate(ig_metadata)
68
+ end
69
+
70
+ def generate_search_tests
71
+ SearchTestGenerator.generate(ig_metadata)
72
+ end
73
+
74
+ def generate_provenance_revinclude_search_tests
75
+ ProvenanceRevincludeSearchTestGenerator.generate(ig_metadata)
76
+ end
77
+
78
+ def generate_groups
79
+ GroupGenerator.generate(ig_metadata)
80
+ end
81
+
82
+ def generate_suites
83
+ SuiteGenerator.generate(ig_metadata)
84
+ end
85
+ end
86
+ end
Binary file
@@ -0,0 +1,146 @@
1
+ require_relative 'fhir_resource_navigation'
2
+
3
+ module IpaTestKit
4
+ module MustSupportTest
5
+ extend Forwardable
6
+ include FHIRResourceNavigation
7
+
8
+ def_delegators 'self.class', :metadata
9
+
10
+ def all_scratch_resources
11
+ scratch_resources[:all]
12
+ end
13
+
14
+ def perform_must_support_test(resources)
15
+ skip_if resources.blank?, "No #{resource_type} resources were found"
16
+
17
+ if (missing_elements(resources) + missing_slices(resources)).length.zero?
18
+ pass
19
+ end
20
+
21
+ skip "Could not find #{missing_must_support_strings.join(', ')} in the #{resources.length} " \
22
+ "provided #{resource_type} resource(s)"
23
+ end
24
+
25
+ def missing_must_support_strings
26
+ missing_elements.map { |element_definition| missing_element_string(element_definition) } +
27
+ missing_slices.map { |slice_definition| slice_definition[:name] } +
28
+ missing_extensions.map { |extension_definition| extension_definition[:id] }
29
+ end
30
+
31
+ def missing_element_string(element_definition)
32
+ if element_definition[:fixed_value].present?
33
+ "#{element_definition[:path]}:#{element_definition[:fixed_value]}"
34
+ else
35
+ element_definition[:path]
36
+ end
37
+ end
38
+
39
+ def must_support_extensions
40
+ metadata.must_supports[:extensions]
41
+ end
42
+
43
+ def missing_extensions(resources = [])
44
+ @missing_extensions ||=
45
+ must_support_extensions.select do |extension_definition|
46
+ resources.none? do |resource|
47
+ resource.extension.any? { |extension| extension.url == extension_definition[:url] }
48
+ end
49
+ end
50
+ end
51
+
52
+ def must_support_elements
53
+ metadata.must_supports[:elements]
54
+ end
55
+
56
+ def missing_elements(resources = [])
57
+ @missing_elements ||=
58
+ must_support_elements.select do |element_definition|
59
+ resources.none? do |resource|
60
+ path = element_definition[:path] #.delete_suffix('[x]')
61
+ value_found = find_a_value_at(resource, path) do |value|
62
+ value_without_extensions =
63
+ value.respond_to?(:to_hash) ? value.to_hash.reject { |key, _| key == 'extension' } : value
64
+
65
+ (value_without_extensions.present? || value_without_extensions == false) &&
66
+ (element_definition[:fixed_value].blank? || value == element_definition[:fixed_value])
67
+ end
68
+
69
+ # Note that false.present? => false, which is why we need to add this extra check
70
+ value_found.present? || value_found == false
71
+ end
72
+ end
73
+ end
74
+
75
+ def must_support_slices
76
+ metadata.must_supports[:slices]
77
+ end
78
+
79
+ def missing_slices(resources = [])
80
+ @missing_slices ||=
81
+ must_support_slices.select do |slice|
82
+ resources.none? do |resource|
83
+ path = slice[:path] # .delete_suffix('[x]')
84
+ find_slice(resource, path, slice[:discriminator]).present?
85
+ end
86
+ end
87
+ end
88
+
89
+ def find_slice(resource, path, discriminator)
90
+ find_a_value_at(resource, path) do |element|
91
+ case discriminator[:type]
92
+ when 'patternCodeableConcept'
93
+ coding_path = discriminator[:path].present? ? "#{discriminator[:path]}.coding" : 'coding'
94
+ find_a_value_at(element, coding_path) do |coding|
95
+ coding.code == discriminator[:code] && coding.system == discriminator[:system]
96
+ end
97
+ when 'patternIdentifier'
98
+ find_a_value_at(element, discriminator[:path]) { |identifier| identifier.system == discriminator[:system] }
99
+ when 'value'
100
+ values = discriminator[:values].map { |value| value.merge(path: value[:path].split('.')) }
101
+ find_slice_by_values(element, values)
102
+ when 'type'
103
+ case discriminator[:code]
104
+ when 'Date'
105
+ begin
106
+ Date.parse(element)
107
+ rescue ArgumentError
108
+ false
109
+ end
110
+ when 'String'
111
+ element.is_a? String
112
+ else
113
+ element.is_a? FHIR.const_get(discriminator[:code])
114
+ end
115
+ end
116
+ end
117
+ end
118
+
119
+ def find_slice_by_values(element, value_definitions)
120
+ path_prefixes = value_definitions.map { |value_definition| value_definition[:path].first }.uniq
121
+ Array.wrap(element).find do |el|
122
+ path_prefixes.all? do |path_prefix|
123
+ value_definitions_for_path =
124
+ value_definitions
125
+ .select { |value_definition| value_definition[:path].first == path_prefix }
126
+ .each { |value_definition| value_definition[:path].shift }
127
+
128
+ find_a_value_at(el, path_prefix) do |el_found|
129
+ child_element_value_definitions, current_element_value_definitions =
130
+ value_definitions_for_path.partition { |value_definition| value_definition[:path].present? }
131
+
132
+ current_element_values_match =
133
+ current_element_value_definitions
134
+ .all? { |value_definition| value_definition[:value] == el_found }
135
+
136
+ child_element_values_match =
137
+ child_element_value_definitions.present? ?
138
+ find_slice_by_values(el_found, child_element_value_definitions) : true
139
+
140
+ current_element_values_match && child_element_values_match
141
+ end
142
+ end
143
+ end
144
+ end
145
+ end
146
+ end
@@ -0,0 +1,62 @@
1
+ module IpaTestKit
2
+ module ReadTest
3
+ def all_scratch_resources
4
+ scratch_resources[:all] ||= []
5
+ end
6
+
7
+ def perform_read_test(resources, reply_handler = nil)
8
+ skip_if resources.blank?, no_resources_skip_message
9
+
10
+ resources_to_read = readable_resources(resources)
11
+
12
+ assert resources_to_read.present?, "No #{resource_type} id found."
13
+
14
+ if config.options[:read_all_resources]
15
+ resources_to_read.each do |resource|
16
+ read_and_validate(resource)
17
+ end
18
+ else
19
+ read_and_validate(resources_to_read.first)
20
+ end
21
+ end
22
+
23
+ def readable_resources(resources)
24
+ resources
25
+ .select { |resource| resource.is_a?(resource_class) || resource.is_a?(FHIR::Reference) }
26
+ .select { |resource| (resource.is_a?(FHIR::Reference) ? resource.reference.split('/').last : resource.id).present? }
27
+ .compact
28
+ .uniq { |resource| resource.is_a?(FHIR::Reference) ? resource.reference.split('/').last : resource.id }
29
+ end
30
+
31
+ def read_and_validate(resource_to_read)
32
+ id = resource_id(resource_to_read)
33
+
34
+ fhir_read resource_type, id
35
+
36
+ assert_response_status(200)
37
+ assert_resource_type(resource_type)
38
+ assert resource.id.present? && resource.id == id, bad_resource_id_message(id)
39
+
40
+ if resource_to_read.is_a? FHIR::Reference
41
+ all_scratch_resources << resource
42
+ end
43
+ end
44
+
45
+ def resource_id(resource)
46
+ resource.is_a?(FHIR::Reference) ? resource.reference.split('/').last : resource.id
47
+ end
48
+
49
+ def no_resources_skip_message
50
+ "No #{resource_type} resources appear to be available. " \
51
+ 'Please use patients with more information.'
52
+ end
53
+
54
+ def bad_resource_id_message(expected_id)
55
+ "Expected resource to have id: `#{id}`, but found `#{resource.id}`"
56
+ end
57
+
58
+ def resource_class
59
+ FHIR.const_get(resource_type)
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,111 @@
1
+ require_relative '../ipa_test_kit/generated/resource_list'
2
+
3
+ module IpaTestKit
4
+ module ReferenceResolutionTest
5
+ include ResourceList
6
+
7
+ def perform_reference_resolution_test(resources)
8
+ skip_if resources.blank?, no_resources_skip_message
9
+
10
+ self.resolution_count = 0
11
+
12
+ resources.each do |resource|
13
+ break if resolution_count >= max_resolutions
14
+
15
+ validate_reference_resolutions(resource)
16
+ end
17
+
18
+ messages.uniq!
19
+ errors_found = messages.any? { |message| message[:type] == 'error' }
20
+
21
+ assert !errors_found, "Inferno was unable to resolve all IPA references"
22
+ end
23
+
24
+ def max_resolutions
25
+ 50
26
+ end
27
+
28
+ def resolution_count
29
+ @resolution_count
30
+ end
31
+
32
+ def resolution_count=(count)
33
+ @resolution_count = count
34
+ end
35
+
36
+ def record_resolved_reference(reference)
37
+ self.resolution_count += 1
38
+ resolved_references.add?(reference.reference)
39
+ end
40
+
41
+ def resolved_references
42
+ scratch[:resolved_references] ||= Set.new
43
+ end
44
+
45
+ def no_resources_skip_message
46
+ "No #{resource_type} resources appear to be available. " \
47
+ 'Please use patients with more information.'
48
+ end
49
+
50
+ def validate_reference_resolutions(resource)
51
+ problems = []
52
+
53
+ resource.each_element do |reference, meta, path|
54
+ next if meta['type'] != 'Reference'
55
+ next if reference.reference.blank?
56
+ next if resolved_references.include?(reference.reference)
57
+ break if resolution_count >= max_resolutions
58
+
59
+ if reference.contained?
60
+ # if reference_id is blank it is referring to itself, so we know it exists
61
+ next if reference.reference_id.blank?
62
+
63
+ unless resource.contained.any? { |contained_resource| contained_resource&.id == reference.reference_id }
64
+ messages << {
65
+ type: 'error',
66
+ message: "#{path} has contained reference to id '#{reference.reference_id}' that does not exist"
67
+ }
68
+ end
69
+
70
+ next
71
+ end
72
+
73
+ # Should potentially update valid? method in fhir_dstu2_models
74
+ # to check for this type of thing
75
+ # e.g. "patient/54520" is invalid (fhir_client resource_class method would expect "Patient/54520")
76
+ if reference.relative?
77
+ begin
78
+ reference.resource_class
79
+ rescue NameError
80
+ problems << "#{path} has invalid resource type in reference: #{reference.type}"
81
+ next
82
+ end
83
+ end
84
+ reference_type = reference.resource_type
85
+
86
+ begin
87
+ # TODO: this request isn't persisted
88
+ resolved_resource = reference.read(fhir_client)
89
+ rescue ClientException => e
90
+ # report error if the resource is a IPA resource type
91
+ messages << {
92
+ type: 'error',
93
+ message: "#{path} did not resolve: #{e}"
94
+ } if RESOURCE_LIST.include?(reference_type)
95
+
96
+ next
97
+ end
98
+
99
+ if resolved_resource&.resourceType == reference_type
100
+ record_resolved_reference(reference)
101
+ else
102
+ messages << {
103
+ type: 'error',
104
+ message: "Expected #{reference.reference} to refer to a #{reference_type} resource, " \
105
+ "but found a #{resolved_resource&.resourceType} resource."
106
+ }
107
+ end
108
+ end
109
+ end
110
+ end
111
+ end
@@ -0,0 +1,46 @@
1
+ module Inferno
2
+ module Utils
3
+ # @private
4
+ module Middleware
5
+ class RequestLogger
6
+ def log_response(response, start_time, end_time, exception = nil)
7
+ elapsed = end_time - start_time
8
+ status, _response_headers, body = response if response
9
+ status, = response if exception
10
+
11
+ logger.info("#{status} in #{elapsed.in_milliseconds} ms")
12
+ return unless body.present?
13
+
14
+ body = body.is_a?(Array) ? body.join : body
15
+
16
+ if body.length > 100
17
+ logger.info("#{body[0..100]}...")
18
+ else
19
+ logger.info(body)
20
+ end
21
+ end
22
+
23
+ def log_request(env)
24
+ method = env['REQUEST_METHOD']
25
+ scheme = env['rack.url_scheme']
26
+ host = env['HTTP_HOST']
27
+ path = env['REQUEST_URI']
28
+ query = env['rack.request.query_string']
29
+ body = env['rack.input']
30
+ body = body.instance_of?(Puma::NullIO) ? nil : body.string
31
+ query_string = query.blank? ? '' : "?#{query}"
32
+
33
+ logger.info("#{method} #{scheme}://#{host}#{path}#{query_string}")
34
+
35
+ return unless body.present?
36
+
37
+ if body.length > 100
38
+ logger.info("#{body[0..100]}...")
39
+ else
40
+ logger.info(body)
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end