diff --git a/resources/test/measure_report_bbmri_new_extension.json b/resources/test/measure_report_bbmri_new_extension.json new file mode 100644 index 0000000..de2162e --- /dev/null +++ b/resources/test/measure_report_bbmri_new_extension.json @@ -0,0 +1 @@ +{"date": "2023-03-03T15:54:21.740195064Z", "extension": [{"url": "https://samply.github.io/blaze/fhir/StructureDefinition/eval-duration", "valueQuantity": {"code": "s", "system": "http://unitsofmeasure.org", "unit": "s", "value": 0.050495759}}, {"url":"https://samply.github.io/blaze/fhir/StructureDefinition/bloom-filter-ratio","valueRatio":{"denominator":{"value":0},"numerator":{"value":0}}}], "group": [{"code": {"text": "patients"}, "population": [{"code": {"coding": [{"code": "initial-population", "system": "http://terminology.hl7.org/CodeSystem/measure-population"}]}, "count": 74}], "stratifier": [{"code": [{"text": "Gender"}], "stratum": [{"population": [{"code": {"coding": [{"code": "initial-population", "system": "http://terminology.hl7.org/CodeSystem/measure-population"}]}, "count": 31}], "value": {"text": "female"}}, {"population": [{"code": {"coding": [{"code": "initial-population", "system": "http://terminology.hl7.org/CodeSystem/measure-population"}]}, "count": 43}], "value": {"text": "male"}}]}, {"code": [{"text": "Age"}], "stratum": [{"population": [{"code": {"coding": [{"code": "initial-population", "system": "http://terminology.hl7.org/CodeSystem/measure-population"}]}, "count": 5}], "value": {"text": "40"}}, {"population": [{"code": {"coding": [{"code": "initial-population", "system": "http://terminology.hl7.org/CodeSystem/measure-population"}]}, "count": 4}], "value": {"text": "50"}}, {"population": [{"code": {"coding": [{"code": "initial-population", "system": "http://terminology.hl7.org/CodeSystem/measure-population"}]}, "count": 14}], "value": {"text": "60"}}, {"population": [{"code": {"coding": [{"code": "initial-population", "system": "http://terminology.hl7.org/CodeSystem/measure-population"}]}, "count": 4}], "value": {"text": "80"}}]}, {"code": [{"text": "Custodian"}], "stratum": [{"population": [{"code": {"coding": [{"code": "initial-population", "system": "http://terminology.hl7.org/CodeSystem/measure-population"}]}, "count": 31}], "value": {"text": "bbmri-eric:ID:CZ_CUNI_PILS:collection:serum_plasma"}}, {"population": [{"code": {"coding": [{"code": "initial-population", "system": "http://terminology.hl7.org/CodeSystem/measure-population"}]}, "count": 43}], "value": {"text": "null"}}]}]}, {"code": {"text": "diagnosis"}, "population": [{"code": {"coding": [{"code": "initial-population", "system": "http://terminology.hl7.org/CodeSystem/measure-population"}]}, "count": 324}], "stratifier": [{"code": [{"text": "diagnosis"}], "stratum": [{"population": [{"code": {"coding": [{"code": "initial-population", "system": "http://terminology.hl7.org/CodeSystem/measure-population"}]}, "count": 26}], "value": {"text": "C34.0"}}, {"population": [{"code": {"coding": [{"code": "initial-population", "system": "http://terminology.hl7.org/CodeSystem/measure-population"}]}, "count": 28}], "value": {"text": "C34.2"}}, {"population": [{"code": {"coding": [{"code": "initial-population", "system": "http://terminology.hl7.org/CodeSystem/measure-population"}]}, "count": 25}], "value": {"text": "C34.8"}}, {"population": [{"code": {"coding": [{"code": "initial-population", "system": "http://terminology.hl7.org/CodeSystem/measure-population"}]}, "count": 27}], "value": {"text": "C78.0"}}, {"population": [{"code": {"coding": [{"code": "initial-population", "system": "http://terminology.hl7.org/CodeSystem/measure-population"}]}, "count": 25}], "value": {"text": "D38.6"}}, {"population": [{"code": {"coding": [{"code": "initial-population", "system": "http://terminology.hl7.org/CodeSystem/measure-population"}]}, "count": 25}], "value": {"text": "R91"}}]}]}, {"code": {"text": "specimen"}, "population": [{"code": {"coding": [{"code": "initial-population", "system": "http://terminology.hl7.org/CodeSystem/measure-population"}]}, "count": 124}], "stratifier": [{"code": [{"text": "sample_kind"}], "stratum": [{"population": [{"code": {"coding": [{"code": "initial-population", "system": "http://terminology.hl7.org/CodeSystem/measure-population"}]}, "count": 62}], "value": {"text": "blood-plasma"}}, {"population": [{"code": {"coding": [{"code": "initial-population", "system": "http://terminology.hl7.org/CodeSystem/measure-population"}]}, "count": 62}], "value": {"text": "blood-serum"}}]}]}], "measure": "urn:uuid:fe7e5bf7-d792-4368-b1d2-5798930db13e", "period": {"end": "2030", "start": "2000"}, "resourceType": "MeasureReport", "status": "complete", "type": "summary", "meta": {"lastUpdated": "2023-06-27T13:12:56.719Z", "versionId": "11"}, "id": "DCH47RNHPKH6TC3W"} \ No newline at end of file diff --git a/src/util.rs b/src/util.rs index 843b789..47cb6df 100644 --- a/src/util.rs +++ b/src/util.rs @@ -8,7 +8,7 @@ use serde_json::{json, Value}; use std::collections::HashMap; use std::fs::File; use std::io::{self, BufRead, BufReader}; -use std::path::{Path, PathBuf}; +use std::path::{Path}; use tracing::warn; #[derive(Debug, Deserialize, Serialize)] @@ -25,11 +25,18 @@ struct ValueQuantity { value: f64, } +#[derive(Debug, Deserialize, Serialize)] +struct ValueRatio { + denominator: Value, + numerator: Value, +} + #[derive(Debug, Deserialize, Serialize)] #[serde(rename_all = "camelCase")] struct Extension { url: String, - value_quantity: ValueQuantity, + value_quantity: Option, + value_ratio: Option, } #[derive(Debug, Deserialize, Serialize)] @@ -351,6 +358,8 @@ mod test { const QUERY_BBMRI: &str = include_str!("../resources/test/query_bbmri.cql"); const EXAMPLE_MEASURE_REPORT_BBMRI: &str = include_str!("../resources/test/measure_report_bbmri.json"); + const EXAMPLE_MEASURE_REPORT_BBMRI_NEW_EXTENSION: &str = + include_str!("../resources/test/measure_report_bbmri_new_extension.json"); const EXAMPLE_MEASURE_REPORT_DKTK: &str = include_str!("../resources/test/measure_report_dktk.json"); const EXAMPLE_MEASURE_REPORT_EXLIQUID: &str = @@ -453,6 +462,52 @@ mod test { pretty_assertions::assert_eq!(replace_cql(decoded_library), expected_result); } + #[test] + fn test_obfuscate_counts_bbmri_new_extension() { + let mut obf_cache = ObfCache { + cache: HashMap::new(), + }; + let obfuscated_json = obfuscate_counts_mr( + EXAMPLE_MEASURE_REPORT_BBMRI_NEW_EXTENSION, + &mut obf_cache, + false, + 1, + DELTA_PATIENT, + DELTA_SPECIMEN, + DELTA_DIAGNOSIS, + DELTA_PROCEDURES, + DELTA_MEDICATION_STATEMENTS, + DELTA_HISTO, + EPSILON, + ROUNDING_STEP, + ) + .unwrap(); + + // Check that the obfuscated JSON can be parsed and has the same structure as the original JSON + let _: MeasureReport = serde_json::from_str(&obfuscated_json).unwrap(); + + // Check that the obfuscated JSON is different from the original JSON + assert_ne!(obfuscated_json, EXAMPLE_MEASURE_REPORT_BBMRI_NEW_EXTENSION); + + // Check that obfuscating the same JSON twice with the same obfuscation cache gives the same result + let obfuscated_json_2 = obfuscate_counts_mr( + EXAMPLE_MEASURE_REPORT_BBMRI_NEW_EXTENSION, + &mut obf_cache, + false, + 1, + DELTA_PATIENT, + DELTA_SPECIMEN, + DELTA_DIAGNOSIS, + DELTA_PROCEDURES, + DELTA_MEDICATION_STATEMENTS, + DELTA_HISTO, + EPSILON, + ROUNDING_STEP, + ) + .unwrap(); + pretty_assertions::assert_eq!(obfuscated_json, obfuscated_json_2); + } + #[test] fn test_obfuscate_counts_bbmri() { let mut obf_cache = ObfCache { @@ -499,6 +554,7 @@ mod test { pretty_assertions::assert_eq!(obfuscated_json, obfuscated_json_2); } + #[test] fn test_obfuscate_counts_dktk() { let mut obf_cache = ObfCache {