001    /*
002     * Copyright 2002-2004 the original author or authors.
003     * 
004     * Licensed under the Apache License, Version 2.0 (the "License"); you may not
005     * use this file except in compliance with the License. You may obtain a copy of
006     * the License at
007     * 
008     * http://www.apache.org/licenses/LICENSE-2.0
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, WITHOUT
012     * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
013     * License for the specific language governing permissions and limitations under
014     * the License.
015     */
016    package org.springframework.richclient.form;
017    
018    import javax.swing.JComponent;
019    import javax.swing.JRootPane;
020    import javax.swing.JTextField;
021    
022    import org.springframework.binding.form.ValidatingFormModel;
023    import org.springframework.richclient.application.support.DefaultApplicationServices;
024    import org.springframework.richclient.core.Guarded;
025    import org.springframework.richclient.test.SpringRichTestCase;
026    import org.springframework.rules.Rules;
027    import org.springframework.rules.support.DefaultRulesSource;
028    
029    /**
030     * @author Peter De Bruycker
031     */
032    public class FormGuardTests extends SpringRichTestCase {
033    
034        private ValidatingFormModel formModel;
035    
036        private TestGuarded guarded;
037    
038        private static class TestGuarded implements Guarded {
039    
040            private boolean enabled = true; // initially enabled
041    
042            public boolean isEnabled() {
043                return enabled;
044            }
045    
046            public void setEnabled(boolean enabled) {
047                this.enabled = enabled;
048            }
049        }
050    
051        private static class TestBean {
052            private String field;
053            private String field2;
054    
055            public String getField() {
056                return field;
057            }
058    
059            public String getField2() {
060                return field2;
061            }
062    
063            public void setField(String string) {
064                field = string;
065            }
066    
067            public void setField2(String string) {
068                field2 = string;
069            }
070        }
071        
072        private static class TestForm extends AbstractForm {
073            TestForm() {
074                this(new TestBean());
075            }
076            TestForm(TestBean bean) {
077                this(FormModelHelper.createFormModel(bean));
078            }
079            TestForm(ValidatingFormModel formModel) {
080                super(formModel, "testform");
081            }
082            protected JComponent createFormControl()
083            {
084                JTextField textControl = (JTextField)getBindingFactory().createBinding("field").getControl();
085                
086                // provide a rootpane for the form's control.
087                JRootPane rootPane= new JRootPane();
088                rootPane.add(textControl);
089                
090                return textControl;
091            }
092            
093            protected String getRevertCommandFaceDescriptorId()
094            {
095                return "revert";
096            }
097            
098            protected String getCommitCommandFaceDescriptorId()
099            {
100                return "commit";
101            }
102            
103        }
104    
105        protected void doSetUp() {
106            guarded = new TestGuarded();
107            TestBean bean = new TestBean();
108            bean.setField("ok"); // initialize rule to be valid.
109            formModel = FormModelHelper.createFormModel(bean);
110            formModel.setEnabled(true);
111        }
112    
113        /**
114         * May be implemented in subclasses that need to register services with the global
115         * application services instance.
116         */
117        protected void registerAdditionalServices( DefaultApplicationServices applicationServices ) {
118            DefaultRulesSource rulesSource = new DefaultRulesSource();
119            Rules rules = new Rules(TestBean.class);
120            rules.add("field", rules.required());
121            rulesSource.addRules(rules);
122    
123            applicationServices.setRulesSource(rulesSource);
124        }
125    
126        public void testEnabledState() {
127            new FormGuard(formModel, guarded);
128            assertTrue("guarded should still be enabled", guarded.isEnabled());
129    
130            formModel.setEnabled(false);
131            assertFalse("guarded should be disabled", guarded.isEnabled());
132    
133            formModel.setEnabled(true);
134            assertTrue("guarded should be enabled", guarded.isEnabled());
135        }
136    
137        public void testErrorState() {        
138            new FormGuard(formModel, guarded);
139            assertTrue("guarded should still be enabled", guarded.isEnabled());
140    
141            formModel.getValueModel("field").setValue(null);
142            assertTrue(formModel.getValidationResults().getHasErrors());
143            assertFalse("guarded should be disabled", guarded.isEnabled());
144    
145            formModel.getValueModel("field").setValue("test");
146            assertFalse(formModel.getValidationResults().getHasErrors());
147            assertTrue("guarded should be enabled", guarded.isEnabled());
148        }
149        
150        
151        // Tests added based on requirements in RCP-39
152        // The form's action commands should get enabled/disabled based on the form's state
153        
154        public void testNewFormCommandGuarding() {
155            TestForm form = new TestForm(formModel);
156            form.attachFormGuard(guarded, FormGuard.LIKE_NEWFORMOBJCOMMAND);
157            Guarded nfCmd = form.getNewFormObjectCommand();
158            
159            //default enabled
160            assertTrue("guarded like newForm should be initially enabled", guarded.isEnabled());
161            assertTrue("newForm should be initially enabled", nfCmd.isEnabled());
162            
163            // disable form --> disabled
164            form.setEnabled(false);
165            assertFalse("guarded like newform should be disabled with form", guarded.isEnabled());
166            assertFalse("newform should be disabled with form", nfCmd.isEnabled());
167            
168            // enable form --> enabled
169            form.setEnabled(true);
170            assertTrue("guarded like newForm should be initially enabled", guarded.isEnabled());
171            assertTrue("newForm should be initially enabled", nfCmd.isEnabled());
172            
173            // trigger validation-error --> still enabled
174            ((JTextField)form.getControl()).setText(null);
175            assertTrue(formModel.getValidationResults().getHasErrors());
176            assertTrue("guarded like newForm should be initially enabled", guarded.isEnabled());
177            assertTrue("newForm should be initially enabled", nfCmd.isEnabled());
178        }
179        
180        public void testRevertCommandGuarding() {
181            TestForm form = new TestForm(formModel);
182            form.attachFormGuard( guarded, FormGuard.LIKE_REVERTCOMMAND);
183            Guarded rvtCmd = form.getRevertCommand();
184            
185            // initially --> disabled
186            assertFalse("guarded like revert should be initially disabled", guarded.isEnabled());
187            assertFalse("revert should be initially disabled", rvtCmd.isEnabled());
188    
189            // create dirt with errors --> enabled
190            ((JTextField)form.getControl()).setText(null);
191            assertTrue(formModel.getValidationResults().getHasErrors());
192            assertTrue(formModel.isDirty());
193            assertTrue("guarded like revert should be enabled when there are changes", guarded.isEnabled());
194            assertTrue("revert should be enabled when there are changes", rvtCmd.isEnabled());
195            
196            // relieve errors --> enabled
197            ((JTextField)form.getControl()).setText("nok");
198            assertFalse(formModel.getValidationResults().getHasErrors());
199            assertTrue(formModel.isDirty());
200            assertTrue("guarded like revert should be enabled when there are changes", guarded.isEnabled());
201            assertTrue("revert should be enabled when there are changes", rvtCmd.isEnabled());
202            
203            // disable form --> disabled
204            form.setEnabled(false);
205            assertFalse("guarded like revert should be disabled with form", guarded.isEnabled());
206            assertFalse("revert should be disabled with form", rvtCmd.isEnabled());
207            
208            // enable form --> enabled
209            form.setEnabled(true);
210            assertTrue("guarded like revert should be enabled with form", guarded.isEnabled());
211            assertTrue("revert should be enabled with form", rvtCmd.isEnabled());
212            
213            // revert --> disabled
214            form.revert();
215            assertFalse("guarded like revert should be disabled when no changes left", guarded.isEnabled());
216            assertFalse("revert should be disabled when no changes left", rvtCmd.isEnabled());
217        }
218    
219        public void testCommitCommandGuarding() {
220            TestForm form = new TestForm(formModel);
221            new FormGuard(formModel, guarded, FormGuard.LIKE_COMMITCOMMAND);
222            Guarded cmtCmd = form.getCommitCommand();
223            
224            // initially --> disabled
225            assertFalse("guarded like commit should be initially disabled", guarded.isEnabled());
226            assertFalse("commit should be initially disabled", cmtCmd.isEnabled());
227    
228            // create dirt with errors --> disabled
229            ((JTextField)form.getControl()).setText(null);
230            assertTrue(formModel.getValidationResults().getHasErrors());
231            assertTrue(formModel.isDirty());
232            assertFalse("guarded like commit should be disabled when model has validation-errors", guarded.isEnabled());
233            assertFalse("commit should be disabled when model has validation-errors", cmtCmd.isEnabled());
234            
235            // relieve errors --> enabled
236            ((JTextField)form.getControl()).setText("nok");
237            assertFalse(formModel.getValidationResults().getHasErrors());
238            assertTrue(formModel.isDirty());
239            assertTrue("guarded like commit should be enabled if there are errors", guarded.isEnabled());
240            assertTrue("commit should be enabled if there are errors", cmtCmd.isEnabled());
241            
242            // disable form --> disabled
243            form.setEnabled(false);
244            assertFalse("guarded like commit should be disabled with form", guarded.isEnabled());
245            assertFalse("commit should be disabled with form", cmtCmd.isEnabled());
246            
247            // enable form --> enabled
248            form.setEnabled(true);
249            assertTrue("guarded like commit should be enabled with form", guarded.isEnabled());
250            assertTrue("commit should be enabled with form", cmtCmd.isEnabled());
251            
252            // revert --> disabled
253            form.revert();
254            assertFalse("guarded like commit should be disabled when no changes left", guarded.isEnabled());
255            assertFalse("commit should be disabled when no changes left", cmtCmd.isEnabled());
256        }
257    }