Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implementation of FHIR R5 release version 4.6.0 #1737

Merged
merged 14 commits into from
May 27, 2021
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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
51 changes: 44 additions & 7 deletions build/DownloadFhirBuildProfile.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

# Script to be run from 'build' directory

$server = "http://hl7.org/fhir/2020Sep/";
$server = "http://hl7.org/fhir/2021May/";
$baseDir = Resolve-Path ..
$srcdir = "$baseDir\src";

Expand Down Expand Up @@ -129,6 +129,33 @@ function RemoveNarrative($name)
$xml.Save($file)
}

function RemoveDoubleVersionsInValueSets($name)
{
if ($server.EndsWith('2021May/') )
{
# Correction for R5, 4.6.0:
# Removed double version '|4.6.0|4.6.0' from <valueSet>

$filename = Join-Path $tempDir $name
[xml]$xml = Get-Content $filename

$ns = New-Object System.Xml.XmlNamespaceManager($xml.NameTable)
$ns.AddNamespace("ns", "http://hl7.org/fhir")

$valuesets = $xml.SelectNodes('//ns:valueSet[substring(@value,string-length(@value) - string-length("|4.6.0|4.6.0") + 1) = "|4.6.0|4.6.0"]', $ns)

foreach ($valueset in $valuesets)
{
$valueAttribute = $valueset.GetAttribute('value')
$valueAttribute = $valueAttribute.Replace("|4.6.0|", "|");
$valueset.SetAttribute('value', $valueAttribute) | Out-null
}

Write-Output "Removed double version '|4.6.0|4.6.0' from '<valueSet> $file"
$xml.Save($filename)
}
}

function ChangeValueElement($name)
{
# Correction for 4B:
Expand All @@ -137,8 +164,8 @@ function ChangeValueElement($name)
$filename = Join-Path $tempDir $name
[xml]$xml = Get-Content $filename

$ns = New-Object System.Xml.XmlNamespaceManager($xml.NameTable)
$ns.AddNamespace("ns", "http://hl7.org/fhir")
$ns = New-Object System.Xml.XmlNamespaceManager($xml.NameTable)
$ns.AddNamespace("ns", "http://hl7.org/fhir")

$extensionNodes = $xml.SelectNodes('//ns:extension[@url="http://hl7.org/fhir/StructureDefinition/structuredefinition-fhir-type"]', $ns)

Expand All @@ -150,10 +177,11 @@ function ChangeValueElement($name)
$extension.ReplaceChild($correctedValueElement, $valueElement) | Out-null
}

Write-Output "Changed 'valueUri' to 'valueUrl' for extension 'structuredefinition-fhir-type' from $file"
Write-Output "Changed 'valueUri' to 'valueUrl' for extension 'structuredefinition-fhir-type' from $file"
$xml.Save($filename)
}


function RemoveDefinitonExtension($name)
{
# Correction for 4B:
Expand All @@ -162,8 +190,8 @@ function RemoveDefinitonExtension($name)
$filename = Join-Path $tempDir $name
[xml]$xml = Get-Content $filename

$ns = New-Object System.Xml.XmlNamespaceManager($xml.NameTable)
$ns.AddNamespace("ns", "http://hl7.org/fhir")
$ns = New-Object System.Xml.XmlNamespaceManager($xml.NameTable)
$ns.AddNamespace("ns", "http://hl7.org/fhir")

$extensionNodes = $xml.SelectNodes('//ns:extension[@url="http://hl7.org/fhir/build/StructureDefinition/definition"]', $ns)

Expand Down Expand Up @@ -213,6 +241,16 @@ foreach($file in $allFiles)
ChangeValueElement $file
}
}

# Corrections for R5 (4.6.0)
if ($server.EndsWith("2021May/"))
{
if ($file.EndsWith('profiles-resources.xml'))
{
RemoveDoubleVersionsInValueSets $file
RemoveDefinitonExtension $file
}
}
}


