package com.berryworks.edireader;
import com.berryworks.edireader.error.*;
import com.berryworks.edireader.util.sax.EDIReaderSAXAdapter;
import org.junit.Before;
import org.junit.Test;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import javax.xml.transform.TransformerException;
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import static com.berryworks.edireader.util.Conversion.ediToxml;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
public class AnsiReaderTest {
private static final String EDI_SAMPLE =
"ISA*00* *00* *ZZ*D00111 *ZZ*0055 *030603*1337*U*00401*000000121*0*T*:^\n" +
"GS*HP*D00111*0055*20030603*1337*1210001*X*004010X091A1^\n" +
"ST*870*0000001^\n" +
"BSR*4*PA*SUPPLIER CONFIRMATION NUMBER*CCYYMMDD^\n" +
"REF*MR*12345^\n" +
"SE*4*0000001^\n" +
"GE*1*1210001^\n" +
"IEA*1*000000121^\n";
private static final String EDI_TA1_SAMPLE =
"ISA*00* *00* *ZZ*D00111 *ZZ*0055 *030603*1337*U*00401*000000121*0*T*:$\n" +
"TA1*1*2*3*R*abc$\n" +
"GS*HP*D00111*0055*20030603*1337*1210001*X*004010X091A1$\n" +
"ST*870*0000001$\n" +
"BSR*4*PA*SUPPLIER CONFIRMATION NUMBER*CCYYMMDD$\n" +
"REF*MR*12345$\n" +
"SE*4*0000001$\n" +
"GE*1*1210001$\n" +
"IEA*1*000000121$\n";
private static final String EDI_BIN_SAMPLE =
"ISA*00* *00* *ZZ*D00111 *ZZ*0055 *030603*1337*U*00401*000000121*0*T*:^\n" +
"GS*HP*D00111*0055*20030603*1337*1210001*X*004010X091A1^\n" +
"ST*870*0000001^\n" +
"BSR*4*PA*SUPPLIER CONFIRMATION NUMBER*CCYYMMDD^\n" +
"BIN*10*1234567890^\n" +
"SE*4*0000001^\n" +
"GE*1*1210001^\n" +
"IEA*1*000000121^\n";
private AnsiReader ansiReader;
private CountingHandler countingHandler;
@Before
public void setUp() {
ansiReader = new AnsiReader();
countingHandler = new CountingHandler();
ansiReader.setContentHandler(countingHandler);
}
@Test
public void canParseSmallSample() throws IOException, SAXException {
ansiReader.parse(new InputSource(new StringReader(EDI_SAMPLE)));
assertEquals(286, ansiReader.getCharCount());
assertEquals(1, ansiReader.getGroupCount());
assertEquals('*', ansiReader.getDelimiter());
assertEquals(':', ansiReader.getSubDelimiter());
assertEquals('^', ansiReader.getTerminator());
assertEquals("\n", ansiReader.getTerminatorSuffix());
assertEquals(16, countingHandler.getElementCount());
assertEquals(2, countingHandler.getSegmentCountWithoutSTandSE());
}
@Test
public void canParseTA1() throws IOException, SAXException {
ansiReader.parse(new InputSource(new StringReader(EDI_TA1_SAMPLE)));
assertEquals(303, ansiReader.getCharCount());
assertEquals(1, ansiReader.getGroupCount());
assertEquals('*', ansiReader.getDelimiter());
assertEquals(':', ansiReader.getSubDelimiter());
assertEquals('$', ansiReader.getTerminator());
assertEquals("\n", ansiReader.getTerminatorSuffix());
assertEquals(17, countingHandler.getElementCount());
assertEquals(2, countingHandler.getSegmentCountWithoutSTandSE());
}
@Test
public void canParseBIN() throws IOException, SAXException {
ansiReader.parse(new InputSource(new StringReader(EDI_BIN_SAMPLE)));
assertEquals(291, ansiReader.getCharCount());
assertEquals(14, countingHandler.getElementCount());
assertEquals(2, countingHandler.getSegmentCountWithoutSTandSE());
}
@Test
public void detectsGroupCountError() throws IOException, SAXException {
String ediText = EDI_SAMPLE.replace("IEA*1*", "IEA*44*");
try {
ansiReader.parse(new InputSource(new StringReader(ediText)));
fail("Functional group count error not detected");
} catch (GroupCountException e) {
assertEquals("Functional group count error in IEA segment. Expected 1 instead of 44 at segment 8, field 2", e.getMessage());
}
}
@Test
public void detectsInterchangeControlNumberError() throws IOException, SAXException {
String ediText = EDI_SAMPLE.replace("IEA*1*000000121", "IEA*1*000000921");
try {
ansiReader.parse(new InputSource(new StringReader(ediText)));
fail("Interchange control number error not detected");
} catch (InterchangeControlNumberException e) {
assertEquals(
"Control number error in IEA segment. Expected 000000121 instead of 000000921 at segment 8, field 3",
e.getMessage());
}
}
@Test
public void detectsTransactionCountError() throws IOException, SAXException {
String ediText = EDI_SAMPLE.replace("GE*1*", "GE*44*");
try {
ansiReader.parse(new InputSource(new StringReader(ediText)));
fail("Transaction count error not detected");
} catch (TransactionCountException e) {
assertEquals("Transaction count error in GE segment. Expected 1 instead of 44 at segment 7, field 2", e.getMessage());
}
}
@Test
public void detectsGroupControlNumberError() throws IOException, SAXException {
String ediText = EDI_SAMPLE.replace("GE*1*1210001^", "GE*1*9210001^");
try {
ansiReader.parse(new InputSource(new StringReader(ediText)));
fail("Group control number error not detected");
} catch (GroupControlNumberException e) {
assertEquals(
"Control number error in GE segment. Expected 1210001 instead of 9210001 at segment 7, field 3",
e.getMessage());
}
}
@Test
public void detectsSegmentCountError() throws IOException, SAXException {
String ediText = EDI_SAMPLE.replace("SE*4*", "SE*44*");
try {
ansiReader.parse(new InputSource(new StringReader(ediText)));
fail("Segment count error not detected");
} catch (SegmentCountException e) {
assertEquals("Segment count error in SE segment. Expected 4 instead of 44 at segment 6, field 2", e.getMessage());
}
}
@Test
public void detectsTransactionControlNumberError() throws IOException, SAXException {
String ediText = EDI_SAMPLE.replace("SE*4*0000001", "SE*4*1111111");
try {
ansiReader.parse(new InputSource(new StringReader(ediText)));
fail("Transaction control number error not detected");
} catch (TransactionControlNumberException e) {
assertEquals(
"Control number error in SE segment. Expected 0000001 instead of 1111111 at segment 6, field 3",
e.getMessage());
}
}
@Test
public void detectsISAFixedLengthError() throws IOException {
String ediText = EDI_SAMPLE.replace("ISA*00*", "ISA*0000*");
try {
ansiReader.parse(new InputSource(new StringReader(ediText)));
fail("ISA fiexed length field error not detected");
} catch (SAXException e) {
assertEquals(
"Incorrect length of fixed-length ISA field. Expected 2 instead of 4 at segment 1, field 2",
e.getMessage());
}
}
@Test
public void detectsGSMandatoryFieldError() throws IOException {
String ediText = EDI_SAMPLE.replace("*1337*1", "**1");
try {
ansiReader.parse(new InputSource(new StringReader(ediText)));
fail("GS mandatory field error not detected");
} catch (SAXException e) {
assertEquals(
"Mandatory element missing. Expected at least one non-space character instead of (empty) at segment 2, field 6",
e.getMessage());
}
}
@Test
public void detectsBiNSegmentLengthError() throws IOException {
String ediText = EDI_BIN_SAMPLE.replace("BIN*10", "BIN*");
try {
ansiReader.parse(new InputSource(new StringReader(ediText)));
fail("BIN length error not detected");
} catch (SAXException e) {
assertEquals(
"BIN segment missing mandatory length field at segment 5, field 2",
e.getMessage());
}
}
@Test
public void detectsBiNSegmentLengthNumericError() throws IOException {
String ediText = EDI_BIN_SAMPLE.replace("BIN*10", "BIN*xx");
try {
ansiReader.parse(new InputSource(new StringReader(ediText)));
fail("BIN numeric length error not detected");
} catch (SAXException e) {
assertEquals(
"BIN object length must be numeric instead of xx at segment 5, field 2",
e.getMessage());
}
}
@Test
public void detectsMissingSEError() throws IOException {
String ediText = EDI_SAMPLE.replace("SE*4*0000001", "SEE*4*0000001");
try {
ansiReader.parse(new InputSource(new StringReader(ediText)));
fail("Missing SE error not detected");
} catch (SAXException e) {
assertEquals(
"Transaction must be terminated with an SE segment at segment 7, field 1",
e.getMessage());
}
}
@Test
public void detectsMissingGEError() throws IOException {
String ediText = EDI_SAMPLE.replace("GE*1*1210001", "xGE*1*1210001");
try {
ansiReader.parse(new InputSource(new StringReader(ediText)));
fail("Missing GE error not detected");
} catch (SAXException e) {
assertEquals(
"Unexpected segment type in this context. Expected GE or ST instead of xGE at segment 7, field 1",
e.getMessage());
}
}
@Test
public void detectsInvalidSegmentStartError() throws IOException {
String ediText = EDI_SAMPLE.replace("GS*HP*", "*HP*");
try {
ansiReader.parse(new InputSource(new StringReader(ediText)));
fail("Invalid segment start not detected");
} catch (SAXException e) {
assertEquals(
"Invalid beginning of segment at segment 1",
e.getMessage());
}
}
@Test
public void detectsSegmentTerminatorProblem() throws IOException {
// ISA*00* *00* *ZZ*D00111 *ZZ*0055 *030603*1337*U*00401*000000121*0*T*:$
String ediText = "ISA*00* *00* *ZZ*ENS_EDI *ZZ*UB920128 *161208*1130*^*00501*014684581*1*P*:\n" +
"GS*HP*ENS_EDI*UB920128*20161208*1130*014684581*X*005010X221A1";
try {
ansiReader.parse(new InputSource(new StringReader(ediText)));
fail("Invalid segment start not detected");
} catch (SAXException e) {
assertEquals(
"Invalid beginning of segment at segment 2",
e.getMessage());
}
}
@Test
public void producesXmlForSimpleCase() throws IOException, SAXException, TransformerException {
ansiReader = new AnsiReader();
StringReader reader = new StringReader(EDI_SAMPLE);
StringWriter writer = new StringWriter();
ediToxml(reader, writer, ansiReader);
assertEquals(
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<ediroot>" +
"<interchange Standard=\"ANSI X.12\" AuthorizationQual=\"00\" Authorization=\" \" SecurityQual=\"00\" Security=\" \" Date=\"030603\" Time=\"1337\" StandardsId=\"U\" Version=\"00401\" Control=\"000000121\" AckRequest=\"0\" TestIndicator=\"T\">" +
"<sender><address Id=\"D00111 \" Qual=\"ZZ\"/></sender>" +
"<receiver><address Id=\"0055 \" Qual=\"ZZ\"/></receiver>" +
"<group GroupType=\"HP\" ApplSender=\"D00111\" ApplReceiver=\"0055\" Date=\"20030603\" Time=\"1337\" Control=\"1210001\" StandardCode=\"X\" StandardVersion=\"004010X091A1\">" +
"<transaction DocType=\"870\" Name=\"Order Status Report\" Control=\"0000001\">" +
"<segment Id=\"BSR\"><element Id=\"BSR01\">4</element><element Id=\"BSR02\">PA</element><element Id=\"BSR03\">SUPPLIER CONFIRMATION NUMBER</element><element Id=\"BSR04\">CCYYMMDD</element></segment>" +
"<segment Id=\"REF\"><element Id=\"REF01\">MR</element><element Id=\"REF02\">12345</element></segment>" +
"</transaction>" +
"</group>" +
"</interchange>" +
"</ediroot>",
writer.toString());
}
private class CountingHandler extends EDIReaderSAXAdapter {
private int segmentCount, elementCount;
public CountingHandler() {
super(new DefaultXMLTags());
}
@Override
protected void beginFirstSegment(Attributes atts) {
segmentCount++;
}
@Override
protected void beginAnotherSegment(Attributes atts) {
segmentCount++;
}
@Override
protected void beginBinaryPackage(Attributes atts) {
segmentCount++;
}
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
super.startElement(uri, localName, qName, attributes);
elementCount++;
}
public int getSegmentCountWithoutSTandSE() {
return segmentCount;
}
public int getElementCount() {
return elementCount;
}
}
}