diff --git a/server/src/test/java/com/mirth/connect/model/converters/TestUtil.java b/server/src/test/java/com/mirth/connect/model/converters/TestUtil.java
index 405550a60f..49ce526840 100644
--- a/server/src/test/java/com/mirth/connect/model/converters/TestUtil.java
+++ b/server/src/test/java/com/mirth/connect/model/converters/TestUtil.java
@@ -52,4 +52,12 @@ public static String prettyPrintXml(String input) throws Exception {
public static String convertCRToCRLF(String input) {
return input.replaceAll("\r", "\r\n");
}
+
+ /**
+ * Collapses CRLF/CR/LF to LF and trims surrounding whitespace, so that expected values stored
+ * in CRLF fixture files compare equal to output whose line separator is platform-dependent.
+ */
+ public static String normalizeLineEndings(String input) {
+ return input.replaceAll("\r\n|\r|\n", "\n").trim();
+ }
}
diff --git a/server/src/test/java/com/mirth/connect/plugins/datatypes/hl7v2/ER7SerializerTest.java b/server/src/test/java/com/mirth/connect/plugins/datatypes/hl7v2/ER7SerializerTest.java
index a7319dca5a..45072bdc82 100644
--- a/server/src/test/java/com/mirth/connect/plugins/datatypes/hl7v2/ER7SerializerTest.java
+++ b/server/src/test/java/com/mirth/connect/plugins/datatypes/hl7v2/ER7SerializerTest.java
@@ -1,27 +1,95 @@
package com.mirth.connect.plugins.datatypes.hl7v2;
+import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
import java.io.File;
import org.apache.commons.io.FileUtils;
import org.junit.BeforeClass;
import org.junit.Test;
+import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import com.mirth.connect.donkey.model.message.MessageSerializerException;
import com.mirth.connect.model.datatype.SerializerProperties;
public class ER7SerializerTest {
+ private static final String XML_DECL = "";
+ private static final String MSH_ER7 = "MSH|^~\\&|A\r";
+ private static final String MSH_XML = "|^~\\&A";
+
private static ER7Serializer serializer;
-
+
@BeforeClass
public static void setupClass() throws Exception {
SerializerProperties serializerProperties = new SerializerProperties(new HL7v2SerializationProperties(), new HL7v2DeserializationProperties(), null);
serializer = new ER7Serializer(serializerProperties);
}
+ private static ER7Serializer serializerWith(boolean convertLineBreaks, String deserializationSegmentDelimiter) {
+ HL7v2SerializationProperties serializationProperties = new HL7v2SerializationProperties();
+ serializationProperties.setConvertLineBreaks(convertLineBreaks);
+
+ HL7v2DeserializationProperties deserializationProperties = new HL7v2DeserializationProperties();
+ deserializationProperties.setSegmentDelimiter(deserializationSegmentDelimiter);
+
+ return new ER7Serializer(new SerializerProperties(serializationProperties, deserializationProperties, null));
+ }
+
+ @Test
+ public void testTransformWithoutSerializingConvertsToOutboundDelimiter() throws Exception {
+ ER7Serializer inbound = serializerWith(true, "\\r");
+ ER7Serializer outbound = serializerWith(true, "\\n");
+
+ assertEquals("MSH|^~\\&|A\nPID|1", inbound.transformWithoutSerializing("MSH|^~\\&|A\rPID|1", outbound));
+ }
+
+ @Test
+ public void testTransformWithoutSerializingNormalizesMixedLineBreaks() throws Exception {
+ ER7Serializer sameEnds = serializerWith(true, "\\r");
+
+ assertEquals("MSH|^~\\&|A\rPID|1", sameEnds.transformWithoutSerializing("MSH|^~\\&|A\r\nPID|1", sameEnds));
+ }
+
+ @Test
+ public void testTransformWithoutSerializingStillConvertsWhenDelimitersMatch() throws Exception {
+ /*
+ * convertLineBreaks is on, so the message goes through conversion and is returned even
+ * though it is unchanged. Only the convertLineBreaks-off case short-circuits to null.
+ */
+ ER7Serializer sameEnds = serializerWith(true, "\\r");
+
+ assertEquals("MSH|^~\\&|A\rPID|1", sameEnds.transformWithoutSerializing("MSH|^~\\&|A\rPID|1", sameEnds));
+ }
+
+ @Test
+ public void testTransformWithoutSerializingReplacesDelimiterWhenLineBreakConversionIsOff() throws Exception {
+ /*
+ * The only test that reaches the StringUtils.replace branch at ER7Serializer.java:170.
+ * Every convertLineBreaks=true configuration short-circuits earlier: either the
+ * skipIntermediateDelimiter fast path at line 162, or (for the delimiters-match case)
+ * the convertLineBreaks(...) call at line 165 with transformed already true. Only
+ * convertLineBreaks=false skips that whole block and falls through to the delimiter
+ * comparison at line 169.
+ */
+ ER7Serializer inbound = serializerWith(false, "\\r");
+ ER7Serializer outbound = serializerWith(true, "\\n");
+
+ assertEquals("MSH|^~\\&|A\nPID|1", inbound.transformWithoutSerializing("MSH|^~\\&|A\rPID|1", outbound));
+ }
+
+ @Test
+ public void testTransformWithoutSerializingReturnsNullWhenNothingToDo() throws Exception {
+ ER7Serializer inbound = serializerWith(false, "\\r");
+ ER7Serializer outbound = serializerWith(true, "\\r");
+
+ assertNull(inbound.transformWithoutSerializing("MSH|^~\\&|A\rPID|1", outbound));
+ }
+
@Test
public void testFromXMLWithExternalDTD() throws Exception {
String xml = FileUtils.readFileToString(new File("tests/test-xxe-hl7-example.xml"), "UTF-8");
@@ -53,4 +121,86 @@ public void testValidFromXMLWithExternalDTD() throws Exception {
assertFalse(exceptionThrown);
}
+
+ @Test
+ public void testToXMLWithCustomEncodingCharacters() throws Exception {
+ String er7 = "MSH#@%\\$#App1#Fac1\rPID#1#Smith@John";
+
+ assertEquals(XML_DECL + "#@%\\$"
+ + "App1"
+ + "Fac1"
+ + "1"
+ + "SmithJohn",
+ serializer.toXML(er7));
+ }
+
+ @Test
+ public void testToXMLWithHeaderOnlyAndNoTrailingFieldSeparator() throws Exception {
+ // Covers ER7Reader's nextDelimiter == -1 branch: MSH-2 runs to end of message.
+ assertEquals(XML_DECL + "|^~\\&",
+ serializer.toXML("MSH|^~\\&"));
+ }
+
+ @Test
+ public void testToXMLAppliesMirth1544FixupToNonHeaderFirstSegment() throws Exception {
+ /*
+ * Characterization of ER7Reader's MIRTH-1544 fixup. The "^~&|" check is a positional
+ * substring test that does not require a header segment, so it also fires on a Z-segment,
+ * installing '&' as the subcomponent separator. Recorded as current behavior, not endorsed.
+ */
+ assertEquals(XML_DECL + ""
+ + ""
+ + ""
+ + "ab"
+ + "",
+ serializer.toXML("ZZZ|^~&|a&b"));
+ }
+
+ @Test
+ public void testToXMLRejectsMessageShorterThanSixCharacters() throws Exception {
+ try {
+ serializer.toXML("MSH");
+ fail("expected MessageSerializerException");
+ } catch (MessageSerializerException e) {
+ assertTrue(e.getCause() instanceof SAXException);
+ assertEquals("Unable to parse message. It is NULL or too short. MSH", e.getCause().getMessage());
+ }
+ }
+
+ @Test
+ public void testToXMLWithConsecutiveRepetitionSeparators() throws Exception {
+ assertEquals(XML_DECL + "" + MSH_XML + ""
+ + "a"
+ + ""
+ + "b"
+ + "",
+ serializer.toXML(MSH_ER7 + "PID|a~~b"));
+ }
+
+ @Test
+ public void testToXMLWithTrailingRepetitionSeparator() throws Exception {
+ assertEquals(XML_DECL + "" + MSH_XML + ""
+ + "a"
+ + ""
+ + "",
+ serializer.toXML(MSH_ER7 + "PID|a~"));
+ }
+
+ @Test
+ public void testToXMLWithTrailingEmptyFields() throws Exception {
+ assertEquals(XML_DECL + "" + MSH_XML + ""
+ + "a"
+ + ""
+ + ""
+ + "",
+ serializer.toXML(MSH_ER7 + "PID|a||"));
+ }
+
+ @Test
+ public void testToXMLSkipsEmptySegments() throws Exception {
+ // StringUtils.split drops empty tokens, so a blank line between segments simply vanishes.
+ assertEquals(XML_DECL + "" + MSH_XML
+ + "1",
+ serializer.toXML("MSH|^~\\&|A\r\rPID|1"));
+ }
}
diff --git a/server/src/test/java/com/mirth/connect/plugins/datatypes/hl7v2/HL7SerializerTests.java b/server/src/test/java/com/mirth/connect/plugins/datatypes/hl7v2/HL7SerializerTest.java
similarity index 74%
rename from server/src/test/java/com/mirth/connect/plugins/datatypes/hl7v2/HL7SerializerTests.java
rename to server/src/test/java/com/mirth/connect/plugins/datatypes/hl7v2/HL7SerializerTest.java
index aae28422bb..2d3340472e 100644
--- a/server/src/test/java/com/mirth/connect/plugins/datatypes/hl7v2/HL7SerializerTests.java
+++ b/server/src/test/java/com/mirth/connect/plugins/datatypes/hl7v2/HL7SerializerTest.java
@@ -11,27 +11,19 @@
import java.io.File;
-import junit.framework.Assert;
-
import org.apache.commons.io.FileUtils;
+import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import com.mirth.connect.model.converters.TestUtil;
-public class HL7SerializerTests {
+public class HL7SerializerTest {
private HL7v2DataTypeProperties defaultProperties;
@Before
public void setUp() throws Exception {
defaultProperties = new HL7v2DataTypeProperties();
-
-// defaultProperties = new Properties();
-// defaultProperties.put("useStrictParser", "false");
-// defaultProperties.put("handleRepetitions", "false");
-// defaultProperties.put("handleSubcomponents", "false");
-// defaultProperties.put("inputSegmentDelimiter", "\\r\\n|\\r|\\n");
-// defaultProperties.put("outputSegmentDelimiter", "\\r");
}
@Test
@@ -39,7 +31,7 @@ public void testToXmlDefault() throws Exception {
String input = FileUtils.readFileToString(new File("tests/test-hl7-input.txt"));
String output = FileUtils.readFileToString(new File("tests/test-hl7-output.xml"));
ER7Serializer serializer = new ER7Serializer(defaultProperties.getSerializerProperties());
- Assert.assertEquals(output, TestUtil.prettyPrintXml(serializer.toXML(input)));
+ Assert.assertEquals(TestUtil.normalizeLineEndings(output), TestUtil.normalizeLineEndings(TestUtil.prettyPrintXml(serializer.toXML(input))));
}
@Test
@@ -55,7 +47,7 @@ public void testToXmlWhitepsace() throws Exception {
String input = FileUtils.readFileToString(new File("tests/test-hl7-whitespace-input.txt"));
String output = FileUtils.readFileToString(new File("tests/test-hl7-whitespace-output.xml"));
ER7Serializer serializer = new ER7Serializer(defaultProperties.getSerializerProperties());
- Assert.assertEquals(output, TestUtil.prettyPrintXml(serializer.toXML(input)));
+ Assert.assertEquals(TestUtil.normalizeLineEndings(output), TestUtil.normalizeLineEndings(TestUtil.prettyPrintXml(serializer.toXML(input))));
}
@Test
@@ -98,11 +90,6 @@ public void testFromXmlMissingSubcomponents() throws Exception {
@Test
public void testFromXmlSingleSegment() throws Exception {
HL7v2DataTypeProperties properties = new HL7v2DataTypeProperties();
-// properties.put("useStrictParser", "false");
-// properties.put("handleRepetitions", "false");
-// properties.put("handleSubcomponents", "true");
-// properties.put("inputSegmentDelimiter", "\\r\\n|\\r|\\n");
-// properties.put("outputSegmentDelimiter", "\\r");
String input = FileUtils.readFileToString(new File("tests/test-hl7-single-segment-input.xml"));
String output = FileUtils.readFileToString(new File("tests/test-hl7-single-segment-output.txt"));
@@ -121,28 +108,16 @@ public void testFromXmlSingleField() throws Exception {
@Test
public void testToXmlWithSubcomponents() throws Exception {
HL7v2DataTypeProperties properties = new HL7v2DataTypeProperties();
-// Properties properties = new Properties();
-// properties.put("useStrictParser", "false");
-// properties.put("handleRepetitions", "false");
-// properties.put("handleSubcomponents", "true");
-// properties.put("inputSegmentDelimiter", "\\r\\n|\\r|\\n");
-// properties.put("outputSegmentDelimiter", "\\r");
String input = FileUtils.readFileToString(new File("tests/test-hl7-subcomponents-input.txt"));
String output = FileUtils.readFileToString(new File("tests/test-hl7-subcomponents-output.xml"));
ER7Serializer serializer = new ER7Serializer(properties.getSerializerProperties());
- Assert.assertEquals(output, TestUtil.prettyPrintXml(serializer.toXML(input)));
+ Assert.assertEquals(TestUtil.normalizeLineEndings(output), TestUtil.normalizeLineEndings(TestUtil.prettyPrintXml(serializer.toXML(input))));
}
@Test
public void testFromXmlWithSubcomponents() throws Exception {
HL7v2DataTypeProperties properties = new HL7v2DataTypeProperties();
-// Properties properties = new Properties();
-// properties.put("useStrictParser", "false");
-// properties.put("handleRepetitions", "false");
-// properties.put("handleSubcomponents", "true");
-// properties.put("inputSegmentDelimiter", "\\r\\n|\\r|\\n");
-// properties.put("outputSegmentDelimiter", "\\r");
String input = FileUtils.readFileToString(new File("tests/test-hl7-subcomponents-output.xml"));
String output = FileUtils.readFileToString(new File("tests/test-hl7-subcomponents-input.txt"));
@@ -153,28 +128,16 @@ public void testFromXmlWithSubcomponents() throws Exception {
@Test
public void testToXmlWithRepetitions() throws Exception {
HL7v2DataTypeProperties properties = new HL7v2DataTypeProperties();
-// Properties properties = new Properties();
-// properties.put("useStrictParser", "false");
-// properties.put("handleRepetitions", "true");
-// properties.put("handleSubcomponents", "false");
-// properties.put("inputSegmentDelimiter", "\\r\\n|\\r|\\n");
-// properties.put("outputSegmentDelimiter", "\\r");
String input = FileUtils.readFileToString(new File("tests/test-hl7-repetitions-input.txt"));
String output = FileUtils.readFileToString(new File("tests/test-hl7-repetitions-output.xml"));
ER7Serializer serializer = new ER7Serializer(properties.getSerializerProperties());
- Assert.assertEquals(output, TestUtil.prettyPrintXml(serializer.toXML(input)));
+ Assert.assertEquals(TestUtil.normalizeLineEndings(output), TestUtil.normalizeLineEndings(TestUtil.prettyPrintXml(serializer.toXML(input))));
}
@Test
public void testFromXmlWithRepetitions() throws Exception {
HL7v2DataTypeProperties properties = new HL7v2DataTypeProperties();
-// Properties properties = new Properties();
-// properties.put("useStrictParser", "false");
-// properties.put("handleRepetitions", "true");
-// properties.put("handleSubcomponents", "false");
-// properties.put("inputSegmentDelimiter", "\\r\\n|\\r|\\n");
-// properties.put("outputSegmentDelimiter", "\\r");
String input = FileUtils.readFileToString(new File("tests/test-hl7-repetitions-output.xml"));
String output = FileUtils.readFileToString(new File("tests/test-hl7-repetitions-input.txt"));
@@ -187,7 +150,7 @@ public void testToXmlWithBatch() throws Exception {
String input = FileUtils.readFileToString(new File("tests/test-hl7-batch-input.txt"));
String output = FileUtils.readFileToString(new File("tests/test-hl7-batch-output.xml"));
ER7Serializer serializer = new ER7Serializer(defaultProperties.getSerializerProperties());
- Assert.assertEquals(output, TestUtil.prettyPrintXml(serializer.toXML(input)));
+ Assert.assertEquals(TestUtil.normalizeLineEndings(output), TestUtil.normalizeLineEndings(TestUtil.prettyPrintXml(serializer.toXML(input))));
}
@Test
@@ -197,4 +160,19 @@ public void testFromXmlWithBatch() throws Exception {
ER7Serializer serializer = new ER7Serializer(defaultProperties.getSerializerProperties());
Assert.assertEquals(output, TestUtil.convertCRToCRLF(serializer.fromXML(input)));
}
+
+ @Test
+ public void testRoundTripAllEr7Fixtures() throws Exception {
+ String[] fixtures = { "tests/test-hl7-input.txt", "tests/test-hl7-whitespace-input.txt",
+ "tests/test-hl7-subcomponents-input.txt", "tests/test-hl7-repetitions-input.txt",
+ "tests/test-hl7-batch-input.txt" };
+
+ ER7Serializer serializer = new ER7Serializer(defaultProperties.getSerializerProperties());
+
+ for (String fixture : fixtures) {
+ String er7 = FileUtils.readFileToString(new File(fixture));
+
+ Assert.assertEquals(fixture, TestUtil.normalizeLineEndings(er7), TestUtil.normalizeLineEndings(serializer.fromXML(serializer.toXML(er7))));
+ }
+ }
}
diff --git a/server/tests/test-hl7-batch-output.xml b/server/tests/test-hl7-batch-output.xml
index f42adc8565..bd1535a037 100644
--- a/server/tests/test-hl7-batch-output.xml
+++ b/server/tests/test-hl7-batch-output.xml
@@ -236,7 +236,10 @@
MRS
Shephard
- Jane MRI W/&W/O CONTRAST
+
+ Jane MRI W/
+ W/O CONTRAST
+
70553
diff --git a/server/tests/test-hl7-output.xml b/server/tests/test-hl7-output.xml
index 4628e91f72..f8e5fc4dda 100644
--- a/server/tests/test-hl7-output.xml
+++ b/server/tests/test-hl7-output.xml
@@ -218,7 +218,10 @@
MRS
Shephard
- Jane MRI W/&W/O CONTRAST
+
+ Jane MRI W/
+ W/O CONTRAST
+
70553