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.form; 016 017 import java.util.ArrayList; 018 import java.util.Collection; 019 import java.util.LinkedList; 020 import java.util.List; 021 import java.util.Map; 022 023 import org.apache.hivemind.util.PropertyUtils; 024 import org.apache.tapestry.IActionListener; 025 import org.apache.tapestry.IBinding; 026 import org.apache.tapestry.IForm; 027 import org.apache.tapestry.IMarkupWriter; 028 import org.apache.tapestry.IRequestCycle; 029 import org.apache.tapestry.IScript; 030 import org.apache.tapestry.PageRenderSupport; 031 import org.apache.tapestry.engine.DirectServiceParameter; 032 import org.apache.tapestry.engine.IEngineService; 033 import org.apache.tapestry.engine.ILink; 034 import org.apache.tapestry.listener.ListenerInvokerTerminator; 035 import org.apache.tapestry.test.Creator; 036 import org.apache.tapestry.util.ScriptUtils; 037 import org.apache.tapestry.valid.IValidationDelegate; 038 import org.apache.tapestry.valid.ValidationConstants; 039 import static org.easymock.EasyMock.*; 040 import org.testng.annotations.Test; 041 042 /** 043 * Tests for {@link org.apache.tapestry.form.Submit}. 044 * 045 * @author Howard M. Lewis Ship 046 * @since 4.0 047 */ 048 @Test 049 public class TestSubmit extends BaseFormComponentTestCase 050 { 051 public void test_Prerendered() 052 { 053 Creator creator = new Creator(); 054 Submit submit = (Submit) creator.newInstance(Submit.class); 055 056 IForm form = newMock(IForm.class); 057 IRequestCycle cycle = newCycle(); 058 IMarkupWriter writer = newWriter(); 059 060 trainGetForm(cycle, form); 061 062 trainWasPrerendered(form, writer, submit, true); 063 064 replay(); 065 066 submit.renderComponent(writer, cycle); 067 068 verify(); 069 } 070 071 public void test_Render() 072 { 073 Creator creator = new Creator(); 074 Submit submit = (Submit) creator.newInstance(Submit.class, new Object[] {"submitType", "submit"}); 075 076 IValidationDelegate delegate = newDelegate(); 077 IForm form = newForm(); 078 IRequestCycle cycle = newCycle(); 079 IMarkupWriter writer = newWriter(); 080 081 trainGetForm(cycle, form); 082 083 trainWasPrerendered(form, writer, submit, false); 084 085 trainGetDelegate(form, delegate); 086 087 delegate.setFormComponent(submit); 088 089 trainGetElementId(form, submit, "fred"); 090 091 trainIsRewinding(form, false); 092 093 trainIsRewinding(cycle, false); 094 095 form.setFormFieldUpdating(true); 096 097 writer.beginEmpty("input"); 098 writer.attribute("type", "submit"); 099 writer.attribute("name", "fred"); 100 writer.attribute("id", "fred"); 101 writer.closeTag(); 102 103 trainIsInError(delegate, false); 104 105 delegate.registerForFocus(submit, ValidationConstants.NORMAL_FIELD); 106 107 replay(); 108 109 submit.renderComponent(writer, cycle); 110 111 verify(); 112 } 113 114 public void test_Render_Function_Hash() 115 { 116 Creator creator = new Creator(); 117 Submit submit = (Submit) creator.newInstance(Submit.class, new Object[] {"submitType", "submit"}); 118 119 IValidationDelegate delegate = newDelegate(); 120 IForm form = newForm(); 121 IRequestCycle cycle = newCycle(); 122 IMarkupWriter writer = newWriter(); 123 124 trainGetForm(cycle, form); 125 126 trainWasPrerendered(form, writer, submit, false); 127 128 trainGetDelegate(form, delegate); 129 130 delegate.setFormComponent(submit); 131 132 trainGetElementId(form, submit, "fred"); 133 134 trainIsRewinding(form, false); 135 136 trainIsRewinding(cycle, false); 137 138 form.setFormFieldUpdating(true); 139 140 writer.beginEmpty("input"); 141 writer.attribute("type", "submit"); 142 writer.attribute("name", "fred"); 143 writer.attribute("id", "fred"); 144 writer.closeTag(); 145 146 trainIsInError(delegate, false); 147 148 delegate.registerForFocus(submit, ValidationConstants.NORMAL_FIELD); 149 150 replay(); 151 152 submit.renderComponent(writer, cycle); 153 154 String hash = ScriptUtils.functionHash("onchange" + submit.hashCode()); 155 156 assertEquals(ScriptUtils.functionHash("onchange" + submit.hashCode()), hash); 157 158 verify(); 159 } 160 161 public void test_Render_Disabled() 162 { 163 Creator creator = new Creator(); 164 Submit submit = (Submit) creator.newInstance(Submit.class, new Object[] 165 { "disabled", Boolean.TRUE, "submitType", "submit" }); 166 167 IValidationDelegate delegate = newDelegate(); 168 IForm form = newForm(); 169 IRequestCycle cycle = newCycle(); 170 IMarkupWriter writer = newWriter(); 171 172 trainGetForm(cycle, form); 173 174 trainWasPrerendered(form, writer, submit, false); 175 176 trainGetDelegate(form, delegate); 177 178 delegate.setFormComponent(submit); 179 180 trainGetElementId(form, submit, "fred"); 181 182 trainIsRewinding(form, false); 183 184 trainIsRewinding(cycle, false); 185 186 form.setFormFieldUpdating(true); 187 188 writer.beginEmpty("input"); 189 writer.attribute("type", "submit"); 190 writer.attribute("name", "fred"); 191 writer.attribute("disabled", "disabled"); 192 writer.attribute("id", "fred"); 193 writer.closeTag(); 194 195 replay(); 196 197 submit.renderComponent(writer, cycle); 198 199 verify(); 200 } 201 202 public void test_Render_With_Label() 203 { 204 Creator creator = new Creator(); 205 Submit submit = (Submit) creator.newInstance(Submit.class, new Object[] 206 { "label", "flintstone", "submitType", "submit" }); 207 208 IValidationDelegate delegate = newDelegate(); 209 IForm form = newForm(); 210 IRequestCycle cycle = newCycle(); 211 IMarkupWriter writer = newWriter(); 212 213 trainGetForm(cycle, form); 214 215 trainWasPrerendered(form, writer, submit, false); 216 217 trainGetDelegate(form, delegate); 218 219 delegate.setFormComponent(submit); 220 221 trainGetElementId(form, submit, "fred"); 222 223 trainIsRewinding(form, false); 224 225 trainIsRewinding(cycle, false); 226 227 form.setFormFieldUpdating(true); 228 229 writer.beginEmpty("input"); 230 writer.attribute("type", "submit"); 231 writer.attribute("name", "fred"); 232 writer.attribute("value", "flintstone"); 233 writer.attribute("id", "fred"); 234 writer.closeTag(); 235 236 trainIsInError(delegate, false); 237 238 delegate.registerForFocus(submit, ValidationConstants.NORMAL_FIELD); 239 240 replay(); 241 242 submit.renderComponent(writer, cycle); 243 244 verify(); 245 } 246 247 public void test_SubmitType_OnClick() 248 { 249 IScript script = newMock(IScript.class); 250 Submit submit = newInstance(Submit.class, 251 new Object[] {"submitType", "cancel", "submitScript", script}); 252 253 IValidationDelegate delegate = newDelegate(); 254 IForm form = newForm(); 255 IRequestCycle cycle = newCycle(); 256 IMarkupWriter writer = newWriter(); 257 258 trainGetForm(cycle, form); 259 260 trainWasPrerendered(form, writer, submit, false); 261 262 trainGetDelegate(form, delegate); 263 264 delegate.setFormComponent(submit); 265 266 trainGetElementId(form, submit, "fred"); 267 268 trainIsRewinding(form, false); 269 270 trainIsRewinding(cycle, false); 271 272 form.setFormFieldUpdating(true); 273 274 writer.beginEmpty("input"); 275 writer.attribute("type", "submit"); 276 writer.attribute("name", "fred"); 277 writer.attribute("id", "fred"); 278 279 expect(form.getClientId()).andReturn("formtest"); 280 281 writer.attribute("onClick", "tapestry.form.cancel('formtest','fred')"); 282 283 writer.closeTag(); 284 285 trainIsInError(delegate, false); 286 287 delegate.registerForFocus(submit, ValidationConstants.NORMAL_FIELD); 288 289 replay(); 290 291 submit.renderComponent(writer, cycle); 292 293 verify(); 294 } 295 296 public void test_SubmitType_OnClick_Disabled() 297 { 298 Submit submit = newInstance(Submit.class, new Object[] { 299 "disabled", Boolean.TRUE 300 }); 301 302 IValidationDelegate delegate = newDelegate(); 303 IForm form = newForm(); 304 IRequestCycle cycle = newCycle(); 305 IMarkupWriter writer = newWriter(); 306 307 trainGetForm(cycle, form); 308 309 trainWasPrerendered(form, writer, submit, false); 310 311 trainGetDelegate(form, delegate); 312 313 delegate.setFormComponent(submit); 314 315 trainGetElementId(form, submit, "fred"); 316 317 trainIsRewinding(form, false); 318 319 trainIsRewinding(cycle, false); 320 321 form.setFormFieldUpdating(true); 322 323 writer.beginEmpty("input"); 324 writer.attribute("type", "submit"); 325 writer.attribute("name", "fred"); 326 writer.attribute("disabled", "disabled"); 327 writer.attribute("id", "fred"); 328 writer.closeTag(); 329 330 replay(); 331 332 submit.renderComponent(writer, cycle); 333 334 verify(); 335 } 336 337 public void test_SubmitType_Script_OnClick() 338 { 339 IScript script = newMock(IScript.class); 340 IForm form = newForm(); 341 IBinding binding = newMock(IBinding.class); 342 343 Submit submit = newInstance(Submit.class, 344 new Object[] {"submitType", "cancel", 345 "submitScript", script, "form", form}); 346 347 submit.setBinding("onClick", binding); 348 349 IRequestCycle cycle = newCycle(); 350 IMarkupWriter writer = newWriter(); 351 352 PageRenderSupport prs = newPageRenderSupport(); 353 trainGetPageRenderSupport(cycle, prs); 354 355 script.execute(eq(submit), eq(cycle), eq(prs), isA(Map.class)); 356 357 replay(); 358 359 submit.renderSubmitBindings(writer, cycle); 360 361 verify(); 362 } 363 364 public void test_Submit_Async() 365 { 366 List updates = new ArrayList(); 367 updates.add("bsComponent"); 368 369 IScript script = newMock(IScript.class); 370 IForm form = newForm(); 371 IBinding binding = newMock(IBinding.class); 372 373 IEngineService engine = newEngineService(); 374 ILink link = newMock(ILink.class); 375 376 Submit submit = newInstance(Submit.class, 377 "submitType", "cancel", 378 "submitScript", script, "form", form, 379 "async", true, "updateComponents", updates, 380 "directService", engine); 381 382 submit.setBinding("onClick", binding); 383 384 IRequestCycle cycle = newCycle(); 385 IMarkupWriter writer = newWriter(); 386 387 expect(engine.getLink(eq(true), isA(DirectServiceParameter.class))).andReturn(link); 388 expect(link.getURL()).andReturn("/test/url"); 389 390 PageRenderSupport prs = newPageRenderSupport(); 391 trainGetPageRenderSupport(cycle, prs); 392 393 script.execute(eq(submit), eq(cycle), eq(prs), isA(Map.class)); 394 395 replay(); 396 397 submit.renderSubmitBindings(writer, cycle); 398 399 verify(); 400 } 401 402 public void test_Rewinding_Disabled() 403 { 404 Creator creator = new Creator(); 405 Submit submit = (Submit) creator.newInstance(Submit.class, new Object[] 406 { "disabled", Boolean.TRUE }); 407 408 IValidationDelegate delegate = newDelegate(); 409 IForm form = newForm(); 410 IRequestCycle cycle = newCycle(); 411 IMarkupWriter writer = newWriter(); 412 413 trainGetForm(cycle, form); 414 415 trainWasPrerendered(form, writer, submit, false); 416 417 expect(form.getDelegate()).andReturn(delegate); 418 419 delegate.setFormComponent(submit); 420 421 trainGetElementId(form, submit, "fred"); 422 423 trainIsRewinding(form, true); 424 425 replay(); 426 427 submit.renderComponent(writer, cycle); 428 429 verify(); 430 } 431 432 public void test_Rewind_Not_Form() 433 { 434 Creator creator = new Creator(); 435 Submit submit = (Submit) creator.newInstance(Submit.class); 436 437 IValidationDelegate delegate = newDelegate(); 438 IForm form = newForm(); 439 IRequestCycle cycle = newCycle(); 440 IMarkupWriter writer = newWriter(); 441 442 trainGetForm(cycle, form); 443 444 trainWasPrerendered(form, writer, submit, false); 445 446 expect(form.getDelegate()).andReturn(delegate); 447 448 delegate.setFormComponent(submit); 449 450 trainGetElementId(form, submit, "fred"); 451 452 trainIsRewinding(form, false); 453 trainIsRewinding(cycle, true); 454 455 replay(); 456 457 submit.renderComponent(writer, cycle); 458 459 verify(); 460 } 461 462 public void test_Rewind_Not_Trigger() 463 { 464 Creator creator = new Creator(); 465 Submit submit = (Submit) creator.newInstance(Submit.class); 466 467 IValidationDelegate delegate = newDelegate(); 468 IForm form = newForm(); 469 IRequestCycle cycle = newCycle(); 470 IMarkupWriter writer = newWriter(); 471 472 trainGetForm(cycle, form); 473 474 trainWasPrerendered(form, writer, submit, false); 475 476 expect(form.getDelegate()).andReturn(delegate); 477 478 delegate.setFormComponent(submit); 479 480 trainGetElementId(form, submit, "fred"); 481 482 trainIsRewinding(form, true); 483 484 trainGetParameter(cycle, "fred", null); 485 486 replay(); 487 488 submit.renderComponent(writer, cycle); 489 490 verify(); 491 } 492 493 public void test_Rewind_Triggered() 494 { 495 Creator creator = new Creator(); 496 Submit submit = (Submit) creator.newInstance(Submit.class, new Object[] 497 { "tag", "clicked" }); 498 499 IBinding binding = newBinding(); 500 submit.setBinding("selected", binding); 501 502 IValidationDelegate delegate = newDelegate(); 503 IForm form = newForm(); 504 IRequestCycle cycle = newCycle(); 505 IMarkupWriter writer = newWriter(); 506 507 trainGetForm(cycle, form); 508 509 trainWasPrerendered(form, writer, submit, false); 510 511 expect(form.getDelegate()).andReturn(delegate); 512 513 delegate.setFormComponent(submit); 514 515 trainGetElementId(form, submit, "fred"); 516 517 trainIsRewinding(form, true); 518 519 trainGetParameter(cycle, "fred", "flintstone"); 520 521 replay(); 522 523 submit.renderComponent(writer, cycle); 524 525 assertEquals("clicked", PropertyUtils.read(submit, "selected")); 526 527 verify(); 528 } 529 530 public void test_Trigger_With_Listener() 531 { 532 IActionListener listener = newListener(); 533 IForm form = newForm(); 534 IRequestCycle cycle = newCycle(); 535 536 Creator creator = new Creator(); 537 Submit submit = (Submit) creator.newInstance(Submit.class, new Object[] 538 { "listener", listener, "listenerInvoker", new ListenerInvokerTerminator() }); 539 540 listener.actionTriggered(submit, cycle); 541 542 replay(); 543 544 submit.handleClick(cycle, form); 545 546 verify(); 547 } 548 549 public void test_Trigger_With_Action() 550 { 551 IActionListener action = newListener(); 552 MockForm form = new MockForm(); 553 IRequestCycle cycle = newCycle(); 554 555 Creator creator = new Creator(); 556 Submit submit = (Submit) creator.newInstance(Submit.class, new Object[] 557 { "action", action, "listenerInvoker", 558 new ListenerInvokerTerminator() }); 559 560 replay(); 561 562 submit.handleClick(cycle, form); 563 564 verify(); 565 566 action.actionTriggered(submit, cycle); 567 568 replay(); 569 570 form.runDeferred(); 571 572 verify(); 573 } 574 575 public void test_Trigger_With_Action_And_Single_Parameter() 576 { 577 IActionListener action = newListener(); 578 MockForm form = new MockForm(); 579 IRequestCycle cycle = newCycle(); 580 581 Object parameter = new Object(); 582 Creator creator = new Creator(); 583 Submit submit = (Submit) creator.newInstance(Submit.class, new Object[] 584 { "action", action, "parameters", parameter, "listenerInvoker", 585 new ListenerInvokerTerminator() }); 586 587 cycle.setListenerParameters(aryEq(new Object[] { parameter })); 588 589 replay(); 590 591 submit.handleClick(cycle, form); 592 593 verify(); 594 595 action.actionTriggered(submit, cycle); 596 597 replay(); 598 599 form.runDeferred(); 600 601 verify(); 602 } 603 604 public void test_Trigger_With_Action_And_Object_Array_Parameter() 605 { 606 IActionListener action = newListener(); 607 MockForm form = new MockForm(); 608 IRequestCycle cycle = newCycle(); 609 610 Object parameter = new Object[] {"p1", "p2"}; 611 Creator creator = new Creator(); 612 Submit submit = (Submit) creator.newInstance(Submit.class, new Object[] 613 { "action", action, "parameters", parameter, "listenerInvoker", 614 new ListenerInvokerTerminator() }); 615 616 cycle.setListenerParameters(aryEq(new Object[] { "p1", "p2" })); 617 618 replay(); 619 620 submit.handleClick(cycle, form); 621 622 verify(); 623 624 action.actionTriggered(submit, cycle); 625 626 replay(); 627 628 form.runDeferred(); 629 630 verify(); 631 } 632 633 public void test_Trigger_With_Action_And_Collection_Parameter() 634 { 635 IActionListener action = newListener(); 636 MockForm form = new MockForm(); 637 IRequestCycle cycle = newCycle(); 638 639 Collection parameters = new LinkedList(); 640 parameters.add("p1"); 641 parameters.add("p2"); 642 643 Creator creator = new Creator(); 644 Submit submit = (Submit) creator.newInstance(Submit.class, new Object[] 645 { "action", action, "parameters", parameters, "listenerInvoker", 646 new ListenerInvokerTerminator() }); 647 648 cycle.setListenerParameters(aryEq(new Object[]{ "p1", "p2" })); 649 650 replay(); 651 652 submit.handleClick(cycle, form); 653 654 verify(); 655 656 action.actionTriggered(submit, cycle); 657 658 replay(); 659 660 form.runDeferred(); 661 662 verify(); 663 } 664 665 public void test_Trigger_With_Listener_And_Action() 666 { 667 IActionListener listener = newListener(); 668 IActionListener action = newListener(); 669 670 MockForm form = new MockForm(); 671 IRequestCycle cycle = newCycle(); 672 673 Creator creator = new Creator(); 674 Submit submit = (Submit) creator.newInstance(Submit.class, new Object[] 675 { "listener", listener, "action", action, "listenerInvoker", 676 new ListenerInvokerTerminator() }); 677 678 listener.actionTriggered(submit, cycle); 679 680 replay(); 681 682 submit.handleClick(cycle, form); 683 684 verify(); 685 686 action.actionTriggered(submit, cycle); 687 688 replay(); 689 690 form.runDeferred(); 691 692 verify(); 693 } 694 695 }