package org.richfaces.renderkit.html; import static org.easymock.EasyMock.expect; import static org.hamcrest.CoreMatchers.allOf; import static org.hamcrest.CoreMatchers.containsString; import static org.hamcrest.CoreMatchers.hasItem; import static org.hamcrest.CoreMatchers.not; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertThat; import java.util.ArrayList; import java.util.Collection; import java.util.Map; import javax.faces.context.FacesContext; import javax.faces.convert.Converter; import javax.faces.convert.NumberConverter; import javax.validation.constraints.Max; import javax.validation.constraints.Min; import org.hamcrest.BaseMatcher; import org.hamcrest.Description; import org.hamcrest.Matcher; import org.jboss.test.faces.mock.Mock; import org.jboss.test.faces.mock.MockTestRunner; import org.junit.Test; import org.junit.runner.RunWith; import org.richfaces.javascript.LibraryFunction; import org.richfaces.javascript.Message; import org.richfaces.javascript.ScriptNotFoundException; import org.richfaces.resource.ResourceKey; import org.richfaces.validator.ConverterDescriptor; import org.richfaces.validator.FacesObjectDescriptor; import org.richfaces.validator.ValidatorDescriptor; import com.google.common.collect.Lists; @RunWith(MockTestRunner.class) public class RendererGetComponentScriptTest extends ValidatorRendererTestBase { private static final String JSF_AJAX_REQUEST = "jsf.ajax.request(element,event)"; private static final String NUMBER_CONVERTER = "numConverter"; private static final Matcher<ResourceKey> CORE_LIBRARY_MATCHER = new BaseMatcher<ResourceKey>() { public boolean matches(Object arg0) { if (arg0 instanceof ResourceKey) { ResourceKey resource = (ResourceKey) arg0; return ORG_RICHFACES.equals(resource.getLibraryName()) && CLIENT_VALIDATORS_JS.equals(resource.getResourceName()); } return false; } public void describeTo(Description arg0) { arg0.appendText("Library is RichFaces core validators"); } }; @Mock private ConverterDescriptor converterDescription; /** * <p class="changed_added_4_0"> * Test generated script for case there is no client-side converter. * </p> * * @throws Exception */ @Test public void testCreateValidatorScriptNoConverter() throws Exception { ClientValidatorRenderer renderer = createStubRenderer(null, createValidatorFunction()); setupBehavior(NumberConverter.class, Min.class); exceptGetAjaxScript(); ComponentValidatorScript validatorScript = callGetScript(renderer); String script = validatorScript.toScript(); // check what generated script contains ajax call only. assertThat( script, allOf(containsString(JSF_AJAX_REQUEST), not(containsString(REGEX_VALIDATOR)), not(containsString(NUMBER_CONVERTER)))); } private void exceptGetAjaxScript() { expect(mockBehavior.getAjaxScript(behaviorContext)).andReturn(JSF_AJAX_REQUEST); expect(behaviorContext.getSourceId()).andStubReturn("clientValidator"); } /** * <p class="changed_added_4_0"> * </p> * * @param renderer */ private ComponentValidatorScript callGetScript(ClientValidatorRenderer renderer) { controller.replay(); ComponentValidatorScript validatorScript = renderer.createValidatorScript(behaviorContext, mockBehavior); controller.verify(); return validatorScript; } /** * <p class="changed_added_4_0"> * Test generated script for case there is no client-side validator scripts. * </p> * * @throws Exception */ @Test public void testCreateValidatorScriptNoValidator() throws Exception { ClientValidatorRenderer renderer = createStubRenderer(createConverterFunction()); setupBehavior(NumberConverter.class, Min.class); exceptGetAjaxScript(); ComponentValidatorScript validatorScript = callGetScript(renderer); String script = validatorScript.toScript(); // check what generated script contains ajax call only. assertThat( script, allOf(containsString(JSF_AJAX_REQUEST), not(containsString(REGEX_VALIDATOR)), not(containsString(NUMBER_CONVERTER)))); } /** * <p class="changed_added_4_0"> * Test generated script for case there is no client-side script for some validator, but exists for other * </p> * * @throws Exception */ @Test public void testCreateValidatorScriptPartialValidator() throws Exception { ClientValidatorRenderer renderer = createStubRenderer(createConverterFunction(), createValidatorFunction()); setupBehavior("alert(1)", "alert(messages)", NumberConverter.class, Min.class, Max.class); exceptGetAjaxScript(); ComponentValidatorScript validatorScript = callGetScript(renderer); String script = validatorScript.toScript(); // check what generated script contains ajax and client side scripts. assertThat(script, allOf(containsString(JSF_AJAX_REQUEST), containsString(REGEX_VALIDATOR), containsString(NUMBER_CONVERTER))); Matcher<java.lang.Iterable<? super ResourceKey>> matcher = hasItem(CORE_LIBRARY_MATCHER); assertThat(validatorScript.getResources(), matcher); assertThat(script, allOf(containsString("alert(1)"), containsString("alert(messages)"))); } /** * <p class="changed_added_4_0"> * Test case when validation does not required at all. * </p> * * @throws Exception */ @Test public void testCreateValidatorScriptEmptyValidator() throws Exception { ClientValidatorRenderer renderer = createStubRenderer(createConverterFunction()); setupBehavior(null); ComponentValidatorScript validatorScript = callGetScript(renderer); assertNull(validatorScript); } /** * <p class="changed_added_4_0"> * Test for case when client side converter is not required. * </p> * * @throws Exception */ @Test public void testCreateValidatorScriptNullConverter() throws Exception { ClientValidatorRenderer renderer = createStubRenderer(null, createValidatorFunction()); setupBehavior("", "", null, Min.class); ComponentValidatorScript validatorScript = callGetScript(renderer); String script = validatorScript.toScript(); // check what generated script contains ajax and client side scripts. assertThat( script, allOf(not(containsString(JSF_AJAX_REQUEST)), containsString(REGEX_VALIDATOR), not(containsString(NUMBER_CONVERTER)))); Matcher<java.lang.Iterable<? super ResourceKey>> matcher = hasItem(CORE_LIBRARY_MATCHER); assertThat(validatorScript.getResources(), matcher); } /** * <p class="changed_added_4_0"> * Test case when all converter and validators available on client. * </p> * * @throws Exception */ @Test public void testCreateValidatorScriptClientOnly() throws Exception { ClientValidatorRenderer renderer = createStubRenderer(createConverterFunction(), createValidatorFunction()); setupBehavior("", "", NumberConverter.class, Min.class); ComponentValidatorScript validatorScript = callGetScript(renderer); String script = validatorScript.toScript(); // check what generated script contains ajax and client side scripts. assertThat(script, allOf(not(containsString(JSF_AJAX_REQUEST)), containsString(REGEX_VALIDATOR), containsString(NUMBER_CONVERTER))); Matcher<java.lang.Iterable<? super ResourceKey>> matcher = hasItem(CORE_LIBRARY_MATCHER); assertThat(validatorScript.getResources(), matcher); } private LibraryScriptFunction createValidatorFunction() { return createFunction(REGEX_VALIDATOR, VALIDATOR_MESSAGE); } private LibraryScriptFunction createConverterFunction() { return createFunction(NUMBER_CONVERTER, VALIDATOR_MESSAGE); } private LibraryScriptFunction createFunction(final String name, Message validatorMessage) { LibraryFunction libraryScript = new LibraryFunction() { public String getName() { return name; } public Iterable<ResourceKey> getResources() { return CLIENT_VALIDATOR_LIBRARY; } }; return new LibraryScriptFunction(libraryScript, validatorMessage, VALIDATOR_PARAMS); } private ClientValidatorRenderer createStubRenderer(final LibraryScriptFunction converterFunction, final LibraryScriptFunction... validatorFunctions) { return new ClientValidatorRenderer() { @Override LibraryScriptFunction getClientSideConverterScript(FacesContext facesContext, ConverterDescriptor converter) throws ScriptNotFoundException { if (null == converterFunction) { throw new ScriptNotFoundException(); } return converterFunction; } @Override Collection<? extends LibraryScriptFunction> getClientSideValidatorScript(FacesContext facesContext, Collection<ValidatorDescriptor> validators) { return Lists.newArrayList(validatorFunctions); } }; } private void setupBehavior(Class<? extends Converter> converter, Class<?>... validators) throws Exception { setupBehaviorContext(input); if (null != converter) { setupDescription(converter, converterDescription); expect(mockBehavior.getConverter(behaviorContext)).andReturn(converterDescription); } else { expect(mockBehavior.getConverter(behaviorContext)).andStubReturn(null); } Collection<ValidatorDescriptor> validatorDescriptors = new ArrayList<ValidatorDescriptor>(validators.length); for (Class<?> validator : validators) { ValidatorDescriptor validatorDescriptor = controller.createNiceMock(ValidatorDescriptor.class); setupDescription(validator, validatorDescriptor); validatorDescriptors.add(validatorDescriptor); } expect(mockBehavior.getValidators(behaviorContext)).andReturn(validatorDescriptors); expect(input.getClientId(environment.getFacesContext())).andStubReturn("foo:bar"); } private void setupBehavior(String onvalid, String oninvalid, Class<? extends Converter> converter, Class<?>... validators) throws Exception { setupBehavior(converter, validators); expect(mockBehavior.getOnvalid()).andReturn(onvalid); expect(mockBehavior.getOninvalid()).andReturn(oninvalid); } private void setupDescription(Class<?> converter, FacesObjectDescriptor descriptor) { expect((Class) descriptor.getImplementationClass()).andStubReturn(converter); expect(converterDescription.getMessage()).andStubReturn(VALIDATOR_MESSAGE); expect((Map) converterDescription.getAdditionalParameters()).andStubReturn(VALIDATOR_PARAMS); } }