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

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