1<!doctype html> 2<!-- 3@license 4Copyright (c) 2015 The Polymer Project Authors. All rights reserved. 5This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt 6The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt 7The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt 8Code distributed by Google as part of the polymer project is also 9subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt 10--> 11<html> 12<head> 13 <title>iron-form</title> 14 15 <script src="../../webcomponentsjs/webcomponents-lite.js"></script> 16 <script src="../../web-component-tester/browser.js"></script> 17 18 <link rel="import" href="../../polymer/polymer.html"> 19 <link rel="import" href="../../paper-checkbox/paper-checkbox.html"> 20 <link rel="import" href="../../paper-input/paper-input.html"> 21 <link rel="import" href="../../paper-button/paper-button.html"> 22 <link rel="import" href="../iron-form.html"> 23 24</head> 25<body> 26 27 <dom-module id="x-input-wrapper"> 28 <template> 29 <input name="check_wrapped" value="foo"/> 30 </template> 31 </dom-module> 32 33 <test-fixture id="serialization"> 34 <template> 35 <div> 36 <iron-form id="native-checkboxes"> 37 <form action="/get" method="get"> 38 <input type="checkbox" name="check1" checked> <!-- default value is "on" --> 39 <input type="checkbox" name="check1" value="1"> 40 <input type="checkbox" name="check1" value="2" checked> 41 <input type="checkbox" name="check2" value="3" checked> 42 <input type="checkbox" name="check3" value="4"> 43 </form> 44 </iron-form> 45 <iron-form id="native-radios"> 46 <form action="/get" method="get"> 47 <input type="radio" name="radio1" checked> <!-- default value is "on" --> 48 <input type="radio" name="radio1" value="1"> 49 <input type="radio" name="radio2" value="2" checked> 50 <input type="radio" name="radio2" value="3" checked> <!-- it's a radio group --> 51 <input type="radio" name="radio3" value="4"> 52 </form> 53 </iron-form> 54 <iron-form id="native-buttons"> 55 <form action="/get" method="get"> 56 <input type="reset" name="reset1" value="reset"> 57 <input type="submit" name="submit1" value="submit"> 58 <button name="button1" value="button">text</button> 59 </form> 60 </iron-form> 61 <iron-form id="native-selects"> 62 <form action="/get" method="get"> 63 <select name="select1" multiple> 64 <option value="1" selected>A</option> 65 <option value="2" selected>B</option> 66 <option value="3">C</option> 67 </select> 68 <select name="select2"> 69 <option value="1" selected>A</option> 70 <option value="2">B</option> 71 </select> 72 </form> 73 </iron-form> 74 <iron-form id="native-inputs"> 75 <form action="/get" method="get"> 76 <input type="text" name="input1"> 77 <input type="text" name="input1" value="foo"> 78 <input type="text" name="input1" value="zag"> 79 <input type="text" name="input2" value="bar"> 80 <input type="password" name="pass1" value="pass"> 81 <input type="number" name="number1" value="35"> 82 <input name="empty" value=""> 83 <input name="empty" value=""> 84 </form> 85 </iron-form> 86 <iron-form id="native-inputs-empty"> 87 <form action="/get" method="get"> 88 <input type="text" name="input1"> 89 </form> 90 </iron-form> 91 <iron-form id="custom-checkboxes"> 92 <form action="/get" method="get"> 93 <paper-checkbox name="check1" checked></paper-checkbox> <!-- default value is "on" --> 94 <paper-checkbox name="check1" value="1"></paper-checkbox> 95 <paper-checkbox name="check1" value="2" checked></paper-checkbox> 96 <paper-checkbox name="check2" value="3" checked></paper-checkbox> 97 <paper-checkbox name="check3" value="4"></paper-checkbox> 98 </form> 99 </iron-form> 100 <iron-form id="custom-inputs"> 101 <form action="/get" method="get"> 102 <paper-input name="input1" value=""></paper-input> 103 <paper-input name="input1" value="foo"></paper-input> 104 <paper-input name="input1" value="zag"></paper-input> 105 <paper-input name="input2" value="bar"></paper-input> 106 <paper-input type="password" name="pass1" value="pass"></paper-input> 107 <paper-input type="number" name="number1" value="35"></paper-input> 108 <paper-input name="empty" value=""></paper-input> 109 <paper-input name="empty" value=""></paper-input> 110 <x-input-wrapper></x-input-wrapper> 111 </form> 112 </iron-form> 113 <iron-form id="nested-elements"> 114 <form action="/get" method="get"> 115 <div> 116 <input type="text" name="input1" value="i1"> 117 </div> 118 <div> 119 <paper-input name="paper-input1" value="p1"></paper-input> 120 </div> 121 <div> 122 <p> 123 <div> 124 <input type="text" name="input2" value="i2"> 125 <paper-input name="paper-input2" value="p2"></paper-input> 126 </div> 127 </p> 128 </div> 129 </form> 130 </iron-form> 131 <iron-form id="duplicate-names"> 132 <form action="/get" method="get"> 133 <input name="input1" value=""> 134 <input name="input1" value="foo"> 135 <paper-input name="input1" value=""></paper-input> 136 <paper-input name="input1" value="bar"></paper-input> 137 <input name="empty" value=""> 138 <input name="empty" value=""> 139 <paper-input name="empty" value=""></paper-input> 140 <paper-input name="empty" value=""></paper-input> 141 </form> 142 </iron-form> 143 144 </div> 145 </template> 146 </test-fixture> 147 148 <test-fixture id="validation"> 149 <template> 150 <div> 151 <iron-form id="native-required"> 152 <form action="/get" method="get"> 153 <input required> 154 </form> 155 </iron-form> 156 157 <iron-form id="native-invalid"> 158 <form action="/get" method="get"> 159 <input pattern="aa" value="b"> 160 </form> 161 </iron-form> 162 163 <iron-form id="custom-required"> 164 <form action="/get" method="get"> 165 <paper-input required></paper-input> 166 </form> 167 </iron-form> 168 169 <iron-form id="custom-invalid"> 170 <form action="/get" method="get"> 171 <paper-input pattern="aa" value="b"></paper-input> 172 </form> 173 </iron-form> 174 175 <iron-form id="mixed-invalid"> 176 <form action="/get" method="get"> 177 <input pattern="aa" value="b"> 178 <paper-input pattern="aa" value="b"></paper-input> 179 </form> 180 </iron-form> 181 </div> 182 </template> 183 </test-fixture> 184 185 <test-fixture id="submission"> 186 <template> 187 <iron-form> 188 <form action="/get" method="get"> 189 <input type="checkbox" name="check1" checked> 190 <input type="submit"> 191 <input type="button"> 192 <paper-button></paper-button> 193 </form> 194 </iron-form> 195 </template> 196 </test-fixture> 197 198 <test-fixture id="resetting"> 199 <template> 200 <iron-form> 201 <form action="/get" method="get"> 202 <input type="input" name="input1" id="input1" value="input1"> 203 <input type="input" name="input2" id="input2"> 204 <input type="checkbox" name="check1" id="check1" checked> 205 <input type="checkbox" name="check2" id="check2"> 206 <input type="radio" name="radio1" id="radio1" checked> 207 <input type="radio" name="radio2" id="radio2"> 208 <paper-checkbox name="papercheck1" id="papercheck1" checked></paper-checkbox> 209 <paper-checkbox name="papercheck2" id="papercheck2"></paper-checkbox> 210 <paper-input name="paper1" id="paper1" value="paper1"></paper-input> 211 <paper-input name="paper2" id="paper2" value=""></paper-input> 212 <input type="reset"> 213 </form> 214 </iron-form> 215 </template> 216 </test-fixture> 217 218 <test-fixture id="content-type"> 219 <template> 220 <div> 221 <iron-form id="simple-form"> 222 <form action="/valid/url" method="post"> 223 <paper-input name="paper1" value="value1"></paper-input> 224 <paper-input name="paper2" value="value2"></paper-input> 225 </form> 226 </iron-form> 227 <iron-form id="json-form"> 228 <form action="/valid/url" method="post" enctype="application/json"> 229 <paper-input name="paper1" value="value1"></paper-input> 230 <paper-input name="paper2" value="value2"></paper-input> 231 </form> 232 </iron-form> 233 <iron-form id="plain-form"> 234 <form action="/valid/url" method="post" enctype="text/plain"> 235 <paper-input name="paper1" value="value1"></paper-input> 236 <paper-input name="paper2" value="value2"></paper-input> 237 </form> 238 </iron-form> 239 </div> 240 </template> 241 </test-fixture> 242 243 <script> 244 suite('serialization', function() { 245 var f; 246 var server; 247 248 suiteSetup(function () { 249 Polymer({is: 'x-input-wrapper'}); 250 }); 251 252 setup(function() { 253 f = fixture('serialization'); 254 255 server = sinon.fakeServer.create(); 256 server.respondWith( 257 'GET', 258 /\/get.*/, 259 [ 260 200, 261 '{"Content-Type":"application/json"}', 262 '{"success":true}' 263 ] 264 ); 265 }); 266 267 teardown(function() { 268 server.restore(); 269 }); 270 271 test('serializes native checkboxes', function(done) { 272 var form = f.querySelector('#native-checkboxes'); 273 form.addEventListener('iron-form-response', function(event) { 274 expect(event.detail.url).to.equal('/get?check1=on&check1=2&check2=3'); 275 expect(event.detail.response.success).to.be.equal(true); 276 done(); 277 }); 278 279 // Wait one tick for observeNodes. 280 Polymer.Base.async(function() { 281 form.submit(); 282 server.respond(); 283 }); 284 }); 285 286 test('serializes native radio buttons', function(done) { 287 var form = f.querySelector('#native-radios'); 288 form.addEventListener('iron-form-response', function(event) { 289 expect(event.detail.url).to.equal('/get?radio1=on&radio2=3'); 290 expect(event.detail.response.success).to.be.equal(true); 291 done(); 292 }); 293 294 // Wait one tick for observeNodes. 295 Polymer.Base.async(function() { 296 form.submit(); 297 server.respond(); 298 }); 299 }); 300 301 test('serializes native buttons', function(done) { 302 var form = f.querySelector('#native-buttons'); 303 form.addEventListener('iron-form-response', function(event) { 304 expect(event.detail.url).to.equal('/get'); 305 expect(event.detail.response.success).to.be.equal(true); 306 done(); 307 }); 308 309 // Wait one tick for observeNodes. 310 Polymer.Base.async(function() { 311 form.submit(); 312 server.respond(); 313 }); 314 }); 315 316 test('serializes native selects', function(done) { 317 var form = f.querySelector('#native-selects'); 318 form.addEventListener('iron-form-response', function(event) { 319 expect(event.detail.url).to.equal('/get?select1=1&select1=2&select2=1'); 320 expect(event.detail.response.success).to.be.equal(true); 321 done(); 322 }); 323 324 // Wait one tick for observeNodes. 325 Polymer.Base.async(function() { 326 form.submit(); 327 server.respond(); 328 }); 329 }); 330 331 test('serializes native inputs', function(done) { 332 var form = f.querySelector('#native-inputs'); 333 334 form.addEventListener('iron-form-response', function(event) { 335 expect(event.detail.url).to.equal('/get?input1=&input1=foo&input1=zag&input2=bar&pass1=pass&number1=35&empty=&empty='); 336 expect(event.detail.response.success).to.be.equal(true); 337 done(); 338 }); 339 340 // Wait one tick for observeNodes. 341 Polymer.Base.async(function() { 342 form.submit(); 343 server.respond(); 344 }); 345 }); 346 347 test('serializes empty native inputs', function(done) { 348 var form = f.querySelector('#native-inputs-empty'); 349 form.addEventListener('iron-form-response', function(event) { 350 expect(event.detail.url).to.equal('/get?input1='); 351 expect(event.detail.response.success).to.be.equal(true); 352 done(); 353 }); 354 355 // Wait one tick for observeNodes. 356 Polymer.Base.async(function() { 357 form.submit(); 358 server.respond(); 359 }); 360 }); 361 362 test('serializes custom checkboxes', function(done) { 363 var form = f.querySelector('#custom-checkboxes'); 364 form.addEventListener('iron-form-response', function(event) { 365 expect(event.detail.url).to.equal('/get?check1=on&check1=2&check2=3'); 366 expect(event.detail.response.success).to.be.equal(true); 367 done(); 368 }); 369 370 // Wait one tick for observeNodes. 371 Polymer.Base.async(function() { 372 form.submit(); 373 server.respond(); 374 }); 375 }); 376 377 test('serializes custom inputs', function(done) { 378 var form = f.querySelector('#custom-inputs'); 379 form.addEventListener('iron-form-response', function(event) { 380 expect(event.detail.url).to.equal('/get?input1=&input1=foo&input1=zag&input2=bar&pass1=pass&number1=35&empty=&empty=&check_wrapped=foo'); 381 expect(event.detail.response.success).to.be.equal(true); 382 done(); 383 }); 384 385 // Wait one tick for observeNodes. 386 Polymer.Base.async(function() { 387 form.submit(); 388 server.respond(); 389 }); 390 }); 391 392 test('serializes elements deeply nested in divs', function(done) { 393 var form = f.querySelector('#nested-elements'); 394 form.addEventListener('iron-form-response', function(event) { 395 expect(event.detail.url).to.equal('/get?input1=i1&paper-input1=p1&input2=i2&paper-input2=p2'); 396 expect(event.detail.response.success).to.be.equal(true); 397 done(); 398 }); 399 // Wait one tick for observeNodes. 400 Polymer.Base.async(function() { 401 form.submit(); 402 server.respond(); 403 }); 404 }); 405 406 test('serializes elements with duplicate names', function(done) { 407 var form = f.querySelector('#duplicate-names'); 408 form.addEventListener('iron-form-response', function(event) { 409 expect(event.detail.url).to.equal('/get?input1=&input1=foo&input1=&input1=bar&empty=&empty=&empty=&empty='); 410 expect(event.detail.response.success).to.be.equal(true); 411 done(); 412 }); 413 // Wait one tick for observeNodes. 414 Polymer.Base.async(function() { 415 form.submit(); 416 server.respond(); 417 }); 418 }); 419 }); 420 421 422 suite('validation', function() { 423 var f; 424 var server; 425 426 setup(function() { 427 f = fixture('validation'); 428 429 server = sinon.fakeServer.create(); 430 server.respondWith( 431 'GET', 432 /\/get.*/, 433 [ 434 200, 435 '{"Content-Type":"application/json"}', 436 '{"success":true}' 437 ] 438 ); 439 }); 440 441 teardown(function() { 442 server.restore(); 443 }); 444 445 test('fires iron-form-invalid if it can\'t submit', function(done) { 446 var form = f.querySelector('#mixed-invalid'); 447 form.addEventListener('iron-form-invalid', function(event) { 448 expect(form.validate()).to.be.equal(false); 449 done(); 450 }); 451 // Wait one tick for observeNodes. 452 Polymer.Base.async(function() { 453 expect(form.validate()).to.be.equal(false); 454 form.submit(); 455 server.respond(); 456 }); 457 }); 458 459 test('<input required> is validated and does not submit the form', function(done) { 460 var form = f.querySelector('#native-required'); 461 462 var responses = 0; 463 form.addEventListener('iron-form-response', function(event) { 464 responses++; 465 }); 466 467 // Wait one tick for observeNodes. 468 Polymer.Base.async(function() { 469 expect(form.validate()).to.be.equal(false); 470 form.submit(); 471 server.respond(); 472 }); 473 474 setTimeout(function() { 475 expect(responses).to.be.equal(0); 476 done(); 477 }, 200); 478 }); 479 480 test('invalid <input> but not required is validated and does not submit the form', function(done) { 481 var form = f.querySelector('#native-invalid'); 482 483 var responses = 0; 484 form.addEventListener('iron-form-response', function(event) { 485 responses++; 486 }); 487 488 // Wait one tick for observeNodes. 489 Polymer.Base.async(function() { 490 expect(form.validate()).to.be.equal(false); 491 form.submit(); 492 server.respond(); 493 }); 494 495 setTimeout(function() { 496 expect(responses).to.be.equal(0); 497 done(); 498 }, 200); 499 }); 500 501 test('<paper-input required> is validated and does not submit the form', function(done) { 502 var form = f.querySelector('#custom-required'); 503 504 var responses = 0; 505 form.addEventListener('iron-form-response', function(event) { 506 responses++; 507 }); 508 509 // Wait one tick for observeNodes. 510 Polymer.Base.async(function() { 511 form.validate(); 512 expect(form.validate()).to.be.equal(false); 513 form.submit(); 514 server.respond(); 515 }); 516 517 setTimeout(function() { 518 expect(responses).to.be.equal(0); 519 done(); 520 }, 200); 521 }); 522 523 test('invalid <paper-input> but not required is validated and does not submit the form', function(done) { 524 var form = f.querySelector('#custom-invalid'); 525 526 var responses = 0; 527 form.addEventListener('iron-form-response', function(event) { 528 responses++; 529 }); 530 531 // Wait one tick for observeNodes. 532 Polymer.Base.async(function() { 533 expect(form.validate()).to.be.equal(false); 534 form.submit(); 535 server.respond(); 536 }); 537 538 setTimeout(function() { 539 expect(responses).to.be.equal(0); 540 done(); 541 }, 200); 542 }); 543 }); 544 545 suite('submission', function() { 546 var form; 547 var server; 548 549 setup(function() { 550 form = fixture('submission'); 551 552 server = sinon.fakeServer.create(); 553 server.respondWith( 554 'GET', 555 /\/get.*/, 556 [ 557 200, 558 '{"Content-Type":"application/json"}', 559 '{"success":true}' 560 ] 561 ); 562 server.respondWith( 563 'POST', 564 /\/post.*/, 565 [ 566 200, 567 '{"Content-Type":"application/json"}', 568 '{"success":true}' 569 ] 570 ); 571 server.respondWith( 572 'GET', 573 /\/error.*/, 574 [ 575 404, 576 '{"Content-Type":"application/text"}', 577 '{"success":false}' 578 ] 579 ); 580 }); 581 582 teardown(function() { 583 server.restore(); 584 }); 585 586 test('calling submit() on a form with method=get', function(done) { 587 form.addEventListener('iron-form-response', function(event) { 588 expect(event.detail.response.success).to.be.equal(true); 589 done(); 590 }); 591 592 // Wait one tick for observeNodes. 593 Polymer.Base.async(function() { 594 form.submit(); 595 server.respond(); 596 }); 597 }); 598 599 test('calling submit() on a form with method=post', function(done) { 600 form.addEventListener('iron-form-response', function(event) { 601 expect(event.detail.response.success).to.be.equal(true); 602 done(); 603 }); 604 605 // Wait one tick for observeNodes. 606 Polymer.Base.async(function() { 607 form._form.setAttribute('method', 'POST'); 608 form._form.setAttribute('action', '/post'); 609 form.submit(); 610 server.respond(); 611 }); 612 }); 613 614 test('calling submit() on a form with method unset', function(done) { 615 form.addEventListener('iron-form-response', function(event) { 616 expect(event.detail.response.success).to.be.equal(true); 617 done(); 618 }); 619 620 // Wait one tick for observeNodes. 621 Polymer.Base.async(function() { 622 form._form.removeAttribute('method'); 623 form.submit(); 624 server.respond(); 625 }); 626 }); 627 628 test('pressing an <input type=submit> submits the form', function(done) { 629 form.addEventListener('iron-form-response', function(event) { 630 expect(event.detail.response.success).to.be.equal(true); 631 done(); 632 }); 633 634 // Wait one tick for observeNodes. 635 Polymer.Base.async(function() { 636 form._form.querySelector('input[type=submit]').click(); 637 server.respond(); 638 }); 639 }); 640 641 test('pressing an <input type=button> with an event handler submits the form', function(done) { 642 form.addEventListener('iron-form-response', function(event) { 643 expect(event.detail.response.success).to.be.equal(true); 644 done(); 645 }); 646 647 // Wait one tick for observeNodes. 648 Polymer.Base.async(function() { 649 var button = form._form.querySelector('input[type=button]'); 650 button.addEventListener('click', function() { 651 form.submit(); 652 }); 653 button.click(); 654 655 server.respond(); 656 }); 657 }); 658 659 test('pressing a paper-button with an event handler submits the form', function(done) { 660 form.addEventListener('iron-form-response', function(event) { 661 expect(event.detail.response.success).to.be.equal(true); 662 done(); 663 }); 664 665 // Wait one tick for observeNodes. 666 Polymer.Base.async(function() { 667 var button = form._form.querySelector('paper-button'); 668 button.addEventListener('click', function() { 669 form.submit(); 670 }); 671 button.click(); 672 673 server.respond(); 674 }); 675 }); 676 677 test('can modify the request in the presubmit', function(done) { 678 var submitted = false; 679 var presubmitted = false; 680 681 form.addEventListener('iron-form-submit', function() { 682 submitted = true; 683 }); 684 form.addEventListener('iron-form-presubmit', function() { 685 presubmitted = true; 686 this.request.params = {batman: true}; 687 }); 688 689 form.addEventListener('iron-form-response', function(event) { 690 expect(submitted).to.be.equal(true); 691 expect(presubmitted).to.be.equal(true); 692 693 // We have changed the json parameters 694 expect(event.detail.url).to.contain('batman=true'); 695 696 var response = event.detail.response; 697 expect(response).to.be.ok; 698 expect(response).to.be.an('object'); 699 expect(response.success).to.be.equal(true); 700 done(); 701 }); 702 703 // Wait one tick for observeNodes. 704 Polymer.Base.async(function() { 705 form.submit(); 706 server.respond(); 707 }); 708 }); 709 710 test('can do a custom submission in the presubmit', function(done) { 711 var presubmitted = false; 712 // Since we are not using the normal form submission, these events should 713 // never be called. 714 var formResponseHandler = sinon.spy(); 715 form.addEventListener('iron-form-response', formResponseHandler); 716 var formSubmitHandler = sinon.spy(); 717 form.addEventListener('iron-form-submit', formSubmitHandler); 718 719 form.addEventListener('iron-form-presubmit', function(event) { 720 presubmitted = true; 721 event.preventDefault(); 722 // Your custom submission logic could go here (like using Firebase). 723 // In this case, fire a custom event as a an example. 724 this.fire('custom-form-submit'); 725 }); 726 form.addEventListener('custom-form-submit', function(event) { 727 expect(presubmitted).to.be.equal(true); 728 expect(formResponseHandler.callCount).to.be.equal(0); 729 expect(formSubmitHandler.callCount).to.be.equal(0); 730 done(); 731 }); 732 // Wait one tick for observeNodes. 733 Polymer.Base.async(function() { 734 form.submit(); 735 }); 736 }); 737 738 test('can relay errors', function(done) { 739 form.addEventListener('iron-form-error', function(event) { 740 var error = event.detail; 741 expect(error).to.be.ok; 742 expect(error).to.be.an('object'); 743 expect(error.error).to.be.ok; 744 done(); 745 }); 746 747 // Wait one tick for observeNodes. 748 Polymer.Base.async(function() { 749 form._form.setAttribute('action', '/error'); 750 form.submit(); 751 server.respond(); 752 }); 753 }); 754 }); 755 756 suite('resetting', function() { 757 test('can reset a form', function(done) { 758 var form = fixture('resetting'); 759 760 // Wait one tick for observeNodes. 761 Polymer.Base.async(function() { 762 var initial = form.serializeForm(); 763 expect(JSON.stringify(initial)).to.be.equal('{"input1":"input1","input2":"","check1":"on","radio1":"on","papercheck1":"on","paper1":"paper1","paper2":""}'); 764 765 // Modify all the values, flip all the inputs. 766 document.getElementById('input1').value = 'input1++'; 767 document.getElementById('input2').value = 'input2++'; 768 document.getElementById('check1').checked = false; 769 document.getElementById('check2').checked = true; 770 document.getElementById('radio1').checked = false; 771 document.getElementById('radio2').checked = true; 772 document.getElementById('papercheck1').checked = false; 773 document.getElementById('papercheck2').checked = true; 774 document.getElementById('paper1').value = 'paper1++'; 775 document.getElementById('paper2').value = 'paper2++'; 776 777 var updated = form.serializeForm(); 778 expect(JSON.stringify(updated)).to.not.be.equal(initial); 779 form.reset(); 780 var final = form.serializeForm(); 781 expect(JSON.stringify(initial)).to.be.equal(JSON.stringify(final)); 782 done(); 783 }); 784 }); 785 }); 786 787 suite('dynamically created', function() { 788 var server; 789 790 setup(function() { 791 server = sinon.fakeServer.create(); 792 server.respondWith( 793 'GET', 794 /\/get.*/, 795 [ 796 200, 797 '{"Content-Type":"application/json"}', 798 '{"success":true}' 799 ] 800 ); 801 }); 802 803 teardown(function() { 804 server.restore(); 805 }); 806 807 test('submits a form', function(done) { 808 var form = document.createElement('iron-form'); 809 // Need to add to the document so observeNodes runs. 810 document.body.appendChild(form); 811 812 var nativeForm = document.createElement('form'); 813 nativeForm.action = '/get'; 814 nativeForm.method = 'get'; 815 816 var input = document.createElement('input'); 817 nativeForm.appendChild(input); 818 input.required = true; 819 input.name = 'foo'; 820 Polymer.dom(form).appendChild(nativeForm); 821 822 form.addEventListener('iron-form-response', function(event) { 823 expect(event.detail.url).to.equal('/get?foo=bar'); 824 expect(event.detail.response.success).to.be.equal(true); 825 document.body.removeChild(form); 826 done(); 827 }); 828 829 // Wait one tick for observeNodes. 830 Polymer.Base.async(function() { 831 expect(form.validate()).to.be.equal(false); 832 input.value = 'bar'; 833 expect(form.validate()).to.be.equal(true); 834 form.submit(); 835 server.respond(); 836 }, 1); 837 }); 838 }); 839 840 suite('content type', function() { 841 var server; 842 var f; 843 844 setup(function() { 845 server = sinon.fakeServer.create(); 846 f = fixture('content-type'); 847 }); 848 849 teardown(function() { 850 server.restore(); 851 }); 852 853 test('submits a form with text/plain', function(done) { 854 var form = f.querySelector('#plain-form'); 855 856 server.respondWith( 857 'POST', 858 /\/valid\/url.*/, 859 function (request) { 860 expect(request.requestHeaders).to.deep.equal({ 861 "content-type": "text/plain;charset=utf-8", 862 "accept": "application/json"}); 863 expect(request.requestBody).to.deep.equal({ 864 "paper1": "value1", 865 "paper2": "value2"}); 866 done(); 867 } 868 ); 869 870 // Wait one tick for observeNodes. 871 Polymer.Base.async(function() { 872 form.submit(); 873 server.respond(); 874 }); 875 }); 876 test('submits a form with application/json', function(done) { 877 var form = f.querySelector('#json-form'); 878 879 server.respondWith( 880 'POST', 881 /\/valid\/url.*/, 882 function (request) { 883 expect(request.requestHeaders).to.deep.equal({ 884 "content-type": "application/json;charset=utf-8", 885 "accept": "application/json"}); 886 expect(request.requestBody).to.equal( 887 '{"paper1":"value1","paper2":"value2"}'); 888 done(); 889 } 890 ); 891 892 // Wait one tick for observeNodes. 893 Polymer.Base.async(function() { 894 form.submit(); 895 server.respond(); 896 }); 897 }); 898 test('submits a form with application/x-www-form-urlencoded', function(done) { 899 var form = f.querySelector('#simple-form'); 900 901 server.respondWith( 902 'POST', 903 /\/valid\/url.*/, 904 function (request) { 905 expect(request.requestHeaders).to.deep.equal({ 906 "content-type": "application/x-www-form-urlencoded;charset=utf-8", 907 "accept": "application/json"}); 908 expect(request.requestBody).to.equal( 909 'paper1=value1&paper2=value2'); 910 done(); 911 } 912 ); 913 914 // Wait one tick for observeNodes. 915 Polymer.Base.async(function() { 916 form.submit(); 917 server.respond(); 918 }); 919 }); 920 }); 921 </script> 922</body> 923</html> 924