Expand All @@ -239,6 +277,5 @@ PowerCurl "$srcdir\Hl7.Fhir.Serialization.Tests\TestData\json-edge-cases.json" "
PowerCurl "$srcdir\Hl7.Fhir.Specification.Tests\TestData\careplan-example-integrated.xml" "$server/careplan-example-integrated.xml"
PowerCurl "$srcdir\Hl7.Fhir.Specification.Tests\TestData\profiles-types.json" "$server/profiles-types.json"


# extract schemas and xsd from fhir-all.zip -> data
ExtractXsdZipFile "$srcdir\Hl7.Fhir.Specification\data"
2 changes: 1 addition & 1 deletion common
10 changes: 5 additions & 5 deletions src/Hl7.Fhir.Core.Tests/ElementModel/PocoTypedElementTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,13 @@ public void PocoTypedElementPocoRoundtrip()
[TestMethod]
public void EmptyValueShouldNotThrowExceptions()
{
var appointment = new Appointment();
var patient = new Patient();

appointment.PriorityElement = new UnsignedInt(null);
appointment.PriorityElement.AddExtension("http://example.com/myExtension", new FhirBoolean(false));
var actual = appointment.ToTypedElement();
patient.ActiveElement = new FhirBoolean(null);
patient.ActiveElement.AddExtension("http://example.com/myExtension", new FhirBoolean(false));
var actual = patient.ToTypedElement();

var prio = actual.Scalar("priority");
var prio = actual.Scalar("active");
Assert.IsNull(prio);
}

Expand Down
4 changes: 2 additions & 2 deletions src/Hl7.Fhir.Core.Tests/Model/ModelTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -698,8 +698,8 @@ public void TestTypeHierarchy()
[TestMethod]
public void TestCheckMinorVersionCompatibiliy()
{
Assert.IsTrue(ModelInfo.CheckMinorVersionCompatibility("4.5.0"));
Assert.IsTrue(ModelInfo.CheckMinorVersionCompatibility("4.5"));
Assert.IsTrue(ModelInfo.CheckMinorVersionCompatibility("4.6.0"));
Assert.IsTrue(ModelInfo.CheckMinorVersionCompatibility("4.6"));
Assert.IsFalse(ModelInfo.CheckMinorVersionCompatibility("4.0.1"));
Assert.IsFalse(ModelInfo.CheckMinorVersionCompatibility("4.0"));
Assert.IsFalse(ModelInfo.CheckMinorVersionCompatibility("4.0.0"));
Expand Down
2 changes: 1 addition & 1 deletion src/Hl7.Fhir.Core.Tests/Rest/ContentTypeTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public void GetResourceFormatFromContentType_handles_invalidcontenttype()
public void TestBuildingContentType()
{
var type = ContentType.BuildContentType(ResourceFormat.Json, ModelInfo.Version);
Assert.AreEqual("application/fhir+json; charset=utf-8; fhirVersion=4.5", type);
Assert.AreEqual("application/fhir+json; charset=utf-8; fhirVersion=4.6", type);
}
}
}
71 changes: 19 additions & 52 deletions src/Hl7.Fhir.Core.Tests/Rest/SearchParamsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,7 @@ public void FormatExceptionOnSingleDashSortParam()
{
var q = new SearchParams();
var formatException = AssertThrows<FormatException>(() => q.Add("_sort", "-"));
Assert.AreEqual("Invalid _sort: one of the values is just a single '-', an element name must be provided", formatException.Message);
Assert.AreEqual("Invalid _sort: one of the values is just a single '-', an element name must be provided", formatException.Message);
}


Expand Down Expand Up @@ -430,58 +430,25 @@ private TException AssertThrows<TException>(Action action) where TException : Ex
}

