<!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);
        });
      });

      test('fall back to start review against old backend', () => {
        stubSaveReview(review => {
          return {}; // old backend won't set ready: true
        });

        return element.send(true, true).then(() => {
          assert.isTrue(startReviewStub.called);
        }).then(() => {
          startReviewStub.reset();
          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('dummy message to force email on start review', () => {
      stubSaveReview(review => {
        assert.equal(review.message, element.START_REVIEW_MESSAGE);
        return {ready: true};
      });
      return element.send(true, true);
    });

    test('buttons disabled until all API calls are resolved', () => {
      stubSaveReview(review => {
        return {}; // old backend won't set ready: true
      });
      // Check that element is disabled asynchronously after the setReady
      // promise is returned. The element should not be reenabled until
      // that promise is resolved.
      sandbox.stub(element, '_maybeSetReady', (startReview, response) => {
        return new Promise(resolve => {
          Polymer.Base.async(() => {
            assert.isTrue(element.disabled);
            resolve();
          });
        });
      });
      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);
      }

      function assertDialogClosed() {
        assert.strictEqual('', 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();
        });
      });

      test('error occurs during startReview', () => {
        stubSaveReview(review => {
          return {}; // old backend won't set ready: true
        });
        const errorStub = sandbox.stub(
            console, 'error', (msg, err) => undefined);
        sandbox.stub(element.$.restAPI, 'startReview', () => {
          throw expectedError;
        });
        return element.send(true, true).then(() => {
          assertDialogClosed();
          assert.isTrue(
              errorStub.calledWith('error setting ready:', expectedError));
        });
      });

      test('non-ok response received by startReview', () => {
        stubSaveReview(review => {
          return {}; // old backend won't set ready: true
        });
        sandbox.stub(element.$.restAPI, 'startReview', (c, b, f) => {
          f({status: 500});
        });
        return element.send(true, true).then(() => {
          assertDialogClosed();
        });
      });

      test('409 response received by startReview', () => {
        stubSaveReview(review => {
          return {}; // old backend won't set ready: true
        });
        sandbox.stub(element.$.restAPI, 'startReview', (c, b, f) => {
          f({status: 409});
        });
        return element.send(true, true).then(() => {
          assertDialogClosed();
        });
      });

      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: 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: true};
      assert.equal(element.getFocusStops().end, element.$.sendButton);
    });

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