Fix #276 - Prevent contained resources being encoded as duplicates

This commit is contained in:
James Agnew 2016-11-25 17:18:57 -05:00
parent 69871bb8c2
commit 81773de261
4 changed files with 100 additions and 69 deletions

View File

@ -244,6 +244,9 @@ public abstract class BaseParser implements IParser {
continue;
}
theContained.addContained(resource);
if (resource.getIdElement().isLocal() && existingIdToContainedResource != null) {
existingIdToContainedResource.remove(resource.getIdElement().getValue());
}
} else {
continue;
}

View File

@ -11,14 +11,10 @@ import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.StringReader;
import java.io.*;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.nio.charset.StandardCharsets;
import java.util.*;
import org.apache.commons.io.IOUtils;
import org.hamcrest.core.IsNot;
@ -84,7 +80,7 @@ public class JsonParserTest {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(JsonParserTest.class);
private void parseAndEncode(String name) throws IOException {
String msg = IOUtils.toString(XmlParser.class.getResourceAsStream(name));
String msg = IOUtils.toString(XmlParser.class.getResourceAsStream(name), StandardCharsets.UTF_8);
// ourLog.info(msg);
msg = msg.replace("\"div\": \"<div>", "\"div\":\"<div xmlns=\\\"http://www.w3.org/1999/xhtml\\\">");
@ -107,6 +103,7 @@ public class JsonParserTest {
assertEquals(exp, act);
}
@Test
public void testDecimalPrecisionPreserved() {
String number = "52.3779939997090374535378485873776474764643249869328698436986235758587";

View File

@ -1,5 +1,6 @@
package ca.uhn.fhir.parser;
import static org.apache.commons.lang3.StringUtils.countMatches;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.empty;
@ -17,7 +18,9 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.util.*;
@ -36,6 +39,7 @@ import org.hl7.fhir.dstu3.model.Enumeration;
import org.hl7.fhir.dstu3.model.Enumerations.AdministrativeGender;
import org.hl7.fhir.dstu3.model.Identifier.IdentifierUse;
import org.hl7.fhir.dstu3.model.Observation.ObservationStatus;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
import org.junit.*;
import org.mockito.ArgumentCaptor;
@ -66,6 +70,32 @@ public class JsonParserDstu3Test {
ourCtx.setNarrativeGenerator(null);
}
/**
* See #276
*/
@Test
public void testDoubleEncodingContainedResources() throws Exception {
Patient patient = new Patient();
patient.setId("#patient-1");
patient.setActive(true);
Coverage coverage = new Coverage();
coverage.setId("#coverage-1");
coverage.getBeneficiary().setResource(patient);
Claim resource = new Claim();
resource.getContained().add(patient);
resource.getContained().add(coverage);
resource.getPatient().setReference("#patient-1");
resource.addCoverage().getCoverage().setReference("#coverage-1");
IParser p = ourCtx.newJsonParser().setPrettyPrint(true);
String encoded = p.encodeResourceToString(resource);
ourLog.info(encoded);
assertEquals(3, countMatches(encoded, "resourceType"));
}
/**
* #480
*/
@ -124,17 +154,16 @@ public class JsonParserDstu3Test {
ArgumentCaptor<String> elementName = ArgumentCaptor.forClass(String.class);
ArgumentCaptor<ValueType> expected = ArgumentCaptor.forClass(ValueType.class);
ArgumentCaptor<ValueType> actual = ArgumentCaptor.forClass(ValueType.class);
verify(errorHandler, atLeastOnce()).incorrectJsonType(Mockito.any(IParseLocation.class),elementName.capture(), expected.capture(), actual.capture());
verify(errorHandler, atLeastOnce()).incorrectJsonType(Mockito.any(IParseLocation.class),Mockito.eq("_id"), Mockito.eq(ValueType.OBJECT), Mockito.eq(ValueType.SCALAR));
verify(errorHandler, atLeastOnce()).incorrectJsonType(Mockito.any(IParseLocation.class),Mockito.eq("__v"), Mockito.eq(ValueType.OBJECT), Mockito.eq(ValueType.SCALAR));
verify(errorHandler, atLeastOnce()).incorrectJsonType(Mockito.any(IParseLocation.class),Mockito.eq("_status"), Mockito.eq(ValueType.OBJECT), Mockito.eq(ValueType.SCALAR));
verify(errorHandler, atLeastOnce()).incorrectJsonType(Mockito.any(IParseLocation.class), elementName.capture(), expected.capture(), actual.capture());
verify(errorHandler, atLeastOnce()).incorrectJsonType(Mockito.any(IParseLocation.class), Mockito.eq("_id"), Mockito.eq(ValueType.OBJECT), Mockito.eq(ValueType.SCALAR));
verify(errorHandler, atLeastOnce()).incorrectJsonType(Mockito.any(IParseLocation.class), Mockito.eq("__v"), Mockito.eq(ValueType.OBJECT), Mockito.eq(ValueType.SCALAR));
verify(errorHandler, atLeastOnce()).incorrectJsonType(Mockito.any(IParseLocation.class), Mockito.eq("_status"), Mockito.eq(ValueType.OBJECT), Mockito.eq(ValueType.SCALAR));
assertEquals("_id", elementName.getAllValues().get(0));
assertEquals(ValueType.OBJECT, expected.getAllValues().get(0));
assertEquals(ValueType.SCALAR, actual.getAllValues().get(0));
}
@Test
public void testEncodeAndParseExtensions() throws Exception {
@ -221,7 +250,6 @@ public class JsonParserDstu3Test {
}
@Test
public void testEncodeAndParseMetaProfileAndTags() {
Patient p = new Patient();
@ -300,7 +328,6 @@ public class JsonParserDstu3Test {
assertEquals("sec_label2", tagList.get(1).getDisplay());
}
/**
* See #336
*/
@ -355,7 +382,6 @@ public class JsonParserDstu3Test {
}
@Test
public void testEncodeAndParseSecurityLabels() {
Patient p = new Patient();
@ -434,8 +460,6 @@ public class JsonParserDstu3Test {
}
/**
* See #326
*/
@ -504,7 +528,6 @@ public class JsonParserDstu3Test {
assertThat(encoded, not(containsString("tag")));
}
/**
* #158
*/
@ -750,12 +773,12 @@ public class JsonParserDstu3Test {
ourLog.info(enc);
assertThat(enc, containsString("\"reference\": \"http://foo.com/Organization/2\""));
parser.setDontStripVersionsFromReferencesAtPaths((String[])null);
parser.setDontStripVersionsFromReferencesAtPaths((String[]) null);
enc = parser.setPrettyPrint(true).encodeResourceToString(auditEvent);
ourLog.info(enc);
assertThat(enc, containsString("\"reference\": \"http://foo.com/Organization/2\""));
parser.setDontStripVersionsFromReferencesAtPaths((List<String>)null);
parser.setDontStripVersionsFromReferencesAtPaths((List<String>) null);
enc = parser.setPrettyPrint(true).encodeResourceToString(auditEvent);
ourLog.info(enc);
assertThat(enc, containsString("\"reference\": \"http://foo.com/Organization/2\""));
@ -1752,7 +1775,6 @@ public class JsonParserDstu3Test {
assertEquals(1, rp.getName().size());
assertEquals("Doe", rp.getName().get(0).getFamilyAsSingleString());
}
/**

View File

@ -46,6 +46,15 @@
or log a warning depending on the configured
error handler.
</action>
<action type="fix" issue="276">
Fix issue when serializing resources that have
contained resources which are referred to
from multiple places. Sometimes when serializing
these resources the contained resource section
would contain duplicates. Thanks to Hugo Soares
and Stefan Evinance for reporting and providing
a test case!
</action>
</release>
<release version="2.1" date="2016-11-11">
<action type="add">