001 // Copyright 2005 The Apache Software Foundation 002 // 003 // Licensed under the Apache License, Version 2.0 (the "License"); 004 // you may not use this file except in compliance with the License. 005 // You may obtain a copy of the License at 006 // 007 // http://www.apache.org/licenses/LICENSE-2.0 008 // 009 // Unless required by applicable law or agreed to in writing, software 010 // distributed under the License is distributed on an "AS IS" BASIS, 011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 012 // See the License for the specific language governing permissions and 013 // limitations under the License. 014 015 package org.apache.tapestry.valid; 016 017 import org.apache.hivemind.Location; 018 import org.apache.hivemind.util.PropertyUtils; 019 import org.apache.tapestry.*; 020 import org.apache.tapestry.form.BaseFormComponentTestCase; 021 import org.apache.tapestry.form.IFormComponent; 022 import org.apache.tapestry.form.MockDelegate; 023 import org.apache.tapestry.html.BasePage; 024 import static org.easymock.EasyMock.checkOrder; 025 import static org.easymock.EasyMock.expect; 026 import org.testng.annotations.Test; 027 028 /** 029 * Tests for {@link org.apache.tapestry.valid.ValidField}. 030 * 031 * @author Howard M. Lewis Ship 032 * @since 4.0 033 */ 034 @Test(sequential=true) 035 public class TestValidField extends BaseFormComponentTestCase 036 { 037 038 public void testWasPrerendered() 039 { 040 IRequestCycle cycle = newCycle(); 041 IForm form = newMock(IForm.class); 042 043 IMarkupWriter writer = newWriter(); 044 045 ValidField component = (ValidField) newInstance(ValidField.class); 046 047 expect(cycle.renderStackPush(component)).andReturn(component); 048 049 trainGetForm(cycle, form); 050 051 trainWasPrerendered(form, writer, component, true); 052 053 expect(cycle.renderStackPop()).andReturn(component); 054 055 replay(); 056 057 component.render(writer, cycle); 058 059 verify(); 060 } 061 062 /** 063 * Check when the form is not rewinding, but the cycle is rewinding (a whole page rewind care of 064 * the action service). 065 */ 066 067 public void testFormNotRewinding() 068 { 069 ValidField component = (ValidField) newInstance(ValidField.class); 070 071 IRequestCycle cycle = newCycle(); 072 IForm form = newMock(IForm.class); 073 074 IMarkupWriter writer = newWriter(); 075 IValidationDelegate delegate = newDelegate(); 076 077 expect(cycle.renderStackPush(component)).andReturn(component); 078 079 trainGetForm(cycle, form); 080 trainWasPrerendered(form, writer, component, false); 081 trainGetDelegate(form, delegate); 082 083 delegate.setFormComponent(component); 084 085 trainGetElementId(form, component, "fred"); 086 trainIsRewinding(form, false); 087 trainIsRewinding(cycle, true); 088 089 expect(cycle.renderStackPop()).andReturn(component); 090 091 replay(); 092 093 component.render(writer, cycle); 094 095 verify(); 096 } 097 098 private void trainToObject(IValidator validator, IFormComponent component, 099 String fieldValue, Object translatedValue) throws ValidatorException 100 { 101 expect(validator.toObject(component, fieldValue)).andReturn(translatedValue); 102 } 103 104 public void testRewind() throws Exception 105 { 106 Object translatedValue = new Object(); 107 108 IValidator validator = newMock(IValidator.class); 109 110 ValidField component = (ValidField) newInstance(ValidField.class, "validator", validator); 111 112 IRequestCycle cycle = newCycle(); 113 IForm form = newMock(IForm.class); 114 115 IMarkupWriter writer = newWriter(); 116 117 IValidationDelegate delegate = newDelegate(); 118 119 expect(cycle.renderStackPush(component)).andReturn(component); 120 121 trainGetForm(cycle, form); 122 trainWasPrerendered(form, writer, component, false); 123 trainGetDelegate(form, delegate); 124 125 delegate.setFormComponent(component); 126 127 trainGetElementId(form, component, "fred"); 128 trainIsRewinding(form, true); 129 130 trainGetParameter(cycle, "fred", "fred-value"); 131 132 delegate.recordFieldInputValue("fred-value"); 133 134 trainToObject(validator, component, "fred-value", translatedValue); 135 136 expect(cycle.renderStackPop()).andReturn(component); 137 138 replay(); 139 140 component.render(writer, cycle); 141 142 verify(); 143 144 assertSame(translatedValue, PropertyUtils.read(component, "value")); 145 } 146 147 public void testRewindNoValidator() 148 { 149 IPage page = (IPage) newInstance(BasePage.class); 150 page.setPageName("Barney"); 151 152 ValidField component = newInstance(ValidField.class, new Object[] 153 { "page", page, "id", "inputFred", "container", page }); 154 155 IRequestCycle cycle = newCycle(); 156 IForm form = newMock(IForm.class); 157 158 IMarkupWriter writer = newWriter(); 159 160 IValidationDelegate delegate = newDelegate(); 161 162 expect(cycle.renderStackPush(component)).andReturn(component); 163 164 trainGetForm(cycle, form); 165 166 Location l = newLocation(); 167 IBinding binding = newBinding(l); 168 169 component.setBinding("validator", binding); 170 171 trainWasPrerendered(form, writer, component, false); 172 trainGetDelegate(form, delegate); 173 174 delegate.setFormComponent(component); 175 176 trainGetElementId(form, component, "fred"); 177 trainIsRewinding(form, true); 178 179 trainGetParameter(cycle, "fred", "fred-value"); 180 181 expect(cycle.renderStackPop()).andReturn(component); 182 183 replay(); 184 185 try 186 { 187 component.render(writer, cycle); 188 unreachable(); 189 } 190 catch (BindingException ex) 191 { 192 assertEquals( 193 "Value for parameter 'validator' in component Barney/inputFred is null, and a non-null value is required.", 194 ex.getMessage()); 195 assertSame(l, ex.getLocation()); 196 assertSame(binding, ex.getBinding()); 197 } 198 199 verify(); 200 } 201 202 public void testRender() 203 { 204 Object value = new Object(); 205 206 IValidator validator = newMock(IValidator.class); 207 208 ValidField component = newInstance(ValidField.class, new Object[] 209 { "value", value, "validator", validator }); 210 211 IRequestCycle cycle = newCycle(); 212 IForm form = newMock(IForm.class); 213 checkOrder(form, false); 214 215 IMarkupWriter writer = newBufferWriter(); 216 217 MockDelegate delegate = new MockDelegate(); 218 219 expect(cycle.renderStackPush(component)).andReturn(component); 220 221 trainGetForm(cycle, form); 222 trainWasPrerendered(form, writer, component, false); 223 trainGetDelegate(form, delegate); 224 225 trainGetElementId(form, component, "fred"); 226 trainIsRewinding(form, false); 227 trainIsRewinding(cycle, false); 228 229 form.setFormFieldUpdating(true); 230 231 trainToString(validator, component, value, "fred value"); 232 233 expect(validator.isRequired()).andReturn(false); 234 235 // Would be nice to have this do something so we could check the timing, but ... 236 237 validator.renderValidatorContribution(component, writer, cycle); 238 239 expect(cycle.renderStackPop()).andReturn(component); 240 241 replay(); 242 243 component.render(writer, cycle); 244 245 verify(); 246 247 assertSame(component, delegate.getFormComponent()); 248 assertBuffer("<span class=\"prefix\"><input type=\"text\" name=\"fred\" " + 249 "value=\"fred value\" id=\"fred\" class=\"validation-delegate\" /></span>"); 250 } 251 252 private void trainToString(IValidator validator, 253 IFormComponent component, Object value, String string) 254 { 255 expect(validator.toString(component, value)).andReturn(string); 256 } 257 258 public void testRenderNull() 259 { 260 IPage page = (IPage) newInstance(BasePage.class); 261 IValidator validator = newMock(IValidator.class); 262 263 ValidField component = newInstance(ValidField.class, new Object[] 264 { "validator", validator, "page", page, "container", page }); 265 266 IRequestCycle cycle = newCycle(); 267 268 page.attach(null, cycle); 269 270 expect(cycle.renderStackPush(component)).andReturn(component); 271 272 IForm form = newMock(IForm.class); 273 checkOrder(form, false); 274 275 IMarkupWriter writer = newBufferWriter(); 276 277 MockDelegate delegate = new MockDelegate(); 278 279 trainGetForm(cycle, form); 280 trainWasPrerendered(form, writer, component, false); 281 trainGetDelegate(form, delegate); 282 283 trainGetElementId(form, component, "fred"); 284 trainIsRewinding(form, false); 285 trainIsRewinding(cycle, false); 286 287 form.setFormFieldUpdating(true); 288 289 trainToString(validator, component, null, null); 290 291 expect(validator.isRequired()).andReturn(false); 292 293 // Would be nice to have this do something so we could check the timing, but ... 294 295 validator.renderValidatorContribution(component, writer, cycle); 296 297 // Short cut this here, so that it appears some other field is 298 // taking the honors ... 299 300 expect(cycle.renderStackPop()).andReturn(component); 301 302 replay(); 303 304 component.render(writer, cycle); 305 306 verify(); 307 308 assertSame(component, delegate.getFormComponent()); 309 assertBuffer("<span class=\"prefix\"><input type=\"text\" name=\"fred\" id=\"fred\" class=\"validation-delegate\" /></span>"); 310 } 311 312 public void testRenderWithError() 313 { 314 Object value = new Object(); 315 316 IValidator validator = newMock(IValidator.class); 317 318 IRequestCycle cycle = newCycle(); 319 IForm form = newMock(IForm.class); 320 checkOrder(form, false); 321 322 ValidField component = newInstance(ValidField.class, new Object[] 323 { "value", value, "validator", validator, "form", form, "name", "fred" }); 324 325 expect(cycle.renderStackPush(component)).andReturn(component); 326 327 IMarkupWriter writer = newBufferWriter(); 328 329 MockDelegate delegate = new MockDelegate(true); 330 delegate.recordFieldInputValue("recorded field value"); 331 332 trainGetForm(cycle, form); 333 trainWasPrerendered(form, writer, component, false); 334 trainGetDelegate(form, delegate); 335 336 trainGetElementId(form, component, "fred"); 337 trainIsRewinding(form, false); 338 trainIsRewinding(cycle, false); 339 340 form.setFormFieldUpdating(true); 341 342 expect(validator.isRequired()).andReturn(true); 343 344 // Would be nice to have this do something so we could check the timing, but ... 345 346 validator.renderValidatorContribution(component, writer, cycle); 347 348 expect(cycle.renderStackPop()).andReturn(component); 349 350 replay(); 351 352 component.render(writer, cycle); 353 354 verify(); 355 356 assertSame(component, delegate.getFormComponent()); 357 assertBuffer("<span class=\"prefix\"><input type=\"text\" name=\"fred\" " + 358 "value=\"recorded field value\" id=\"fred\" class=\"validation-delegate\" /></span>"); 359 } 360 }