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 }