001/**
002 * Copyright 2005-2014 The Kuali Foundation
003 *
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/ecl2.php
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.kuali.rice.krad.web.controller;
017
018import org.apache.commons.lang3.StringUtils;
019import org.junit.Before;
020import org.junit.Test;
021import org.kuali.rice.krad.test.MockController;
022import org.kuali.rice.krad.test.TestForm;
023import org.kuali.rice.krad.uif.UifParameters;
024import org.kuali.rice.krad.uif.lifecycle.ViewPostMetadata;
025import org.kuali.rice.krad.web.form.UifFormBase;
026import org.kuali.rice.krad.web.form.UifFormManager;
027import org.springframework.mock.web.MockHttpServletRequest;
028import org.springframework.web.method.HandlerMethod;
029
030import java.lang.reflect.Method;
031
032import static org.junit.Assert.fail;
033
034/**
035 * Test cases for {@link org.kuali.rice.krad.web.controller.UifControllerHandlerInterceptor}.
036 *
037 * @author Kuali Rice Team (rice.collab@kuali.org)
038 */
039public class UifControllerHandlerInterceptorTest {
040
041    private UifControllerHandlerInterceptor handlerInterceptor;
042    private MockController controller;
043    private MockHttpServletRequest request;
044    private UifFormBase model;
045
046    @Before
047    public void setUp() throws Exception {
048        request = new MockHttpServletRequest();
049        request.setMethod("POST");
050
051        UifFormManager uifFormManager = new UifFormManager();
052
053        String formKey = "TEST";
054
055        model = new TestForm();
056        model.setFormKey(formKey);
057        uifFormManager.addSessionForm(model);
058
059        request.getSession().setAttribute(UifParameters.FORM_MANAGER, uifFormManager);
060        request.setParameter(UifParameters.FORM_KEY, formKey);
061
062        handlerInterceptor = new UifControllerHandlerInterceptor();
063        controller = new MockController();
064    }
065
066    /**
067     * Tests method access is being granted where annotations are present and the method is within
068     * the view configuration.
069     */
070    @Test
071    public void testCheckHandlerMethodAccess() throws Exception {
072        ViewPostMetadata viewPostMetadata = new ViewPostMetadata();
073        model.setViewPostMetadata(viewPostMetadata);
074
075        assertMethodAccess("Accessible annotation not picked up", "method1", true);
076        assertMethodAccess("Custom method should be allowed due to not being in the available methods", "method2", true);
077        viewPostMetadata.addAvailableMethodToCall( "method2" );
078        assertMethodAccess("Accessible annotation picked up where not present", "method2", false);
079
080        viewPostMetadata.addAccessibleMethodToCall("method4");
081        viewPostMetadata.addAccessibleMethodToCall("method6");
082
083        assertMethodAccess("Accessible method by view not picked up", "method4", true);
084        assertMethodAccess("Accessible method by view not picked up", "method6", true);
085
086        assertMethodAccess("Method not accessible for empty method to call", null, true);
087    }
088
089    /**
090     * Helper method for testing {@link UifControllerHandlerInterceptor#checkHandlerMethodAccess}.
091     *
092     * @param failureMessage message to show if assert fails
093     * @param methodToCall controller method to check access for
094     * @param access expected access result
095     * @throws Exception
096     */
097    protected void assertMethodAccess(String failureMessage, String methodToCall, boolean access) throws Exception {
098        request.setParameter(UifParameters.METHOD_TO_CALL, methodToCall);
099
100        // if method to call is blank, pick a method as the default handler
101        if (StringUtils.isBlank(methodToCall)) {
102            methodToCall = "method5";
103        }
104
105        try {
106            handlerInterceptor.checkHandlerMethodAccess(request, getHandlerMethod(methodToCall));
107        } catch (MethodAccessException e) {
108            if (access) {
109                fail(failureMessage);
110            }
111
112            return;
113        }
114
115        if (!access) {
116            fail(failureMessage);
117        }
118    }
119
120    /**
121     * Builds instance of a handler method (using the controller) for the given method to call.
122     *
123     * @param methodToCall method on controller to build handler for
124     * @return handler method instance
125     */
126    protected HandlerMethod getHandlerMethod(String methodToCall) {
127        Method method = null;
128
129        for (Method controllerMethod : controller.getClass().getMethods()) {
130            if (StringUtils.equals(controllerMethod.getName(), methodToCall)) {
131                method = controllerMethod;
132            }
133        }
134
135        if (method != null) {
136            return new HandlerMethod(controller, method);
137        }
138
139        return null;
140    }
141}