<!DOCTYPE html>
<!--
@license
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="/test/common-test-setup.js"></script>
<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>

<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.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>
  function cloneableResponse(status, text) {
    return {
      ok: false,
      status,
      text() {
        return Promise.resolve(text);
      },
      clone() {
        return {
          ok: false,
          status,
          text() {
            return Promise.resolve(text);
          },
        };
      },
    };
  }

  suite('gr-reply-dialog tests', () => {
    let element;
    let changeNum;
    let patchNum;

    let sandbox;
    let getDraftCommentStub;
    let setDraftCommentStub;
    let eraseDraftCommentStub;

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

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

      changeNum = 42;
      patchNum = 1;

      stub('gr-rest-api-interface', {
        getConfig() { return Promise.resolve({}); },
        getAccount() { return Promise.resolve({}); },
        getChange() { return Promise.resolve({}); },
        getChangeSuggestedReviewers() { 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',
        ],
      };

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

      sandbox.stub(element, 'fetchChangeUpdates')
          .returns(Promise.resolve({isLatest: true}));

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

    teardown(() => {
      sandbox.restore();
    });

    function stubSaveReview(jsonResponseProducer) {
      return sandbox.stub(element, '_saveReview', review => {
        return new Promise((resolve, reject) => {
          try {
            const result = jsonResponseProducer(review) || {};
            const resultStr =
                element.$.restAPI.JSON_PREFIX + JSON.stringify(result);
            resolve({
              ok: true,
              text() {
                return Promise.resolve(resultStr);
              },
            });
          } catch (err) {
            reject(err);
          }
        });
      });
    }

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

          stubSaveReview(review => {
            assert.deepEqual(review, {
              drafts: 'PUBLISH_ALL_REVISIONS',
              labels: {
                'Code-Review': 0,
                'Verified': 0,
              },
              message: 'I wholeheartedly disapprove',
              reviewers: [],
            });
            assert.isFalse(element.$.commentList.hidden);
            done();
          });

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

    test('keep drafts with reply', 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(() => {
        flush(() => {
          element.draft = 'I wholeheartedly disapprove';

          stubSaveReview(review => {
            assert.deepEqual(review, {
              drafts: 'KEEP',
              labels: {
                'Code-Review': 0,
                'Verified': 0,
              },
              message: 'I wholeheartedly disapprove',
              reviewers: [],
            });
            assert.isTrue(element.$.commentList.hidden);
            done();
          });

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

    test('label picker', done => {
      element.draft = 'I wholeheartedly disapprove';
      stubSaveReview(review => {
        assert.deepEqual(review, {
          drafts: 'PUBLISH_ALL_REVISIONS',
          labels: {
            'Code-Review': -1,
            'Verified': -1,
          },
          message: 'I wholeheartedly disapprove',
          reviewers: [],
        });
      });

      sandbox.stub(element.$.labelScores, 'getLabelValues', () => {
        return {
          'Code-Review': -1,
          'Verified': -1,
        };
      });

      element.addEventListener('send', () => {
        // Flush to ensure properties are updated.
        flush(() => {
          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(() => {
        MockInteractions.tap(element.$$('.send'));
        assert.isTrue(element.disabled);
      });
    });

    test('getlabelValue returns value', done => {
      flush(() => {
        element.$$('gr-label-scores').$$(`gr-label-score-row[name="Verified"]`)
            .setSelectedValue(-1);
        assert.equal('-1', element.getLabelValue('Verified'));
        done();
      });
    });

    test('getlabelValue when no score is selected', done => {
      flush(() => {
        element.$$('gr-label-scores')
            .$$(`gr-label-score-row[name="Code-Review"]`).setSelectedValue(-1);
        assert.strictEqual(element.getLabelValue('Verified'), ' 0');
        done();
      });
    });

    test('setlabelValue', done => {
      element._account = {_account_id: 1};
      flush(() => {
        const label = 'Verified';
        const value = '+1';
        element.setLabelValue(label, value);

        const labels = element.$.labelScores.getLabelValues();
        assert.deepEqual(labels, {
          'Code-Review': 0,
          'Verified': 1,
        });
        done();
      });
    });

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

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

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

    function isFocusInsideElement(element) {
      // In Polymer 2 focused element either <paper-input> or nested
      // native input <input> element depending on the current focus
      // in browser window.
      // For example, the focus is changed if the developer console
      // get a focus.
      let activeElement = getActiveElement();
      while (activeElement) {
        if (activeElement === element) {
          return true;
        }
        if (activeElement.parentElement) {
          activeElement = activeElement.parentElement;
        } else {
          activeElement = activeElement.getRootNode().host;
        }
      }
      return false;
    }

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

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

      // Cause the confirmation dialog to display.
      let observer = overlayObserver('opened');
      const group = {
        id: 'id',
        name: 'name',
      };
      if (cc) {
        element._ccPendingConfirmation = {
          group,
          count: 10,
        };
      } else {
        element._reviewerPendingConfirmation = {
          group,
          count: 10,
        };
      }
      flushAsynchronousOperations();

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

      observer.then(() => {
        assert.isTrue(isVisible(element.$.reviewerConfirmationOverlay));
        observer = overlayObserver('closed');
        const expected = 'Group name has 10 members';
        assert.notEqual(
            element.$.reviewerConfirmationOverlay.innerText.indexOf(expected),
            -1);
        MockInteractions.tap(noButton); // close the overlay
        return observer;
      }).then(() => {
        assert.isFalse(isVisible(element.$.reviewerConfirmationOverlay));

        // We should be focused on account entry input.
        assert.isTrue(
            isFocusInsideElement(element.$.reviewers.$.entry.$.input.$.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,
            count: 10,
          };
        } else {
          element._reviewerPendingConfirmation = {
            group,
            count: 10,
          };
        }
        return observer;
      }).then(() => {
        assert.isTrue(isVisible(element.$.reviewerConfirmationOverlay));
        observer = overlayObserver('closed');
        MockInteractions.tap(yesButton); // Confirm the group.
        return observer;
      }).then(() => {
        assert.isFalse(isVisible(element.$.reviewerConfirmationOverlay));
        const 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.
        if (cc) {
          assert.isTrue(
              isFocusInsideElement(element.$.ccs.$.entry.$.input.$.input));
        } else {
          assert.isTrue(
              isFocusInsideElement(element.$.reviewers.$.entry.$.input.$.input));
        }
      }).then(done);
    }

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

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

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

    test('_reviewersMutated when account-text-change is fired from ccs', () => {
      flushAsynchronousOperations();
      assert.isFalse(element._reviewersMutated);
      assert.isTrue(element.$.ccs.allowAnyInput);
      assert.isFalse(element.$$('#reviewers').allowAnyInput);
      element.$.ccs.dispatchEvent(new CustomEvent('account-text-changed',
          {bubbles: true, composed: true}));
      assert.isTrue(element._reviewersMutated);
    });

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

    test('gets draft from storage even when text is already present', () => {
      const storedDraft = 'hello world';
      getDraftCommentStub.returns({message: storedDraft});
      element.draft = 'foo bar';
      element.open();
      assert.isTrue(getDraftCommentStub.called);
      assert.equal(element.draft, storedDraft);
    });

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

    test('does not check stored draft when quote is present', () => {
      const storedDraft = 'hello world';
      const quote = '> foo bar';
      getDraftCommentStub.returns({message: storedDraft});
      element.quote = quote;
      element.open();
      assert.isFalse(getDraftCommentStub.called);
      assert.equal(element.draft, quote);
      assert.isNotOk(element.quote);
    });

    test('updates stored draft on edits', () => {
      const firstEdit = 'hello';
      const 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', done => {
      sandbox.stub(window, 'fetch', () => {
        const text = '....{"reviewers":{"id1":{"error":"first error"}},' +
          '"ccs":{"id2":{"error":"second error"}}}';
        return Promise.resolve(cloneableResponse(400, text));
      });

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

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

    test('non-json 400 is treated as a normal server-error', done => {
      sandbox.stub(window, 'fetch', () => {
        const text = 'Comment validation error!';
        return Promise.resolve(cloneableResponse(400, text));
      });

      element.addEventListener('server-error', event => {
        if (event.target !== element) {
          return;
        }
        event.detail.response.text().then(body => {
          assert.equal(body, 'Comment validation error!');
          done();
        });
      });

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

    test('filterReviewerSuggestion', () => {
      const owner = makeAccount();
      const reviewer1 = makeAccount();
      const reviewer2 = makeGroup();
      const cc1 = makeAccount();
      const cc2 = makeGroup();
      let filter = element._filterReviewerSuggestionGenerator(false);

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

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

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

      // Existing and pending reviewers should be excluded when isCC = false.
      assert.isFalse(filter({account: reviewer1}));
      assert.isFalse(filter({group: reviewer2}));

      filter = element._filterReviewerSuggestionGenerator(true);

      // Existing and pending CCs should be excluded when isCC = true;.
      assert.isFalse(filter({account: cc1}));
      assert.isFalse(filter({group: cc2}));
    });

    test('_focusOn', () => {
      sandbox.spy(element, '_chooseFocusTarget');
      flushAsynchronousOperations();
      const textareaStub = sandbox.stub(element.$.textarea, 'async');
      const reviewerEntryStub = sandbox.stub(element.$.reviewers.focusStart,
          'async');
      const ccStub = sandbox.stub(element.$.ccs.focusStart, 'async');
      element._focusOn();
      assert.equal(element._chooseFocusTarget.callCount, 1);
      assert.deepEqual(textareaStub.callCount, 1);
      assert.deepEqual(reviewerEntryStub.callCount, 0);
      assert.deepEqual(ccStub.callCount, 0);

      element._focusOn(element.FocusTarget.ANY);
      assert.equal(element._chooseFocusTarget.callCount, 2);
      assert.deepEqual(textareaStub.callCount, 2);
      assert.deepEqual(reviewerEntryStub.callCount, 0);
      assert.deepEqual(ccStub.callCount, 0);

      element._focusOn(element.FocusTarget.BODY);
      assert.equal(element._chooseFocusTarget.callCount, 2);
      assert.deepEqual(textareaStub.callCount, 3);
      assert.deepEqual(reviewerEntryStub.callCount, 0);
      assert.deepEqual(ccStub.callCount, 0);

      element._focusOn(element.FocusTarget.REVIEWERS);
      assert.equal(element._chooseFocusTarget.callCount, 2);
      assert.deepEqual(textareaStub.callCount, 3);
      assert.deepEqual(reviewerEntryStub.callCount, 1);
      assert.deepEqual(ccStub.callCount, 0);

      element._focusOn(element.FocusTarget.CCS);
      assert.equal(element._chooseFocusTarget.callCount, 2);
      assert.deepEqual(textareaStub.callCount, 3);
      assert.deepEqual(reviewerEntryStub.callCount, 1);
      assert.deepEqual(ccStub.callCount, 1);
    });

    test('_chooseFocusTarget', () => {
      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', done => {
      flush(() => {
        stubSaveReview(review => {
          assert.deepEqual(review.labels, {
            'Code-Review': 0,
            'Verified': -1,
          });
        });

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

        element.$$('gr-label-scores').$$(
            'gr-label-score-row[name="Verified"]').setSelectedValue(-1);
        MockInteractions.tap(element.$$('.send'));
      });
    });

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

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

    test('_purgeReviewersPendingRemove', () => {
      const removeStub = sandbox.stub(element, '_removeAccount');
      const mock = function() {
        element._reviewersPendingRemove = {
          test: [makeAccount()],
          test2: [makeAccount(), makeAccount()],
        };
      };
      const checkObjEmpty = function(obj) {
        for (const 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', done => {
      sandbox.stub(element.$.restAPI, 'removeChangeReviewer')
          .returns(Promise.resolve({ok: true}));
      const arr = [makeAccount(), makeAccount()];
      element.change.reviewers = {
        REVIEWER: arr.slice(),
      };

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

    test('moving from cc to reviewer', () => {
      element._reviewersPendingRemove = {
        CC: [],
        REVIEWER: [],
      };
      flushAsynchronousOperations();

      const reviewer1 = makeAccount();
      const reviewer2 = makeAccount();
      const reviewer3 = makeAccount();
      const cc1 = makeAccount();
      const cc2 = makeAccount();
      const cc3 = makeAccount();
      const cc4 = makeAccount();
      element._reviewers = [reviewer1, reviewer2, reviewer3];
      element._ccs = [cc1, cc2, cc3, cc4];
      element.push('_reviewers', cc1);
      flushAsynchronousOperations();

      assert.deepEqual(element._reviewers,
          [reviewer1, reviewer2, reviewer3, cc1]);
      assert.deepEqual(element._ccs, [cc2, cc3, cc4]);
      assert.deepEqual(element._reviewersPendingRemove.CC, [cc1]);

      element.push('_reviewers', cc4, cc3);
      flushAsynchronousOperations();

      assert.deepEqual(element._reviewers,
          [reviewer1, reviewer2, reviewer3, cc1, cc4, cc3]);
      assert.deepEqual(element._ccs, [cc2]);
      assert.deepEqual(element._reviewersPendingRemove.CC, [cc1, cc4, cc3]);
    });

    test('moving from reviewer to cc', () => {
      element._reviewersPendingRemove = {
        CC: [],
        REVIEWER: [],
      };
      flushAsynchronousOperations();

      const reviewer1 = makeAccount();
      const reviewer2 = makeAccount();
      const reviewer3 = makeAccount();
      const cc1 = makeAccount();
      const cc2 = makeAccount();
      const cc3 = makeAccount();
      const cc4 = makeAccount();
      element._reviewers = [reviewer1, reviewer2, reviewer3];
      element._ccs = [cc1, cc2, cc3, cc4];
      element.push('_ccs', reviewer1);
      flushAsynchronousOperations();

      assert.deepEqual(element._reviewers,
          [reviewer2, reviewer3]);
      assert.deepEqual(element._ccs, [cc1, cc2, cc3, cc4, reviewer1]);
      assert.deepEqual(element._reviewersPendingRemove.REVIEWER, [reviewer1]);

      element.push('_ccs', reviewer3, reviewer2);
      flushAsynchronousOperations();

      assert.deepEqual(element._reviewers, []);
      assert.deepEqual(element._ccs,
          [cc1, cc2, cc3, cc4, reviewer1, reviewer3, reviewer2]);
      assert.deepEqual(element._reviewersPendingRemove.REVIEWER,
          [reviewer1, reviewer3, reviewer2]);
    });

    test('migrate reviewers between states', done => {
      element._reviewersPendingRemove = {
        CC: [],
        REVIEWER: [],
      };
      flushAsynchronousOperations();
      const reviewers = element.$.reviewers;
      const ccs = element.$.ccs;
      const reviewer1 = makeAccount();
      const reviewer2 = makeAccount();
      const cc1 = makeAccount();
      const cc2 = makeAccount();
      const cc3 = makeAccount();
      element._reviewers = [reviewer1, reviewer2];
      element._ccs = [cc1, cc2, cc3];

      const mutations = [];

      stubSaveReview(review => mutations.push(...review.reviewers));

      sandbox.stub(element, '_removeAccount', (account, type) => {
        mutations.push({state: 'REMOVED', 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});
      ccs.fire('remove', {account: cc3});
      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}});
      const mapReviewer = function(reviewer, opt_state) {
        const result = {reviewer: reviewer._account_id, confirmed: undefined};
        if (opt_state) {
          result.state = opt_state;
        }
        return result;
      };

      // Send and purge and verify moves, delete cc3.
      element.send()
          .then(keepReviewers =>
              element._purgeReviewersPendingRemove(false, keepReviewers))
          .then(() => {
            assert.deepEqual(
                mutations, [
                  mapReviewer(cc1),
                  mapReviewer(cc2),
                  mapReviewer(reviewer1, 'CC'),
                  mapReviewer(reviewer2, 'CC'),
                  {account: cc3, state: 'REMOVED'},
                ]);
            done();
          });
    });

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

      assert.isTrue(cancelHandler.called);
    });

    test('should not send on enter key', () => {
      stubSaveReview(() => undefined);
      element.addEventListener('send', () => assert.fail('wrongly called'));
      MockInteractions.pressAndReleaseKeyOn(element, 13, null, 'enter');
      flushAsynchronousOperations();
    });

    test('emit send on ctrl+enter key', done => {
      stubSaveReview(() => undefined);
      element.addEventListener('send', () => done());
      MockInteractions.pressAndReleaseKeyOn(element, 13, 'ctrl', 'enter');
      flushAsynchronousOperations();
    });

    test('_computeMessagePlaceholder', () => {
      assert.equal(
          element._computeMessagePlaceholder(false),
          'Say something nice...');
      assert.equal(
          element._computeMessagePlaceholder(true),
          'Add a note for your reviewers...');
    });

    test('_computeSendButtonLabel', () => {
      assert.equal(
          element._computeSendButtonLabel(false),
          'Send');
      assert.equal(
          element._computeSendButtonLabel(true),
          'Start review');
    });

    test('_handle400Error reviewrs and CCs', done => {
      const error1 = 'error 1';
      const error2 = 'error 2';
      const error3 = 'error 3';
      const text = ')]}\'' + JSON.stringify({
        reviewers: {
          username1: {
            input: 'user 1',
            error: error1,
          },
          username2: {
            input: 'user 2',
            error: error2,
          },
        },
        ccs: {
          username3: {
            input: 'user 3',
            error: error3,
          },
        },
      });
      element.addEventListener('server-error', e => {
        e.detail.response.text().then(text => {
          assert.equal(text, [error1, error2, error3].join(', '));
          done();
        });
      });
      element._handle400Error(cloneableResponse(400, text));
    });

    test('_handle400Error CCs only', done => {
      const error1 = 'error 1';
      const text = ')]}\'' + JSON.stringify({
        ccs: {
          username1: {
            input: 'user 1',
            error: error1,
          },
        },
      });
      element.addEventListener('server-error', e => {
        e.detail.response.text().then(text => {
          assert.equal(text, error1);
          done();
        });
      });
      element._handle400Error(cloneableResponse(400, text));
    });

    test('fires height change when the drafts load', done => {
      // Flush DOM operations before binding to the autogrow event so we don't
      // catch the events fired from the initial layout.
      flush(() => {
        const autoGrowHandler = sinon.stub();
        element.addEventListener('autogrow', autoGrowHandler);
        element.diffDrafts = {};
        flush(() => {
          assert.isTrue(autoGrowHandler.called);
          done();
        });
      });
    });

    suite('post review API', () => {
      let startReviewStub;

      setup(() => {
        startReviewStub = sandbox.stub(element.$.restAPI, 'startReview', () => {
          return Promise.resolve();
        });
      });

      test('ready property in review input on start review', () => {
        stubSaveReview(review => {
          assert.isTrue(review.ready);
          return {ready: true};
        });
        return element.send(true, true).then(() => {
          assert.isFalse(startReviewStub.called);
        });
      });

      test('no ready property in review input on save review', () => {
        stubSaveReview(review => {
          assert.isUndefined(review.ready);
        });
        return element.send(true, false).then(() => {
          assert.isFalse(startReviewStub.called);
        });
      });
    });

    suite('start review and save buttons', () => {
      let sendStub;

      setup(() => {
        sendStub = sandbox.stub(element, 'send', () => Promise.resolve());
        element.canBeStarted = true;
        // Flush to make both Start/Save buttons appear in DOM.
        flushAsynchronousOperations();
      });

      test('start review sets ready', () => {
        MockInteractions.tap(element.$$('.send'));
        flushAsynchronousOperations();
        assert.isTrue(sendStub.calledWith(true, true));
      });

      test('save review doesn\'t set ready', () => {
        MockInteractions.tap(element.$$('.save'));
        flushAsynchronousOperations();
        assert.isTrue(sendStub.calledWith(true, false));
      });
    });

    test('buttons disabled until all API calls are resolved', () => {
      stubSaveReview(review => {
        return {ready: true};
      });
      return element.send(true, true).then(() => {
        assert.isFalse(element.disabled);
      });
    });

    suite('error handling', () => {
      const expectedDraft = 'draft';
      const expectedError = new Error('test');

      setup(() => {
        element.draft = expectedDraft;
      });

      function assertDialogOpenAndEnabled() {
        assert.strictEqual(expectedDraft, element.draft);
        assert.isFalse(element.disabled);
      }

      test('error occurs in _saveReview', () => {
        stubSaveReview(review => {
          throw expectedError;
        });
        return element.send(true, true).catch(err => {
          assert.strictEqual(expectedError, err);
          assertDialogOpenAndEnabled();
        });
      });

      suite('pending diff drafts?', () => {
        test('yes', () => {
          const promise = mockPromise();
          const refreshHandler = sandbox.stub();

          element.addEventListener('comment-refresh', refreshHandler);
          sandbox.stub(element.$.restAPI, 'hasPendingDiffDrafts').returns(true);
          element.$.restAPI._pendingRequests.sendDiffDraft = [promise];
          element.open();

          assert.isFalse(refreshHandler.called);
          assert.isTrue(element._savingComments);

          promise.resolve();

          return element.$.restAPI.awaitPendingDiffDrafts().then(() => {
            assert.isTrue(refreshHandler.called);
            assert.isFalse(element._savingComments);
          });
        });

        test('no', () => {
          sandbox.stub(element.$.restAPI, 'hasPendingDiffDrafts').returns(false);
          element.open();
          assert.notOk(element._savingComments);
        });
      });
    });

    test('_computeSendButtonDisabled', () => {
      const fn = element._computeSendButtonDisabled.bind(element);
      assert.isFalse(fn(
          /* buttonLabel= */ 'Start review',
          /* drafts= */ {},
          /* text= */ '',
          /* reviewersMutated= */ false,
          /* labelsChanged= */ false,
          /* includeComments= */ false,
          /* disabled= */ false,
      ));
      assert.isTrue(fn(
          /* buttonLabel= */ 'Send',
          /* drafts= */ {},
          /* text= */ '',
          /* reviewersMutated= */ false,
          /* labelsChanged= */ false,
          /* includeComments= */ false,
          /* disabled= */ false,
      ));
      // Mock nonempty comment draft array, with seding comments.
      assert.isFalse(fn(
          /* buttonLabel= */ 'Send',
          /* drafts= */ {file: ['draft']},
          /* text= */ '',
          /* reviewersMutated= */ false,
          /* labelsChanged= */ false,
          /* includeComments= */ true,
          /* disabled= */ false,
      ));
      // Mock nonempty comment draft array, without seding comments.
      assert.isTrue(fn(
          /* buttonLabel= */ 'Send',
          /* drafts= */ {file: ['draft']},
          /* text= */ '',
          /* reviewersMutated= */ false,
          /* labelsChanged= */ false,
          /* includeComments= */ false,
          /* disabled= */ false,
      ));
      // Mock nonempty change message.
      assert.isFalse(fn(
          /* buttonLabel= */ 'Send',
          /* drafts= */ {},
          /* text= */ 'test',
          /* reviewersMutated= */ false,
          /* labelsChanged= */ false,
          /* includeComments= */ false,
          /* disabled= */ false,
      ));
      // Mock reviewers mutated.
      assert.isFalse(fn(
          /* buttonLabel= */ 'Send',
          /* drafts= */ {},
          /* text= */ '',
          /* reviewersMutated= */ true,
          /* labelsChanged= */ false,
          /* includeComments= */ false,
          /* disabled= */ false,
      ));
      // Mock labels changed.
      assert.isFalse(fn(
          /* buttonLabel= */ 'Send',
          /* drafts= */ {},
          /* text= */ '',
          /* reviewersMutated= */ false,
          /* labelsChanged= */ true,
          /* includeComments= */ false,
          /* disabled= */ false,
      ));
      // Whole dialog is disabled.
      assert.isTrue(fn(
          /* buttonLabel= */ 'Send',
          /* drafts= */ {},
          /* text= */ '',
          /* reviewersMutated= */ false,
          /* labelsChanged= */ true,
          /* includeComments= */ false,
          /* disabled= */ true,
      ));
    });

    test('_submit blocked when no mutations exist', () => {
      const sendStub = sandbox.stub(element, 'send').returns(Promise.resolve());
      // Stub the below function to avoid side effects from the send promise
      // resolving.
      sandbox.stub(element, '_purgeReviewersPendingRemove');
      element.diffDrafts = {};
      flushAsynchronousOperations();

      MockInteractions.tap(element.$$('gr-button.send'));
      assert.isFalse(sendStub.called);

      element.diffDrafts = {test: [{val: true}]};
      flushAsynchronousOperations();

      MockInteractions.tap(element.$$('gr-button.send'));
      assert.isTrue(sendStub.called);
    });

    test('getFocusStops', () => {
      // Setting diffDrafts to an empty object causes _sendDisabled to be
      // computed to false.
      element.diffDrafts = {};
      assert.equal(element.getFocusStops().end, element.$.cancelButton);
      element.diffDrafts = {test: [{val: true}]};
      assert.equal(element.getFocusStops().end, element.$.sendButton);
    });

    test('setPluginMessage', () => {
      element.setPluginMessage('foo');
      assert.equal(element.$.pluginMessage.textContent, 'foo');
    });
  });
</script>
