<!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-lite.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">

<script>void(0);</script>

<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;

    var lastId = 0;
    var makeAccount = function() { return {_account_id: lastId++}; };
    var makeGroup = function() { return {id: lastId++}; };

    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('default to publishing drafts with reply', function(done) {
      // 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() {
          element.draft = 'I wholeheartedly disapprove';

          var saveReviewStub = sandbox.stub(element, '_saveReview',
              function(review) {
            assert.deepEqual(review, {
              drafts: 'PUBLISH_ALL_REVISIONS',
              labels: {},
              message: 'I wholeheartedly disapprove',
              reviewers: [],
            });
            assert.isFalse(element.$.commentList.hidden);
            done();
            return Promise.resolve({ok: true});
          });

          // 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'));
          });
        });
      });
    });

    test('keep drafts with reply', function(done) {
      MockInteractions.tap(element.$$('#includeComments'));
      assert.equal(element._includeComments, false);

      // 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() {
          element.draft = 'I wholeheartedly disapprove';

          var saveReviewStub = sandbox.stub(element, '_saveReview',
              function(review) {
            assert.deepEqual(review, {
              drafts: 'KEEP',
              labels: {},
              message: 'I wholeheartedly disapprove',
              reviewers: [],
            });
            assert.isTrue(element.$.commentList.hidden);
            done();
            return Promise.resolve({ok: true});
          });

          // 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'));
          });
        });
      });
    });

    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 = sandbox.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);
            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);
      });
    }

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

      element.serverConfig = {note_db_enabled: true};
      element._ccPendingConfirmation = null;
      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',
      };
      if (cc) {
        element._ccPendingConfirmation = {
          group: group,
          count: 10,
        };
      } else {
        element._reviewerPendingConfirmation = {
          group: group,
          count: 10,
        };
      }
      flushAsynchronousOperations();

      if (cc) {
        assert.deepEqual(
            element._ccPendingConfirmation,
            element._pendingConfirmationDetails);
      } else {
        assert.deepEqual(
            element._reviewerPendingConfirmation,
            element._pendingConfirmationDetails);
      }

      observer.then(function() {
        assert.isTrue(isVisible(element.$.reviewerConfirmationOverlay));
        observer = overlayObserver('closed');
        var expected = 'Group name has 10 members';
        assert.notEqual(
            element.$.reviewerConfirmationOverlay.innerText.indexOf(expected),
            -1);
        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/CC should have been added.
        assert.equal(element.$$('#ccs').additions().length, 0);
        assert.equal(element.$.reviewers.additions().length, 0);

        // Reopen confirmation dialog.
        observer = overlayObserver('opened');
        if (cc) {
          element._ccPendingConfirmation = {
            group: group,
            count: 10,
          };
        } else {
          element._reviewerPendingConfirmation = {
            group: group,
            count: 10,
          };
        }
        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));
        var additions = cc ?
            element.$$('#ccs').additions() :
            element.$.reviewers.additions();
        assert.deepEqual(
            additions,
            [
              {
                group: {
                  id: 'id',
                  name: 'name',
                  confirmed: true,
                  _group: true,
                  _pendingAdd: true,
                },
              },
            ]);

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

    test('cc confirmation', function(done) {
      testConfirmationDialog(done, true);
    });

    test('reviewer confirmation', function(done) {
      testConfirmationDialog(done, false);
    });

    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 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 = sandbox.stub(element, '_saveReview',
            function(review) {
          assert.deepEqual(review.labels, {Verified: -1});
          return Promise.resolve({ok: true});
        });

        element.addEventListener('send', function() {
          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);
    });

    test('_processReviewerChange', function() {
      var mockIndexSplices = function(toRemove) {
        return [{
          removed: [toRemove],
        }];
      };

      element._processReviewerChange(
          mockIndexSplices(makeAccount()), 'REVIEWER');
      assert.equal(element._reviewersPendingRemove.REVIEWER.length, 1);
    });

    test('_purgeReviewersPendingRemove', function() {
      var removeStub = sandbox.stub(element, '_removeAccount');
      var mock = function() {
        element._reviewersPendingRemove = {
          test: [makeAccount()],
          test2: [makeAccount(), makeAccount()],
        };
      };
      var checkObjEmpty = function(obj) {
        for (var prop in obj) {
          if (obj.hasOwnProperty(prop) && obj[prop].length) { return false; }
        }
        return true;
      };
      mock();
      element._purgeReviewersPendingRemove(true); // Cancel
      assert.isFalse(removeStub.called);
      assert.isTrue(checkObjEmpty(element._reviewersPendingRemove));

      mock();
      element._purgeReviewersPendingRemove(false); // Submit
      assert.isTrue(removeStub.called);
      assert.isTrue(checkObjEmpty(element._reviewersPendingRemove));
    });

    test('_removeAccount', function(done) {
      sandbox.stub(element.$.restAPI, 'removeChangeReviewer')
          .returns(Promise.resolve({ok: true}));
      var arr = [makeAccount(), makeAccount()];
      element.change.reviewers = {
        REVIEWER: arr.slice(),
      };

      element._removeAccount(arr[1], 'REVIEWER').then(function() {
        assert.equal(element.change.reviewers.REVIEWER.length, 1);
        assert.deepEqual(element.change.reviewers.REVIEWER, arr.slice(0, 1));
        done();
      });
    });

    test('migrate reviewers between states', function(done) {
      element.serverConfig = {note_db_enabled: true};
      element._reviewersPendingRemove = {
        CC: [],
        REVIEWER: [],
      };
      flushAsynchronousOperations();
      var reviewers = element.$.reviewers;
      var ccs = element.$$('#ccs');
      var reviewer1 = makeAccount();
      var reviewer2 = makeAccount();
      var cc1 = makeAccount();
      var cc2 = makeAccount();
      element._reviewers = [reviewer1, reviewer2];
      element._ccs = [cc1, cc2];

      var mutations = [];

      var saveReviewStub = sandbox.stub(element, '_saveReview',
          function(review) {
        mutations.push.apply(mutations, review.reviewers);
        return Promise.resolve({ok: true});
      });

      var removeAccountStub = sandbox.stub(element, '_removeAccount',
          function(account, type) {
        mutations.push({state: 'REMOVED', account: account});
        return Promise.resolve();
      });

      // Remove and add to other field.
      reviewers.fire('remove', {account: reviewer1});
      ccs.$.entry.fire('add', {value: {account: reviewer1}});
      ccs.fire('remove', {account: cc1});
      reviewers.$.entry.fire('add', {value: {account: cc1}});

      // Add to other field without removing from former field.
      // (Currently not possible in UI, but this is a good consistency check).
      reviewers.$.entry.fire('add', {value: {account: cc2}});
      ccs.$.entry.fire('add', {value: {account: reviewer2}});
      var mapReviewer = function(reviewer, opt_state) {
        var result = {reviewer: reviewer._account_id, confirmed: undefined};
        if (opt_state) {
          result.state = opt_state;
        }
        return result;
      };

      // Send and purge and verify moves without deletions.
      element.send()
          .then(element._purgeReviewersPendingRemove.bind(element))
          .then(function() {
        assert.deepEqual(
            mutations, [
                mapReviewer(cc1),
                mapReviewer(cc2),
                mapReviewer(reviewer1, 'CC'),
                mapReviewer(reviewer2, 'CC'),
            ]);
        done();
      });
    });

    test('emits cancel on esc key', function() {
      var cancelHandler = sandbox.spy();
      element.addEventListener('cancel', cancelHandler);
      MockInteractions.pressAndReleaseKeyOn(element, 27, null, 'esc');
      flushAsynchronousOperations();

      assert.isTrue(cancelHandler.called);
    });
  });
</script>