[TestMethod]
public void CheckManualFixesOfTemplateModelInfo()
[DataRow("DiagnosticReport", "encounter", ResourceType.EpisodeOfCare, "05bfc4f1d0a4568ca405e248c055a8a16d857ffb")]
[DataRow("RiskAssessment", "encounter", ResourceType.EpisodeOfCare, "3b071d478ff3cb744cb6668ac8512dc7362e6737")]
[DataRow("List", "encounter", ResourceType.EpisodeOfCare, "3b071d478ff3cb744cb6668ac8512dc7362e6737")]
[DataRow("VisionPrescription", "encounter", ResourceType.EpisodeOfCare, "3b071d478ff3cb744cb6668ac8512dc7362e6737")]
[DataRow("ServiceRequest", "encounter", ResourceType.EpisodeOfCare, "3b071d478ff3cb744cb6668ac8512dc7362e6737")]
[DataRow("Flag", "encounter", ResourceType.EpisodeOfCare, "3b071d478ff3cb744cb6668ac8512dc7362e6737")]
[DataRow("Observation", "encounter", ResourceType.EpisodeOfCare, "3b071d478ff3cb744cb6668ac8512dc7362e6737")]
[DataRow("NutritionOrder", "encounter", ResourceType.EpisodeOfCare, "3b071d478ff3cb744cb6668ac8512dc7362e6737")]
[DataRow("Composition", "encounter", ResourceType.EpisodeOfCare, "3b071d478ff3cb744cb6668ac8512dc7362e6737")]
[DataRow("DeviceRequest", "encounter", ResourceType.EpisodeOfCare, "3b071d478ff3cb744cb6668ac8512dc7362e6737")]
[DataRow("Procedure", "encounter", ResourceType.EpisodeOfCare, "3b071d478ff3cb744cb6668ac8512dc7362e6737")]
public void CheckManualFixesOfTemplateModelInfo(string resource, string spName, ResourceType targetResource, string commit)
{
//Manualy removed target of EpisodeOfCare from searchparameter DiagnosticReport.encounter
//Commit: 05bfc4f1d0a4568ca405e248c055a8a16d857ffb
var sp = ModelInfo.SearchParameters.Where(s => s.Resource == "DiagnosticReport" && s.Name == "encounter").FirstOrDefault();
Assert.IsNotNull(sp);
Assert.IsTrue(sp.Path.Contains("DiagnosticReport.encounter"));
Assert.IsFalse(sp.Target.Contains(ResourceType.EpisodeOfCare));

//Manualy removed this target from more occurances of the same searchparameter
//Commit: 3b071d478ff3cb744cb6668ac8512dc7362e6737


var sp3 = ModelInfo.SearchParameters.Where(s => s.Resource == "RiskAssessment" && s.Name == "encounter").FirstOrDefault();
Assert.IsNotNull(sp3);
Assert.IsFalse(sp3.Target.Contains(ResourceType.EpisodeOfCare));

var sp4 = ModelInfo.SearchParameters.Where(s => s.Resource == "List" && s.Name == "encounter").FirstOrDefault();
Assert.IsNotNull(sp4);
Assert.IsFalse(sp4.Target.Contains(ResourceType.EpisodeOfCare));

var sp5 = ModelInfo.SearchParameters.Where(s => s.Resource == "VisionPrescription" && s.Name == "encounter").FirstOrDefault();
Assert.IsNotNull(sp5);
Assert.IsFalse(sp5.Target.Contains(ResourceType.EpisodeOfCare));

var sp6 = ModelInfo.SearchParameters.Where(s => s.Resource == "ServiceRequest" && s.Name == "encounter").FirstOrDefault();
Assert.IsNotNull(sp6);
Assert.IsFalse(sp6.Target.Contains(ResourceType.EpisodeOfCare));

var sp7 = ModelInfo.SearchParameters.Where(s => s.Resource == "Flag" && s.Name == "encounter").FirstOrDefault();
Assert.IsNotNull(sp7);
Assert.IsFalse(sp7.Target.Contains(ResourceType.EpisodeOfCare));

var sp8 = ModelInfo.SearchParameters.Where(s => s.Resource == "Observation" && s.Name == "encounter").FirstOrDefault();
Assert.IsNotNull(sp8);
Assert.IsFalse(sp8.Target.Contains(ResourceType.EpisodeOfCare));

var sp9 = ModelInfo.SearchParameters.Where(s => s.Resource == "NutritionOrder" && s.Name == "encounter").FirstOrDefault();
Assert.IsNotNull(sp9);
Assert.IsFalse(sp9.Target.Contains(ResourceType.EpisodeOfCare));

var sp10 = ModelInfo.SearchParameters.Where(s => s.Resource == "Composition" && s.Name == "encounter").FirstOrDefault();
Assert.IsNotNull(sp10);
Assert.IsFalse(sp10.Target.Contains(ResourceType.EpisodeOfCare));

var sp11 = ModelInfo.SearchParameters.Where(s => s.Resource == "DeviceRequest" && s.Name == "encounter").FirstOrDefault();
Assert.IsNotNull(sp11);
Assert.IsFalse(sp11.Target.Contains(ResourceType.EpisodeOfCare));

var sp12 = ModelInfo.SearchParameters.Where(s => s.Resource == "Procedure" && s.Name == "encounter").FirstOrDefault();
Assert.IsNotNull(sp12);
Assert.IsFalse(sp12.Target.Contains(ResourceType.EpisodeOfCare));
var sp = ModelInfo.SearchParameters.Where(s => s.Resource == resource && s.Name == spName).FirstOrDefault();
if (sp is not null)
{
Assert.IsFalse(sp.Target.Contains(targetResource),
$"Manualy removed target {targetResource} from searchparameter {resource}.{spName}. Commit: {commit}");
}
}
}
}
25 changes: 10 additions & 15 deletions src/Hl7.Fhir.Core.Tests/Serialization/SummarySerializationTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,15 @@
* available at https://raw.githubusercontent.com/FirelyTeam/firely-net-sdk/master/LICENSE
*/

