Module: DaVinciDTRTestKit::DTRPayerServerV220::QuestionnaireResponseReferenceValidation

Instance Method Summary collapse

Instance Method Details

#absolute_reference?(reference) ⇒ Boolean

Returns:

  • (Boolean)


108
109
110
111
112
# File 'lib/davinci_dtr_test_kit/server/v2.2.0/questionnaire_response_reference_validation.rb', line 108

def absolute_reference?(reference)
  URI.parse(reference).absolute?
rescue URI::InvalidURIError
  false
end

#answer_value_reference_locations(items, item_location = 'item', locations = []) ⇒ Object

Returns the locations of QuestionnaireResponse answer value references.

Given QuestionnaireResponse items with the following JSON representation: [{ "answer": [{ "valueReference": { "reference": "#observation" } }] }]

it returns: ['item[0].answer[0].valueReference.reference']



93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/davinci_dtr_test_kit/server/v2.2.0/questionnaire_response_reference_validation.rb', line 93

def answer_value_reference_locations(items, item_location = 'item', locations = [])
  items.each_with_index do |item, item_index|
    location = "#{item_location}[#{item_index}]"
    answer_value_reference_locations(item.item, "#{location}.item", locations)

    item.answer.each_with_index do |answer, answer_index|
      answer_location = "#{location}.answer[#{answer_index}]"
      locations << "#{answer_location}.valueReference.reference" if answer.valueReference&.reference.present?
      answer_value_reference_locations(answer.item, "#{answer_location}.item", locations)
    end
  end

  locations
end

#invalid_absolute_reference?(reference, client_fhir_endpoint) ⇒ Boolean

Returns:

  • (Boolean)


120
121
122
123
# File 'lib/davinci_dtr_test_kit/server/v2.2.0/questionnaire_response_reference_validation.rb', line 120

def invalid_absolute_reference?(reference, client_fhir_endpoint)
  client_fhir_endpoint.present? && absolute_reference?(reference) &&
    !reference_on_client_endpoint?(reference, client_fhir_endpoint)
end

#invalid_contained_reference_locations(questionnaire_response) ⇒ Object



50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/davinci_dtr_test_kit/server/v2.2.0/questionnaire_response_reference_validation.rb', line 50

def invalid_contained_reference_locations(questionnaire_response)
  permitted_locations = answer_value_reference_locations(questionnaire_response.item)
  invalid_references = []

  questionnaire_response_references(questionnaire_response).each do |reference|
    reference_value = reference[:value]
    location = reference[:location]
    next unless reference_value.start_with?('#') && !permitted_locations.include?(location)

    invalid_references << "#{location} references `#{reference_value}`"
  end

  invalid_references
end

#invalid_questionnaire_response_references(questionnaire_response, client_fhir_endpoint) ⇒ Object



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/davinci_dtr_test_kit/server/v2.2.0/questionnaire_response_reference_validation.rb', line 32

def invalid_questionnaire_response_references(questionnaire_response, client_fhir_endpoint)
  contained_ids = questionnaire_response.contained.filter_map(&:id)
  invalid_references = []

  questionnaire_response_references(questionnaire_response).each do |reference|
    reference_value = reference[:value]
    location = reference[:location]
    if reference_value.start_with?('#')
      invalid_references << "#{location} references `#{reference_value}`" \
        unless contained_ids.include?(reference_value.delete_prefix('#'))
    elsif invalid_absolute_reference?(reference_value, client_fhir_endpoint)
      invalid_references << "#{location} references `#{reference_value}`"
    end
  end

  invalid_references
end

#questionnaire_response_has_absolute_reference?(questionnaire_response) ⇒ Boolean

Returns:

  • (Boolean)


114
115
116
117
118
# File 'lib/davinci_dtr_test_kit/server/v2.2.0/questionnaire_response_reference_validation.rb', line 114

def questionnaire_response_has_absolute_reference?(questionnaire_response)
  questionnaire_response_references(questionnaire_response).any? do |reference|
    absolute_reference?(reference[:value])
  end
end

#questionnaire_response_references(questionnaire_response) ⇒ Object

Returns all populated FHIR Reference values below a FHIR resource.

Given a QuestionnaireResponse with the following JSON representation: { "subject": { "reference": "Patient/123" }, "item": [{ "answer": [{ "valueReference": { "reference": "#observation" } }] }] }

it returns: [{ value: 'Patient/123', location: 'subject.reference' }, { value: '#observation', location: 'item[0].answer[0].valueReference.reference' }]



74
75
76
77
78
79
80
81
82
83
84
# File 'lib/davinci_dtr_test_kit/server/v2.2.0/questionnaire_response_reference_validation.rb', line 74

def questionnaire_response_references(questionnaire_response)
  references = []

  questionnaire_response.each_element do |element, , path|
    next unless element.is_a?(FHIR::Reference) && element.reference.present?

    references << { value: element.reference, location: "#{path}.reference" }
  end

  references
end

#questionnaire_responses_from_request(request) ⇒ Object



8
9
10
11
12
13
# File 'lib/davinci_dtr_test_kit/server/v2.2.0/questionnaire_response_reference_validation.rb', line 8

def questionnaire_responses_from_request(request)
  resource = FHIR.from_contents(request.response_body)
  questionnaire_responses_from_resource(resource)
rescue JSON::ParserError, FHIR::ClientException
  []
end

#questionnaire_responses_from_resource(resource) ⇒ Object



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/davinci_dtr_test_kit/server/v2.2.0/questionnaire_response_reference_validation.rb', line 15

def questionnaire_responses_from_resource(resource)
  case resource&.resourceType
  when 'QuestionnaireResponse'
    [resource]
  when 'Bundle'
    resource.entry.filter_map do |entry|
      questionnaire_responses_from_resource(entry.resource)
    end.flatten
  when 'Parameters'
    resource.parameter.filter_map do |parameter|
      questionnaire_responses_from_resource(parameter.resource)
    end.flatten
  else
    []
  end
end

#reference_on_client_endpoint?(reference, client_fhir_endpoint) ⇒ Boolean

Returns:

  • (Boolean)


125
126
127
128
129
130
# File 'lib/davinci_dtr_test_kit/server/v2.2.0/questionnaire_response_reference_validation.rb', line 125

def reference_on_client_endpoint?(reference, client_fhir_endpoint)
  return false if client_fhir_endpoint.blank?

  normalized_endpoint = client_fhir_endpoint.delete_suffix('/')
  reference == normalized_endpoint || reference.start_with?("#{normalized_endpoint}/")
end