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

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

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

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

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

<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
<script src="../../../bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../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',
        ],
      };
      element.serverConfig = {};

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

      sandbox.stub(element, 'fetchIsLatestKnown',
          () => { return Promise.resolve(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.serverConfig = {note_db_enabled: true};
      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('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('blank if no stored draft', () => {
      getDraftCommentStub.returns(null);
      element.open();
      assert.isTrue(getDraftCommentStub.called);
      assert.equal(element.draft, '');
    });

    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('ccs are displayed if NoteDb is enabled', () => {
      function hasCc() {
        flushAsynchronousOperations();
        return !!element.$$('#ccs');
      }

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

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

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