package org.richfaces.javascript.client.validator;
import static org.easymock.EasyMock.expect;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.validator.Validator;
import javax.faces.validator.ValidatorException;
import javax.validation.ValidationException;
import net.sourceforge.htmlunit.corejs.javascript.JavaScriptException;
import net.sourceforge.htmlunit.corejs.javascript.NativeObject;
import org.ajax4jsf.javascript.JSFunction;
import org.junit.Test;
import org.richfaces.javascript.Message;
import org.richfaces.javascript.client.MockTestBase;
import org.richfaces.javascript.client.RunParameters;
import org.richfaces.validator.FacesValidatorServiceImpl;
import com.gargoylesoftware.htmlunit.ScriptException;
public abstract class ValidatorTestBase extends MockTestBase {
/**
* <p class="changed_added_4_0">
* TODO remove to check all messages.
* </p>
*
* @deprecated Remove this option then all messages will be passed properly.
*/
public static final String IGNORE_MESSAGE = "ignoreMessage";
private static final Converter NUMBER_CONVERTER = new Converter() {
public String getAsString(FacesContext context, UIComponent component, Object value) {
return String.valueOf(value);
}
public Object getAsObject(FacesContext context, UIComponent component, String value) {
return Double.valueOf(value);
}
};
public ValidatorTestBase(RunParameters criteria) {
super(criteria);
}
@Test
public void testValidator() throws Exception {
Validator validator = createValidator();
try {
validator.validate(facesEnvironment.getFacesContext(), input, criteria.getValue());
validateOnClient(validator);
} catch (ValidatorException e) {
// client-side script has to throw exception too.
try {
validateOnClient(validator);
assertFalse("JSF validator throws exception for value: " + criteria.getValue() + ", validator options: "
+ getOptions(), true);
} catch (ScriptException e2) {
// both methods throws exceptions - it's ok.
Throwable cause = e2.getCause();
assertTrue(cause instanceof JavaScriptException);
if (!getOptions().containsKey(IGNORE_MESSAGE)) {
NativeObject value = (NativeObject) ((JavaScriptException) cause).getValue();
assertEquals(e.getFacesMessage().getDetail(), value.get("detail"));
assertEquals(e.getFacesMessage().getSummary(), value.get("summary"));
}
}
}
}
protected Object validateOnClient(Validator validator) throws ValidationException {
JSFunction clientSideFunction = new JSFunction("RichFaces.csv." + getJavaScriptFunctionName(), criteria.getValue(),
TEST_COMPONENT_ID, getJavaScriptOptions(), getErrorMessage(validator));
return qunit.runScript(clientSideFunction.toScript());
}
private Object getErrorMessage(Validator validator) {
FacesValidatorServiceImpl validatorService = new FacesValidatorServiceImpl();
FacesMessage message = validatorService.getMessage(facesEnvironment.getFacesContext(), validator, input, null);
return new Message(message);
}
protected abstract Validator createValidator();
@Override
protected void recordMocks() {
super.recordMocks();
expect(facesEnvironment.getApplication().createConverter("javax.faces.Number")).andStubReturn(NUMBER_CONVERTER);
}
}