using Microsoft.VisualStudio.TestTools.UnitTesting;
using Hl7.Fhir.ElementModel;
using Hl7.Fhir.Model;
using Hl7.Fhir.Rest;
using Hl7.Fhir.Serialization;
using Hl7.Fhir.Utility;
using Hl7.Fhir.Introspection;
using Newtonsoft.Json.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using Hl7.Fhir.ElementModel;
using Hl7.Fhir.Rest;
using System.IO;
using System.Linq;

namespace Hl7.Fhir.Tests.Serialization
{
Expand Down Expand Up @@ -58,9 +53,9 @@ public void TestSummary()
q.Item.Add(new Questionnaire.ItemComponent()
{
LinkId = "linkid",
Text = "TEXT"
Text = new Markdown("TEXT")
});

Assert.IsNull(q.Meta, "Meta element has not been created.");
var qfull = FhirXmlSerializer.SerializeToString(q);
Assert.IsNull(q.Meta, "Meta element should not be introduced here.");
Expand Down Expand Up @@ -123,11 +118,11 @@ public void TestIncludeMandatory()
l.Id = "testId";
l.Language = "testLang";
var summaryElements = FhirXmlSerializer.SerializeToString(l, Fhir.Rest.SummaryType.Count);

Assert.IsFalse(summaryElements.Contains("<language"));
Assert.IsTrue(summaryElements.Contains("<type>"));
Assert.IsTrue(summaryElements.Contains("<id value=\"testId\""));

var customMaskingNode = new MaskingNode(new ScopedNode(l.ToTypedElement()), new MaskingNodeSettings
{
IncludeMandatory = true,
Expand Down Expand Up @@ -157,7 +152,7 @@ public void TestIncludeMandatory()
});

result = customMaskingNodeForBundle.ToXml(settings: new FhirXmlSerializationSettings());

Assert.IsTrue(result.Contains("<type value=\"collection\""));
Assert.IsFalse(result.Contains("<id value=\"bundle-id\""));
}
Expand All @@ -171,7 +166,7 @@ public void TestElements()
Photo = new List<Attachment>() { new Attachment() { ContentType = "text/plain" } }
};
var elements = new[] { "photo" };

