Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 18 additions & 9 deletions lib/resource_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ class RequiredElementGenerationError < StandardError; end
}.freeze
}.freeze
SIMPLE_QUANTITY_FIELDS = {
'Observation' => [:valueQuantity],
'Range' => [:low, :high],
'SampledData' => [:origin],
'Observation::ReferenceRange' => [:low, :high]
Expand Down Expand Up @@ -642,15 +643,7 @@ def self.relative_fhir_class_name(model)
def self.apply_r5_invariants!(resource)
case resource
when FHIR::R5::UsageContext
ensure_serializable_choice!(
resource,
'value',
'valueCodeableConcept',
textonly_codeableconcept(
'Generated usage context',
namespace: FHIR::R5
)
)
apply_usage_context_invariant!(resource, namespace: FHIR::R5)
when FHIR::R5::BiologicallyDerivedProduct::Property
ensure_serializable_choice!(
resource,
Expand Down Expand Up @@ -737,6 +730,18 @@ def self.apply_r5_invariants!(resource)
resource
end

def self.apply_usage_context_invariant!(resource, namespace:)
ensure_serializable_choice!(
resource,
'value',
'valueCodeableConcept',
textonly_codeableconcept(
'Generated usage context',
namespace: namespace
)
)
end

def self.ensure_serializable_choice!(resource, prefix, selected_field, value)
fields = multiple_type_fields(resource.class).fetch(prefix).values
populated_fields = fields.select do |field|
Expand Down Expand Up @@ -794,6 +799,10 @@ def self.ensure_r5_test_script_action!(test)
def self.apply_invariants!(resource)
fix_codeable_reference(resource)
clear_prohibited_observation_quantity_comparators!(resource)
apply_usage_context_invariant!(resource, namespace: FHIR) if
resource.is_a?(FHIR::UsageContext)
apply_usage_context_invariant!(resource, namespace: FHIR::R4B) if
resource.is_a?(FHIR::R4B::UsageContext)
apply_r5_invariants!(resource) if
Crucible::FHIRVersion.for_class(resource) == :r5

Expand Down
13 changes: 10 additions & 3 deletions test/unit/observation_generation_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,22 @@ def test_observation_simple_quantities_have_no_comparator_across_namespaces
end
end

def test_r4_and_r4b_observation_quantities_that_allow_comparators_are_unchanged
def test_r4_and_r4b_observation_quantity_comparators_are_selectively_cleared
VERSIONS.each do |version, namespace|
observation = observation_with_allowed_comparators(namespace)
expected = allowed_quantities(observation).map { |path, quantity| [path, quantity.comparator] }

Crucible::Tests::ResourceGenerator.apply_invariants!(observation)

actual = allowed_quantities(observation).map { |path, quantity| [path, quantity.comparator] }
assert_equal expected, actual, "#{version} cleared an allowed Quantity comparator"
expected = [
["valueQuantity", nil],
["valueRatio.numerator", ">"],
["valueRatio.denominator", "<="],
["component[0].valueQuantity", ">="],
["component[0].valueRatio.numerator", "<="],
["component[0].valueRatio.denominator", ">"]
]
assert_equal expected, actual, "#{version} applied the wrong Quantity comparator invariant"
end
end

Expand Down
41 changes: 41 additions & 0 deletions test/unit/resource_generator_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,47 @@ def test_empty_r4b_codeable_reference_gets_a_concept
assert_nil reference.reference
end

def test_empty_r4_usage_context_gets_a_value
context = FHIR::UsageContext.new

Crucible::Tests::ResourceGenerator.apply_invariants!(context)

assert_instance_of FHIR::CodeableConcept, context.valueCodeableConcept
assert_not_empty context.valueCodeableConcept.text
assert_nil context.valueQuantity
assert_nil context.valueRange
assert_nil context.valueReference
end

def test_empty_r4b_usage_context_gets_a_value
context = FHIR::R4B::UsageContext.new

Crucible::Tests::ResourceGenerator.apply_invariants!(context)

assert_instance_of FHIR::R4B::CodeableConcept, context.valueCodeableConcept
assert_not_empty context.valueCodeableConcept.text
assert_nil context.valueQuantity
assert_nil context.valueRange
assert_nil context.valueReference
end

def test_observation_value_quantity_comparator_is_cleared_for_supported_versions
[
[FHIR::Observation, FHIR::Quantity],
[FHIR::R4B::Observation, FHIR::R4B::Quantity],
[FHIR::R5::Observation, FHIR::R5::Quantity]
].each do |observation_class, quantity_class|
quantity = quantity_class.new(value: 10, comparator: '>')
observation = observation_class.new(valueQuantity: quantity)

Crucible::Tests::ResourceGenerator.apply_invariants!(observation)

assert_instance_of quantity_class, observation.valueQuantity
assert_equal 10, observation.valueQuantity.value
assert_nil observation.valueQuantity.comparator
end
end

def test_populated_r4b_codeable_reference_is_preserved
reference = FHIR::R4B::CodeableReference.new
reference.reference = FHIR::R4B::Reference.new(display: 'Existing reference')
Expand Down