View Javadoc
1   package emissary.test.core.junit5;
2   
3   import emissary.core.DiffCheckConfiguration;
4   import emissary.core.IBaseDataObject;
5   import emissary.core.IBaseDataObjectXmlCodecs;
6   import emissary.core.IBaseDataObjectXmlHelper;
7   import emissary.test.core.junit5.LogbackTester.SimplifiedLogEvent;
8   import emissary.util.PlaceComparisonHelper;
9   import emissary.util.io.ResourceReader;
10  
11  import jakarta.annotation.Nullable;
12  import org.jdom2.Document;
13  import org.jdom2.Element;
14  
15  import java.net.URISyntaxException;
16  import java.nio.file.Path;
17  import java.nio.file.Paths;
18  import java.util.ArrayList;
19  import java.util.List;
20  
21  import static emissary.core.IBaseDataObjectXmlCodecs.SHA256_ELEMENT_ENCODERS;
22  import static emissary.core.constants.IbdoXmlElementNames.ANSWERS;
23  import static emissary.core.constants.IbdoXmlElementNames.SETUP;
24  import static org.junit.jupiter.api.Assertions.assertIterableEquals;
25  import static org.junit.jupiter.api.Assertions.assertNotNull;
26  import static org.junit.jupiter.api.Assertions.assertNull;
27  import static org.junit.jupiter.api.Assertions.fail;
28  
29  /**
30   * <p>
31   * This test acts similarly to ExtractionTest; however, it compares the entire BDO instead of just what is defined in
32   * the XML. In other words, the XML must define exactly the output of the Place, no more and no less. There are methods
33   * provided to generate the XML required.
34   * </p>
35   * 
36   * <p>
37   * To implement this for a test, you should:
38   * </p>
39   * <ol>
40   * <li>Extend this class</li>
41   * <li>Either Override {@link #generateAnswers()} to return true or set the generateAnswers system property to true,
42   * which will generate the XML answer files</li>
43   * <li>Optionally, to generate answers file without changing code run {@code mvn clean test -DgenerateAnswers=true}</li>
44   * <li>Optionally, override the various provided methods if you want to customise the behaviour of providing the IBDO
45   * before/after processing</li>
46   * <li>Run the tests, which should pass - if they don't, you either have incorrect processing which needs fixing, or you
47   * need to further customise the initial/final IBDOs.</li>
48   * <li>Once the tests pass, you can remove the overridden method(s) added above.</li>
49   * </ol>
50   */
51  public abstract class RegressionTest extends ExtractionTest {
52  
53      /* Difference configuration to use when comparing IBDO's. */
54      private static final DiffCheckConfiguration DIFF_CHECK = DiffCheckConfiguration.configure().enableData().enableKeyValueParameterDiff().build();
55  
56      @Override
57      public String getAnswerXsd() {
58          return "emissary/test/core/schemas/regression.xsd";
59      }
60  
61      @Override
62      protected AnswerGenerator createAnswerGenerator() {
63          return new RegressionTestAnswerGenerator();
64      }
65  
66      /**
67       * This method returns the XML element encoders.
68       *
69       * @return the XML element encoders.
70       */
71      @Override
72      protected IBaseDataObjectXmlCodecs.ElementEncoders getEncoders() {
73          return SHA256_ELEMENT_ENCODERS;
74      }
75  
76      @Override
77      @Nullable
78      protected String getInitialForm(final String resource) {
79          try {
80              final Path datFileUrl = Paths.get(new ResourceReader().getResource(resource).toURI());
81              final InitialFinalFormFormat datFile = new InitialFinalFormFormat(datFileUrl);
82              return datFile.getInitialForm();
83          } catch (final URISyntaxException e) {
84              fail("Unable to get initial form from filename", e);
85              return null;
86          }
87      }
88  
89      @Override
90      protected void setupPayload(final IBaseDataObject payload, final Document answers) {
91          final Element root = answers.getRootElement();
92  
93          if (root != null) {
94              final Element parent = root.getChild(SETUP);
95  
96              if (parent != null) {
97                  payload.popCurrentForm(); // Remove default form put on by ExtractionTest.
98                  payload.setFileType(null); // Remove default filetype put on by ExtractionTest.
99                  // The only other fields set are data and filename.
100 
101                 IBaseDataObjectXmlHelper.ibdoFromXmlMainElements(parent, payload, getDecoders(payload.getFilename()));
102             }
103         }
104     }
105 
106     @Override
107     protected void checkAnswers(final Document answers, final IBaseDataObject payload,
108             final List<IBaseDataObject> attachments, final String tname) {
109 
110         final Element root = answers.getRootElement();
111         final Element parent = root.getChild(ANSWERS);
112 
113         assertNotNull(parent, "No 'answers' section found!");
114 
115         final List<IBaseDataObject> expectedAttachments = new ArrayList<>();
116         final IBaseDataObject expectedIbdo = IBaseDataObjectXmlHelper.ibdoFromXml(answers, expectedAttachments, getDecoders(tname));
117         final String differences = PlaceComparisonHelper.checkDifferences(expectedIbdo, payload, expectedAttachments,
118                 attachments, place.getClass().getName(), DIFF_CHECK);
119 
120         assertNull(differences, generateAnswers() ? differences
121                 + "\nNOTE: Since 'generateAnswers' is true, these differences could indicate non-deterministic processing in the tested code path\n"
122                 : differences);
123 
124         assertIterableEquals(SimplifiedLogEvent.fromXml(parent), actualSimplifiedLogEvents);
125     }
126 }