package org.jpos.jposext.isomsgaction.testing.service.support;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Font;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.Map.Entry;
import javax.swing.BoxLayout;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import junit.framework.AssertionFailedError;
import junit.framework.TestCase;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.betwixt.io.BeanWriter;
import org.jpos.iso.ISOMsg;
import org.jpos.iso.ISOUtil;
import org.jpos.jposext.isomsgaction.model.SimpleContextWrapper;
import org.jpos.jposext.isomsgaction.model.validation.ValidationError;
import org.jpos.jposext.isomsgaction.model.validation.ValidationErrorTypeEnum;
import org.jpos.jposext.isomsgaction.service.IISOMsgAction;
import org.jpos.jposext.isomsgaction.service.support.ISOMsgActionCheckField;
import org.jpos.jposext.isomsgaction.testing.model.ComparisonContext;
import org.jpos.jposext.isomsgaction.testing.model.ISOCmpDiff;
import org.jpos.jposext.isomsgaction.testing.model.ManualCheck;
public class MappingTest extends TestCase {
class MyErreurValidation extends ValidationError {
private MyErreurValidation() {
super();
}
private MyErreurValidation(ValidationError validationError) {
super();
setTypeErreur(validationError.getTypeErreur());
setParamName(validationError.getParamName());
}
private MyErreurValidation(ValidationErrorTypeEnum typeErreur,
String paramName) {
super(typeErreur, paramName);
}
private MyErreurValidation(ValidationErrorTypeEnum typeErreur) {
super(typeErreur);
}
public int hashCode() {
// On choisit les deux nombres impairs
int result = 7;
final int multiplier = 17;
// Pour chaque attribut, on calcule le hashcode
// que l'on ajoute au r�sultat apr�s l'avoir multipli�
// par le nombre "multiplieur" :
result = multiplier * result + this.getParamName().hashCode();
result = multiplier * result + this.getTypeErreur().hashCode();
// On retourne le r�sultat :
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
final MyErreurValidation other = (MyErreurValidation) obj;
if (getParamName() == null) {
if (other.getParamName() != null) {
return false;
}
} else if (!(getParamName().equals(other.getParamName()))) {
return false;
}
if (getTypeErreur() == null) {
if (other.getTypeErreur() != null) {
return false;
}
} else if (!(getTypeErreur().equals(other.getTypeErreur()))) {
return false;
}
return true;
}
}
private List<ISOMsg> lstSrcISOMsg = new ArrayList<ISOMsg>();
private ISOMsg expectedISOMsg;
private Map<String, Object> context = new HashMap<String, Object>();
private Map<String, ManualCheck> mapManualChecks = new TreeMap<String, ManualCheck>();
private Map<String, List<ValidationErrorTypeEnum>> mapExpectedErrsByIdPath;
private IISOMsgAction action;
private boolean showManualCheckReminder;
private Map<String, Object> expectedContext = new HashMap<String, Object>();
private List<String> expectedContextBinaryAttrs = new ArrayList<String>();
private List<String> expectedContextNullAttrs = new ArrayList<String>();
@Override
protected void runTest() throws Throwable {
List<ISOCmpDiff> resList = new ArrayList<ISOCmpDiff>();
try {
ISOMsg targetMsg = new ISOMsg();
ISOMsg[] tabISOMsg = new ISOMsg[1 + lstSrcISOMsg.size()];
tabISOMsg[0] = targetMsg;
for (int i = 1; i <= lstSrcISOMsg.size(); i++) {
tabISOMsg[i] = lstSrcISOMsg.get(i - 1);
dumpMessage(System.out, tabISOMsg[i],
String.format("Source ISO Message [%d]", i));
}
if (null != expectedISOMsg) {
dumpMessage(System.out, expectedISOMsg,
"Expected ISO Message (excluding fields needing manual check)");
}
action.process(tabISOMsg, context);
if (null != targetMsg) {
dumpMessage(System.out, targetMsg, "Result ISO message");
}
ComparisonContext ctx = new ComparisonContext();
ctx.setResList(resList);
ctx.setMapManualChecks(mapManualChecks);
Map<MyErreurValidation, ValidationError> mapErrsInattendues = new HashMap<MyErreurValidation, ValidationError>();
Map<MyErreurValidation, ValidationError> mapErrsAttenduesTrouvees = new HashMap<MyErreurValidation, ValidationError>();
Map<MyErreurValidation, ValidationError> mapErrsAttenduesNonTrouvees = new HashMap<MyErreurValidation, ValidationError>();
List<ValidationError> lstErrsEnSortie = null;
if (context
.containsKey(ISOMsgActionCheckField.VALIDATION_ERRORS_LIST_ATTRNAME)) {
lstErrsEnSortie = (List<ValidationError>) context
.get(ISOMsgActionCheckField.VALIDATION_ERRORS_LIST_ATTRNAME);
if (lstErrsEnSortie.size() > 0) {
dumpErrorsList(
System.out,
(List<ValidationError>) context
.get(ISOMsgActionCheckField.VALIDATION_ERRORS_LIST_ATTRNAME));
}
for (ValidationError validationError : lstErrsEnSortie) {
if (mapExpectedErrsByIdPath.containsKey(validationError
.getParamName())) {
List<ValidationErrorTypeEnum> typesErreurAttendus = mapExpectedErrsByIdPath
.get(validationError.getParamName());
if (!typesErreurAttendus.contains(validationError
.getTypeErreur())) {
mapErrsInattendues.put(new MyErreurValidation(
validationError), validationError);
} else {
mapErrsAttenduesTrouvees.put(
new MyErreurValidation(validationError),
validationError);
}
} else {
mapErrsInattendues.put(new MyErreurValidation(
validationError), validationError);
}
}
for (Entry<String, List<ValidationErrorTypeEnum>> entry : mapExpectedErrsByIdPath
.entrySet()) {
String idPath = entry.getKey();
for (ValidationErrorTypeEnum validationErrorTypeEnum : entry
.getValue()) {
MyErreurValidation errValid = new MyErreurValidation(
validationErrorTypeEnum, idPath);
if (!(mapErrsAttenduesTrouvees.containsKey(errValid))) {
mapErrsAttenduesNonTrouvees.put(
new MyErreurValidation(errValid), errValid);
}
}
}
for (Entry<MyErreurValidation, ValidationError> entry : mapErrsAttenduesNonTrouvees
.entrySet()) {
MyErreurValidation erreurValidation = entry.getKey();
resList.add(new ISOCmpDiff(
erreurValidation.getParamName(),
String.format(
"Field %s : a validation error [%s] was expected",
erreurValidation.getParamName(),
erreurValidation.getTypeErreur().name())));
}
for (Entry<MyErreurValidation, ValidationError> entry : mapErrsInattendues
.entrySet()) {
MyErreurValidation erreurValidation = entry.getKey();
resList.add(new ISOCmpDiff(
erreurValidation.getParamName(),
String.format(
"Field %s : validation error [%s] was not expected",
erreurValidation.getParamName(),
erreurValidation.getTypeErreur().name())));
}
}
boolean expectedContextPopulationFailure = false;
if (null != expectedContext) {
for (Entry<String, Object> entry : expectedContext.entrySet()) {
String ctxPath = entry.getKey();
String expectedValue = (String) entry.getValue();
Object effectiveObject = PropertyUtils.getProperty(
new SimpleContextWrapper(context), ctxPath);
boolean nullValueExpected = expectedContextNullAttrs.contains(ctxPath);
if (nullValueExpected) {
if (null != effectiveObject) {
expectedContextPopulationFailure = true;
resList.add(new ISOCmpDiff(
ctxPath,
String.format(
"Attribute %s : null expected, but set=[%s]",
ctxPath, effectiveObject.toString())));
}
} else {
String effectiveValue = null;
if (null == effectiveObject) {
effectiveValue = null;
} else if (effectiveObject.getClass().isPrimitive()) {
effectiveValue = (String) effectiveObject;
} else if (effectiveObject instanceof String) {
effectiveValue = (String) effectiveObject;
} else {
effectiveValue = effectiveObject.toString();
}
if (!(expectedValue.equals(effectiveValue))) {
expectedContextPopulationFailure = true;
boolean dumpHex = expectedContextBinaryAttrs
.contains(ctxPath);
if (null != effectiveValue) {
resList.add(new ISOCmpDiff(
ctxPath,
String.format(
"Attribute %s : expected %s=[%s], was %s=[%s]",
ctxPath,
dumpHex ? "(hex dump)" : "",
dumpHex ? ISOUtil
.hexdump(expectedValue
.getBytes())
: expectedValue,
dumpHex ? "(hex dump)" : "",
dumpHex ? ISOUtil
.hexdump(effectiveValue
.getBytes())
: effectiveValue)));
} else {
resList.add(new ISOCmpDiff(
ctxPath,
String.format(
"Attribute %s : expected %s=[%s], but not set",
ctxPath,
dumpHex ? "(hex dump)" : "",
dumpHex ? ISOUtil
.hexdump(expectedValue
.getBytes())
: expectedValue)));
}
}
}
}
}
if (null != expectedISOMsg) {
ISOComponentComparator comparator = new ISOComponentComparator(
ctx, "", "");
if (comparator.compare(expectedISOMsg, targetMsg) != 0) {
throw new AssertionFailedError("Test failed");
}
}
if (mapErrsAttenduesNonTrouvees.size() + mapErrsInattendues.size() > 0) {
throw new AssertionFailedError("Test failed");
}
if (expectedContextPopulationFailure) {
throw new AssertionFailedError("Test failed");
}
if (mapManualChecks.size() > 0) {
if (showManualCheckReminder) {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
PrintStream printStream = new PrintStream(bos);
printStream.println("Generated ISO message :");
targetMsg.dump(printStream, "");
printStream.println();
printStream.println("Resulting context :");
BeanWriter beanWriter = new BeanWriter(printStream);
beanWriter.enablePrettyPrint();
beanWriter.write(context);
final JTextArea textArea = new JTextArea();
textArea.setFont(new Font("Sans-Serif", Font.PLAIN, 12));
textArea.setEditable(false);
textArea.setText(bos.toString());
JScrollPane scrollPane = new JScrollPane(textArea);
scrollPane.setPreferredSize(new Dimension(450, 350));
JPanel panel = new JPanel();
BorderLayout layout = new BorderLayout();
panel.setLayout(layout);
panel.add(scrollPane, BorderLayout.CENTER);
JPanel panLstVerif = new JPanel();
panLstVerif.setLayout(new BoxLayout(panLstVerif,
BoxLayout.Y_AXIS));
panLstVerif.add(new JLabel("Manual checks :"));
for (Entry<String, ManualCheck> entry : mapManualChecks
.entrySet()) {
panLstVerif.add(new JLabel(String.format("\t* %s : %s",
entry.getKey(), entry.getValue().getDesc())));
}
panLstVerif
.add(new JLabel(
"Do you confirm that checked values complies to their expected check rules ?"));
panel.add(panLstVerif, BorderLayout.SOUTH);
Object[] options = { "Yes", "No" };
int n = JOptionPane
.showOptionDialog(
null,
panel,
String.format("Manual checks (%s)",
this.getName()),
JOptionPane.YES_NO_OPTION,
JOptionPane.QUESTION_MESSAGE, null,
options, options[1]);
if (n == 1) {
throw new AssertionFailedError("Test failed");
}
}
}
}
catch (AssertionFailedError t) {
t.setStackTrace(new StackTraceElement[] {});
StringBuffer buf = new StringBuffer();
buf.append(t.getMessage());
buf.append("\n\n");
if (resList.size() > 0) {
buf.append("Differences list :");
buf.append("\n");
for (ISOCmpDiff resElt : resList) {
buf.append(String.format("\t* %s", resElt));
buf.append("\n");
}
buf.append("\n");
}
if (mapManualChecks.size() > 0) {
buf.append("Some of the manual checks have failed among :");
buf.append("\n");
for (Entry<String, ManualCheck> entry : mapManualChecks
.entrySet()) {
buf.append(String.format("\t* champ %s : %s",
entry.getKey(), entry.getValue().getDesc()));
buf.append("\n");
}
buf.append("\n");
}
throw new AssertionFailedError(buf.toString());
}
}
protected void dumpErrorsList(PrintStream ps, List<ValidationError> lstErrs) {
if (null != lstErrs) {
for (ValidationError err : lstErrs) {
ps.println(String.format("id=%s, error=%s", err.getParamName(),
err.getTypeErreur()));
}
}
}
protected String genIdPathFromTab(int[] tab, String sep) {
StringBuffer buf = new StringBuffer();
String sepInter = "";
for (int idx : tab) {
buf.append(sepInter);
buf.append(idx);
sepInter = sep;
}
return buf.toString();
}
private void dumpMessage(PrintStream ps, ISOMsg msg, String libelleMsg) {
String lineSep = "================================================================================";
ps.println(lineSep);
ps.println(libelleMsg);
ps.println(lineSep);
msg.dump(ps, "");
ps.println(lineSep);
ps.println("");
}
public void addSrcISOMsg(ISOMsg isoMsg) {
lstSrcISOMsg.add(isoMsg);
}
public void addManualCheck(String idPath, String desc) {
mapManualChecks.put(idPath, new ManualCheck(idPath, desc));
}
public List<ISOMsg> getLstSrcISOMsg() {
return lstSrcISOMsg;
}
public void setLstSrcISOMsg(List<ISOMsg> lstSrcISOMsg) {
this.lstSrcISOMsg = lstSrcISOMsg;
}
public Map<String, Object> getContext() {
return context;
}
public void setContext(Map<String, Object> context) {
this.context = context;
}
public ISOMsg getExpectedISOMsg() {
return expectedISOMsg;
}
public void setExpectedISOMsg(ISOMsg expectedISOMsg) {
this.expectedISOMsg = expectedISOMsg;
}
public IISOMsgAction getAction() {
return action;
}
public void setAction(IISOMsgAction action) {
this.action = action;
}
public Map<String, List<ValidationErrorTypeEnum>> getMapExpectedErrsByIdPath() {
return mapExpectedErrsByIdPath;
}
public void setMapExpectedErrsByIdPath(
Map<String, List<ValidationErrorTypeEnum>> mapExpectedErrsByIdPath) {
this.mapExpectedErrsByIdPath = mapExpectedErrsByIdPath;
}
public boolean isShowManualCheckReminder() {
return showManualCheckReminder;
}
public void setShowManualCheckReminder(boolean showManualCheckReminder) {
this.showManualCheckReminder = showManualCheckReminder;
}
public Map<String, Object> getExpectedContext() {
return expectedContext;
}
public void setExpectedContext(Map<String, Object> expectedContext) {
this.expectedContext = expectedContext;
}
public List<String> getExpectedContextBinaryAttrs() {
return expectedContextBinaryAttrs;
}
public void setExpectedContextBinaryAttrs(
List<String> expectedContextBinaryAttrs) {
this.expectedContextBinaryAttrs = expectedContextBinaryAttrs;
}
public List<String> getExpectedContextNullAttrs() {
return expectedContextNullAttrs;
}
public void setExpectedContextNullAttrs(
List<String> expectedContextNullAttrs) {
this.expectedContextNullAttrs = expectedContextNullAttrs;
}
}