001 /** 002 * Copyright 2005-2013 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 */ 016 package org.kuali.rice.krad.util; 017 018 import org.junit.Assert; 019 import org.junit.Test; 020 import org.kuali.rice.krad.datadictionary.state.StateMapping; 021 import org.kuali.rice.krad.datadictionary.state.StateMappingBase; 022 import org.kuali.rice.krad.datadictionary.validation.constraint.BaseConstraint; 023 import org.kuali.rice.krad.datadictionary.validation.constraint.Constraint; 024 import org.kuali.rice.krad.datadictionary.validation.constraint.ValidCharactersConstraint; 025 import org.kuali.rice.krad.uif.util.ConstraintStateUtils; 026 import org.kuali.rice.krad.uif.view.View; 027 import org.kuali.rice.krad.web.form.UifFormBase; 028 029 import java.util.ArrayList; 030 import java.util.Arrays; 031 import java.util.HashMap; 032 import java.util.List; 033 import java.util.Map; 034 035 /** 036 * Tests for constraintStateUtils class to insure correct logic for applicable constraints in state based validation 037 * 038 * @author Kuali Rice Team (rice.collab@kuali.org) 039 */ 040 public class ConstraintStateUtilsTest { 041 042 /** 043 * Testing state based validation utility methods that the service uses to determine applicable constraints 044 */ 045 @Test 046 public void testStateValidationUtil() { 047 BaseConstraint genericConstraint = new ValidCharactersConstraint() {}; 048 List<String> cStates = new ArrayList<String>(); 049 cStates.add("state1"); 050 cStates.add("state3>state5"); 051 cStates.add("state7+"); 052 genericConstraint.setStates(cStates); 053 054 StateMapping genericStateMapping = new StateMappingBase(); 055 List<String> states = new ArrayList<String>(); 056 states.add("state1"); 057 states.add("state2"); 058 states.add("state3"); 059 states.add("state4"); 060 states.add("state5"); 061 states.add("state6"); 062 states.add("state7"); 063 states.add("state8"); 064 genericStateMapping.setStates(states); 065 066 //constraint applies for state1 067 boolean applies = ConstraintStateUtils.constraintAppliesForState("state1", genericConstraint, 068 genericStateMapping); 069 Assert.assertTrue(applies); 070 Constraint constraintResult = ConstraintStateUtils.getApplicableConstraint(genericConstraint, "state1", 071 genericStateMapping); 072 Assert.assertNotNull(constraintResult); 073 074 //constraint does not apply for state2 075 applies = ConstraintStateUtils.constraintAppliesForState("state2", genericConstraint, genericStateMapping); 076 Assert.assertFalse(applies); 077 constraintResult = ConstraintStateUtils.getApplicableConstraint(genericConstraint, "state2", 078 genericStateMapping); 079 Assert.assertNull(constraintResult); 080 081 //constraint applies for state3 through state5 082 applies = ConstraintStateUtils.constraintAppliesForState("state3", genericConstraint, genericStateMapping); 083 Assert.assertTrue(applies); 084 constraintResult = ConstraintStateUtils.getApplicableConstraint(genericConstraint, "state3", 085 genericStateMapping); 086 Assert.assertNotNull(constraintResult); 087 088 applies = ConstraintStateUtils.constraintAppliesForState("state4", genericConstraint, genericStateMapping); 089 Assert.assertTrue(applies); 090 constraintResult = ConstraintStateUtils.getApplicableConstraint(genericConstraint, "state4", 091 genericStateMapping); 092 Assert.assertNotNull(constraintResult); 093 094 applies = ConstraintStateUtils.constraintAppliesForState("state5", genericConstraint, genericStateMapping); 095 Assert.assertTrue(applies); 096 constraintResult = ConstraintStateUtils.getApplicableConstraint(genericConstraint, "state5", 097 genericStateMapping); 098 Assert.assertNotNull(constraintResult); 099 100 //constraint applies for state7 and after 101 applies = ConstraintStateUtils.constraintAppliesForState("state7", genericConstraint, genericStateMapping); 102 Assert.assertTrue(applies); 103 constraintResult = ConstraintStateUtils.getApplicableConstraint(genericConstraint, "state7", 104 genericStateMapping); 105 Assert.assertNotNull(constraintResult); 106 107 applies = ConstraintStateUtils.constraintAppliesForState("state8", genericConstraint, genericStateMapping); 108 Assert.assertTrue(applies); 109 constraintResult = ConstraintStateUtils.getApplicableConstraint(genericConstraint, "state8", 110 genericStateMapping); 111 Assert.assertNotNull(constraintResult); 112 113 //constraint does not apply for non-listed states or the empty state 114 applies = ConstraintStateUtils.constraintAppliesForState("fake", genericConstraint, genericStateMapping); 115 Assert.assertFalse(applies); 116 constraintResult = ConstraintStateUtils.getApplicableConstraint(genericConstraint, "notListed", 117 genericStateMapping); 118 Assert.assertNull(constraintResult); 119 120 //constraint applies if no state (state validation not setup or "stateless") 121 applies = ConstraintStateUtils.constraintAppliesForState(null, genericConstraint, genericStateMapping); 122 Assert.assertTrue(applies); 123 constraintResult = ConstraintStateUtils.getApplicableConstraint(genericConstraint, null, genericStateMapping); 124 Assert.assertNotNull(constraintResult); 125 126 applies = ConstraintStateUtils.constraintAppliesForState("", genericConstraint, genericStateMapping); 127 Assert.assertTrue(applies); 128 constraintResult = ConstraintStateUtils.getApplicableConstraint(genericConstraint, "", genericStateMapping); 129 Assert.assertNotNull(constraintResult); 130 131 //applies for stateless situations 132 applies = ConstraintStateUtils.constraintAppliesForState(null, genericConstraint, null); 133 Assert.assertTrue(applies); 134 constraintResult = ConstraintStateUtils.getApplicableConstraint(genericConstraint, null, null); 135 Assert.assertNotNull(constraintResult); 136 137 //constraint applies if null state mapping (state validation not setup or "stateless") 138 applies = ConstraintStateUtils.constraintAppliesForState("state3", genericConstraint, null); 139 Assert.assertTrue(applies); 140 constraintResult = ConstraintStateUtils.getApplicableConstraint(genericConstraint, "state3", null); 141 Assert.assertNotNull(constraintResult); 142 143 //throws error if stateMapping does not contain the current state (bad state mapping object) 144 try { 145 applies = ConstraintStateUtils.constraintAppliesForState("state3", genericConstraint, 146 new StateMappingBase()); 147 } catch (Exception e) { 148 Assert.assertNotNull(e); 149 } 150 151 List<BaseConstraint> constraintStateOverrides = new ArrayList<BaseConstraint>(); 152 final List<String> overrideStates = Arrays.asList(new String[]{"state2", "state3"}); 153 BaseConstraint override = new ValidCharactersConstraint() {{ 154 setStates(overrideStates); 155 }}; 156 constraintStateOverrides.add(override); 157 158 genericConstraint.setConstraintStateOverrides(constraintStateOverrides); 159 160 //should return back the same constraint 161 constraintResult = ConstraintStateUtils.getApplicableConstraint(genericConstraint, "state1", 162 genericStateMapping); 163 Assert.assertNotNull(constraintResult); 164 Assert.assertEquals(genericConstraint, constraintResult); 165 166 //should return back the override (testing common case) 167 constraintResult = ConstraintStateUtils.getApplicableConstraint(genericConstraint, "state3", 168 genericStateMapping); 169 Assert.assertNotNull(constraintResult); 170 Assert.assertEquals(override, constraintResult); 171 172 //should return back the override (testing where constraint does not apply but override does) 173 constraintResult = ConstraintStateUtils.getApplicableConstraint(genericConstraint, "state2", 174 genericStateMapping); 175 Assert.assertNotNull(constraintResult); 176 Assert.assertEquals(override, constraintResult); 177 178 //should return back the same constraint (testing where overrides are configured but none match 179 //but the constraint is applicable for this state) 180 constraintResult = ConstraintStateUtils.getApplicableConstraint(genericConstraint, "state4", 181 genericStateMapping); 182 Assert.assertNotNull(constraintResult); 183 Assert.assertEquals(genericConstraint, constraintResult); 184 185 //should return back null (testing where the constrain overrides and the constraint do not match state) 186 constraintResult = ConstraintStateUtils.getApplicableConstraint(genericConstraint, "state6", 187 genericStateMapping); 188 Assert.assertNull(constraintResult); 189 190 } 191 192 /** 193 * Test for getClientViewValidationState method that returns the state the client should validate for 194 */ 195 @Test 196 public void testCustomClientsideUtilMethod() { 197 View view = new View(); 198 StateMapping genericStateMapping = new StateMappingBase(); 199 List<String> states = new ArrayList<String>(); 200 states.add("state1"); 201 states.add("state2"); 202 states.add("state3"); 203 states.add("state4"); 204 states.add("state5"); 205 states.add("state6"); 206 states.add("state7"); 207 states.add("state8"); 208 genericStateMapping.setStates(states); 209 genericStateMapping.setStatePropertyName("state"); 210 UifFormBase model = new UifFormBase(); 211 212 Map<String, String> customClientStateMap = new HashMap<String, String>(); 213 customClientStateMap.put("state1", "state3"); 214 customClientStateMap.put("state4", "state8"); 215 customClientStateMap.put("state7", "state7"); 216 genericStateMapping.setCustomClientSideValidationStates(customClientStateMap); 217 view.setStateMapping(genericStateMapping); 218 219 //custom 220 model.setState("state1"); 221 String state = ConstraintStateUtils.getClientViewValidationState(model, view); 222 Assert.assertEquals("state3", state); 223 model.setState("state4"); 224 state = ConstraintStateUtils.getClientViewValidationState(model, view); 225 Assert.assertEquals("state8", state); 226 model.setState("state7"); 227 state = ConstraintStateUtils.getClientViewValidationState(model, view); 228 Assert.assertEquals("state7", state); 229 230 //should return next state 231 model.setState("state2"); 232 state = ConstraintStateUtils.getClientViewValidationState(model, view); 233 Assert.assertEquals("state3", state); 234 model.setState("state3"); 235 state = ConstraintStateUtils.getClientViewValidationState(model, view); 236 Assert.assertEquals("state4", state); 237 model.setState("state5"); 238 state = ConstraintStateUtils.getClientViewValidationState(model, view); 239 Assert.assertEquals("state6", state); 240 241 //should return state8 (no next state) 242 model.setState("state8"); 243 state = ConstraintStateUtils.getClientViewValidationState(model, view); 244 Assert.assertEquals("state8", state); 245 246 //should back same state sent in - bad or no configurations, if then used for get applicableConstraint 247 //will get back the appropriate constraint 248 model.setState("fake"); 249 state = ConstraintStateUtils.getClientViewValidationState(model, view); 250 Assert.assertEquals("fake", state); 251 252 model.setState(null); 253 state = ConstraintStateUtils.getClientViewValidationState(model, view); 254 Assert.assertNull(state); 255 256 model.setState(""); 257 state = ConstraintStateUtils.getClientViewValidationState(model, view); 258 Assert.assertEquals("", state); 259 260 model.setState("state1"); 261 StateMapping emptyStateMapping = new StateMappingBase(); 262 emptyStateMapping.setStatePropertyName("state"); 263 view.setStateMapping(emptyStateMapping); 264 state = ConstraintStateUtils.getClientViewValidationState(model, view); 265 Assert.assertEquals("state1", state); 266 267 //return back null state when StateMapping is not configured 268 view.setStateMapping(null); 269 state = ConstraintStateUtils.getClientViewValidationState(model, view); 270 Assert.assertNull(state); 271 } 272 }