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
5 changes: 4 additions & 1 deletion src/Firely.Fhir.Validation/Impl/ResourceSchema.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,10 @@ internal override ElementSchema WithMembers(IEnumerable<IAssertion> members)
/// </summary>
internal static Canonical[] GetMetaProfileSchemas(PocoNode instance, ValidationSettings vc, ValidationState state)
{
var profiles = instance.NavigateTo("meta.profile").Select(pn => new Canonical((string)pn.GetValue()!)).ToArray();
// An entry can lack a value (e.g. when it only carries an extension), and a lenient parse keeps a non-string
// JSON value as is. Neither names a profile, so both are skipped.
var profiles = instance.NavigateTo("meta.profile").Select(pn => pn.GetValue()).OfType<string>()
.Select(profile => new Canonical(profile)).ToArray();

return callback(vc.SelectValidationProfiles).Invoke(instance.GetLocation(), profiles, instance, vc);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,23 @@ public void DoesValidateBasedOnActualType()
result.Evidence.Should().ContainSingle(ass => ass is IssueAssertion && ((IssueAssertion)ass).IssueNumber == Issue.CONTENT_ELEMENT_CHOICE_INVALID_INSTANCE_TYPE.Code);
}

[Fact]
public void ValidatesMetaProfileWithoutValue()
{
// A meta.profile entry may carry just an extension, and then names no profile to validate against.
#if STU3
// STU3's data-absent-reason has the context datatype '*', which the validator does not accept yet.
var extension = "{\"url\":\"http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor\",\"valueCode\":\"UNK\"}";
#else
var extension = "{\"url\":\"http://hl7.org/fhir/StructureDefinition/data-absent-reason\",\"valueCode\":\"unknown\"}";
#endif
var json = "{\"resourceType\":\"Patient\",\"meta\":{\"_profile\":[{\"extension\":[" + extension + "]}]}}";
var p = new FhirJsonDeserializer().DeserializeResource(json);
var schema = _fixture.SchemaResolver.GetSchema(Canonical.ForCoreType("Resource"))!;
var result = schema.Validate(p.ToPocoNode(), _fixture.NewValidationSettings());
result.IsSuccessful.Should().BeTrue();
}

private Meta setMetaForVersion(string uri)
{
#if STU3
Expand Down
13 changes: 13 additions & 0 deletions test/Firely.Fhir.Validation.Tests/Impl/ResourceSchemaTests.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using FluentAssertions;
using Hl7.Fhir.ElementModel;
using Hl7.Fhir.Model;
using Hl7.Fhir.Serialization;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Linq;
Expand Down Expand Up @@ -36,6 +37,18 @@ static Canonical[] callback(string location, Canonical[] orignalMetaProfiles, Po
static Canonical[] declineAll(string location, Canonical[] orignalMetaProfiles, PocoNode input, ValidationSettings vc) => [];
}

[DataTestMethod]
[DataRow("{\"resourceType\":\"Patient\",\"meta\":{\"profile\":[\"profile1\",null],\"_profile\":[null,{\"extension\":[{\"url\":\"http://example.org/ext\",\"valueString\":\"x\"}]}]}}")]
[DataRow("{\"resourceType\":\"Patient\",\"meta\":{\"profile\":[\"profile1\",5]}}")]
public void MetaProfileWithoutStringValueIsSkipped(string json)
{
var instance = new FhirJsonDeserializer(new DeserializerSettings().UsingMode(DeserializationMode.SyntaxOnly)).DeserializeResource(json).ToPocoNode();

var result = ResourceSchema.GetMetaProfileSchemas(instance, new ValidationSettings(), new ValidationState());

result.Should().BeEquivalentTo(new Canonical[] { "profile1" });
}

[TestMethod]
public void GetImposedProfilesTest()
{
Expand Down
Loading