<!DOCTYPE html>
<!--
Copyright (C) 2015 The Android Open Source Project

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->

<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-reply-dialog</title>

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

<link rel="import" href="../../../bower_components/iron-test-helpers/iron-test-helpers.html">
<link rel="import" href="gr-reply-dialog.html">

<test-fixture id="basic">
  <template>
    <gr-reply-dialog></gr-reply-dialog>
  </template>
</test-fixture>

<script>
  suite('gr-reply-dialog tests', function() {
    var element;
    var changeNum;
    var patchNum;

    var sandbox;
    var getDraftCommentStub;
    var setDraftCommentStub;
    var eraseDraftCommentStub;

    setup(function() {
      sandbox = sinon.sandbox.create();

      changeNum = 42;
      patchNum = 1;

      stub('gr-rest-api-interface', {
        getConfig: function() { return Promise.resolve({}); },
        getAccount: function() { return Promise.resolve({}); },
      });

      element = fixture('basic');
      element.change = {
        _number: changeNum,
        labels: {
          Verified: {
            values: {
              '-1': 'Fails',
              ' 0': 'No score',
              '+1': 'Verified',
            },
            default_value: 0,
          },
          'Code-Review': {
            values: {
              '-2': 'Do not submit',
              '-1': 'I would prefer that you didn\'t submit this',
              ' 0': 'No score',
              '+1': 'Looks good to me, but someone else must approve',
              '+2': 'Looks good to me, approved',
            },
            default_value: 0,
          },
        },
      };
      element.patchNum = patchNum;
      element.permittedLabels = {
        'Code-Review': [
          '-1',
          ' 0',
          '+1',
        ],
        Verified: [
          '-1',
          ' 0',
          '+1',
        ],
      };
      element.serverConfig = {};

      getDraftCommentStub = sandbox.stub(element.$.storage, 'getDraftComment');
      setDraftCommentStub = sandbox.stub(element.$.storage, 'setDraftComment');
      eraseDraftCommentStub = sandbox.stub(element.$.storage,
          'eraseDraftComment');

      // Allow the elements created by dom-repeat to be stamped.
      flushAsynchronousOperations();
    });

    teardown(function() {
      sandbox.restore();
    });

    test('changes in label score are reflected in the DOM', function() {
      element._account = {_account_id: 1};
      element.set(['change', 'labels', 'Verified', 'all'],
          [{_account_id: 1, value: -1}]);
      flushAsynchronousOperations();
      var selector = element.$$('iron-selector[data-label="Verified"]');
      assert.equal(selector.selected, 0); // Index 0, value -1
      element.set(['change', 'labels', 'Verified', 'all'],
         [{_account_id: 1, value: 1}]);
      flushAsynchronousOperations();
      assert.equal(selector.selected, 2); // Index 2, value 1
    });

    test('cancel event', function(done) {
      element.addEventListener('cancel', function() { done(); });
      MockInteractions.tap(element.$$('.cancel'));
    });

    test('label picker', function(done) {
      element.revisions = {};
      element.patchNum = '';

      // Async tick is needed because iron-selector content is distributed and
      // distributed content requires an observer to be set up.
      // Note: Double flush seems to be needed in Safari. {@see Issue 4963}.
      flush(function() {
        flush(function() {
          for (var label in element.permittedLabels) {
            assert.ok(element.$$('iron-selector[data-label="' + label + '"]'),
                label);
          }
          element.draft = 'I wholeheartedly disapprove';
          MockInteractions.tap(element.$$(
              'iron-selector[data-label="Code-Review"] > ' +
              'gr-button[data-value="-1"]'));
          MockInteractions.tap(element.$$(
              'iron-selector[data-label="Verified"] > ' +
              'gr-button[data-value="-1"]'));

          var saveReviewStub = sinon.stub(element, '_saveReview',
              function(review) {
            assert.deepEqual(review, {
              drafts: 'PUBLISH_ALL_REVISIONS',
              labels: {
                'Code-Review': -1,
                'Verified': -1,
              },
              message: 'I wholeheartedly disapprove',
              reviewers: [],
            });
            return Promise.resolve({ok: true});
          });

          element.addEventListener('send', function() {
            assert.isFalse(element.disabled,
                'Element should be enabled when done sending reply.');
            assert.equal(element.draft.length, 0);
            saveReviewStub.restore();
            done();
          });

          // This is needed on non-Blink engines most likely due to the ways in
          // which the dom-repeat elements are stamped.
          flush(function() {
            MockInteractions.tap(element.$$('.send'));
            assert.isTrue(element.disabled);
          });
        });
      });
    });

    function getActiveElement() {
      return Polymer.IronOverlayManager.deepActiveElement;
    }

    function isVisible(el) {
      assert.ok(el);
      return getComputedStyle(el).getPropertyValue('display') != 'none';
    }

    function overlayObserver(mode) {
      return new Promise(function(resolve) {
        function listener() {
          element.removeEventListener('iron-overlay-' + mode, listener);
          resolve();
        }
        element.addEventListener('iron-overlay-' + mode, listener);
      });
    }

    test('reviewer confirmation', function(done) {
      var yesButton =
          element.$$('.reviewerConfirmationButtons gr-button:first-child');
      var noButton =
          element.$$('.reviewerConfirmationButtons gr-button:last-child');

      element._reviewerPendingConfirmation = null;
      flushAsynchronousOperations();
      assert.isFalse(isVisible(element.$.reviewerConfirmationOverlay));

      // Cause the confirmation dialog to display.
      var observer = overlayObserver('opened');
      var group = {
        id: 'id',
        name: 'name',
        count: 10,
      };
      element._reviewerPendingConfirmation = {
        group: group,
      };

      observer.then(function() {
        assert.isTrue(isVisible(element.$.reviewerConfirmationOverlay));
        observer = overlayObserver('closed');
        MockInteractions.tap(noButton); // close the overlay
        return observer;
      }).then(function() {
        assert.isFalse(isVisible(element.$.reviewerConfirmationOverlay));

        // We should be focused on account entry input.
        assert.equal(getActiveElement().id, 'input');

        // No reviewer should have been added.
        assert.deepEqual(element.$.reviewers.additions(), []);

        // Reopen confirmation dialog.
        observer = overlayObserver('opened');
        element._reviewerPendingConfirmation = {
          group: group,
        };
        return observer;
      }).then(function() {
        assert.isTrue(isVisible(element.$.reviewerConfirmationOverlay));
        observer = overlayObserver('closed');
        MockInteractions.tap(yesButton); // Confirm the group.
        return observer;
      }).then(function() {
        assert.isFalse(isVisible(element.$.reviewerConfirmationOverlay));
        assert.deepEqual(
            element.$.reviewers.additions(),
            [
              {
                group: {
                  id: 'id',
                  name: 'name',
                  count: 10,
                  confirmed: true,
                  _group: true,
                  _pendingAdd: true,
                },
              },
            ]);

        // We should be focused on account entry input.
        assert.equal(getActiveElement().id, 'input');
      }).then(done);
    });

    test('_getStorageLocation', function() {
      var actual = element._getStorageLocation();
      assert.equal(actual.changeNum, changeNum);
      assert.equal(actual.patchNum, patchNum);
      assert.equal(actual.path, '@change');
    });

    test('gets draft from storage on open', function() {
      var storedDraft = 'hello world';
      getDraftCommentStub.returns({message: storedDraft});
      element.open();
      assert.isTrue(getDraftCommentStub.called);
      assert.equal(element.draft, storedDraft);
    });

    test('blank if no stored draft', function() {
      getDraftCommentStub.returns(null);
      element.open();
      assert.isTrue(getDraftCommentStub.called);
      assert.equal(element.draft, '');
    });

    test('updates stored draft on edits', function() {
      var firstEdit = 'hello';
      var location = element._getStorageLocation();

      element.draft = firstEdit;
      element.flushDebouncer('store');

      assert.isTrue(setDraftCommentStub.calledWith(location, firstEdit));

      element.draft = '';
      element.flushDebouncer('store');

      assert.isTrue(eraseDraftCommentStub.calledWith(location));
    });

    test('400 converts to human-readable server-error', function(done) {
      sandbox.stub(window, 'fetch', function() {
        var text = '....{"reviewers":{"id1":{"error":"first error"}},' +
          '"ccs":{"id2":{"error":"second error"}}}';
        return Promise.resolve({
          ok: false,
          status: 400,
          text: function() { return Promise.resolve(text); },
        });
      });

      element.addEventListener('server-error', function(event) {
        if (event.target !== element) {
          return;
        }
        event.detail.response.text().then(function(body) {
          assert.equal(body, 'first error, second error');
        });
      });

      // Async tick is needed because iron-selector content is distributed and
      // distributed content requires an observer to be set up.
      flush(function() { element.send().then(done); });
    });

    test('ccs are displayed if NoteDb is enabled', function() {
      function hasCc() {
        flushAsynchronousOperations();
        return !!element.$$('#ccs');
      }

      element.serverConfig = {};
      assert.isFalse(hasCc());

      element.serverConfig = {note_db_enabled: true};
      assert.isTrue(hasCc());
    });

    test('filterReviewerSuggestion', function() {
      var counter = 0;
      function makeAccount() {
        return {_account_id: counter++};
      }
      function makeGroup() {
        return {id: counter++};
      }

      var owner = makeAccount();
      var reviewer1 = makeAccount();
      var reviewer2 = makeGroup();
      var cc1 = makeAccount();
      var cc2 = makeGroup();

      element._owner = owner;
      element._reviewers = [reviewer1, reviewer2];
      element._ccs = [cc1, cc2];

      assert.isTrue(
          element._filterReviewerSuggestion({account: makeAccount()}));
      assert.isTrue(element._filterReviewerSuggestion({group: makeGroup()}));

      // Owner should be excluded.
      assert.isFalse(element._filterReviewerSuggestion({account: owner}));

      // Existing and pending reviewers should be excluded.
      assert.isFalse(element._filterReviewerSuggestion({account: reviewer1}));
      assert.isFalse(element._filterReviewerSuggestion({group: reviewer2}));

      // Existing and pending CCs should be excluded.
      assert.isFalse(element._filterReviewerSuggestion({account: cc1}));
      assert.isFalse(element._filterReviewerSuggestion({group: cc2}));
    });

    test('_chooseFocusTarget', function() {
      element._account = null;
      assert.strictEqual(
          element._chooseFocusTarget(), element.FocusTarget.BODY);

      element._account = {_account_id: 1};
      assert.strictEqual(
          element._chooseFocusTarget(), element.FocusTarget.BODY);

      element.change.owner = {_account_id: 2};
      assert.strictEqual(
          element._chooseFocusTarget(), element.FocusTarget.BODY);

      element.change.owner._account_id = 1;
      element.change._reviewers = null;
      assert.strictEqual(
          element._chooseFocusTarget(), element.FocusTarget.REVIEWERS);

      element._reviewers = [];
      assert.strictEqual(
          element._chooseFocusTarget(), element.FocusTarget.REVIEWERS);

      element._reviewers.push({});
      assert.strictEqual(
          element._chooseFocusTarget(), element.FocusTarget.BODY);
    });

    test('only send labels that have changed', function(done) {
      flush(function() {
        var saveReviewStub = sinon.stub(element, '_saveReview',
            function(review) {
          assert.deepEqual(review.labels, {Verified: -1});
          return Promise.resolve({ok: true});
        });

        element.addEventListener('send', function() {
          saveReviewStub.restore();
          done();
        });
        // Without wrapping this test in flush(), the below two calls to
        // MockInteractions.tap() cause a race in some situations in shadow DOM.
        // The send button can be tapped before the others, causing the test to
        // fail.
        MockInteractions.tap(element.$$(
            'iron-selector[data-label="Verified"] > ' +
            'gr-button[data-value="-1"]'));
        MockInteractions.tap(element.$$('.send'));
      });
    });

    test('do not display tooltips on touch devices', function() {
      element._account = {_account_id: 1};
      element.set(['change', 'labels', 'Verified', 'all'],
          [{_account_id: 1, value: -1}]);
      element.labels = {
        Verified: {
          values: {
            '-1': 'Fails',
            ' 0': 'No score',
            '+1': 'Verified'
          },
          default_value: 0
        },
        'Code-Review': {
          values: {
            '-2': 'Do not submit',
            '-1': 'I would prefer that you didn\'t submit this',
            ' 0': 'No score',
            '+1': 'Looks good to me, but someone else must approve',
            '+2': 'Looks good to me, approved'
          },
          default_value: 0
        }
      };

      flushAsynchronousOperations();

      var verifiedBtn = element.$$(
          'iron-selector[data-label="Verified"] > ' +
          'gr-button[data-value="-1"]');

      // On touch devices, tooltips should not be shown.
      verifiedBtn._isTouchDevice = true;
      verifiedBtn._handleShowTooltip();
      assert.isNotOk(verifiedBtn._tooltip);
      verifiedBtn._handleHideTooltip();
      assert.isNotOk(verifiedBtn._tooltip);

      // On other devices, tooltips should be shown.
      verifiedBtn._isTouchDevice = false;
      verifiedBtn._handleShowTooltip();
      assert.isOk(verifiedBtn._tooltip);
      verifiedBtn._handleHideTooltip();
      assert.isNotOk(verifiedBtn._tooltip);
    });
  });
</script>
