/* * Copyright 2010 Lincoln Baxter, III * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.ocpsoft.pretty.faces.config.annotation; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import java.util.Arrays; import java.util.Collections; import java.util.List; import org.junit.Test; import com.ocpsoft.pretty.faces.annotation.URLAction; import com.ocpsoft.pretty.faces.annotation.URLAction.PhaseId; import com.ocpsoft.pretty.faces.annotation.URLActions; import com.ocpsoft.pretty.faces.annotation.URLBeanName; import com.ocpsoft.pretty.faces.annotation.URLMapping; import com.ocpsoft.pretty.faces.annotation.URLMappings; import com.ocpsoft.pretty.faces.annotation.URLQueryParameter; import com.ocpsoft.pretty.faces.annotation.URLValidator; import com.ocpsoft.pretty.faces.config.PrettyConfig; import com.ocpsoft.pretty.faces.config.PrettyConfigBuilder; import com.ocpsoft.pretty.faces.config.mapping.PathValidator; import com.ocpsoft.pretty.faces.config.mapping.QueryParameter; import com.ocpsoft.pretty.faces.config.mapping.UrlAction; import com.ocpsoft.pretty.faces.config.mapping.UrlMapping; import com.ocpsoft.pretty.faces.el.ConstantExpression; import com.ocpsoft.pretty.faces.el.LazyExpression; public class PrettyAnnotationHandlerTest { @Test public void testNotAnnotatedClass() { // create handler and process class PrettyAnnotationHandler handler = new PrettyAnnotationHandler(null); handler.visit(NotAnnotatedClass.class); // build configuration PrettyConfigBuilder configBuilder = new PrettyConfigBuilder(); handler.build(configBuilder); PrettyConfig config = configBuilder.build(); // no mappings added assertNotNull(config.getMappings()); assertEquals(0, config.getMappings().size()); } @Test public void testSimpleMapping() { // create handler and process class PrettyAnnotationHandler handler = new PrettyAnnotationHandler(null); handler.visit(ClassWithSimpleMapping.class); // build configuration PrettyConfigBuilder configBuilder = new PrettyConfigBuilder(); handler.build(configBuilder); PrettyConfig config = configBuilder.build(); // no mappings added assertNotNull(config.getMappings()); assertEquals(1, config.getMappings().size()); // validate mapping properties UrlMapping mapping = config.getMappings().get(0); assertEquals("simple", mapping.getId()); assertEquals("/some/url", mapping.getPattern()); assertEquals("/view.jsf", mapping.getViewId()); assertEquals(false, mapping.isOutbound()); assertEquals(false, mapping.isOnPostback()); assertEquals(0, mapping.getActions().size()); assertEquals(0, mapping.getQueryParams().size()); assertEquals(0, mapping.getPathValidators().size()); } @Test public void testMappingWithPathValidation() { // create handler and process class PrettyAnnotationHandler handler = new PrettyAnnotationHandler(null); handler.visit(ClassWithMappingAndPathValidation.class); // build configuration PrettyConfigBuilder configBuilder = new PrettyConfigBuilder(); handler.build(configBuilder); PrettyConfig config = configBuilder.build(); // no mappings added assertNotNull(config.getMappings()); assertEquals(1, config.getMappings().size()); // validate mapping properties UrlMapping mapping = config.getMappings().get(0); assertEquals("simple", mapping.getId()); assertEquals("/some/url", mapping.getPattern()); assertEquals("/view.jsf", mapping.getViewId()); assertEquals(true, mapping.isOutbound()); assertEquals(true, mapping.isOnPostback()); assertEquals(0, mapping.getActions().size()); assertEquals(0, mapping.getQueryParams().size()); assertEquals(1, mapping.getPathValidators().size()); // check path validation PathValidator validator = mapping.getPathValidators().get(0); assertEquals(0, validator.getIndex()); assertEquals("#{bean.action}", validator.getOnError()); assertEquals("myValidator myOtherValidator", validator.getValidatorIds()); } @Test public void testMappingWithOneLazyExpressionAction() { // create handler and process class PrettyAnnotationHandler handler = new PrettyAnnotationHandler(null); handler.visit(ClassWithSingleLazyExpressionAction.class); // build configuration PrettyConfigBuilder configBuilder = new PrettyConfigBuilder(); handler.build(configBuilder); PrettyConfig config = configBuilder.build(); // no mappings added assertNotNull(config.getMappings()); assertEquals(1, config.getMappings().size()); // validate mapping properties UrlMapping mapping = config.getMappings().get(0); assertEquals("singleLazyExpressionAction", mapping.getId()); assertEquals("/some/url", mapping.getPattern()); assertEquals("/view.jsf", mapping.getViewId()); assertEquals(true, mapping.isOutbound()); assertEquals(true, mapping.isOnPostback()); assertEquals(0, mapping.getQueryParams().size()); assertEquals(1, mapping.getActions().size()); assertEquals(0, mapping.getPathValidators().size()); // validate action UrlAction action = mapping.getActions().get(0); assertEquals(PhaseId.RESTORE_VIEW, action.getPhaseId()); // validate PrettyExpression assertNotNull(action.getAction()); assertEquals(LazyExpression.class, action.getAction().getClass()); LazyExpression actionExpression = (LazyExpression) action.getAction(); assertEquals(ClassWithSingleLazyExpressionAction.class, actionExpression.getBeanClass()); assertEquals("actionMethod", actionExpression.getComponent()); } @Test public void testMappingWithOneConstantExpressionAction() { // create handler and process class PrettyAnnotationHandler handler = new PrettyAnnotationHandler(null); handler.visit(ClassWithSingleConstantExpressionAction.class); // build configuration PrettyConfigBuilder configBuilder = new PrettyConfigBuilder(); handler.build(configBuilder); PrettyConfig config = configBuilder.build(); // no mappings added assertNotNull(config.getMappings()); assertEquals(1, config.getMappings().size()); // validate mapping properties UrlMapping mapping = config.getMappings().get(0); assertEquals("singleConstantExpressionAction", mapping.getId()); assertEquals("/some/url", mapping.getPattern()); assertEquals("/view.jsf", mapping.getViewId()); assertEquals(true, mapping.isOutbound()); assertEquals(true, mapping.isOnPostback()); assertEquals(0, mapping.getQueryParams().size()); assertEquals(1, mapping.getActions().size()); assertEquals(0, mapping.getPathValidators().size()); // validate action UrlAction action = mapping.getActions().get(0); assertEquals(PhaseId.RESTORE_VIEW, action.getPhaseId()); // validate PrettyExpression assertNotNull(action.getAction()); assertEquals(ConstantExpression.class, action.getAction().getClass()); assertEquals("#{someBean.actionMethod}", action.getAction().getELExpression()); } @Test public void testMappingWithMultipleActions() { // create handler and process class PrettyAnnotationHandler handler = new PrettyAnnotationHandler(null); handler.visit(ClassWithMultipleActions.class); // build configuration PrettyConfigBuilder configBuilder = new PrettyConfigBuilder(); handler.build(configBuilder); PrettyConfig config = configBuilder.build(); // no mappings added assertNotNull(config.getMappings()); assertEquals(1, config.getMappings().size()); // validate mapping properties UrlMapping mapping = config.getMappings().get(0); assertEquals("multipleActions", mapping.getId()); assertEquals("/some/url", mapping.getPattern()); assertEquals("/view.jsf", mapping.getViewId()); assertEquals(true, mapping.isOutbound()); assertEquals(true, mapping.isOnPostback()); assertEquals(0, mapping.getQueryParams().size()); assertEquals(2, mapping.getActions().size()); assertEquals(0, mapping.getPathValidators().size()); // validate first action UrlAction firstAction = mapping.getActions().get(0); assertEquals(PhaseId.RENDER_RESPONSE, firstAction.getPhaseId()); assertNotNull(firstAction.getAction()); assertEquals(LazyExpression.class, firstAction.getAction().getClass()); LazyExpression firstActionExpression = (LazyExpression) firstAction.getAction(); assertEquals(ClassWithMultipleActions.class, firstActionExpression.getBeanClass()); assertEquals("actionMethod", firstActionExpression.getComponent()); // validate second action UrlAction secondAction = mapping.getActions().get(1); assertEquals(PhaseId.INVOKE_APPLICATION, secondAction.getPhaseId()); assertNotNull(secondAction.getAction()); assertEquals(LazyExpression.class, secondAction.getAction().getClass()); LazyExpression secondActionExpression = (LazyExpression) secondAction.getAction(); assertEquals(ClassWithMultipleActions.class, secondActionExpression.getBeanClass()); assertEquals("actionMethod", secondActionExpression.getComponent()); } @Test public void testMappingWithSingleQueryParameter() { // create handler and process class PrettyAnnotationHandler handler = new PrettyAnnotationHandler(null); handler.visit(ClassWithSingleQueryParameter.class); // build configuration PrettyConfigBuilder configBuilder = new PrettyConfigBuilder(); handler.build(configBuilder); PrettyConfig config = configBuilder.build(); // no mappings added assertNotNull(config.getMappings()); assertEquals(1, config.getMappings().size()); // validate mapping properties UrlMapping mapping = config.getMappings().get(0); assertEquals("singleQueryParamater", mapping.getId()); assertEquals("/some/url", mapping.getPattern()); assertEquals("/view.jsf", mapping.getViewId()); assertEquals(true, mapping.isOutbound()); assertEquals(true, mapping.isOnPostback()); assertEquals(0, mapping.getActions().size()); assertEquals(1, mapping.getQueryParams().size()); assertEquals(0, mapping.getPathValidators().size()); // validate query parameter QueryParameter queryParameter = mapping.getQueryParams().get(0); assertEquals("myQueryParam", queryParameter.getName()); assertEquals(true, queryParameter.isOnPostback()); // validate PrettyExpression assertNotNull(queryParameter.getExpression()); assertEquals(ConstantExpression.class, queryParameter.getExpression().getClass()); assertEquals("#{myQueryParamBean.someParameter}", queryParameter.getExpression().getELExpression()); } @Test public void testMappingWithSingleQueryParameterAndValidation() { // create handler and process class PrettyAnnotationHandler handler = new PrettyAnnotationHandler(null); handler.visit(ClassWithSingleQueryParameterAndValidation.class); // build configuration PrettyConfigBuilder configBuilder = new PrettyConfigBuilder(); handler.build(configBuilder); PrettyConfig config = configBuilder.build(); // no mappings added assertNotNull(config.getMappings()); assertEquals(1, config.getMappings().size()); // validate mapping properties UrlMapping mapping = config.getMappings().get(0); assertEquals("singleQueryParamater", mapping.getId()); assertEquals("/some/url", mapping.getPattern()); assertEquals("/view.jsf", mapping.getViewId()); assertEquals(true, mapping.isOutbound()); assertEquals(true, mapping.isOnPostback()); assertEquals(0, mapping.getActions().size()); assertEquals(1, mapping.getQueryParams().size()); assertEquals(0, mapping.getPathValidators().size()); // validate query parameter QueryParameter queryParameter = mapping.getQueryParams().get(0); assertEquals("myQueryParam", queryParameter.getName()); assertEquals(false, queryParameter.isOnPostback()); assertEquals("#{bean.action}", queryParameter.getOnError()); assertEquals(2, queryParameter.getValidatorIdList().size()); assertEquals("myValidator myOtherValidator", queryParameter.getValidatorIds()); // validate PrettyExpression assertNotNull(queryParameter.getExpression()); assertEquals(ConstantExpression.class, queryParameter.getExpression().getClass()); assertEquals("#{myQueryParamBean.someParameter}", queryParameter.getExpression().getELExpression()); } @Test public void testClassWithMultipleMappings() { // create handler and process class PrettyAnnotationHandler handler = new PrettyAnnotationHandler(null); handler.visit(ClassWithMultipleMappings.class); // build configuration PrettyConfigBuilder configBuilder = new PrettyConfigBuilder(); handler.build(configBuilder); PrettyConfig config = configBuilder.build(); // no mappings added assertNotNull(config.getMappings()); assertEquals(2, config.getMappings().size()); // validate mapping properties for mappingA UrlMapping mappingA = config.getMappingById("mappingA"); assertNotNull(mappingA); assertEquals("mappingA", mappingA.getId()); assertEquals("/some/url/a", mappingA.getPattern()); assertEquals("/view.jsf", mappingA.getViewId()); assertEquals(true, mappingA.isOutbound()); assertEquals(true, mappingA.isOnPostback()); assertEquals(1, mappingA.getActions().size()); assertEquals(2, mappingA.getQueryParams().size()); assertEquals(0, mappingA.getPathValidators().size()); assertEquals("#{multiMappingBean.actionForBoth}", mappingA.getActions().get(0).getAction().getELExpression()); // we don't know the order in which the query parameters are added List<String> queryParamExpressionsA = Arrays.asList( mappingA.getQueryParams().get(0).getExpression().getELExpression(), mappingA.getQueryParams().get(1).getExpression().getELExpression() ); Collections.sort(queryParamExpressionsA); assertEquals("#{multiMappingBean.queryParameterForA}", queryParamExpressionsA.get(0)); assertEquals("#{multiMappingBean.queryParameterForBoth}", queryParamExpressionsA.get(1)); // validate mapping properties for mappingB UrlMapping mappingB = config.getMappingById("mappingB"); assertNotNull(mappingB); assertEquals("mappingB", mappingB.getId()); assertEquals("/some/url/b", mappingB.getPattern()); assertEquals("/view.jsf", mappingB.getViewId()); assertEquals(true, mappingB.isOutbound()); assertEquals(true, mappingB.isOnPostback()); assertEquals(2, mappingB.getActions().size()); assertEquals(1, mappingB.getQueryParams().size()); assertEquals(0, mappingB.getPathValidators().size()); assertEquals("#{multiMappingBean.queryParameterForBoth}", mappingB.getQueryParams().get(0).getExpression().getELExpression()); // we don't know the order in which the actions are added List<String> actionExpressionsB = Arrays.asList( mappingB.getActions().get(0).getAction().getELExpression(), mappingB.getActions().get(1).getAction().getELExpression() ); Collections.sort(actionExpressionsB); assertEquals("#{multiMappingBean.actionForBoth}", actionExpressionsB.get(0)); assertEquals("#{multiMappingBean.actionForB}", actionExpressionsB.get(1)); } /** * Simple class without any PrettyFaces annotations */ public class NotAnnotatedClass { // nothing } /** * Simple class with a single {@link URLMapping} annotation */ @URLMapping(id = "simple", pattern = "/some/url", viewId = "/view.jsf", outbound = false, onPostback = false) public class ClassWithSimpleMapping { // nothing } /** * Simple class with a single {@link URLMapping} annotation and a validation rule */ @URLMapping(id = "simple", pattern = "/some/url", viewId = "/view.jsf", validation = @URLValidator(index = 0, onError = "#{bean.action}", validatorIds = { "myValidator", "myOtherValidator" })) public class ClassWithMappingAndPathValidation { // nothing } /** * Simple class with a mapping and one annotated action method (lazy expression) */ @URLMapping(id = "singleLazyExpressionAction", pattern = "/some/url", viewId = "/view.jsf") public class ClassWithSingleLazyExpressionAction { @URLAction public void actionMethod() { // nothing } } /** * Simple class with a mapping and one annotated action method (constant expression) */ @URLMapping(id = "singleConstantExpressionAction", pattern = "/some/url", viewId = "/view.jsf") @URLBeanName("someBean") public class ClassWithSingleConstantExpressionAction { @URLAction public void actionMethod() { // nothing } } /** * Simple class with a mapping and an action method referenced by multiple {@link URLAction}s. */ @URLMapping(id = "multipleActions", pattern = "/some/url", viewId = "/view.jsf") public class ClassWithMultipleActions { @URLActions(actions = { @URLAction(phaseId = URLAction.PhaseId.RENDER_RESPONSE), @URLAction(phaseId = URLAction.PhaseId.INVOKE_APPLICATION) }) public void actionMethod() { // nothing } } /** * Simple class with a single mapping and a query parameter */ @URLMapping(id = "singleQueryParamater", pattern = "/some/url", viewId = "/view.jsf") @URLBeanName("myQueryParamBean") public class ClassWithSingleQueryParameter { @URLQueryParameter("myQueryParam") private String someParameter; } /** * Simple class with a single mapping and a query parameter with validation */ @URLMapping(id = "singleQueryParamater", pattern = "/some/url", viewId = "/view.jsf") @URLBeanName("myQueryParamBean") public class ClassWithSingleQueryParameterAndValidation { @URLQueryParameter(value = "myQueryParam", onPostback = false) @URLValidator(index = 0, onError = "#{bean.action}", validatorIds = { "myValidator", "myOtherValidator" }) private String someParameter; } /* * Class with two mappings */ @URLMappings(mappings = { @URLMapping(id = "mappingA", pattern = "/some/url/a", viewId = "/view.jsf"), @URLMapping(id = "mappingB", pattern = "/some/url/b", viewId = "/view.jsf") }) @URLBeanName("multiMappingBean") public class ClassWithMultipleMappings { // assigned to both mappings @URLQueryParameter("q1") private String queryParameterForBoth; // assigned to both mappings @URLQueryParameter(value = "q2", mappingId = "mappingA") private String queryParameterForA; // assigned to both mappings @URLAction public void actionForBoth() { // nothing } // assigned to both mappings @URLAction(mappingId = "mappingB") public void actionForB() { // nothing } } }