var summaryElements = FhirXmlSerializer.SerializeToString(p, Fhir.Rest.SummaryType.False, elements: elements);
Assert.IsFalse(summaryElements.Contains("<birthDate"));
Assert.IsTrue(summaryElements.Contains("<photo"));
Expand Down
10 changes: 5 additions & 5 deletions src/Hl7.Fhir.Core.Tests/TestData/careplan-example-f201-renal.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?><CarePlan xmlns="http://hl7.org/fhir">
<id value="f201"/>
<text><status value="generated"/><div xmlns="http://www.w3.org/1999/xhtml"><p><b>Generated Narrative</b></p><p><b>id</b>: f201</p><p><b>status</b>: draft</p><p><b>intent</b>: proposal</p><p><b>subject</b>: <a>Roel. Generated Summary: id: f201; BSN: 123456789 (OFFICIAL), BSN: 123456789 (OFFICIAL); active; Roel(OFFICIAL); ph: +31612345678(MOBILE), ph: +31201234567(HOME); gender: male; birthDate: 1960-03-13; <span>Legally married</span>; </a></p><p><b>period</b>: 2013-03-11 --&gt; 2013-03-13</p><p><b>careTeam</b>: <a> </a></p><blockquote><p><b>id</b>: careteam</p><blockquote><p><b>participant</b></p><p><b>role</b>: <span>Review of care plan</span></p><p><b>member</b>: <a>Dokter Bronsig. Generated Summary: id: f201; UZI-nummer: 12345678901 (OFFICIAL); active; Dokter Bronsig(OFFICIAL); ph: +31715269111(WORK); gender: male; birthDate: 1956-12-24</a></p></blockquote><blockquote><p><b>participant</b></p><p><b>role</b>: <span>Carer</span></p><p><b>member</b>: <a>Nurse Carla Espinosa. Generated Summary: id: f204; UZI-nummer: 12345678904 (OFFICIAL); Carla Espinosa; ph: +31715262169(WORK); gender: female; birthDate: 1967-11-05</a></p></blockquote></blockquote><p><b>addresses</b>: </p><p><b>goal</b>: <a> </a></p><blockquote><p><b>id</b>: goal</p><p><b>lifecycleStatus</b>: completed</p><p><b>achievementStatus</b>: <span>Achieved</span></p><p><b>description</b>: <span>Re-established renal function with at least healthy nutrients.</span></p><p><b>subject</b>: <a>Roel. Generated Summary: id: f201; BSN: 123456789 (OFFICIAL), BSN: 123456789 (OFFICIAL); active; Roel(OFFICIAL); ph: +31612345678(MOBILE), ph: +31201234567(HOME); gender: male; birthDate: 1960-03-13; <span>Legally married</span>; </a></p></blockquote><blockquote><p><b>activity</b></p><h3>Details</h3><table><tr><td>-</td><td><b>Kind</b></td><td><b>Code</b></td><td><b>Status</b></td><td><b>DoNotPerform</b></td><td><b>Scheduled[x]</b></td><td><b>Product[x]</b></td><td><b>DailyAmount</b></td></tr><tr><td>*</td><td>NutritionOrder</td><td><span>Potassium supplementation</span></td><td>completed</td><td>false</td><td>daily</td><td><a>Potassium. Generated Summary: id: f203; id: 1234; <span>Chemical</span>; <span>Potassium</span></a></td><td>80 mmol</td></tr></table></blockquote><blockquote><p><b>activity</b></p><h3>Details</h3><table><tr><td>-</td><td><b>Kind</b></td><td><b>Code</b></td><td><b>Status</b></td><td><b>DoNotPerform</b></td></tr><tr><td>*</td><td>ServiceRequest</td><td><span>Echography of kidney</span></td><td>completed</td><td>false</td></tr></table></blockquote></div></text><contained>
<text><status value="generated"/><div xmlns="http://www.w3.org/1999/xhtml"><p><b>Generated Narrative</b></p><p><b>status</b>: draft</p><p><b>intent</b>: proposal</p><p><b>subject</b>: <a>Roel. Generated Summary: BSN: 123456789 (OFFICIAL), BSN: 123456789 (OFFICIAL); active; Roel(OFFICIAL); Phone: +31612345678, Phone: +31201234567; gender: male; birthDate: 1960-03-13; <span>Legally married</span>; </a></p><p><b>period</b>: 2013-03-11 --&gt; 2013-03-13</p><p><b>careTeam</b>: <a> </a></p><blockquote><blockquote><p><b>participant</b></p><p><b>role</b>: <span>Review of care plan</span></p><p><b>member</b>: <a>Dokter Bronsig. Generated Summary: UZI-nummer: 12345678901 (OFFICIAL); active; Dokter Bronsig(OFFICIAL); Phone: +31715269111; gender: male; birthDate: 1956-12-24</a></p></blockquote><blockquote><p><b>participant</b></p><p><b>role</b>: <span>Carer</span></p><p><b>member</b>: <a>Nurse Carla Espinosa. Generated Summary: UZI-nummer: 12345678904 (OFFICIAL); Carla Espinosa; Phone: +31715262169; gender: female; birthDate: 1967-11-05</a></p></blockquote></blockquote><h3>Addresses</h3><table><tr><td>-</td></tr><tr><td>*</td></tr></table><p><b>goal</b>: <a> </a></p><blockquote><p><b>lifecycleStatus</b>: completed</p><p><b>achievementStatus</b>: <span>Achieved</span></p><p><b>description</b>: <span>Re-established renal function with at least healthy nutrients.</span></p><p><b>subject</b>: <a>Roel. Generated Summary: BSN: 123456789 (OFFICIAL), BSN: 123456789 (OFFICIAL); active; Roel(OFFICIAL); Phone: +31612345678, Phone: +31201234567; gender: male; birthDate: 1960-03-13; <span>Legally married</span>; </a></p></blockquote><blockquote><p><b>activity</b></p><h3>PlannedActivityDetails</h3><table><tr><td>-</td><td><b>Kind</b></td><td><b>Code</b></td><td><b>Status</b></td><td><b>DoNotPerform</b></td><td><b>Scheduled[x]</b></td><td><b>Product[x]</b></td><td><b>DailyAmount</b></td></tr><tr><td>*</td><td>NutritionOrder</td><td><span>Potassium supplementation</span></td><td>completed</td><td>false</td><td>daily</td><td><a>Potassium. Generated Summary: id: 1234; <span>Chemical</span></a></td><td>80 mmol</td></tr></table></blockquote><blockquote><p><b>activity</b></p><h3>PlannedActivityDetails</h3><table><tr><td>-</td><td><b>Kind</b></td><td><b>Code</b></td><td><b>Status</b></td><td><b>DoNotPerform</b></td></tr><tr><td>*</td><td>ServiceRequest</td><td><span>Echography of kidney</span></td><td>completed</td><td>false</td></tr></table></blockquote></div></text><contained>
<CareTeam>
<id value="careteam"/>
<participant>
Expand Down Expand Up @@ -79,7 +79,7 @@
</goal>
<activity>
<!-- Potassium supplement -->
<detail>
<plannedActivityDetail>
<kind value="NutritionOrder"/>
<code>
<coding>
Expand All @@ -102,11 +102,11 @@
<system value="http://snomed.info/sct"/>
<code value="258718000"/>
</dailyAmount>
</detail>
</plannedActivityDetail>
</activity>
<activity>
<!-- Echo of the kidney -->
<detail>
<plannedActivityDetail>
<kind value="ServiceRequest"/>
<code>
<coding>
Expand All @@ -117,6 +117,6 @@
</code>
<status value="completed"/>
<doNotPerform value="false"/>
</detail>
</plannedActivityDetail>
</activity>
</CarePlan>
Binary file modified src/Hl7.Fhir.Core.Tests/TestData/examples-json.zip
Binary file not shown.
Binary file modified src/Hl7.Fhir.Core.Tests/TestData/examples.zip
Binary file not shown.
Loading