<!doctype html>
<!--
@license
Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
Code distributed by Google as part of the polymer project is also
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
-->
<html>

  <head>

    <title>paper-dialog-behavior tests</title>

    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">

    <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
    <script src="../../web-component-tester/browser.js"></script>

    <link rel="import" href="../../paper-icon-button/paper-icon-button.html">
    <link rel="import" href="../../iron-icons/iron-icons.html">
    <link rel="import" href="../../iron-test-helpers/iron-test-helpers.html">
    <link rel="import" href="test-dialog.html">
    <link rel="import" href="test-buttons.html">

  </head>

  <body>

    <test-fixture id="basic">
      <template>
        <test-dialog>
          <p>Dialog</p>
          <div class="buttons">
            <button extra>extra</button>
            <button dialog-dismiss>dismiss</button>
            <button dialog-confirm>confirm</button>
          </div>
        </test-dialog>
      </template>
    </test-fixture>

    <test-fixture id="buttons">
      <template>
        <test-dialog>
          <p>Dialog with test-buttons</p>
          <test-buttons class="buttons"></test-buttons>
        </test-dialog>
      </template>
    </test-fixture>

    <test-fixture id="custom-element-button">
      <template>
        <test-dialog>
          <p>Dialog</p>
          <div class="buttons">
            <paper-icon-button icon="cancel" dialog-dismiss></paper-icon-button>
            <paper-icon-button icon="add-circle" dialog-confirm></paper-icon-button>
            <paper-icon-button icon="favorite"></paper-icon-button>
          </div>
        </test-dialog>
      </template>
    </test-fixture>

    <test-fixture id="modal">
      <template>
        <test-dialog modal>
          <p>Dialog</p>
          <div class="buttons">
            <button dialog-dismiss>dismiss</button>
            <button dialog-confirm autofocus>confirm</button>
          </div>
        </test-dialog>
      </template>
    </test-fixture>

    <test-fixture id="like-modal">
      <template>
        <test-dialog no-cancel-on-esc-key no-cancel-on-outside-click with-backdrop>
          <p>Dialog</p>
        </test-dialog>
      </template>
    </test-fixture>

    <test-fixture id="header">
      <template>
        <test-dialog>
          <h2>Dialog</h2>
          <div class="buttons">
            <button dialog-dismiss>dismiss</button>
            <button dialog-confirm autofocus>confirm</button>
          </div>
        </test-dialog>
      </template>
    </test-fixture>

    <test-fixture id="header-with-id">
      <template>
        <test-dialog>
          <h2 id="header">Dialog</h2>
          <div class="buttons">
            <button dialog-dismiss>dismiss</button>
            <button dialog-confirm autofocus>confirm</button>
          </div>
        </test-dialog>
      </template>
    </test-fixture>

    <test-fixture id="multiple">
      <template>
        <test-dialog modal id="dialog1">
          <p>Dialog 1</p>
        </test-dialog>
        <test-dialog modal id="dialog2">
          <p>Dialog 2</p>
        </test-dialog>
      </template>
    </test-fixture>

    <test-fixture id="nestedmodals">
      <template>
        <test-dialog modal opened>
          <p>Dialog 1</p>
          <div class="buttons">
            <button dialog-dismiss>dismiss</button>
            <button dialog-confirm autofocus>confirm</button>
          </div>

          <test-dialog modal opened>
            <p>Dialog 2</p>
            <div class="buttons">
              <button dialog-dismiss>dismiss</button>
              <button dialog-confirm autofocus>confirm</button>
            </div>
          </test-dialog>
        </test-dialog>
      </template>
    </test-fixture>

    <script>

      function runAfterOpen(dialog, callback) {
        dialog.addEventListener('iron-overlay-opened', callback);
        dialog.open();
      }

      suite('basic', function() {

        test('clicking dialog does not cancel the dialog', function(done) {
          var dialog = fixture('basic');
          runAfterOpen(dialog, function() {
            dialog.addEventListener('iron-overlay-closed', function() {
              assert('dialog should not close');
            });
            MockInteractions.tap(dialog);
            setTimeout(function() {
              done();
            }, 100);
          });
        });

        test('clicking dialog-dismiss button closes the dialog without confirmation', function(done) {
          var dialog = fixture('basic');
          runAfterOpen(dialog, function() {
            dialog.addEventListener('iron-overlay-closed', function(event) {
              assert.isFalse(event.detail.canceled, 'dialog is not canceled');
              assert.isFalse(event.detail.confirmed, 'dialog is not confirmed');
              done();
            });
            MockInteractions.tap(Polymer.dom(dialog).querySelector('[dialog-dismiss]'));
          });
        });

        test('dialog-dismiss on a custom element is handled', function(done) {
          var dialog = fixture('custom-element-button');
          runAfterOpen(dialog, function() {
            dialog.addEventListener('iron-overlay-closed', function(event) {
              assert.isFalse(event.detail.canceled, 'dialog is not canceled');
              assert.isFalse(event.detail.confirmed, 'dialog is not confirmed');
              done();
            });
            MockInteractions.tap(Polymer.dom(dialog).querySelector('[dialog-dismiss]'));
          });
        });

        test('dialog-dismiss button inside a custom element is handled', function(done) {
          var dialog = fixture('buttons');
          runAfterOpen(dialog, function() {
            dialog.addEventListener('iron-overlay-closed', function(event) {
              assert.isFalse(event.detail.canceled, 'dialog is not canceled');
              assert.isFalse(event.detail.confirmed, 'dialog is not confirmed');
              done();
            });
            MockInteractions.tap(Polymer.dom(dialog).querySelector('test-buttons').$.dismiss);
          });
        });

        test('clicking dialog-confirm button closes the dialog with confirmation', function(done) {
          var dialog = fixture('basic');
          runAfterOpen(dialog, function() {
            dialog.addEventListener('iron-overlay-closed', function(event) {
              assert.isFalse(event.detail.canceled, 'dialog is not canceled');
              assert.isTrue(event.detail.confirmed, 'dialog is confirmed');
              done();
            });
            MockInteractions.tap(Polymer.dom(dialog).querySelector('[dialog-confirm]'));
          });
        });

        test('dialog-confirm on a custom element handled', function(done) {
          var dialog = fixture('custom-element-button');
          runAfterOpen(dialog, function() {
            dialog.addEventListener('iron-overlay-closed', function(event) {
              assert.isFalse(event.detail.canceled, 'dialog is not canceled');
              assert.isTrue(event.detail.confirmed, 'dialog is confirmed');
              done();
            });
            MockInteractions.tap(Polymer.dom(dialog).querySelector('[dialog-confirm]'));
          });
        });

        test('dialog-confirm button inside a custom element is handled', function(done) {
          var dialog = fixture('buttons');
          runAfterOpen(dialog, function() {
            dialog.addEventListener('iron-overlay-closed', function(event) {
              assert.isFalse(event.detail.canceled, 'dialog is not canceled');
              assert.isTrue(event.detail.confirmed, 'dialog is confirmed');
              done();
            });
            MockInteractions.tap(Polymer.dom(dialog).querySelector('test-buttons').$.confirm);
          });
        });

        test('clicking dialog-dismiss button closes only the dialog where is contained', function(done) {
          var dialog = fixture('nestedmodals');
          var innerDialog = Polymer.dom(dialog).querySelector('test-dialog');
          MockInteractions.tap(Polymer.dom(innerDialog).querySelector('[dialog-dismiss]'));
          setTimeout(function() {
            assert.isFalse(innerDialog.opened, 'inner dialog is closed');
            assert.isTrue(dialog.opened, 'dialog is still open');
            done();
          }, 10);
        });

        test('clicking dialog-confirm button closes only the dialog where is contained', function(done) {
          var dialog = fixture('nestedmodals');
          var innerDialog = Polymer.dom(dialog).querySelector('test-dialog');
          MockInteractions.tap(Polymer.dom(innerDialog).querySelector('[dialog-confirm]'));
          setTimeout(function() {
            assert.isFalse(innerDialog.opened, 'inner dialog is closed');
            assert.isTrue(dialog.opened, 'dialog is still open');
            done();
          }, 10);
        });

        var properties = ['noCancelOnEscKey', 'noCancelOnOutsideClick', 'withBackdrop'];
        properties.forEach(function(property) {

          test('modal sets ' + property + ' to true', function() {
            var dialog = fixture('modal');
            assert.isTrue(dialog[property], property);
          });

          test('modal toggling keeps current value of ' + property, function() {
            var dialog = fixture('modal');
            // Changed to false while modal is true.
            dialog[property] = false;
            dialog.modal = false;
            assert.isFalse(dialog[property], property + ' is false');
          });

          test('modal toggling keeps previous value of ' + property, function() {
            var dialog = fixture('basic');
            // Changed before modal is true.
            dialog[property] = true;
            // Toggle twice to trigger observer.
            dialog.modal = true;
            dialog.modal = false;
            assert.isTrue(dialog[property], property + ' is still true');
          });

          test('default modal does not override ' + property +' (attribute)', function() {
            // Property is set on ready from attribute.
            var dialog = fixture('like-modal');
            assert.isTrue(dialog[property], property + ' is true');
          });

          test('modal toggling keeps previous value of ' + property + ' (attribute)', function() {
            // Property is set on ready from attribute.
            var dialog = fixture('like-modal');
            // Toggle twice to trigger observer.
            dialog.modal = true;
            dialog.modal = false;
            assert.isTrue(dialog[property], property + ' is still true');
          });

        });

        test('clicking outside a modal dialog does not move focus from dialog', function(done) {
          var dialog = fixture('modal');
          runAfterOpen(dialog, function() {
            MockInteractions.tap(document.body);
            setTimeout(function() {
              assert.equal(document.activeElement, Polymer.dom(dialog).querySelector('[autofocus]'), 'document.activeElement is the autofocused button');
              done();
            }, 10);
          });
        });

        test('removing a child element on click does not cause an exception', function(done) {
          var dialog = fixture('basic');
          runAfterOpen(dialog, function() {
            var button = Polymer.dom(dialog).querySelector('[extra]');
            button.addEventListener('click', function(event) {
              Polymer.dom(event.target.parentNode).removeChild(event.target);
              // should not throw exception here
              done();
            });
            MockInteractions.tap(button);
          });
        });

        test('multiple modal dialogs opened, handle focus change', function(done) {
          var dialogs = fixture('multiple');

          runAfterOpen(dialogs[0], function() {
            runAfterOpen(dialogs[1], function() {
              // Each modal dialog will trap the focus within its children.
              // Multiple modal dialogs doing it might result in an infinite loop
              // dialog1 focus -> dialog2 focus -> dialog1 focus -> dialog2 focus...
              // causing a "Maximum call stack size exceeded" error.
              // Wait 50ms and verify this does not happen.
              Polymer.Base.async(function() {
                // Should not enter in an infinite loop.
                done();
              }, 50);
            });
          });
        });

        test('multiple modal dialogs opened, handle outside click', function(done) {
          var dialogs = fixture('multiple');

          runAfterOpen(dialogs[0], function() {
            runAfterOpen(dialogs[1], function() {
              // Click should be handled only by dialogs[1].
              MockInteractions.tap(document.body);
              // Each modal dialog will trap the focus within its children.
              // Multiple modal dialogs doing it might result in an infinite loop
              // dialog1 focus -> dialog2 focus -> dialog1 focus -> dialog2 focus...
              // causing a "Maximum call stack size exceeded" error.
              // Wait 50ms and verify this does not happen.
              Polymer.Base.async(function() {
                // Should not enter in an infinite loop.
                done();
              }, 50);
            });
          });
        });

        test('focus is given to the autofocus element when clicking on backdrop', function(done) {
          var dialog = fixture('modal');
          dialog.addEventListener('iron-overlay-opened', onFirstOpen);
          dialog.open();

          function onFirstOpen() {
            dialog.removeEventListener('iron-overlay-opened', onFirstOpen);
            dialog.addEventListener('iron-overlay-closed', onFirstClose);
            // Set the focus on dismiss button
            MockInteractions.focus(Polymer.dom(dialog).querySelector('[dialog-dismiss]'));
            // Close the dialog
            dialog.close();
          }

          function onFirstClose() {
            dialog.removeEventListener('iron-overlay-closed', onFirstClose);
            dialog.addEventListener('iron-overlay-opened', onSecondOpen);
            dialog.open();
          }

          function onSecondOpen() {
            MockInteractions.tap(document.body);
            setTimeout(function() {
              assert.equal(document.activeElement, Polymer.dom(dialog).querySelector('[autofocus]'), 'document.activeElement is the autofocused button');
              done();
            }, 10);
          }
        });

      });

      suite('a11y', function() {

        test('dialog has role="dialog"', function() {
          var dialog = fixture('basic');
          assert.equal(dialog.getAttribute('role'), 'dialog', 'has role="dialog"');
        });

      });
    </script>

  </body>

</html>
