Skip to content

Commit 5d5d360

Browse files
authored
Merge pull request #2825 from FirelyTeam/bugfix/2792-excluding-parent-property-shouldn't-exclude-children
ValueSet expander: excluding a code, shouldn't remove its children
2 parents c150395 + ac0c22b commit 5d5d360

File tree

2 files changed

+129
-1
lines changed

2 files changed

+129
-1
lines changed

src/Hl7.Fhir.Shims.Base/Specification/Terminology/ValueSetExpander.cs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -322,8 +322,12 @@ public static ValueSet.ContainsComponent Add(this List<ValueSet.ContainsComponen
322322

323323
public static void Remove(this List<ValueSet.ContainsComponent> dest, string system, string code)
324324
{
325+
var children = dest.Where(c => c.System == system && c.Code == code).SelectMany(c => c.Contains).ToList();
325326
dest.RemoveAll(c => c.System == system && c.Code == code);
326327

328+
//add children back to the list, they do not necessarily need to be removed when the parent is removed.
329+
dest.AddRange(children);
330+
327331
// Look for this code in children too
328332
foreach (var component in dest)
329333
{
@@ -334,9 +338,15 @@ public static void Remove(this List<ValueSet.ContainsComponent> dest, string sys
334338

335339
public static void Remove(this List<ValueSet.ContainsComponent> dest, List<ValueSet.ContainsComponent> source)
336340
{
337-
//TODO: Pretty unclear what to do with child concepts in the source - they all need to be removed from dest?
338341
foreach (var sourceConcept in source)
342+
{
339343
dest.Remove(sourceConcept.System, sourceConcept.Code);
344+
345+
//check if there are children that need to be removed too.
346+
if (sourceConcept.Contains.Any())
347+
dest.Remove(sourceConcept.Contains);
348+
}
349+
340350
}
341351

342352
internal static ValueSet.ContainsComponent ToContainsComponent(this CodeSystem.ConceptDefinitionComponent source, CodeSystem system, ValueSetExpanderSettings settings)

src/Hl7.Fhir.Specification.Shared.Tests/Terminology/SharedExpansionTests.cs

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,5 +113,123 @@ public async Tasks.Task TestExpandingVsWithUnknownSystem()
113113
var job = async () => await expander.ExpandAsync(vs);
114114
await job.Should().ThrowAsync<ValueSetUnknownException>().WithMessage("The ValueSet expander cannot find codesystem 'http://www.unknown.org/', so the expansion cannot be completed.");
115115
}
116+
117+
[Fact]
118+
public async Tasks.Task TestExcludingOnlyParent()
119+
{
120+
var resolver = new InMemoryResourceResolver();
121+
var vs = new ValueSet
122+
{
123+
Compose = new()
124+
{
125+
Include = new List<ValueSet.ConceptSetComponent>
126+
{
127+
new()
128+
{
129+
System = "http://www.unknown.org/",
130+
Filter = new List<ValueSet.FilterComponent>
131+
{
132+
new()
133+
{
134+
Property = "concept",
135+
Op = FilterOperator.IsA,
136+
Value = "parent"
137+
}
138+
}
139+
}
140+
},
141+
Exclude = new List<ValueSet.ConceptSetComponent>
142+
{
143+
new()
144+
{
145+
System = "http://www.unknown.org/",
146+
Concept = new List<ValueSet.ConceptReferenceComponent>
147+
{
148+
new()
149+
{
150+
Code = "parent"
151+
}
152+
}
153+
}
154+
}
155+
}
156+
};
157+
158+
var cs = new CodeSystem
159+
{
160+
Url = "http://www.unknown.org/",
161+
Content = CodeSystemContentMode.Complete,
162+
Concept = new List<CodeSystem.ConceptDefinitionComponent>
163+
{
164+
new()
165+
{
166+
Code = "parent",
167+
Concept = new List<CodeSystem.ConceptDefinitionComponent>
168+
{
169+
new()
170+
{
171+
Code = "child1"
172+
},
173+
new()
174+
{
175+
Code = "child2"
176+
}
177+
}
178+
}
179+
}
180+
};
181+
182+
resolver.Add(cs, vs);
183+
184+
var expander = new ValueSetExpander(new ValueSetExpanderSettings { ValueSetSource = resolver });
185+
await expander.ExpandAsync(vs);
186+
vs.Expansion.Contains.Select(c => c.Code).Should().BeEquivalentTo(["child1", "child2"]);
187+
188+
189+
vs.Compose.Exclude = new List<ValueSet.ConceptSetComponent>
190+
{
191+
new()
192+
{
193+
System = "http://www.unknown.org/",
194+
Concept = new List<ValueSet.ConceptReferenceComponent>
195+
{
196+
new()
197+
{
198+
Code = "parent"
199+
},
200+
new()
201+
{
202+
Code = "child1"
203+
}
204+
}
205+
}
206+
};
207+
208+
resolver.Reload(cs, vs);
209+
await expander.ExpandAsync(vs);
210+
vs.Expansion.Contains.Select(c => c.Code).Should().BeEquivalentTo(["child2"]);
211+
212+
vs.Compose.Exclude = new List<ValueSet.ConceptSetComponent>
213+
{
214+
new()
215+
{
216+
System = "http://www.unknown.org/",
217+
Filter = new List<ValueSet.FilterComponent>
218+
{
219+
new()
220+
{
221+
Property = "concept",
222+
Op = FilterOperator.IsA,
223+
Value = "parent"
224+
}
225+
}
226+
}
227+
};
228+
229+
resolver.Reload(cs, vs);
230+
await expander.ExpandAsync(vs);
231+
vs.Expansion.Contains.Select(c => c.Code).Should().BeEmpty();
232+
233+
}
116234
}
117235
}

0 commit comments

Comments
 (0)