}\r
break;\r
case TEXT:\r
+ if (!value.treesMatch()) {\r
+ failureReason = " : DOM TREE MISMATCH; ";\r
+ return false;\r
+ }\r
if (value.countFor(TreeWalkResults.TreeWalkEntry.STATUS.TEXT_DIFFERENT)>0) {\r
failureReason = " : DOM TEXT_DIFFERENT; ";\r
return false;\r
import java.util.Map;\r
\r
import org.collectionspace.services.IntegrationTests.xmlreplay.TreeWalkResults.TreeWalkEntry;\r
+import org.jdom.output.XMLOutputter;\r
\r
/**\r
* User: laramie\r
}\r
List l = left.getChildren();\r
Map foundRightMap = new HashMap();\r
+ List<String> foundRepeatingList = new ArrayList<String>();\r
boolean result = true;\r
for (Object o : l) {\r
if (!(o instanceof Element)){\r
continue;\r
}\r
String leftChildPath = Tools.glue(parentPath, "/", leftChildName);\r
- Element rightChild = (Element)selectSingleNode(right,leftChildName);\r
- if (rightChild == null){\r
- TreeWalkEntry entry = new TreeWalkEntry();\r
- entry.lpath = leftChildPath;\r
- entry.status = TreeWalkEntry.STATUS.R_MISSING;\r
- msgList.add(entry);\r
+\r
+ if (foundRepeatingList.indexOf(leftChildPath)>=0){\r
continue;\r
}\r
- foundRightMap.put(leftChildName, "OK");\r
- String leftChildTextTrim = leftChild.getText().trim();\r
- String rightChildTextTrim = rightChild.getText().trim();\r
- TreeWalkEntry entry = new TreeWalkEntry();\r
- entry.ltextTrimmed = leftChildTextTrim;\r
- entry.rtextTrimmed = rightChildTextTrim;\r
- entry.lpath = leftChildPath;\r
- entry.rpath = leftChildPath; //same\r
-\r
- if (leftChildTextTrim.equals(rightChildTextTrim)){\r
- entry.status = TreeWalkEntry.STATUS.MATCHED;\r
- msgList.add(entry);\r
+ List leftlist = select(left, leftChildName);\r
+ if (leftlist != null && leftlist.size() > 1){\r
+ //System.out.println("-----------------doRepeating------"+leftChildPath);\r
+ foundRepeatingList.add(leftChildPath);\r
+ boolean repeatingIdentical =\r
+ doRepeatingFieldComparison(leftlist, leftChildPath, leftChildName, left, right, msgList) ; //todo: deal with foundRightMap in this repeating field block.\r
+ if ( ! repeatingIdentical ){\r
+ //System.out.println("\r\n\r\n\r\n*****************************\r\nOne repeating field failed: "+msgList);\r
+ return false;\r
+ }\r
+ foundRightMap.put(leftChildName, "OK");\r
} else {\r
- entry.status = TreeWalkEntry.STATUS.TEXT_DIFFERENT;\r
- msgList.add(entry);\r
- }\r
+ Element rightChild = (Element)selectSingleNode(right,leftChildName);\r
+ if (rightChild == null){\r
+ TreeWalkEntry entry = new TreeWalkEntry();\r
+ entry.lpath = leftChildPath;\r
+ entry.status = TreeWalkEntry.STATUS.R_MISSING;\r
+ msgList.add(entry);\r
+ continue;\r
+ }\r
+ foundRightMap.put(leftChildName, "OK");\r
+ String leftChildTextTrim = leftChild.getText().trim();\r
+ String rightChildTextTrim = rightChild.getText().trim();\r
+ TreeWalkEntry entry = new TreeWalkEntry();\r
+ entry.ltextTrimmed = leftChildTextTrim;\r
+ entry.rtextTrimmed = rightChildTextTrim;\r
+ entry.lpath = leftChildPath;\r
+ entry.rpath = leftChildPath; //same\r
\r
- //============ DIVE !! =====================================================\r
- result = result && treeWalk( leftChild, rightChild, leftChildPath, msgList);\r
+ if (leftChildTextTrim.equals(rightChildTextTrim)){\r
+ entry.status = TreeWalkEntry.STATUS.MATCHED;\r
+ msgList.add(entry);\r
+ } else {\r
+ entry.status = TreeWalkEntry.STATUS.TEXT_DIFFERENT;\r
+ msgList.add(entry);\r
+ }\r
+ //============ DIVE !! =====================================================\r
+ result = result && treeWalk( leftChild, rightChild, leftChildPath, msgList);\r
+ }\r
}\r
for (Object r : right.getChildren()){\r
if (!(r instanceof Element)){\r
}\r
return true;\r
}\r
- \r
+\r
+ private static void dumpXML_OUT(Element el) throws Exception {\r
+ XMLOutputter outputter = new XMLOutputter();\r
+ outputter.output(el, System.out);\r
+ }\r
+ private static String dumpXML(Element el) throws Exception {\r
+ XMLOutputter outputter = new XMLOutputter();\r
+ return outputter.outputString(el);\r
+ }\r
+\r
+ public static boolean doRepeatingFieldComparison(List leftList, String leftChildPath, String leftChildName, Element left, Element right, TreeWalkResults msgList)\r
+ throws Exception {\r
+ //todo: deal with foundRightMap in this repeating field block.\r
+ List rightList = select(right, leftChildName);\r
+ if (rightList == null || rightList.size() == 0 || rightList.size() < leftList.size()){\r
+ TreeWalkEntry twe = new TreeWalkEntry();\r
+ twe.lpath = leftChildPath;\r
+ twe.status = TreeWalkEntry.STATUS.R_MISSING;\r
+ String rmsg = (rightList == null)\r
+ ? " Right: 0"\r
+ : " Right: "+rightList.size();\r
+ twe.message = "Repeating field count not matched. Field: "+leftChildPath+" Left: "+leftList.size()+rmsg;\r
+ msgList.add(twe);\r
+ return false;\r
+ }\r
+ if (rightList.size() > leftList.size()){\r
+ TreeWalkEntry twe = new TreeWalkEntry();\r
+ twe.lpath = leftChildPath;\r
+ twe.status = TreeWalkEntry.STATUS.R_ADDED;\r
+ twe.message = "Repeating field count not matched. Field: "+leftChildPath+" Left: "+leftList.size()+" Right: "+rightList.size();\r
+ msgList.add(twe);\r
+ return false;\r
+ }\r
+\r
+ for (Object le : leftList){\r
+ boolean found = false;\r
+ Element leftEl = (Element)le;\r
+ //pl("left", leftEl);\r
+ for(Object re : rightList){\r
+ Element rightEl = (Element)re;\r
+ //pl("right", rightEl);\r
+ TreeWalkResults msgListInner = new TreeWalkResults();\r
+ treeWalk(leftEl, rightEl, leftChildPath, msgListInner);\r
+ if (msgListInner.isStrictMatch()){\r
+ found = true;\r
+ TreeWalkEntry twe = new TreeWalkEntry();\r
+ twe.lpath = leftChildPath;\r
+ twe.status = TreeWalkEntry.STATUS.MATCHED;\r
+ msgList.add(twe);\r
+ //System.out.println("===========================\r\nfound match for "+leftEl+"\r\n===========================\r\n");\r
+ rightList.remove(re); //found it, don't need to inspect this element again. Since we are breaking from loop, removing element won't mess up iterator--we get a new one on the next loop.\r
+ break;\r
+ }\r
+ }\r
+ if ( ! found){\r
+ TreeWalkEntry twe = new TreeWalkEntry();\r
+ twe.lpath = leftChildPath;\r
+ twe.status = TreeWalkEntry.STATUS.R_MISSING;\r
+ twe.message = "Repeating field not matched. Source: {"+dumpXML(leftEl)+"}";\r
+ msgList.add(twe);\r
+ return false;\r
+ }\r
+ }\r
+ return true;\r
+ }\r
+\r
+ private static void pl(String name, Element el) throws Exception {\r
+ Object lobid = selectSingleNode(el, "@ID");\r
+ String lid = "";\r
+ if (lobid!=null){\r
+ lid = lobid.toString();\r
+ }\r
+\r
+ System.out.println(name+": "+lid);\r
+ dumpXML_OUT(el);\r
+ System.out.println();\r
+\r
+ }\r
}\r
}\r
return document;\r
}\r
+ protected static String validateResponseSinglePayload(ServiceResult serviceResult,\r
+ Map<String, ServiceResult> serviceResultsMap,\r
+ PartsStruct expectedResponseParts,\r
+ XmlReplayEval evalStruct)\r
+ throws Exception {\r
+ String OK = "";\r
+ byte[] b = FileUtils.readFileToByteArray(new File(expectedResponseParts.singlePartPayloadFilename));\r
+ String expectedPartContent = new String(b);\r
+ expectedPartContent = evalStruct.eval(expectedPartContent, serviceResultsMap, evalStruct.jexl, evalStruct.jc);\r
+ String label = "NOLABEL";\r
+ String leftID = "{from expected part, label:"+label+" filename: "+expectedResponseParts.singlePartPayloadFilename+"}";\r
+ String rightID = "{from server, label:"+label\r
+ +" fromTestID: "+serviceResult.fromTestID\r
+ +" URL: "+serviceResult.fullURL\r
+ +"}";\r
+ TreeWalkResults list =\r
+ XmlCompareJdom.compareParts(expectedPartContent,\r
+ leftID,\r
+ serviceResult.result,\r
+ rightID);\r
+ serviceResult.addPartSummary(label, list);\r
+ return OK;\r
+ }\r
\r
protected static String validateResponse(ServiceResult serviceResult,\r
Map<String, ServiceResult> serviceResultsMap,\r
- PartsStruct expectedResponseParts){\r
+ PartsStruct expectedResponseParts,\r
+ XmlReplayEval evalStruct){\r
String OK = "";\r
if (expectedResponseParts == null) return OK;\r
if (serviceResult == null) return OK;\r
if (serviceResult.result.length() == 0) return OK;\r
String responseDump = serviceResult.result;\r
- //System.out.println("responseDump: "+responseDump);\r
- PayloadLogger.HttpTraffic traffic = PayloadLogger.readPayloads(responseDump, serviceResult.boundary, serviceResult.contentLength);\r
try {\r
+ if (expectedResponseParts.bDoingSinglePartPayload){\r
+ return validateResponseSinglePayload(serviceResult, serviceResultsMap, expectedResponseParts, evalStruct);\r
+ }\r
+ //System.out.println("responseDump: "+responseDump);\r
+ PayloadLogger.HttpTraffic traffic = PayloadLogger.readPayloads(responseDump, serviceResult.boundary, serviceResult.contentLength);\r
+\r
for (int i=0; i<expectedResponseParts.partsList.size(); i++){\r
String fileName = expectedResponseParts.filesList.get(i);\r
String label = expectedResponseParts.partsList.get(i);\r
byte[] b = FileUtils.readFileToByteArray(new File(fileName));\r
String expectedPartContent = new String(b);\r
+ expectedPartContent = evalStruct.eval(expectedPartContent, serviceResultsMap, evalStruct.jexl, evalStruct.jc);\r
System.out.println("expected: "+label+ " content ==>\r\n"+expectedPartContent);\r
PayloadLogger.Part partFromServer = traffic.getPart(label);\r
String partFromServerContent = "";\r
serviceResult.payloadStrictness = level;\r
}\r
\r
- String vError = validateResponse(serviceResult, serviceResultsMap, expectedResponseParts);\r
+ String vError = validateResponse(serviceResult, serviceResultsMap, expectedResponseParts, evalStruct);\r
if (Tools.notEmpty(vError)){\r
serviceResult.error = vError;\r
serviceResult.failureReason = " : VALIDATION ERROR; ";\r
\r
\r
<!-- <run controlFile="objectexit/object-exit.xml" testGroup="CRUDL" />--> \r
- <run controlFile="objectexit/object-exit.xml" testGroup="domwalk" />\r
+ <!--<run controlFile="objectexit/object-exit.xml" testGroup="domwalk" />\r
<run controlFile="objectexit/object-exit.xml" testGroup="repeat" />\r
+ <run controlFile="objectexit/object-exit.xml" testGroup="CRUDL" />\r
+ -->\r
+ <run controlFile="objectexit/object-exit.xml" testGroup="DOMLIST" />\r
\r
\r
</xmlReplayMaster>\r
<auth ID="testAdministator">YWRtaW5AY29sbGVjdGlvbnNwYWNlLm9yZzpBZG1pbmlzdHJhdG9y</auth>\r
</auths>\r
\r
- <dump payloads="true" dumpServiceResult="minimal" />\r
-\r
\r
<testGroup ID="domwalk" autoDeletePOSTS="true">\r
<test ID="oe1" auth="test">\r
</test>\r
</testGroup>\r
\r
+ <!-- ================================================================================ -->\r
\r
<testGroup ID="CRUDL" autoDeletePOSTS="true">\r
<test ID="oe1" auth="admin@collectionspace.org">\r
<test ID="oe6">\r
<method>GET</method>\r
<uri>/cspace-services/objectexit/</uri>\r
- <reponse>oe6.res.xml</reponse>\r
+ <response>\r
+ <expected level="TEXT" />\r
+ <filename>objectexit/res/oe6.res.xml</filename>\r
+ </response>\r
+ <!--reponse>oe6.res.xml</reponse-->\r
<!--response elements will need parts, too, e.g. personauthorities_common -->\r
<!-- inside oe6.res.xml, there is a CSID which will change every time, and should be ref'd as 6f7a1e3e-5821-4ef2-bfcf ==> ${oe1.CSID}\r
-->\r
\r
</testGroup>\r
\r
+ <!-- =========== DOMWALK LIST ================================================ -->\r
+\r
+ <testGroup ID="DOMLIST" autoDeletePOSTS="true">\r
+ <test ID="oe1" auth="admin@collectionspace.org">\r
+ <method>POST</method>\r
+ <uri>/cspace-services/objectexit/</uri>\r
+ <part>\r
+ <label>objectexit_common</label>\r
+ <filename>objectexit/oe1.xml</filename>\r
+ </part>\r
+ </test>\r
+ <test ID="oe3">\r
+ <method>POST</method>\r
+ <uri>/cspace-services/objectexit/</uri>\r
+ <part>\r
+ <label>objectexit_common</label>\r
+ <filename>objectexit/oe3.xml</filename>\r
+ </part>\r
+ </test>\r
+ <test ID="oe4">\r
+ <method>POST</method>\r
+ <uri>/cspace-services/objectexit/</uri>\r
+ <part>\r
+ <label>objectexit_common</label>\r
+ <filename>objectexit/oe4.xml</filename>\r
+ </part>\r
+ </test>\r
+ <test ID="oe5">\r
+ <method>POST</method>\r
+ <uri>/cspace-services/objectexit/</uri>\r
+ <part>\r
+ <label>objectexit_common</label>\r
+ <filename>objectexit/oe5.xml</filename>\r
+ </part>\r
+ </test>\r
+ <test ID="oe6">\r
+ <method>GET</method>\r
+ <uri>/cspace-services/objectexit/</uri>\r
+ <response>\r
+ <expected level="TEXT" />\r
+ <filename>objectexit/res/oe6.res.xml</filename>\r
+ </response>\r
+ </test>\r
+ </testGroup>\r
+\r
</xmlReplay>\r
\r
\r
xmlns:ns2="http://collectionspace.org/services/objectexit" \r
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" \r
xsi:schemaLocation="http://collectionspace.org/services/objectexit http://services.collectionspace.org/objectexit/objectexit_common.xsd">\r
-<exitNumber>objectexitNumber-1290026472360\r
-<second>\r
- second content\r
- </second>\r
-</exitNumber>\r
-<first>\r
- <second>\r
- second content\r
- </second>\r
-</first>\r
-\r
+<exitNumber>objectexitNumber-1290026472360</exitNumber>\r
<depositor>urn:cspace:org.collectionspace.demo:orgauthority:name(TestOrgAuth):organization:name(Northern Climes Museum)'Northern Climes Museum'</depositor>\r
-<newField>objectexitNumber-1290026472360</newField>\r
+<exitMethods></exitMethods>\r
</ns2:objectexit_common>\r
\r
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\r
-<ns2:objectexit_common_list xmlns:ns2="http://collectionspace.org/services/objectexit" \r
- xmlns:ns3="http://collectionspace.org/services/jaxb">\r
- <pageNum>0</pageNum><pageSize>40</pageSize><itemsInPage>4</itemsInPage><totalItems>4</totalItems><fieldsReturned>currentOwner|depositor|exitDate|exitMethod|exitNote|exitNumber|exitReason|packingNote|uri|csid</fieldsReturned><objectexit_list_item><exitNumber>objectexitNumber-1290026473391</exitNumber><uri>/objectexit/${oe3.CSID}</uri><csid>${oe3.CSID}</csid></objectexit_list_item><objectexit_list_item><exitNumber>objectexitNumber-1290026473626</exitNumber><uri>/objectexit/${oe4.CSID}</uri><csid>${oe4.CSID}</csid></objectexit_list_item><objectexit_list_item><exitNumber>objectexitNumber-1290026473860</exitNumber><uri>/objectexit/${oe5.CSID}</uri><csid>${oe5.CSID}</csid></objectexit_list_item><objectexit_list_item><exitNumber>objectexitNumber-1290026472360</exitNumber><uri>/objectexit/${oe1.CSID}</uri><csid>${oe1.CSID}</csid></objectexit_list_item></ns2:objectexit_common_list>\r
+<ns2:objectexit_common_list\r
+xmlns:ns2="http://collectionspace.org/services/objectexit"\r
+xmlns:ns3="http://collectionspace.org/services/jaxb">\r
+ <pageNum>0</pageNum>\r
+ <pageSize>40</pageSize>\r
+ <itemsInPage>4</itemsInPage>\r
+ <totalItems>4</totalItems>\r
+ <fieldsReturned>exitNumber|currentOwner|uri|csid</fieldsReturned>\r
+\r
+ <objectexit_list_item ID="e1-oe5">\r
+ <exitNumber>objectexitNumber-1290026473860</exitNumber>\r
+ <uri>/objectexit/${oe5.CSID}</uri>\r
+ <csid>${oe5.CSID}</csid>\r
+ </objectexit_list_item>\r
+ \r
+ <objectexit_list_item ID="e2-oe3">\r
+ <exitNumber>objectexitNumber-1290026473391</exitNumber>\r
+ <uri>/objectexit/${oe3.CSID}</uri>\r
+ <csid>${oe3.CSID}</csid>\r
+ </objectexit_list_item>\r
+ \r
+ <objectexit_list_item ID="e3-oe4">\r
+ <exitNumber>objectexitNumber-1290026473626</exitNumber>\r
+ <uri>/objectexit/${oe4.CSID}</uri>\r
+ <csid>${oe4.CSID}</csid>\r
+ </objectexit_list_item>\r
+\r
+ <objectexit_list_item ID="e4-oe1">\r
+ <exitNumber>objectexitNumber-1290026472360</exitNumber>\r
+ <uri>/objectexit/${oe1.CSID}</uri>\r
+ <csid>${oe1.CSID}</csid>\r
+ </objectexit_list_item>\r
+ </ns2:objectexit_common_list>\r
+\r
\r
<protoHostPort>http://localhost:8180</protoHostPort>\r
\r
<!-- legal values for dumpServiceResult=[minimal,detailed,full] -->\r
- <dump payloads="true" dumpServiceResult="full" />\r
+ <dump payloads="false" dumpServiceResult="minimal" />\r
\r
<auths default="admin@collectionspace.org">\r
<auth ID="admin@collectionspace.org">YWRtaW5AY29sbGVjdGlvbnNwYWNlLm9yZzpBZG1pbmlzdHJhdG9y</auth>\r