Module: DaVinciCRDTestKit::MockEHR::FHIRRequestHandler
- Included in:
- FHIRCreateEndpoint, FHIRDeleteEndpoint, FHIRReadEndpoint, FHIRSearchEndpoint, FHIRUpdateEndpoint
- Defined in:
- lib/davinci_crd_test_kit/server/endpoints/mock_ehr/fhir_request_handler.rb
Class Method Summary collapse
Instance Method Summary collapse
- #add_provided_resource_to_mock_ehr_bundle ⇒ Object
-
#assign_id_to_provided_resource(target_id: SecureRandom.uuid) ⇒ Object
————————————————————————— Create, Update —————————————————————————.
- #error_body(severity, code, text) ⇒ Object
- #interaction_type ⇒ Object
-
#mock_ehr_bundle ⇒ Object
————————————————————————— Mock Bundle Management —————————————————————————.
- #mock_ehr_bundle_input_name ⇒ Object
- #mock_ehr_bundle_present? ⇒ Boolean
-
#prepare_response ⇒ Object
————————————————————————— Response Generation —————————————————————————.
-
#provided_resource ⇒ Object
————————————————————————— Request Provided Resource (body) —————————————————————————.
- #provided_resource_valid? ⇒ Boolean
-
#remove_target_resource_from_bundle ⇒ Object
————————————————————————— Delete —————————————————————————.
-
#resource_id ⇒ Object
————————————————————————— Request Resource Id —————————————————————————.
- #resource_id_present? ⇒ Boolean
-
#resource_type ⇒ Object
————————————————————————— Request Resource Type —————————————————————————.
- #resource_type_present? ⇒ Boolean
- #return_provided_resource(status: 201) ⇒ Object
- #return_target_resource(status: 200) ⇒ Object
- #return_unhandled_error(error) ⇒ Object
- #save_mock_ehr_bundle_to_input ⇒ Object
- #target_resource ⇒ Object
- #target_resource_entry ⇒ Object
-
#target_resource_entry_index ⇒ Object
————————————————————————— Reading —————————————————————————.
- #target_resource_present? ⇒ Boolean
-
#test_run_identifier ⇒ Object
————————————————————————— Session Matching —————————————————————————.
- #token_to_session_id(token_to_decode) ⇒ Object
- #update_target_resource_in_mock_ehr_bundle ⇒ Object
Class Method Details
.session_id_to_token(session_id, exp_min = 5) ⇒ Object
20 21 22 23 24 25 26 27 28 |
# File 'lib/davinci_crd_test_kit/server/endpoints/mock_ehr/fhir_request_handler.rb', line 20 def self.session_id_to_token(session_id, exp_min = 5) token_structure = { session_id:, expiration: exp_min.minutes.from_now.to_i, nonce: SecureRandom.hex(8) }.to_json Base64.urlsafe_encode64(token_structure, padding: false) end |
Instance Method Details
#add_provided_resource_to_mock_ehr_bundle ⇒ Object
185 186 187 188 |
# File 'lib/davinci_crd_test_kit/server/endpoints/mock_ehr/fhir_request_handler.rb', line 185 def add_provided_resource_to_mock_ehr_bundle mock_ehr_bundle.entry << FHIR::Bundle::Entry.new({ resource: provided_resource }) save_mock_ehr_bundle_to_input end |
#assign_id_to_provided_resource(target_id: SecureRandom.uuid) ⇒ Object
Create, Update
181 182 183 |
# File 'lib/davinci_crd_test_kit/server/endpoints/mock_ehr/fhir_request_handler.rb', line 181 def assign_id_to_provided_resource(target_id: SecureRandom.uuid) provided_resource.id = target_id end |
#error_body(severity, code, text) ⇒ Object
39 40 41 42 43 44 45 46 |
# File 'lib/davinci_crd_test_kit/server/endpoints/mock_ehr/fhir_request_handler.rb', line 39 def error_body(severity, code, text) FHIR::OperationOutcome.new( issue: FHIR::OperationOutcome::Issue.new(severity:, code:, details: FHIR::CodeableConcept.new( text: )) ).to_json end |
#interaction_type ⇒ Object
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/davinci_crd_test_kit/server/endpoints/mock_ehr/fhir_request_handler.rb', line 54 def interaction_type case request.env['REQUEST_METHOD'] when 'GET' if resource_id.present? 'Read' else 'Search' end when 'POST' if request.env['PATH_INFO'].ends_with?('_search') 'Search' else 'Create' end when 'PUT' 'Update' when 'DELETE' 'Delete' end end |
#mock_ehr_bundle ⇒ Object
Mock Bundle Management
216 217 218 219 220 221 222 223 224 225 226 |
# File 'lib/davinci_crd_test_kit/server/endpoints/mock_ehr/fhir_request_handler.rb', line 216 def mock_ehr_bundle @mock_ehr_bundle ||= begin bundle_json = Inferno::Repositories::SessionData.new.load( test_session_id: test_run.test_session_id, name: mock_ehr_bundle_input_name ) FHIR.from_contents(bundle_json) rescue StandardError nil end end |
#mock_ehr_bundle_input_name ⇒ Object
228 229 230 231 232 |
# File 'lib/davinci_crd_test_kit/server/endpoints/mock_ehr/fhir_request_handler.rb', line 228 def mock_ehr_bundle_input_name return 'mock_ehr_bundle' unless test.config.[:mock_ehr_bundle_input_name].present? test.config.[:mock_ehr_bundle_input_name].to_s end |
#mock_ehr_bundle_present? ⇒ Boolean
234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 |
# File 'lib/davinci_crd_test_kit/server/endpoints/mock_ehr/fhir_request_handler.rb', line 234 def mock_ehr_bundle_present? if mock_ehr_bundle.blank? response.status = 400 response.body = error_body('warning', 'required', "No Bundle provided in input #{mock_ehr_bundle_input_name}") return false end unless mock_ehr_bundle.is_a?(FHIR::Bundle) response.status = 400 response.body = error_body('warning', 'required', "Input #{mock_ehr_bundle_input_name} does not contain a FHIR Bundle.") return false end true end |
#prepare_response ⇒ Object
Response Generation
34 35 36 37 |
# File 'lib/davinci_crd_test_kit/server/endpoints/mock_ehr/fhir_request_handler.rb', line 34 def prepare_response response.format = 'application/fhir+json' response.headers['Access-Control-Allow-Origin'] = '*' end |
#provided_resource ⇒ Object
Request Provided Resource (body)
111 112 113 114 115 116 117 |
# File 'lib/davinci_crd_test_kit/server/endpoints/mock_ehr/fhir_request_handler.rb', line 111 def provided_resource @provided_resource ||= begin FHIR.from_contents(request.body.read) rescue StandardError nil end end |
#provided_resource_valid? ⇒ Boolean
119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 |
# File 'lib/davinci_crd_test_kit/server/endpoints/mock_ehr/fhir_request_handler.rb', line 119 def provided_resource_valid? if provided_resource.blank? response.status = 400 response.body = error_body('error', 'structure', 'Invalid resource') return false end if provided_resource.resourceType != resource_type response.status = 400 response.body = error_body('error', 'structure', "Incorrect resource type: url indicates `#{resource_type}`, " \ "body contains `#{provided_resource.resourceType}`") return false end true end |
#remove_target_resource_from_bundle ⇒ Object
Delete
205 206 207 208 209 210 |
# File 'lib/davinci_crd_test_kit/server/endpoints/mock_ehr/fhir_request_handler.rb', line 205 def remove_target_resource_from_bundle return if target_resource_entry_index.nil? mock_ehr_bundle.entry.delete_at(target_resource_entry_index) save_mock_ehr_bundle_to_input end |
#resource_id ⇒ Object
Request Resource Id
95 96 97 |
# File 'lib/davinci_crd_test_kit/server/endpoints/mock_ehr/fhir_request_handler.rb', line 95 def resource_id request.params[:resource_id] end |
#resource_id_present? ⇒ Boolean
99 100 101 102 103 104 105 |
# File 'lib/davinci_crd_test_kit/server/endpoints/mock_ehr/fhir_request_handler.rb', line 99 def resource_id_present? return true if resource_id.present? response.status = 400 response.body = error_body('error', 'required', 'No recognized resource id in URL') false end |
#resource_type ⇒ Object
Request Resource Type
79 80 81 |
# File 'lib/davinci_crd_test_kit/server/endpoints/mock_ehr/fhir_request_handler.rb', line 79 def resource_type request.params[:resource_type] end |
#resource_type_present? ⇒ Boolean
83 84 85 86 87 88 89 |
# File 'lib/davinci_crd_test_kit/server/endpoints/mock_ehr/fhir_request_handler.rb', line 83 def resource_type_present? return true if resource_type.present? response.status = 400 response.body = error_body('error', 'required', 'No recognized resource type in URL') false end |
#return_provided_resource(status: 201) ⇒ Object
137 138 139 140 |
# File 'lib/davinci_crd_test_kit/server/endpoints/mock_ehr/fhir_request_handler.rb', line 137 def return_provided_resource(status: 201) response.status = status if status.present? response.body = provided_resource.to_json end |
#return_target_resource(status: 200) ⇒ Object
172 173 174 175 |
# File 'lib/davinci_crd_test_kit/server/endpoints/mock_ehr/fhir_request_handler.rb', line 172 def return_target_resource(status: 200) response.status = status if status.present? response.body = target_resource.to_json end |
#return_unhandled_error(error) ⇒ Object
48 49 50 51 52 |
# File 'lib/davinci_crd_test_kit/server/endpoints/mock_ehr/fhir_request_handler.rb', line 48 def return_unhandled_error(error) logger.error("FHIR #{interaction_type} error: #{error.}") response.status = 500 response.body = error_body('error', 'processing', error.) end |
#save_mock_ehr_bundle_to_input ⇒ Object
251 252 253 254 255 256 257 258 |
# File 'lib/davinci_crd_test_kit/server/endpoints/mock_ehr/fhir_request_handler.rb', line 251 def save_mock_ehr_bundle_to_input Inferno::Repositories::SessionData.new.save( test_session_id: test_run.test_session_id, name: mock_ehr_bundle_input_name, value: mock_ehr_bundle.to_json, type: test.available_inputs[mock_ehr_bundle_input_name.to_sym]&.type ) end |
#target_resource ⇒ Object
157 158 159 |
# File 'lib/davinci_crd_test_kit/server/endpoints/mock_ehr/fhir_request_handler.rb', line 157 def target_resource @target_resource ||= target_resource_entry&.resource end |
#target_resource_entry ⇒ Object
152 153 154 155 |
# File 'lib/davinci_crd_test_kit/server/endpoints/mock_ehr/fhir_request_handler.rb', line 152 def target_resource_entry @target_resource_entry ||= target_resource_entry_index.present? ? mock_ehr_bundle.entry[target_resource_entry_index] : nil end |
#target_resource_entry_index ⇒ Object
Reading
146 147 148 149 150 |
# File 'lib/davinci_crd_test_kit/server/endpoints/mock_ehr/fhir_request_handler.rb', line 146 def target_resource_entry_index @target_resource_entry_index ||= mock_ehr_bundle.entry.find_index do |entry| entry.resource&.resourceType == resource_type && entry.resource&.id == resource_id end end |
#target_resource_present? ⇒ Boolean
161 162 163 164 165 166 167 168 169 170 |
# File 'lib/davinci_crd_test_kit/server/endpoints/mock_ehr/fhir_request_handler.rb', line 161 def target_resource_present? if target_resource.blank? response.status = 404 response.body = error_body('error', 'not-found', "No resource found with id #{resource_type}/#{resource_id}") return false end true end |
#test_run_identifier ⇒ Object
Session Matching
10 11 12 |
# File 'lib/davinci_crd_test_kit/server/endpoints/mock_ehr/fhir_request_handler.rb', line 10 def test_run_identifier token_to_session_id(request.headers['authorization']&.delete_prefix('Bearer ')) end |
#token_to_session_id(token_to_decode) ⇒ Object
14 15 16 17 18 |
# File 'lib/davinci_crd_test_kit/server/endpoints/mock_ehr/fhir_request_handler.rb', line 14 def token_to_session_id(token_to_decode) JSON.parse(Base64.urlsafe_decode64(token_to_decode))&.dig('session_id') rescue JSON::ParserError, ArgumentError nil end |
#update_target_resource_in_mock_ehr_bundle ⇒ Object
190 191 192 193 194 195 196 197 198 199 |
# File 'lib/davinci_crd_test_kit/server/endpoints/mock_ehr/fhir_request_handler.rb', line 190 def update_target_resource_in_mock_ehr_bundle if target_resource_entry.present? target_resource_entry.resource = provided_resource save_mock_ehr_bundle_to_input response.status = 200 else add_provided_resource_to_mock_ehr_bundle response.status = 201 end end |