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    }