<!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="../../../bower_components/webcomponentsjs/webcomponents-lite.min.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>
  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', () => {
      element._account = {_account_id: 1};
      flushAsynchronousOperations();
      const label = 'Verified';
      const value = '+1';
      element.setLabelValue(label, value);
      flushAsynchronousOperations();
      const labels = element.$.labelScores.getLabelValues();
      assert.deepEqual(labels, {
        'Code-Review': 0,
        'Verified': 1,
      });
    });

    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 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.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,
            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.
        assert.equal(getActiveElement().id, '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}));
      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({
          ok: false,
          status: 400,
          text() { return Promise.resolve(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('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('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 response = {
        status: 400,
        text() {
          return Promise.resolve(')]}\'' + 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(response);
    });

    test('_handle400Error CCs only', done => {
      const error1 = 'error 1';
      const response = {
        status: 400,
        text() {
          return Promise.resolve(')]}\'' + 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(response);
    });

    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('Start review'));
      assert.isTrue(fn('Send', {}, '', false, false, false));
      // Mock nonempty comment draft array, with seding comments.
      assert.isFalse(fn('Send', {file: ['draft']}, '', false, false, true));
      // Mock nonempty comment draft array, without seding comments.
      assert.isTrue(fn('Send', {file: ['draft']}, '', false, false, false));
      // Mock nonempty change message.
      assert.isFalse(fn('Send', {}, 'test', false, false, false));
      // Mock reviewers mutated.
      assert.isFalse(fn('Send', {}, '', true, false, false));
      // Mock labels changed.
      assert.isFalse(fn('Send', {}, '', false, true, false));
      // Whole dialog is disabled.
      assert.isTrue(fn('Send', {}, '', false, true, false, 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>
