/**
 * @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.
 */

import '../../../test/common-test-setup-karma.js';
import {IronOverlayManager} from '@polymer/iron-overlay-behavior/iron-overlay-manager.js';
import './gr-reply-dialog.js';
import {mockPromise, stubStorage} from '../../../test/test-utils.js';
import {ReviewerState, SpecialFilePath} from '../../../constants/constants.js';
import {appContext} from '../../../services/app-context.js';
import {addListenerForTest} from '../../../test/test-utils.js';
import {stubRestApi} from '../../../test/test-utils.js';
import {JSON_PREFIX} from '../../shared/gr-rest-api-interface/gr-rest-apis/gr-rest-api-helper.js';
import {CODE_REVIEW} from '../../../utils/label-util.js';
import {createAccountWithId} from '../../../test/test-data-generators.js';

const basicFixture = fixtureFromElement('gr-reply-dialog');

function cloneableResponse(status, text) {
  return {
    ok: false,
    status,
    text() {
      return Promise.resolve(text);
    },
    clone() {
      return {
        ok: false,
        status,
        text() {
          return Promise.resolve(text);
        },
      };
    },
  };
}

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

  let getDraftCommentStub;
  let setDraftCommentStub;
  let eraseDraftCommentStub;

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

  setup(() => {
    changeNum = 42;
    patchNum = 1;

    stubRestApi('getAccount').returns(Promise.resolve({}));
    stubRestApi('getChange').returns(Promise.resolve({}));
    stubRestApi('getChangeSuggestedReviewers').returns(Promise.resolve([]));

    sinon.stub(appContext.flagsService, 'isEnabled').returns(true);

    element = basicFixture.instantiate();
    element.change = {
      _number: changeNum,
      owner: {
        _account_id: 999,
        display_name: 'Kermit',
      },
      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 = stubStorage('getDraftComment');
    setDraftCommentStub = stubStorage('setDraftComment');
    eraseDraftCommentStub = stubStorage('eraseDraftComment');

    // sinon.stub(patchSetUtilMockProxy, 'fetchChangeUpdates')
    //     .returns(Promise.resolve({isLatest: true}));

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

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

  function interceptSaveReview() {
    let resolver;
    const promise = new Promise(resolve => { resolver = resolve; });
    stubSaveReview(review => { resolver(review); });
    return promise;
  }

  test('default to publishing draft comments with reply', async () => {
    // Async tick is needed because iron-selector content is distributed and
    // distributed content requires an observer to be set up.
    await flush();
    element.draft = 'I wholeheartedly disapprove';
    const saveReviewPromise = interceptSaveReview();

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

    const review = await saveReviewPromise;
    assert.deepEqual(review, {
      drafts: 'PUBLISH_ALL_REVISIONS',
      labels: {
        'Code-Review': 0,
        'Verified': 0,
      },
      comments: {
        [SpecialFilePath.PATCHSET_LEVEL_COMMENTS]: [{
          message: 'I wholeheartedly disapprove',
          unresolved: false,
        }],
      },
      reviewers: [],
      add_to_attention_set: [],
      remove_from_attention_set: [],
      ignore_automatic_attention_set_rules: true,
    });
    assert.isFalse(element.$.commentList.hidden);
  });

  test('modified attention set', done => {
    element._newAttentionSet = new Set([314]);
    const buttonEl = element.shadowRoot.querySelector('.edit-attention-button');
    MockInteractions.tap(buttonEl);
    flush();

    stubSaveReview(review => {
      assert.isTrue(review.ignore_automatic_attention_set_rules);
      assert.deepEqual(review.add_to_attention_set, [{
        user: 314,
        reason: 'Anonymous replied on the change',
      }]);
      assert.deepEqual(review.remove_from_attention_set, []);
      done();
    });
    MockInteractions.tap(element.shadowRoot.querySelector('.send'));
  });

  function checkComputeAttention(status, userId, reviewerIds, ownerId,
      attSetIds, replyToIds, expectedIds, uploaderId, hasDraft = true,
      includeComments = true) {
    const user = {_account_id: userId};
    const reviewers = {base: reviewerIds.map(id => {
      return {_account_id: id};
    })};
    let draftThreads = [];
    if (hasDraft) {
      draftThreads = [
        {comments: [{__draft: true, unresolved: true}]},
      ];
    }
    replyToIds.forEach(id => draftThreads[0].comments.push({
      author: {_account_id: id},
    }));
    const change = {
      owner: {_account_id: ownerId},
      status,
      attention_set: {},
    };
    attSetIds.forEach(id => change.attention_set[id] = {});
    if (uploaderId) {
      change.current_revision = 1;
      change.revisions = [{}, {uploader: {_account_id: uploaderId}}];
    }
    element.change = change;
    element._reviewers = reviewers.base;

    flush();
    const hasDrafts = draftThreads.length > 0;
    element._computeNewAttention(
        user, reviewers, [], change, draftThreads, includeComments, undefined,
        hasDrafts);
    assert.sameMembers([...element._newAttentionSet], expectedIds);
  }

  test('computeNewAttention NEW', () => {
    checkComputeAttention('NEW', 1, [], 999, [], [], [999]);
    checkComputeAttention('NEW', 1, [], 999, [1], [], [999]);
    checkComputeAttention('NEW', 1, [22], 999, [], [], [999]);
    checkComputeAttention('NEW', 1, [22], 999, [22], [], [22, 999]);
    checkComputeAttention('NEW', 1, [22], 999, [], [22], [22, 999]);
    checkComputeAttention('NEW', 1, [22, 33], 999, [33], [22], [22, 33, 999]);
    // If the owner replies, then do not add them.
    checkComputeAttention('NEW', 1, [], 1, [], [], []);
    checkComputeAttention('NEW', 1, [], 1, [1], [], []);
    checkComputeAttention('NEW', 1, [22], 1, [], [], []);

    checkComputeAttention('NEW', 1, [22], 1, [], [22], [22]);
    checkComputeAttention('NEW', 1, [22, 33], 1, [33], [22], [22, 33]);
    checkComputeAttention('NEW', 1, [22, 33], 1, [], [22], [22]);
    checkComputeAttention('NEW', 1, [22, 33], 1, [], [22, 33], [22, 33]);
    checkComputeAttention('NEW', 1, [22, 33], 1, [22, 33], [], [22, 33]);
    // with uploader
    checkComputeAttention('NEW', 1, [], 1, [], [2], [2], 2);
    checkComputeAttention('NEW', 1, [], 1, [2], [], [2], 2);
    checkComputeAttention('NEW', 1, [], 3, [], [], [2, 3], 2);
  });

  test('computeNewAttention MERGED', () => {
    checkComputeAttention('MERGED', 1, [], 999, [], [], [], undefined, false);
    checkComputeAttention('MERGED', 1, [], 999, [], [], [999], undefined);
    checkComputeAttention(
        'MERGED', 1, [], 999, [], [], [], undefined, true, false);
    checkComputeAttention('MERGED', 1, [], 999, [1], [], [], undefined, false);
    checkComputeAttention('MERGED', 1, [22], 999, [], [], [], undefined, false);
    checkComputeAttention('MERGED', 1, [22], 999, [22], [], [22], undefined,
        false);
    checkComputeAttention('MERGED', 1, [22], 999, [], [22], []);
    checkComputeAttention('MERGED', 1, [22, 33], 999, [33], [22], [33]);
    checkComputeAttention('MERGED', 1, [], 1, [], [], []);
    checkComputeAttention('MERGED', 1, [], 1, [], [], [], undefined, true);
    checkComputeAttention('MERGED', 1, [], 1, [1], [], []);
    checkComputeAttention('MERGED', 1, [], 1, [1], [], [], undefined, true);
    checkComputeAttention('MERGED', 1, [22], 1, [], [], []);
    checkComputeAttention('MERGED', 1, [22], 1, [], [22], []);
    checkComputeAttention('MERGED', 1, [22, 33], 1, [33], [22], [33]);
    checkComputeAttention('MERGED', 1, [22, 33], 1, [], [22], []);
    checkComputeAttention('MERGED', 1, [22, 33], 1, [], [22, 33], []);
    checkComputeAttention('MERGED', 1, [22, 33], 1, [22, 33], [], [22, 33]);
  });

  test('computeNewAttention when adding reviewers', () => {
    const user = {_account_id: 1};
    const reviewers = {base: [
      {_account_id: 1, _pendingAdd: true},
      {_account_id: 2, _pendingAdd: true},
    ]};
    const change = {
      owner: {_account_id: 5},
      status: 'NEW',
      attention_set: {},
    };
    element.change = change;
    element._reviewers = reviewers.base;
    flush();

    element._computeNewAttention(user, reviewers, [], change, [], true);
    assert.sameMembers([...element._newAttentionSet], [1, 2]);

    // If the user votes on the change, then they should not be added to the
    // attention set, even if they have just added themselves as reviewer.
    // But voting should also add the owner (5).
    const labelsChanged = true;
    element._computeNewAttention(
        user, reviewers, [], change, [], true, labelsChanged);
    assert.sameMembers([...element._newAttentionSet], [2, 5]);
  });

  test('computeNewAttention when sending wip change for review', () => {
    const reviewers = {base: [
      {_account_id: 2},
      {_account_id: 3},
    ]};
    const change = {
      owner: {_account_id: 1},
      status: 'NEW',
      attention_set: {},
    };
    element.change = change;
    element._reviewers = reviewers.base;
    flush();

    // For an active change there is no reason to add anyone to the set.
    let user = {_account_id: 1};
    element._computeNewAttention(user, reviewers, [], change, [], false);
    assert.sameMembers([...element._newAttentionSet], []);

    // If the change is "work in progress" and the owner sends a reply, then
    // add all reviewers.
    element.canBeStarted = true;
    flush();
    user = {_account_id: 1};
    element._computeNewAttention(user, reviewers, [], change, [], false);
    assert.sameMembers([...element._newAttentionSet], [2, 3]);

    // ... but not when someone else replies.
    user = {_account_id: 4};
    element._computeNewAttention(user, reviewers, [], change, [], false);
    assert.sameMembers([...element._newAttentionSet], []);
  });

  test('computeNewAttentionAccounts', () => {
    element._reviewers = [
      {_account_id: 123, display_name: 'Ernie'},
      {_account_id: 321, display_name: 'Bert'},
    ];
    element._ccs = [
      {_account_id: 7, display_name: 'Elmo'},
    ];
    const compute = (currentAtt, newAtt) =>
      element._computeNewAttentionAccounts(
          undefined, new Set(currentAtt), new Set(newAtt))
          .map(a => a._account_id);

    assert.sameMembers(compute([], []), []);
    assert.sameMembers(compute([], [999]), [999]);
    assert.sameMembers(compute([999], []), []);
    assert.sameMembers(compute([999], [999]), []);
    assert.sameMembers(compute([123, 321], [999]), [999]);
    assert.sameMembers(compute([999], [7, 123, 999]), [7, 123]);
  });

  test('_computeCommentAccounts', () => {
    element.change = {
      labels: {
        'Code-Review': {
          all: [
            {_account_id: 1, value: 0},
            {_account_id: 2, value: 1},
            {_account_id: 3, value: 2},
          ],
          values: {
            '-2': 'Do not submit',
            '-1': 'I would prefer that you didnt submit this',
            ' 0': 'No score',
            '+1': 'Looks good to me, but someone else must approve',
            '+2': 'Looks good to me, approved',
          },
        },
      },
    };
    const threads = [
      {
        comments: [
          {author: {_account_id: 1}, unresolved: false},
          {author: {_account_id: 2}, unresolved: true},
        ],
      },
      {
        comments: [
          {author: {_account_id: 3}, unresolved: false},
          {author: {_account_id: 4}, unresolved: false},
        ],
      },
    ];
    const actualAccounts = [...element._computeCommentAccounts(threads)];
    // Account 3 is not included, because the comment is resolved *and* they
    // have given the highest possible vote on the Code-Review label.
    assert.sameMembers(actualAccounts, [1, 2, 4]);
  });

  test('toggle resolved checkbox', async () => {
    const checkboxEl = element.shadowRoot.querySelector(
        '#resolvedPatchsetLevelCommentCheckbox');
    MockInteractions.tap(checkboxEl);

    // Async tick is needed because iron-selector content is distributed and
    // distributed content requires an observer to be set up.
    await flush();
    element.draft = 'I wholeheartedly disapprove';
    const saveReviewPromise = interceptSaveReview();

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

    const review = await saveReviewPromise;
    assert.deepEqual(review, {
      drafts: 'PUBLISH_ALL_REVISIONS',
      labels: {
        'Code-Review': 0,
        'Verified': 0,
      },
      comments: {
        [SpecialFilePath.PATCHSET_LEVEL_COMMENTS]: [{
          message: 'I wholeheartedly disapprove',
          unresolved: true,
        }],
      },
      reviewers: [],
      add_to_attention_set: [],
      remove_from_attention_set: [],
      ignore_automatic_attention_set_rules: true,
    });
  });

  test('label picker', async () => {
    element.draft = 'I wholeheartedly disapprove';
    const saveReviewPromise = interceptSaveReview();

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

    // This is needed on non-Blink engines most likely due to the ways in
    // which the dom-repeat elements are stamped.
    await flush();
    MockInteractions.tap(element.shadowRoot.querySelector('.send'));
    assert.isTrue(element.disabled);

    const review = await saveReviewPromise;
    await flush();
    assert.isFalse(element.disabled,
        'Element should be enabled when done sending reply.');
    assert.equal(element.draft.length, 0);
    assert.deepEqual(review, {
      drafts: 'PUBLISH_ALL_REVISIONS',
      labels: {
        'Code-Review': -1,
        'Verified': -1,
      },
      comments: {
        [SpecialFilePath.PATCHSET_LEVEL_COMMENTS]: [{
          message: 'I wholeheartedly disapprove',
          unresolved: false,
        }],
      },
      reviewers: [],
      add_to_attention_set: [],
      remove_from_attention_set: [],
      ignore_automatic_attention_set_rules: true,
    });
  });

  test('keep draft comments with reply', async () => {
    MockInteractions.tap(element.shadowRoot.querySelector('#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.
    await flush();
    element.draft = 'I wholeheartedly disapprove';
    const saveReviewPromise = interceptSaveReview();

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

    const review = await saveReviewPromise;
    await flush();
    assert.deepEqual(review, {
      drafts: 'KEEP',
      labels: {
        'Code-Review': 0,
        'Verified': 0,
      },
      comments: {
        [SpecialFilePath.PATCHSET_LEVEL_COMMENTS]: [{
          message: 'I wholeheartedly disapprove',
          unresolved: false,
        }],
      },
      reviewers: [],
      add_to_attention_set: [],
      remove_from_attention_set: [],
      ignore_automatic_attention_set_rules: true,
    });
  });

  test('getlabelValue returns value', done => {
    flush(() => {
      element.shadowRoot
          .querySelector('gr-label-scores')
          .shadowRoot
          .querySelector(`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.shadowRoot
          .querySelector('gr-label-scores')
          .shadowRoot
          .querySelector(`gr-label-score-row[name="Code-Review"]`)
          .setSelectedValue(-1);
      assert.strictEqual(element.getLabelValue('Verified'), ' 0');
      done();
    });
  });

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

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

  function getActiveElement() {
    return IronOverlayManager.deepActiveElement;
  }

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

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

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

  async function testConfirmationDialog(cc) {
    const yesButton = element
        .shadowRoot
        .querySelector('.reviewerConfirmationButtons gr-button:first-child');
    const noButton = element
        .shadowRoot
        .querySelector('.reviewerConfirmationButtons gr-button:last-child');

    element._ccPendingConfirmation = null;
    element._reviewerPendingConfirmation = null;
    flush();
    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,
      };
    }
    flush();

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

    await observer;
    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

    await observer;
    assert.isFalse(isVisible(element.$.reviewerConfirmationOverlay));

    // We should be focused on account entry input.
    assert.isTrue(
        isFocusInsideElement(
            element.$.reviewers.$.entry.$.input.$.input
        )
    );

    // No reviewer/CC should have been added.
    assert.equal(element.$.ccs.additions().length, 0);
    assert.equal(element.$.reviewers.additions().length, 0);

    // Reopen confirmation dialog.
    observer = overlayObserver('opened');
    if (cc) {
      element._ccPendingConfirmation = {
        group,
        count: 10,
      };
    } else {
      element._reviewerPendingConfirmation = {
        group,
        count: 10,
      };
    }

    await observer;
    assert.isTrue(isVisible(element.$.reviewerConfirmationOverlay));
    observer = overlayObserver('closed');
    MockInteractions.tap(yesButton); // Confirm the group.

    await observer;
    assert.isFalse(isVisible(element.$.reviewerConfirmationOverlay));
    const additions = cc ?
      element.$.ccs.additions() :
      element.$.reviewers.additions();
    assert.deepEqual(
        additions,
        [
          {
            group: {
              id: 'id',
              name: 'name',
              confirmed: true,
              _group: true,
              _pendingAdd: true,
            },
          },
        ]);

    // We should be focused on account entry input.
    if (cc) {
      assert.isTrue(
          isFocusInsideElement(
              element.$.ccs.$.entry.$.input.$.input
          )
      );
    } else {
      assert.isTrue(
          isFocusInsideElement(
              element.$.reviewers.$.entry.$.input.$.input
          )
      );
    }
  }

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

  test('reviewer confirmation', async () => {
    testConfirmationDialog(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', () => {
    flush();
    assert.isFalse(element._reviewersMutated);
    assert.isTrue(element.$.ccs.allowAnyInput);
    assert.isFalse(element.shadowRoot
        .querySelector('#reviewers').allowAnyInput);
    element.$.ccs.dispatchEvent(new CustomEvent('account-text-changed',
        {bubbles: true, composed: true}));
    assert.isTrue(element._reviewersMutated);
  });

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

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

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

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

  test('updates stored draft on edits', () => {
    const firstEdit = 'hello';
    const location = element._getStorageLocation();

    element.draft = firstEdit;
    element.storeTask.flush();

    assert.isTrue(setDraftCommentStub.calledWith(location, firstEdit));

    element.draft = '';
    element.storeTask.flush();

    assert.isTrue(eraseDraftCommentStub.calledWith(location));
  });

  test('400 converts to human-readable server-error', done => {
    stubRestApi('saveChangeReview').callsFake(
        (changeNum, patchNum, review, errFn) => {
          errFn(cloneableResponse(
              400,
              '....{"reviewers":{"id1":{"error":"human readable"}}}'
          ));
          return Promise.resolve(undefined);
        }
    );

    const listener = event => {
      if (event.target !== document) return;
      event.detail.response.text().then(body => {
        if (body === 'human readable') {
          done();
        }
      });
    };
    addListenerForTest(document, 'server-error', listener);

    flush(() => { element.send(); });
  });

  test('non-json 400 is treated as a normal server-error', done => {
    stubRestApi('saveChangeReview').callsFake(
        (changeNum, patchNum, review, errFn) => {
          errFn(cloneableResponse(400, 'Comment validation error!'));
          return Promise.resolve(undefined);
        }
    );

    const listener = event => {
      if (event.target !== document) return;
      event.detail.response.text().then(body => {
        if (body === 'Comment validation error!') {
          done();
        }
      });
    };
    addListenerForTest(document, 'server-error', listener);

    // 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', async () => {
    sinon.spy(element, '_chooseFocusTarget');
    element._focusOn();
    await flush();
    assert.equal(element._chooseFocusTarget.callCount, 1);
    assert.equal(element.shadowRoot.activeElement.tagName, 'GR-TEXTAREA');
    assert.equal(element.shadowRoot.activeElement.id, 'textarea');

    element._focusOn(element.FocusTarget.ANY);
    await flush();
    assert.equal(element._chooseFocusTarget.callCount, 2);
    assert.equal(element.shadowRoot.activeElement.tagName, 'GR-TEXTAREA');
    assert.equal(element.shadowRoot.activeElement.id, 'textarea');

    element._focusOn(element.FocusTarget.BODY);
    await flush();
    assert.equal(element._chooseFocusTarget.callCount, 2);
    assert.equal(element.shadowRoot.activeElement.tagName, 'GR-TEXTAREA');
    assert.equal(element.shadowRoot.activeElement.id, 'textarea');

    element._focusOn(element.FocusTarget.REVIEWERS);
    await flush();
    assert.equal(element._chooseFocusTarget.callCount, 2);
    assert.equal(element.shadowRoot.activeElement.tagName, 'GR-ACCOUNT-LIST');
    assert.equal(element.shadowRoot.activeElement.id, 'reviewers');

    element._focusOn(element.FocusTarget.CCS);
    await flush();
    assert.equal(element._chooseFocusTarget.callCount, 2);
    assert.equal(element.shadowRoot.activeElement.tagName, 'GR-ACCOUNT-LIST');
    assert.equal(element.shadowRoot.activeElement.id, 'ccs');
  });

  test('_chooseFocusTarget', () => {
    element._account = undefined;
    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.shadowRoot
          .querySelector('gr-label-scores').shadowRoot
          .querySelector(
              'gr-label-score-row[name="Verified"]')
          .setSelectedValue(-1);
      MockInteractions.tap(element.shadowRoot
          .querySelector('.send'));
    });
  });

  test('moving from cc to reviewer', () => {
    flush();

    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);
    flush();

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

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

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

  test('update attention section when reviewers and ccs change', () => {
    element._account = makeAccount();
    element._reviewers = [makeAccount(), makeAccount()];
    element._ccs = [makeAccount(), makeAccount()];
    element.draftCommentThreads = [];
    const modifyButton =
        element.shadowRoot.querySelector('.edit-attention-button');
    MockInteractions.tap(modifyButton);
    flush();

    // "Modify" button disabled, because "Send" button is disabled.
    assert.isFalse(element._attentionExpanded);
    element.draft = 'a test comment';
    MockInteractions.tap(modifyButton);
    flush();
    assert.isTrue(element._attentionExpanded);

    let accountLabels = Array.from(element.shadowRoot.querySelectorAll(
        '.attention-detail gr-account-label'));
    assert.equal(accountLabels.length, 5);

    element.push('_reviewers', makeAccount());
    element.push('_ccs', makeAccount());
    flush();

    // The 'attention modified' section collapses and resets when reviewers or
    // ccs change.
    assert.isFalse(element._attentionExpanded);

    MockInteractions.tap(
        element.shadowRoot.querySelector('.edit-attention-button'));
    flush();

    assert.isTrue(element._attentionExpanded);
    accountLabels = Array.from(element.shadowRoot.querySelectorAll(
        '.attention-detail gr-account-label'));
    assert.equal(accountLabels.length, 7);

    element.pop('_reviewers', makeAccount());
    element.pop('_reviewers', makeAccount());
    element.pop('_ccs', makeAccount());
    element.pop('_ccs', makeAccount());

    MockInteractions.tap(
        element.shadowRoot.querySelector('.edit-attention-button'));
    flush();

    accountLabels = Array.from(element.shadowRoot.querySelectorAll(
        '.attention-detail gr-account-label'));
    assert.equal(accountLabels.length, 3);
  });

  test('moving from reviewer to cc', () => {
    flush();

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

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

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

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

  test('migrate reviewers between states', async () => {
    flush();
    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];

    element.change.reviewers = {
      [ReviewerState.CC]: [],
      [ReviewerState.REVIEWER]: [{_account_id: 33}],
    };

    const mutations = [];

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

    // Remove and add to other field.
    reviewers.dispatchEvent(
        new CustomEvent('remove', {
          detail: {account: reviewer1},
          composed: true, bubbles: true,
        }));
    ccs.$.entry.dispatchEvent(
        new CustomEvent('add', {
          detail: {value: {account: reviewer1}},
          composed: true, bubbles: true,
        }));
    ccs.dispatchEvent(
        new CustomEvent('remove', {
          detail: {account: cc1},
          composed: true, bubbles: true,
        }));
    ccs.dispatchEvent(
        new CustomEvent('remove', {
          detail: {account: cc3},
          composed: true, bubbles: true,
        }));
    reviewers.$.entry.dispatchEvent(
        new CustomEvent('add', {
          detail: {value: {account: cc1}},
          composed: true, bubbles: true,
        }));

    // Add to other field without removing from former field.
    // (Currently not possible in UI, but this is a good consistency check).
    reviewers.$.entry.dispatchEvent(
        new CustomEvent('add', {
          detail: {value: {account: cc2}},
          composed: true, bubbles: true,
        }));
    ccs.$.entry.dispatchEvent(
        new CustomEvent('add', {
          detail: {value: {account: reviewer2}},
          composed: true, bubbles: true,
        }));
    const mapReviewer = function(reviewer, opt_state) {
      const result = {reviewer: reviewer._account_id};
      if (opt_state) {
        result.state = opt_state;
      }
      return result;
    };

    // Send and purge and verify moves, delete cc3.
    await element.send();
    expect(mutations).to.have.lengthOf(5);
    expect(mutations[0]).to.deep.equal(mapReviewer(cc1,
        ReviewerState.REVIEWER));
    expect(mutations[1]).to.deep.equal(mapReviewer(cc2,
        ReviewerState.REVIEWER));
    expect(mutations[2]).to.deep.equal(mapReviewer(reviewer1,
        ReviewerState.CC));
    expect(mutations[3]).to.deep.equal(mapReviewer(reviewer2,
        ReviewerState.CC));

    // Only 1 account was initially part of the change
    expect(mutations[4]).to.deep.equal({reviewer: 33, state:
        ReviewerState.REMOVED});
  });

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

    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');
    flush();
  });

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

  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),
        'Send and Start review');
  });

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

  test('fires height change when the drafts comments 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.draftCommentThreads = [];
      flush(() => {
        assert.isTrue(autoGrowHandler.called);
        done();
      });
    });
  });

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

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

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

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

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

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

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

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

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

    suite('pending diff drafts?', () => {
      test('yes', async () => {
        const promise = mockPromise();
        const refreshSpy = sinon.spy();
        element.addEventListener('comment-refresh', refreshSpy);
        stubRestApi('hasPendingDiffDrafts').returns(true);
        stubRestApi('awaitPendingDiffDrafts').returns(promise);

        element.open();

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

        promise.resolve();
        await flush();

        assert.isTrue(refreshSpy.called);
        assert.isFalse(element._savingComments);
      });

      test('no', () => {
        stubRestApi('hasPendingDiffDrafts').returns(false);
        element.open();
        assert.isFalse(element._savingComments);
      });
    });
  });

  test('_computeSendButtonDisabled_canBeStarted', () => {
    // Mock canBeStarted
    assert.isFalse(element._computeSendButtonDisabled(
        /* canBeStarted= */ true,
        /* draftCommentThreads= */ [],
        /* text= */ '',
        /* reviewersMutated= */ false,
        /* labelsChanged= */ false,
        /* includeComments= */ false,
        /* disabled= */ false,
        /* commentEditing= */ false,
        /* change= */ element.change,
        /* account= */ makeAccount()
    ));
  });

  test('_computeSendButtonDisabled_allFalse', () => {
    // Mock everything false
    assert.isTrue(element._computeSendButtonDisabled(
        /* canBeStarted= */ false,
        /* draftCommentThreads= */ [],
        /* text= */ '',
        /* reviewersMutated= */ false,
        /* labelsChanged= */ false,
        /* includeComments= */ false,
        /* disabled= */ false,
        /* commentEditing= */ false,
        /* change= */ element.change,
        /* account= */ makeAccount()
    ));
  });

  test('_computeSendButtonDisabled_draftCommentsSend', () => {
    // Mock nonempty comment draft array, with sending comments.
    assert.isFalse(element._computeSendButtonDisabled(
        /* canBeStarted= */ false,
        /* draftCommentThreads= */ [{comments: [{__draft: true}]}],
        /* text= */ '',
        /* reviewersMutated= */ false,
        /* labelsChanged= */ false,
        /* includeComments= */ true,
        /* disabled= */ false,
        /* commentEditing= */ false,
        /* change= */ element.change,
        /* account= */ makeAccount()
    ));
  });

  test('_computeSendButtonDisabled_draftCommentsDoNotSend', () => {
    // Mock nonempty comment draft array, without sending comments.
    assert.isTrue(element._computeSendButtonDisabled(
        /* canBeStarted= */ false,
        /* draftCommentThreads= */ [{comments: [{__draft: true}]}],
        /* text= */ '',
        /* reviewersMutated= */ false,
        /* labelsChanged= */ false,
        /* includeComments= */ false,
        /* disabled= */ false,
        /* commentEditing= */ false,
        /* change= */ element.change,
        /* account= */ makeAccount()
    ));
  });

  test('_computeSendButtonDisabled_changeMessage', () => {
    // Mock nonempty change message.
    assert.isFalse(element._computeSendButtonDisabled(
        /* canBeStarted= */ false,
        /* draftCommentThreads= */ {},
        /* text= */ 'test',
        /* reviewersMutated= */ false,
        /* labelsChanged= */ false,
        /* includeComments= */ false,
        /* disabled= */ false,
        /* commentEditing= */ false,
        /* change= */ element.change,
        /* account= */ makeAccount()
    ));
  });

  test('_computeSendButtonDisabled_reviewersChanged', () => {
    // Mock reviewers mutated.
    assert.isFalse(element._computeSendButtonDisabled(
        /* canBeStarted= */ false,
        /* draftCommentThreads= */ {},
        /* text= */ '',
        /* reviewersMutated= */ true,
        /* labelsChanged= */ false,
        /* includeComments= */ false,
        /* disabled= */ false,
        /* commentEditing= */ false,
        /* change= */ element.change,
        /* account= */ makeAccount()
    ));
  });

  test('_computeSendButtonDisabled_labelsChanged', () => {
    // Mock labels changed.
    assert.isFalse(element._computeSendButtonDisabled(
        /* canBeStarted= */ false,
        /* draftCommentThreads= */ {},
        /* text= */ '',
        /* reviewersMutated= */ false,
        /* labelsChanged= */ true,
        /* includeComments= */ false,
        /* disabled= */ false,
        /* commentEditing= */ false,
        /* change= */ element.change,
        /* account= */ makeAccount()
    ));
  });

  test('_computeSendButtonDisabled_dialogDisabled', () => {
    // Whole dialog is disabled.
    assert.isTrue(element._computeSendButtonDisabled(
        /* canBeStarted= */ false,
        /* draftCommentThreads= */ {},
        /* text= */ '',
        /* reviewersMutated= */ false,
        /* labelsChanged= */ true,
        /* includeComments= */ false,
        /* disabled= */ true,
        /* commentEditing= */ false,
        /* change= */ element.change,
        /* account= */ makeAccount()
    ));
  });

  test('_computeSendButtonDisabled_existingVote', async () => {
    const account = createAccountWithId();
    element.change.labels[CODE_REVIEW].all = [account];
    await flush();

    // User has already voted.
    assert.isFalse(element._computeSendButtonDisabled(
        /* canBeStarted= */ false,
        /* draftCommentThreads= */ {},
        /* text= */ '',
        /* reviewersMutated= */ false,
        /* labelsChanged= */ false,
        /* includeComments= */ false,
        /* disabled= */ false,
        /* commentEditing= */ false,
        /* change= */ element.change,
        /* account= */ account
    ));
  });

  test('_submit blocked when no mutations exist', async () => {
    const sendStub = sinon.stub(element, 'send').returns(Promise.resolve());
    element.account = makeAccount();
    element.draftCommentThreads = [];
    await flush();

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

    element.draftCommentThreads = [{comments: [
      {__draft: true, path: 'test', line: 1, patch_set: 1},
    ]}];
    await flush();

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

  test('getFocusStops', async () => {
    // Setting draftCommentThreads to an empty object causes _sendDisabled to be
    // computed to false.
    element.draftCommentThreads = [];
    element.account = makeAccount();
    await flush();

    assert.equal(element.getFocusStops().end, element.$.cancelButton);
    element.draftCommentThreads = [
      {comments: [{__draft: true, path: 'test', line: 1, patch_set: 1}]},
    ];
    await flush();

    assert.equal(element.getFocusStops().end, element.$.sendButton);
  });

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

