/**
 * @license
 * Copyright 2015 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import '../../../test/common-test-setup';
import './gr-reply-dialog';
import {
  addListenerForTest,
  isVisible,
  mockPromise,
  pressKey,
  query,
  queryAll,
  queryAndAssert,
  stubFlags,
  stubRestApi,
  waitUntilVisible,
} from '../../../test/test-utils';
import {ChangeStatus, ReviewerState} from '../../../constants/constants';
import {JSON_PREFIX} from '../../shared/gr-rest-api-interface/gr-rest-apis/gr-rest-api-helper';
import {StandardLabels} from '../../../utils/label-util';
import {
  createAccountWithEmail,
  createAccountWithId,
  createChange,
  createComment,
  createCommentThread,
  createDraft,
  createRevision,
  createServiceUserWithId,
} from '../../../test/test-data-generators';
import {GrReplyDialog} from './gr-reply-dialog';
import {
  AccountId,
  AccountInfo,
  CommitId,
  DetailedLabelInfo,
  EmailAddress,
  GroupId,
  GroupName,
  NumericChangeId,
  PatchSetNum,
  ReviewerInput,
  ReviewInput,
  ReviewResult,
  RevisionPatchSetNum,
  Suggestion,
  Timestamp,
  UrlEncodedCommentId,
  UserId,
} from '../../../types/common';
import {CommentThread} from '../../../utils/comment-util';
import {GrAccountList} from '../../shared/gr-account-list/gr-account-list';
import {GrLabelScoreRow} from '../gr-label-score-row/gr-label-score-row';
import {GrLabelScores} from '../gr-label-scores/gr-label-scores';
import {GrThreadList} from '../gr-thread-list/gr-thread-list';
import {fixture, html, waitUntil, assert} from '@open-wc/testing';
import {accountKey} from '../../../utils/account-util';
import {GrButton} from '../../shared/gr-button/gr-button';
import {GrAccountLabel} from '../../shared/gr-account-label/gr-account-label';
import {KnownExperimentId} from '../../../services/flags/flags';
import {Key, Modifier} from '../../../utils/dom-util';
import {GrComment} from '../../shared/gr-comment/gr-comment';
import {testResolver} from '../../../test/common-test-setup';
import {
  CommentsModel,
  commentsModelToken,
} from '../../../models/comments/comments-model';

function cloneableResponse(status: number, text: string) {
  return {
    ...new Response(),
    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: GrReplyDialog;
  let changeNum: NumericChangeId;
  let patchNum: PatchSetNum;
  let commentsModel: CommentsModel;

  let lastId = 1;
  const makeAccount = function () {
    return {
      _account_id: lastId++ as AccountId,
      email: `${lastId}.com` as EmailAddress,
    };
  };
  const makeGroup = function () {
    return {id: `${lastId++}` as GroupId};
  };

  setup(async () => {
    changeNum = 42 as NumericChangeId;
    patchNum = 1 as PatchSetNum;

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

    element = await fixture<GrReplyDialog>(html`
      <gr-reply-dialog></gr-reply-dialog>
    `);

    element.change = {
      ...createChange(),
      _number: changeNum,
      owner: {
        _account_id: 999 as AccountId,
        display_name: 'Kermit',
        email: 'abcd' as EmailAddress,
      },
      labels: {
        Verified: {
          values: {
            '-1': 'Fails',
            ' 0': 'No score',
            '+1': 'Verified',
          },
          default_value: 0,
        },
        'Code-Review': {
          values: {
            '-2': 'This shall not be submitted',
            '-1': 'I would prefer this is not submitted as is',
            ' 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.draftCommentThreads = [];

    await element.updateComplete;
    commentsModel = testResolver(commentsModelToken);
  });

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

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

  test('renders', () => {
    assert.shadowDom.equal(
      element,
      /* HTML */ `
        <div tabindex="-1">
          <section class="peopleContainer">
            <gr-endpoint-decorator name="reply-reviewers">
              <gr-endpoint-param name="change"> </gr-endpoint-param>
              <gr-endpoint-param name="reviewers"> </gr-endpoint-param>
              <div class="peopleList">
                <div class="peopleListLabel">Reviewers</div>
                <gr-account-list id="reviewers"> </gr-account-list>
                <gr-endpoint-slot name="right"> </gr-endpoint-slot>
              </div>
              <gr-endpoint-slot name="below"> </gr-endpoint-slot>
            </gr-endpoint-decorator>
            <div class="peopleList">
              <div class="peopleListLabel">CC</div>
              <gr-account-list allow-any-input="" id="ccs"> </gr-account-list>
            </div>
            <dialog tabindex="-1" id="reviewerConfirmationModal">
              <div class="reviewerConfirmation">
                Group
                <span class="groupName"> </span>
                has
                <span class="groupSize"> </span>
                members.
                <br />
                Are you sure you want to add them all?
              </div>
              <div class="reviewerConfirmationButtons">
                <gr-button aria-disabled="false" role="button" tabindex="0">
                  Yes
                </gr-button>
                <gr-button aria-disabled="false" role="button" tabindex="0">
                  No
                </gr-button>
              </div>
            </dialog>
          </section>
          <section class="labelsContainer">
            <gr-endpoint-decorator name="reply-label-scores">
              <gr-label-scores id="labelScores"> </gr-label-scores>
              <gr-endpoint-param name="change"> </gr-endpoint-param>
            </gr-endpoint-decorator>
            <div id="pluginMessage"></div>
          </section>
          <section class="newReplyDialog textareaContainer">
            <div class="patchsetLevelContainer resolved">
              <gr-endpoint-decorator name="reply-text">
                <gr-comment
                  hide-header=""
                  id="patchsetLevelComment"
                  permanent-editing-mode=""
                >
                </gr-comment>
                <gr-endpoint-param name="change"> </gr-endpoint-param>
              </gr-endpoint-decorator>
            </div>
          </section>
          <div class="newReplyDialog stickyBottom">
            <gr-endpoint-decorator name="reply-bottom">
              <gr-endpoint-param name="change"> </gr-endpoint-param>
              <section class="attention">
                <div class="attentionSummary">
                  <div>
                    <span> No changes to the attention set. </span>
                    <gr-tooltip-content
                      has-tooltip=""
                      title="Edit attention set changes"
                    >
                      <gr-button
                        aria-disabled="true"
                        disabled=""
                        class="edit-attention-button"
                        data-action-key="edit"
                        data-action-type="change"
                        data-label="Edit"
                        link=""
                        position-below=""
                        role="button"
                        tabindex="-1"
                      >
                        <div>
                          <gr-icon icon="edit" filled small></gr-icon>
                          <span>Modify</span>
                        </div>
                      </gr-button>
                    </gr-tooltip-content>
                  </div>
                  <div>
                    <a
                      href="https://gerrit-review.googlesource.com/Documentation/user-attention-set.html"
                      target="_blank"
                    >
                      <gr-icon icon="help" title="read documentation"></gr-icon>
                    </a>
                  </div>
                </div>
              </section>
              <gr-endpoint-slot name="above-actions"> </gr-endpoint-slot>
              <section class="actions">
                <div class="left"></div>
                <div class="right">
                  <gr-button
                    aria-disabled="false"
                    class="action cancel"
                    id="cancelButton"
                    link=""
                    role="button"
                    tabindex="0"
                  >
                    Cancel
                  </gr-button>
                  <gr-tooltip-content has-tooltip="" title="Send reply">
                    <gr-button
                      aria-disabled="true"
                      disabled=""
                      class="action send"
                      id="sendButton"
                      primary=""
                      role="button"
                      tabindex="-1"
                    >
                      Send
                    </gr-button>
                  </gr-tooltip-content>
                </div>
              </section>
            </gr-endpoint-decorator>
          </div>
        </div>
      `
    );
  });

  test('renders private change info when reviewer is added', async () => {
    element.change!.is_private = true;
    element.requestUpdate();
    await element.updateComplete;
    const peopleContainer = queryAndAssert<HTMLDivElement>(
      element,
      '.peopleContainer'
    );

    // Info is rendered only if reviewer is added
    assert.dom.equal(
      peopleContainer,
      `
      <section class="peopleContainer">
        <gr-endpoint-decorator name="reply-reviewers">
          <gr-endpoint-param name="change"> </gr-endpoint-param>
          <gr-endpoint-param name="reviewers"> </gr-endpoint-param>
          <div class="peopleList">
            <div class="peopleListLabel">Reviewers</div>
            <gr-account-list id="reviewers"> </gr-account-list>
            <gr-endpoint-slot name="right"> </gr-endpoint-slot>
          </div>
          <gr-endpoint-slot name="below"> </gr-endpoint-slot>
        </gr-endpoint-decorator>
        <div class="peopleList">
          <div class="peopleListLabel">CC</div>
          <gr-account-list allow-any-input="" id="ccs"> </gr-account-list>
        </div>
        <dialog
          tabindex="-1"
          id="reviewerConfirmationModal"
        >
          <div class="reviewerConfirmation">
            Group
            <span class="groupName"> </span>
            has
            <span class="groupSize"> </span>
            members.
            <br />
            Are you sure you want to add them all?
          </div>
          <div class="reviewerConfirmationButtons">
            <gr-button aria-disabled="false" role="button" tabindex="0">
              Yes
            </gr-button>
            <gr-button aria-disabled="false" role="button" tabindex="0">
              No
            </gr-button>
          </div>
        </dialog>
      </section>
    `
    );

    const account = createAccountWithId(22);
    element.reviewersList!.accounts = [];
    element.reviewersList!.addAccountItem({account, count: 1});
    element.reviewersList!.dispatchEvent(
      new CustomEvent('account-added', {
        detail: {account},
      })
    );
    element.requestUpdate();
    await element.updateComplete;

    assert.dom.equal(
      peopleContainer,
      `
      <section class="peopleContainer">
        <gr-endpoint-decorator name="reply-reviewers">
          <gr-endpoint-param name="change"> </gr-endpoint-param>
          <gr-endpoint-param name="reviewers"> </gr-endpoint-param>
          <div class="peopleList">
            <div class="peopleListLabel">Reviewers</div>
            <gr-account-list id="reviewers"> </gr-account-list>
            <gr-endpoint-slot name="right"> </gr-endpoint-slot>
          </div>
          <gr-endpoint-slot name="below"> </gr-endpoint-slot>
        </gr-endpoint-decorator>
        <div class="peopleList">
          <div class="peopleListLabel">CC</div>
          <gr-account-list allow-any-input="" id="ccs"> </gr-account-list>
        </div>
        <dialog
          tabindex="-1"
          id="reviewerConfirmationModal"
        >
          <div class="reviewerConfirmation">
            Group
            <span class="groupName"> </span>
            has
            <span class="groupSize"> </span>
            members.
            <br />
            Are you sure you want to add them all?
          </div>
          <div class="reviewerConfirmationButtons">
            <gr-button aria-disabled="false" role="button" tabindex="0">
              Yes
            </gr-button>
            <gr-button aria-disabled="false" role="button" tabindex="0">
              No
            </gr-button>
          </div>
        </dialog>
        <div class="privateVisiblityInfo">
          <gr-icon icon="info">
          </gr-icon>
          <div>
            Adding a reviewer/CC will make this private change visible to them
          </div>
        </div>
      </section>
    `
    );
  });

  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 element.updateComplete;
    element.patchsetLevelDraftMessage = 'I wholeheartedly disapprove';
    element.draftCommentThreads = [createCommentThread([createComment()])];

    element.includeComments = true;
    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 element.updateComplete;
    queryAndAssert<GrButton>(element, '.send').click();
    await element.updateComplete;

    const review = await saveReviewPromise;
    assert.deepEqual(review, {
      drafts: 'PUBLISH_ALL_REVISIONS',
      labels: {
        'Code-Review': 0,
        Verified: 0,
      },
      reviewers: [],
      add_to_attention_set: [
        {reason: '<GERRIT_ACCOUNT_1> replied on the change', user: 999},
      ],
      remove_from_attention_set: [],
      ignore_automatic_attention_set_rules: true,
    });
    assert.isFalse(
      queryAndAssert<GrThreadList>(element, '#commentList').hidden
    );
  });

  test('modified attention set', async () => {
    await element.updateComplete;

    // required so that "Send" button is enabled
    element.canBeStarted = true;
    await element.updateComplete;

    element.account = {_account_id: 123 as AccountId};
    element.newAttentionSet = new Set([314 as AccountId]);
    element.uploader = createAccountWithId(314);
    const saveReviewPromise = interceptSaveReview();

    queryAndAssert<GrButton>(element, '.send').click();
    const review = await saveReviewPromise;

    assert.deepEqual(review, {
      drafts: 'PUBLISH_ALL_REVISIONS',
      labels: {
        'Code-Review': 0,
        Verified: 0,
      },
      add_to_attention_set: [
        {reason: '<GERRIT_ACCOUNT_123> replied on the change', user: 314},
      ],
      reviewers: [],
      ready: true,
      remove_from_attention_set: [],
      ignore_automatic_attention_set_rules: true,
    });
  });

  test('modified attention set by anonymous', async () => {
    await element.updateComplete;

    // required so that "Send" button is enabled
    element.canBeStarted = true;
    await element.updateComplete;

    element.account = {};
    element.uploader = createAccountWithId(314);
    element.newAttentionSet = new Set([314 as AccountId]);
    const saveReviewPromise = interceptSaveReview();

    queryAndAssert<GrButton>(element, '.send').click();
    const review = await saveReviewPromise;

    assert.deepEqual(review, {
      drafts: 'PUBLISH_ALL_REVISIONS',
      labels: {
        'Code-Review': 0,
        Verified: 0,
      },
      add_to_attention_set: [
        // Name coming from createUserConfig in test-data-generator
        {reason: 'Name of user not set replied on the change', user: 314},
      ],
      reviewers: [],
      ready: true,
      remove_from_attention_set: [],
      ignore_automatic_attention_set_rules: true,
    });
    element.newAttentionSet = new Set();
    await element.updateComplete;
  });

  async function checkComputeAttention(
    element: GrReplyDialog,
    status: ChangeStatus,
    userId?: AccountId,
    reviewerIds?: AccountId[],
    ownerId?: AccountId,
    attSetIds?: AccountId[],
    replyToIds?: AccountId[],
    expectedIds?: AccountId[],
    uploaderId?: AccountId,
    hasDraft = true,
    includeComments = true
  ) {
    element.account = {_account_id: userId};
    element.reviewers =
      reviewerIds?.map(id => {
        return {_account_id: id};
      }) ?? [];
    let draftThreads: CommentThread[] = [];
    if (hasDraft) {
      draftThreads = [
        {
          ...createCommentThread([{...createDraft(), unresolved: true}]),
        },
      ];
    }
    replyToIds?.forEach(id =>
      draftThreads[0].comments.push({
        ...createComment(),
        author: {_account_id: id},
      })
    );
    const change = {
      ...createChange(),
      owner: {_account_id: ownerId},
      status,
      reviewers: {
        [ReviewerState.REVIEWER]: element.reviewers,
      },
    };
    attSetIds?.forEach(id => {
      if (!change.attention_set) change.attention_set = {};
      change.attention_set[id.toString()] = {
        account: createAccountWithId(id),
      };
    });
    if (uploaderId) {
      change.current_revision = 'b' as CommitId;
      change.revisions = {
        a: createRevision(1),
        b: {...createRevision(2), uploader: {_account_id: uploaderId}},
      };
    }
    element.change = change;
    element._ccs = [];
    element.draftCommentThreads = draftThreads;
    element.includeComments = includeComments;

    await element.updateComplete;

    element.computeNewAttention();
    assert.sameMembers([...element.newAttentionSet], expectedIds!);
  }

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

    await checkComputeAttention(
      element,
      ChangeStatus.NEW,
      1 as AccountId,
      [22 as AccountId],
      1 as AccountId,
      [],
      [22 as AccountId],
      [22 as AccountId]
    );
    await checkComputeAttention(
      element,
      ChangeStatus.NEW,
      1 as AccountId,
      [22 as AccountId, 33 as AccountId],
      1 as AccountId,
      [33 as AccountId],
      [22 as AccountId],
      [22 as AccountId, 33 as AccountId]
    );
    await checkComputeAttention(
      element,
      ChangeStatus.NEW,
      1 as AccountId,
      [22 as AccountId, 33 as AccountId],
      1 as AccountId,
      [],
      [22 as AccountId],
      [22 as AccountId]
    );
    await checkComputeAttention(
      element,
      ChangeStatus.NEW,
      1 as AccountId,
      [22 as AccountId, 33 as AccountId],
      1 as AccountId,
      [],
      [22 as AccountId, 33 as AccountId],
      [22 as AccountId, 33 as AccountId]
    );
    await checkComputeAttention(
      element,
      ChangeStatus.NEW,
      1 as AccountId,
      [22 as AccountId, 33 as AccountId],
      1 as AccountId,
      [22 as AccountId, 33 as AccountId],
      [],
      [22 as AccountId, 33 as AccountId]
    );
    // with uploader
    await checkComputeAttention(
      element,
      ChangeStatus.NEW,
      1 as AccountId,
      [],
      1 as AccountId,
      [],
      [2 as AccountId],
      [2 as AccountId],
      2 as AccountId
    );
    await checkComputeAttention(
      element,
      ChangeStatus.NEW,
      1 as AccountId,
      [],
      1 as AccountId,
      [2 as AccountId],
      [],
      [2 as AccountId],
      2 as AccountId
    );
    await checkComputeAttention(
      element,
      ChangeStatus.NEW,
      1 as AccountId,
      [],
      3 as AccountId,
      [],
      [],
      [2 as AccountId, 3 as AccountId],
      2 as AccountId
    );
  });

  test('computeNewAttention MERGED', async () => {
    await checkComputeAttention(
      element,
      ChangeStatus.MERGED,
      undefined,
      [],
      999 as AccountId,
      [],
      [],
      [],
      undefined,
      false
    );
    await checkComputeAttention(
      element,
      ChangeStatus.MERGED,
      1 as AccountId,
      [],
      999 as AccountId,
      [],
      [],
      [],
      undefined,
      false
    );
    await checkComputeAttention(
      element,
      ChangeStatus.MERGED,
      1 as AccountId,
      [],
      999 as AccountId,
      [],
      [],
      [999 as AccountId],
      undefined,
      true
    );
    await checkComputeAttention(
      element,
      ChangeStatus.MERGED,
      1 as AccountId,
      [],
      999 as AccountId,
      [],
      [],
      [],
      undefined,
      true,
      false
    );
    await checkComputeAttention(
      element,
      ChangeStatus.MERGED,
      1 as AccountId,
      [],
      999 as AccountId,
      [1 as AccountId],
      [],
      [],
      undefined,
      false
    );
    await checkComputeAttention(
      element,
      ChangeStatus.MERGED,
      1 as AccountId,
      [22 as AccountId],
      999 as AccountId,
      [],
      [],
      [],
      undefined,
      false
    );
    await checkComputeAttention(
      element,
      ChangeStatus.MERGED,
      1 as AccountId,
      [22 as AccountId],
      999 as AccountId,
      [22 as AccountId],
      [],
      [22 as AccountId],
      undefined,
      false
    );
    await checkComputeAttention(
      element,
      ChangeStatus.MERGED,
      1 as AccountId,
      [22 as AccountId],
      999 as AccountId,
      [],
      [22 as AccountId],
      []
    );
    await checkComputeAttention(
      element,
      ChangeStatus.MERGED,
      1 as AccountId,
      [22 as AccountId, 33 as AccountId],
      999 as AccountId,
      [33 as AccountId],
      [22 as AccountId],
      [33 as AccountId]
    );
    await checkComputeAttention(
      element,
      ChangeStatus.MERGED,
      1 as AccountId,
      [],
      1 as AccountId,
      [],
      [],
      []
    );
    await checkComputeAttention(
      element,
      ChangeStatus.MERGED,
      1 as AccountId,
      [],
      1 as AccountId,
      [],
      [],
      [],
      undefined,
      true
    );
    await checkComputeAttention(
      element,
      ChangeStatus.MERGED,
      1 as AccountId,
      [],
      1 as AccountId,
      [1 as AccountId],
      [],
      []
    );
    await checkComputeAttention(
      element,
      ChangeStatus.MERGED,
      1 as AccountId,
      [],
      1 as AccountId,
      [1 as AccountId],
      [],
      [],
      undefined,
      true
    );
    await checkComputeAttention(
      element,
      ChangeStatus.MERGED,
      1 as AccountId,
      [22 as AccountId],
      1 as AccountId,
      [],
      [],
      []
    );
    await checkComputeAttention(
      element,
      ChangeStatus.MERGED,
      1 as AccountId,
      [22 as AccountId],
      1 as AccountId,
      [],
      [22 as AccountId],
      []
    );
    await checkComputeAttention(
      element,
      ChangeStatus.MERGED,
      1 as AccountId,
      [22 as AccountId, 33 as AccountId],
      1 as AccountId,
      [33 as AccountId],
      [22 as AccountId],
      [33 as AccountId]
    );
    await checkComputeAttention(
      element,
      ChangeStatus.MERGED,
      1 as AccountId,
      [22 as AccountId, 33 as AccountId],
      1 as AccountId,
      [],
      [22 as AccountId],
      []
    );
    await checkComputeAttention(
      element,
      ChangeStatus.MERGED,
      1 as AccountId,
      [22 as AccountId, 33 as AccountId],
      1 as AccountId,
      [],
      [22 as AccountId, 33 as AccountId],
      []
    );
    await checkComputeAttention(
      element,
      ChangeStatus.MERGED,
      1 as AccountId,
      [22 as AccountId, 33 as AccountId],
      1 as AccountId,
      [22 as AccountId, 33 as AccountId],
      [],
      [22 as AccountId, 33 as AccountId]
    );
  });

  test('computeNewAttention when adding reviewers', async () => {
    element.account = {_account_id: 1 as AccountId};
    element.change = {
      ...createChange(),
      owner: {_account_id: 5 as AccountId},
      status: ChangeStatus.NEW,
      attention_set: {},
    };
    // let rebuildReviewers triggered by change update finish running
    await element.updateComplete;

    element.reviewers = [
      {_account_id: 1 as AccountId},
      {_account_id: 2 as AccountId},
    ];
    element._ccs = [];
    element.draftCommentThreads = [];
    element.includeComments = true;
    element.canBeStarted = true;
    await element.updateComplete;
    assert.sameMembers(
      [...element.newAttentionSet],
      [1 as AccountId, 2 as AccountId]
    );

    // 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).
    element.labelsChanged = true;
    await element.updateComplete;
    assert.sameMembers(
      [...element.newAttentionSet],
      [2 as AccountId, 5 as AccountId]
    );
  });

  test('computeNewAttention when sending wip change for review', async () => {
    element.change = {
      ...createChange(),
      owner: {_account_id: 1 as AccountId},
      status: ChangeStatus.NEW,
      attention_set: {},
      reviewers: {
        [ReviewerState.REVIEWER]: [
          {...createAccountWithId(2)},
          {...createAccountWithId(3)},
        ],
      },
    };
    // let rebuildReviewers triggered by change update finish running
    await element.updateComplete;

    element.reviewers = [
      {...createAccountWithId(2)},
      {...createAccountWithId(3)},
    ];

    element._ccs = [];
    element.draftCommentThreads = [];
    element.includeComments = false;
    element.account = {_account_id: 1 as AccountId};

    await element.updateComplete;

    // For an active change there is no reason to add anyone to the set.
    element.computeNewAttention();
    assert.sameMembers([...element.newAttentionSet], []);

    // If the change is "work in progress" and the owner sends a reply, then
    // add all reviewers.
    element.canBeStarted = true;
    element.computeNewAttention();
    await element.updateComplete;
    assert.sameMembers(
      [...element.newAttentionSet],
      [2 as AccountId, 3 as AccountId]
    );

    // ... but not when someone else replies.
    element.account = {_account_id: 4 as AccountId};
    element.computeNewAttention();
    assert.sameMembers([...element.newAttentionSet], []);
  });

  test('computeNewAttentionAccounts', () => {
    element.reviewers = [
      {_account_id: 123 as AccountId, display_name: 'Ernie'},
      {_account_id: 321 as AccountId, display_name: 'Bert'},
    ];
    element._ccs = [{_account_id: 7 as AccountId, display_name: 'Elmo'}];
    const compute = (currentAtt: AccountId[], newAtt: AccountId[]) => {
      element.currentAttentionSet = new Set(currentAtt);
      element.newAttentionSet = new Set(newAtt);
      return element.computeNewAttentionAccounts().map(a => a?._account_id);
    };

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

  test('computeCommentAccounts', () => {
    element.change = {
      ...createChange(),
      labels: {
        'Code-Review': {
          all: [
            {_account_id: 1 as AccountId, value: 0},
            {_account_id: 2 as AccountId, value: 1},
            {_account_id: 3 as AccountId, value: 2},
          ],
          values: {
            '-2': 'This shall not be submitted',
            '-1': 'I would prefer this is not submitted as is',
            ' 0': 'No score',
            '+1': 'Looks good to me, but someone else must approve',
            '+2': 'Looks good to me, approved',
          },
        },
      },
    };
    const threads = [
      {
        ...createCommentThread([
          {
            ...createComment(),
            id: '1' as UrlEncodedCommentId,
            author: {_account_id: 1 as AccountId},
            unresolved: false,
          },
          {
            ...createComment(),
            id: '2' as UrlEncodedCommentId,
            in_reply_to: '1' as UrlEncodedCommentId,
            author: {_account_id: 2 as AccountId},
            unresolved: true,
          },
        ]),
      },
      {
        ...createCommentThread([
          {
            ...createComment(),
            id: '3' as UrlEncodedCommentId,
            author: {_account_id: 3 as AccountId},
            unresolved: false,
          },
          {
            ...createComment(),
            id: '4' as UrlEncodedCommentId,
            in_reply_to: '3' as UrlEncodedCommentId,
            author: {_account_id: 4 as AccountId},
            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('label picker', async () => {
    element.patchsetLevelDraftMessage = 'I wholeheartedly disapprove';
    element.draftCommentThreads = [createCommentThread([createComment()])];

    const saveReviewPromise = interceptSaveReview();

    sinon.stub(element.getLabelScores(), '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 element.updateComplete;
    queryAndAssert<GrButton>(element, '.send').click();
    assert.isTrue(element.disabled);

    const review = await saveReviewPromise;
    await element.updateComplete;
    await waitUntil(() => element.disabled === false);
    assert.equal(element.patchsetLevelDraftMessage.length, 0);
    assert.deepEqual(review, {
      drafts: 'PUBLISH_ALL_REVISIONS',
      labels: {
        'Code-Review': -1,
        Verified: -1,
      },
      reviewers: [],
      add_to_attention_set: [
        {user: 999, reason: '<GERRIT_ACCOUNT_1> replied on the change'},
      ],
      remove_from_attention_set: [],
      ignore_automatic_attention_set_rules: true,
    });
  });

  test('keep draft comments with reply', async () => {
    element.draftCommentThreads = [createCommentThread([createComment()])];
    await element.updateComplete;

    queryAndAssert<HTMLInputElement>(element, '#includeComments').click();
    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 element.updateComplete;
    element.patchsetLevelDraftMessage = '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 element.updateComplete;
    queryAndAssert<GrButton>(element, '.send').click();

    const review = await saveReviewPromise;
    await element.updateComplete;
    assert.deepEqual(review, {
      drafts: 'KEEP',
      labels: {
        'Code-Review': 0,
        Verified: 0,
      },
      reviewers: [],
      add_to_attention_set: [
        {reason: '<GERRIT_ACCOUNT_1> replied on the change', user: 999},
      ],
      remove_from_attention_set: [],
      ignore_automatic_attention_set_rules: true,
    });
  });

  test('getlabelValue returns value', async () => {
    const el = queryAndAssert<GrLabelScoreRow>(
      queryAndAssert(element, 'gr-label-scores'),
      'gr-label-score-row[name="Verified"]'
    );
    el.setSelectedValue('-1');
    assert.equal('-1', element.getLabelValue('Verified'));
  });

  test('getlabelValue when no score is selected', async () => {
    const el = queryAndAssert<GrLabelScoreRow>(
      queryAndAssert(element, 'gr-label-scores'),
      'gr-label-score-row[name="Code-Review"]'
    );
    el.setSelectedValue('-1');
    assert.strictEqual(element.getLabelValue('Verified'), ' 0');
  });

  test('setlabelValue', async () => {
    element.account = {_account_id: 1 as AccountId};
    await element.updateComplete;
    const label = 'Verified';
    const value = '+1';
    element.setLabelValue(label, value);
    await element.updateComplete;

    const labels = queryAndAssert<GrLabelScores>(
      element,
      '#labelScores'
    ).getLabelValues();
    assert.deepEqual(labels, {
      'Code-Review': 0,
      Verified: 1,
    });
  });

  async function testConfirmationDialog(cc?: boolean) {
    const yesButton = queryAndAssert<GrButton>(
      element,
      '.reviewerConfirmationButtons gr-button:first-child'
    );
    const noButton = queryAndAssert<GrButton>(
      element,
      '.reviewerConfirmationButtons gr-button:last-child'
    );

    element.ccPendingConfirmation = null;
    element.reviewerPendingConfirmation = null;
    await element.updateComplete;
    assert.isFalse(
      isVisible(queryAndAssert(element, '#reviewerConfirmationModal'))
    );

    const group = {
      id: 'id' as GroupId,
      name: 'name' as GroupName,
    };
    if (cc) {
      element.ccPendingConfirmation = {
        group,
        confirm: false,
        count: 10,
      };
    } else {
      element.reviewerPendingConfirmation = {
        group,
        confirm: false,
        count: 10,
      };
    }
    await element.updateComplete;

    if (cc) {
      assert.deepEqual(
        element.ccPendingConfirmation,
        element.pendingConfirmationDetails
      );
    } else {
      assert.deepEqual(
        element.reviewerPendingConfirmation,
        element.pendingConfirmationDetails
      );
    }

    assert.isTrue(
      isVisible(queryAndAssert(element, '#reviewerConfirmationModal'))
    );
    const expected = 'Group name has 10 members';
    assert.notEqual(
      queryAndAssert<HTMLElement>(
        element,
        '#reviewerConfirmationModal'
      ).innerText.indexOf(expected),
      -1
    );
    noButton.click(); // close the dialog
    await waitUntil(
      () => !isVisible(queryAndAssert(element, '#reviewerConfirmationModal'))
    );

    // TODO(dhruvsri): figure out why focus is not on the input element
    // We should be focused on account entry input.
    // const reviewersEntry = queryAndAssert<GrAccountList>(element, '#reviewers');
    // assert.isTrue(
    //   isFocusInsideElement(
    //     queryAndAssert<GrAutocomplete>(reviewersEntry.entry, '#input').input!
    //   )
    // );

    // No reviewer/CC should have been added.
    assert.equal(element.ccsList?.additions().length, 0);
    assert.equal(element.reviewersList?.additions().length, 0);

    if (cc) {
      element.ccPendingConfirmation = {
        group,
        confirm: false,
        count: 1,
      };
    } else {
      element.reviewerPendingConfirmation = {
        group,
        confirm: false,
        count: 1,
      };
    }
    await element.updateComplete;

    assert.isTrue(
      isVisible(queryAndAssert(element, '#reviewerConfirmationModal'))
    );

    yesButton.click(); // Confirm the group.
    await waitUntil(
      () => !isVisible(queryAndAssert(element, '#reviewerConfirmationModal'))
    );
    const additions = cc
      ? element.ccsList?.additions()
      : element.reviewersList?.additions();
    assert.deepEqual(additions, [
      {
        confirmed: true,
        id: 'id' as GroupId,
        name: 'name' as GroupName,
      },
    ]);

    // We should be focused on account entry input.
    // TODO(dhruvsri): figure out why focus is not on the input element
    // if (cc) {
    //   const ccsEntry = queryAndAssert<GrAccountList>(element, '#ccs');
    //   assert.isTrue(
    //     isFocusInsideElement(
    //       queryAndAssert<GrAutocomplete>(ccsEntry.entry, '#input').input!
    //     )
    //   );
    // } else {
    //   const reviewersEntry = queryAndAssert<GrAccountList>(
    //     element,
    //     '#reviewers'
    //   );
    //   assert.isTrue(
    //     isFocusInsideElement(
    //       queryAndAssert<GrAutocomplete>(reviewersEntry.entry, '#input').input!
    //     )
    //   );
    // }
  }

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

  test('reviewer confirmation', async () => {
    testConfirmationDialog(false);
  });

  suite('reviewer toast for WIP changes', () => {
    let fireStub: sinon.SinonStub;
    setup(() => {
      fireStub = sinon.stub(element, 'dispatchEvent');
    });

    test('toast not fired if change is already active', async () => {
      element.change = {
        ...createChange(),
        status: ChangeStatus.NEW,
      };
      element.send(false, false);

      await waitUntil(() => fireStub.called);

      const events = fireStub.args.map(arg => arg[0].type || '');
      assert.isFalse(events.includes('show-alert'));
    });

    test('toast is not fired if change is WIP and becomes active', async () => {
      const account = createAccountWithId(22);
      element.reviewersList!.accounts = [];
      element.reviewersList!.addAccountItem({account, count: 1});
      element.reviewersList!.dispatchEvent(
        new CustomEvent('account-added', {
          detail: {account},
        })
      );
      element.change = {
        ...createChange(),
        status: ChangeStatus.NEW,
        work_in_progress: true,
      };
      element.send(false, true);

      await waitUntil(() => fireStub.called);

      const events = fireStub.args.map(arg => arg[0].type || '');
      assert.isFalse(events.includes('show-alert'));
    });

    test('toast is fired if change is WIP and becomes active and reviewer added', async () => {
      const account = createAccountWithId(22);
      element.reviewersList!.accounts = [];
      element.reviewersList!.addAccountItem({account, count: 1});
      element.reviewersList!.dispatchEvent(
        new CustomEvent('account-added', {
          detail: {account},
        })
      );
      element.change = {
        ...createChange(),
        status: ChangeStatus.NEW,
        work_in_progress: true,
      };
      element.send(false, false);

      await waitUntil(() => fireStub.called);

      const events = fireStub.args.map(arg => arg[0].type || '');
      assert.isTrue(events.includes('show-alert'));
    });
  });

  test('reviewersMutated when account-text-change is fired from ccs', () => {
    assert.isFalse(element.reviewersMutated);
    assert.isTrue(queryAndAssert<GrAccountList>(element, '#ccs').allowAnyInput);
    assert.isFalse(
      queryAndAssert<GrAccountList>(element, '#reviewers').allowAnyInput
    );
    queryAndAssert(element, '#ccs').dispatchEvent(
      new CustomEvent('account-text-changed', {bubbles: true, composed: true})
    );
    assert.isTrue(element.reviewersMutated);
  });

  test('400 converts to human-readable server-error', async () => {
    stubRestApi('saveChangeReview').callsFake(
      (_changeNum, _patchNum, _review, errFn) => {
        // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
        errFn!(
          cloneableResponse(
            400,
            '....{"reviewers":{"id1":{"error":"human readable"}}}'
          ) as Response
        );
        return Promise.resolve(new Response());
      }
    );

    const promise = mockPromise();
    const listener = (event: Event) => {
      if (event.target !== document) return;
      (event as CustomEvent).detail.response.text().then((body: string) => {
        if (body === 'human readable') {
          promise.resolve();
        }
      });
    };
    addListenerForTest(document, 'server-error', listener);

    await element.updateComplete;
    element.send(false, false);
    await promise;
  });

  test('non-json 400 is treated as a normal server-error', async () => {
    stubRestApi('saveChangeReview').callsFake(
      (_changeNum, _patchNum, _review, errFn) => {
        // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
        errFn!(cloneableResponse(400, 'Comment validation error!') as Response);
        return Promise.resolve(new Response());
      }
    );
    const promise = mockPromise();
    const listener = (event: Event) => {
      if (event.target !== document) return;
      (event as CustomEvent).detail.response.text().then((body: string) => {
        if (body === 'Comment validation error!') {
          promise.resolve();
        }
      });
    };
    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.
    await element.updateComplete;
    element.send(false, false);
    await promise;
  });

  test('filterReviewerSuggestion', () => {
    const owner = makeAccount();
    const reviewer1 = makeAccount();
    const reviewer2 = makeGroup();
    const cc1 = makeAccount();
    const cc2 = makeGroup();
    let filter = element.filterReviewerSuggestionGenerator(false);

    element.change = createChange();
    element.change.owner = owner;
    element.reviewers = [reviewer1, reviewer2];
    element._ccs = [cc1, cc2];

    assert.isTrue(filter({account: makeAccount()} as Suggestion));
    assert.isTrue(filter({group: makeGroup()} as Suggestion));

    // Owner should be excluded.
    assert.isFalse(filter({account: owner} as Suggestion));

    // Existing and pending reviewers should be excluded when isCC = false.
    assert.isFalse(filter({account: reviewer1} as Suggestion));
    assert.isFalse(filter({group: reviewer2} as Suggestion));

    filter = element.filterReviewerSuggestionGenerator(true);

    // Existing and pending CCs should be excluded when isCC = true;.
    assert.isFalse(filter({account: cc1} as Suggestion));
    assert.isFalse(filter({group: cc2} as Suggestion));
  });

  test('focusOn', async () => {
    await element.updateComplete;
    const chooseFocusTargetSpy = sinon.spy(element, 'chooseFocusTarget');
    element.focusOn();
    await waitUntilVisible(element); // let whenVisible resolve

    assert.equal(chooseFocusTargetSpy.callCount, 1);
    assert.equal(element?.shadowRoot?.activeElement?.tagName, 'GR-COMMENT');
    assert.equal(
      element?.shadowRoot?.activeElement?.id,
      'patchsetLevelComment'
    );

    element.focusOn(element.FocusTarget.ANY);
    await waitUntilVisible(element); // let whenVisible resolve

    assert.equal(chooseFocusTargetSpy.callCount, 2);
    assert.equal(element?.shadowRoot?.activeElement?.tagName, 'GR-COMMENT');
    assert.equal(
      element?.shadowRoot?.activeElement?.id,
      'patchsetLevelComment'
    );

    element.focusOn(element.FocusTarget.BODY);
    await waitUntilVisible(element); // let whenVisible resolve

    assert.equal(chooseFocusTargetSpy.callCount, 2);
    assert.equal(element?.shadowRoot?.activeElement?.tagName, 'GR-COMMENT');
    assert.equal(
      element?.shadowRoot?.activeElement?.id,
      'patchsetLevelComment'
    );

    element.focusOn(element.FocusTarget.REVIEWERS);
    await waitUntilVisible(element); // let whenVisible resolve

    assert.equal(chooseFocusTargetSpy.callCount, 2);
    await waitUntil(
      () => element?.shadowRoot?.activeElement?.tagName === 'GR-ACCOUNT-LIST'
    );
    assert.equal(element?.shadowRoot?.activeElement?.id, 'reviewers');

    element.focusOn(element.FocusTarget.CCS);
    assert.equal(chooseFocusTargetSpy.callCount, 2);
    assert.equal(
      element?.shadowRoot?.activeElement?.tagName,
      'GR-ACCOUNT-LIST'
    );
    await waitUntil(() => element?.shadowRoot?.activeElement?.id === 'ccs');
  });

  test('chooseFocusTarget', () => {
    element.account = undefined;
    assert.equal(element.chooseFocusTarget(), element.FocusTarget.BODY);

    element.account = element.change!.owner;
    assert.equal(element.chooseFocusTarget(), element.FocusTarget.REVIEWERS);

    element.change!.reviewers.REVIEWER = [createAccountWithId(314)];
    assert.equal(element.chooseFocusTarget(), element.FocusTarget.BODY);

    element.change!.reviewers.REVIEWER = [createServiceUserWithId(314)];
    assert.equal(element.chooseFocusTarget(), element.FocusTarget.REVIEWERS);

    element.change!.reviewers.REVIEWER = [
      createAccountWithId(314),
      createServiceUserWithId(314),
    ];
    assert.equal(element.chooseFocusTarget(), element.FocusTarget.BODY);
  });

  test('only send labels that have changed', async () => {
    await element.updateComplete;
    stubSaveReview((review: ReviewInput) => {
      assert.deepEqual(review?.labels, {
        'Code-Review': 0,
        Verified: -1,
      });
    });

    const promise = mockPromise();
    element.addEventListener('send', () => {
      promise.resolve();
    });
    // Without wrapping this test in await element.updateComplete, the below two
    // calls to tap() cause a race in some situations in shadow DOM. The send
    // button can be tapped before the others, causing the test to fail.
    const el = queryAndAssert<GrLabelScoreRow>(
      queryAndAssert(element, 'gr-label-scores'),
      'gr-label-score-row[name="Verified"]'
    );
    el.setSelectedValue('-1');

    // required so that "Send" button is enabled
    element.canBeStarted = true;
    await element.updateComplete;

    queryAndAssert<GrButton>(element, '.send').click();
    await promise;
  });

  test('moving from cc to reviewer', async () => {
    const reviewer1 = makeAccount();
    const reviewer2 = makeAccount();
    const reviewer3 = makeAccount();
    const cc1 = makeAccount();
    const cc2 = makeAccount();
    const cc3 = makeAccount();
    const cc4 = makeAccount();
    element.reviewersList!.accounts = [reviewer1, reviewer2, reviewer3];
    element.ccsList!.accounts = [cc1, cc2, cc3, cc4];
    await element.updateComplete;
    element.reviewersList!.accounts.push(cc1);

    element.reviewers = element.reviewersList!.accounts;
    element.ccs = element.ccsList!.accounts;

    element.reviewersList!.dispatchEvent(
      new CustomEvent('account-added', {
        detail: {account: cc1},
      })
    );
    await element.updateComplete;

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

    element.reviewersList!.addAccountItem({account: cc4, count: 1});
    element.reviewersList!.dispatchEvent(
      new CustomEvent('account-added', {
        detail: {account: cc4},
      })
    );
    await element.updateComplete;

    element.reviewersList!.addAccountItem({account: cc3, count: 1});
    element.reviewersList!.dispatchEvent(
      new CustomEvent('account-added', {
        detail: {account: cc3},
      })
    );
    await element.updateComplete;

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

  test('update attention section when reviewers and ccs change', async () => {
    element.account = makeAccount();
    element.reviewers = [makeAccount(), makeAccount()];
    element._ccs = [makeAccount(), makeAccount()];
    element.draftCommentThreads = [];

    const modifyButton = queryAndAssert<GrButton>(
      element,
      '.edit-attention-button'
    );
    modifyButton.click();

    await element.updateComplete;

    assert.isFalse(element.attentionExpanded);

    element.patchsetLevelDraftMessage = 'a test comment';
    await element.updateComplete;

    modifyButton.click();

    await element.updateComplete;

    assert.isTrue(element.attentionExpanded);

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

    element.reviewers = [...element.reviewers, makeAccount()];
    element._ccs = [...element.ccs, makeAccount()];
    await element.updateComplete;

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

    queryAndAssert<GrButton>(element, '.edit-attention-button').click();
    await element.updateComplete;

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

    element.reviewers.pop();
    element.reviewers.pop();
    element._ccs.pop();
    element._ccs.pop();
    element.reviewers = [...element.reviewers];
    element._ccs = [...element.ccs]; // trigger willUpdate observer

    await element.updateComplete;

    queryAndAssert<GrButton>(element, '.edit-attention-button').click();

    await element.updateComplete;

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

  test('moving from reviewer to cc', async () => {
    const reviewer1 = makeAccount();
    const reviewer2 = makeAccount();
    const reviewer3 = makeAccount();
    const cc1 = makeAccount();
    const cc2 = makeAccount();
    const cc3 = makeAccount();
    const cc4 = makeAccount();
    element.reviewersList!.accounts = [reviewer1, reviewer2, reviewer3];
    element.ccsList!.accounts = [cc1, cc2, cc3, cc4];
    element.reviewers = element.reviewersList!.accounts;
    element._ccs = element.ccsList!.accounts;
    element._ccs.push(reviewer1);
    element.ccsList!.dispatchEvent(
      new CustomEvent('account-added', {
        detail: {account: reviewer1},
      })
    );

    await element.updateComplete;
    await element.updateComplete;
    await element.updateComplete;
    await element.updateComplete;

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

    element.ccsList!.addAccountItem({account: reviewer3, count: 1});
    element.ccsList!.dispatchEvent(
      new CustomEvent('account-added', {
        detail: {account: reviewer3},
      })
    );
    await element.updateComplete;

    element.ccsList!.addAccountItem({account: reviewer2, count: 1});
    element.ccsList!.dispatchEvent(
      new CustomEvent('account-added', {
        detail: {account: reviewer2},
      })
    );
    await element.updateComplete;

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

  test('migrate reviewers between states', async () => {
    const reviewers = queryAndAssert<GrAccountList>(element, '#reviewers');
    const ccs = queryAndAssert<GrAccountList>(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 as AccountId}],
    };
    await element.updateComplete;

    const mutations: ReviewerInput[] = [];

    stubSaveReview((review: ReviewInput) => {
      mutations.push(...review.reviewers!);
    });

    assert.isFalse(element.reviewersMutated);

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

    await element.updateComplete;
    assert.isTrue(element.reviewersMutated);
    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,
      })
    );

    assert.deepEqual(
      element.reviewers.map(v => accountKey(v)),
      [reviewer2, cc1].map(v => accountKey(v))
    );
    assert.deepEqual(
      element.ccs.map(v => accountKey(v)),
      [cc2, reviewer1].map(v => accountKey(v))
    );

    // Add to Reviewer/CC which will automatically remove from CC/Reviewer.
    reviewers.entry!.dispatchEvent(
      new CustomEvent('add', {
        detail: {value: {account: cc2}},
        composed: true,
        bubbles: true,
      })
    );

    await element.updateComplete;

    assert.deepEqual(
      element.reviewers.map(v => accountKey(v)),
      [reviewer2, cc1, cc2].map(v => accountKey(v))
    );
    assert.deepEqual(
      element.ccs.map(v => accountKey(v)),
      [reviewer1].map(v => accountKey(v))
    );

    ccs.entry!.dispatchEvent(
      new CustomEvent('add', {
        detail: {value: {account: reviewer2}},
        composed: true,
        bubbles: true,
      })
    );

    await element.updateComplete;

    assert.deepEqual(
      element.reviewers.map(v => accountKey(v)),
      [cc1, cc2].map(v => accountKey(v))
    );
    assert.deepEqual(
      element.ccs.map(v => accountKey(v)),
      [reviewer1, reviewer2].map(v => accountKey(v))
    );

    const mapReviewer = function (
      reviewer: AccountInfo,
      opt_state?: ReviewerState
    ) {
      const result: ReviewerInput = {
        reviewer: reviewer._account_id as AccountId,
      };
      if (opt_state) {
        result.state = opt_state;
      }
      return result;
    };

    // Send and purge and verify moves, delete cc3.
    await element.send(false, false);
    await element.updateComplete;
    assert.equal(mutations.length, 5);

    assert.deepEqual(mutations[0], mapReviewer(cc1, ReviewerState.REVIEWER));
    assert.deepEqual(mutations[1], mapReviewer(cc2, ReviewerState.REVIEWER));
    assert.deepEqual(mutations[2], mapReviewer(reviewer1, ReviewerState.CC));
    assert.deepEqual(mutations[3], mapReviewer(reviewer2, ReviewerState.CC));

    // Only 1 account was initially part of the change
    assert.deepEqual(mutations[4], {
      reviewer: 33 as UserId,
      state: ReviewerState.REMOVED,
    });
  });

  test('Ignore removal requests if being added as reviewer/CC', async () => {
    await element.updateComplete;
    const reviewers = queryAndAssert<GrAccountList>(element, '#reviewers');
    const ccs = queryAndAssert<GrAccountList>(element, '#ccs');
    const reviewer1 = makeAccount();
    element.reviewers = [reviewer1];
    element._ccs = [];

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

    await element.updateComplete;

    const mutations: ReviewerInput[] = [];

    stubSaveReview((review: ReviewInput) => {
      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,
      })
    );

    await element.send(false, false);
    assert.lengthOf(mutations, 1);
    // Only 1 account was initially part of the change
    assert.deepEqual(mutations[0], {
      reviewer: reviewer1._account_id,
      state: ReviewerState.CC,
    });
  });

  test('Ignore removal requests from reviewer if owner', async () => {
    await element.updateComplete;
    const reviewer1 = makeAccount();
    element.reviewers = [reviewer1];
    element._ccs = [];
    element.change!.owner = reviewer1;

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

    await element.updateComplete;

    const mutations: ReviewerInput[] = [];

    stubSaveReview((review: ReviewInput) => {
      mutations.push(...review.reviewers!);
    });

    await element.send(false, false);
    assert.lengthOf(mutations, 0);
  });

  test('emits cancel on esc key', async () => {
    const cancelHandler = sinon.spy();
    element.addEventListener('cancel', cancelHandler);
    pressKey(element, Key.ESC);
    await element.updateComplete;

    assert.isTrue(cancelHandler.called);
  });

  test('should not send on enter key', () => {
    stubSaveReview(() => undefined);
    element.addEventListener('send', () => assert.fail('wrongly called'));
    pressKey(element, Key.ENTER);
  });

  test('emit send on ctrl+enter key', async () => {
    // required so that "Send" button is enabled
    element.canBeStarted = true;
    await element.updateComplete;

    stubSaveReview(() => undefined);
    const promise = mockPromise();
    element.addEventListener('send', () => promise.resolve());
    pressKey(element, Key.ENTER, Modifier.CTRL_KEY);
    await promise;
  });

  test('computeMessagePlaceholder', async () => {
    element.canBeStarted = false;
    await element.updateComplete;
    assert.equal(element.messagePlaceholder, 'Say something nice...');

    element.canBeStarted = true;
    await element.updateComplete;
    assert.equal(
      element.messagePlaceholder,
      'Add a note for your reviewers...'
    );
  });

  test('computeSendButtonLabel', async () => {
    element.canBeStarted = false;
    await element.updateComplete;
    assert.equal(element.sendButtonLabel, 'Send');

    element.canBeStarted = true;
    await element.updateComplete;
    assert.equal(element.sendButtonLabel, 'Send and Start review');
  });

  test('handle400Error reviewers and CCs', async () => {
    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 promise = mockPromise();
    const listener = (e: Event) => {
      (e as CustomEvent).detail.response.text().then((text: string) => {
        assert.equal(text, [error1, error2, error3].join(', '));
        promise.resolve();
      });
    };
    addListenerForTest(document, 'server-error', listener);
    element.handle400Error(cloneableResponse(400, text) as Response);
    await promise;
  });

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

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

    test('start review sets ready', async () => {
      queryAndAssert<GrButton>(element, '.send').click();
      await element.updateComplete;
      assert.isTrue(sendStub.calledWith(true, true));
    });

    test("save review doesn't set ready", async () => {
      queryAndAssert<GrButton>(element, '.save').click();
      await element.updateComplete;
      assert.isTrue(sendStub.calledWith(true, false));
    });
  });

  test('buttons disabled until all API calls are resolved', () => {
    stubSaveReview(() => {
      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.patchsetLevelDraftMessage = expectedDraft;
    });

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

    test('error occurs in saveReview', () => {
      stubSaveReview(() => {
        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(1);
        stubRestApi('awaitPendingDiffDrafts').returns(promise as Promise<void>);

        element.open();

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

        promise.resolve();
        await element.updateComplete;

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

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

  test('computeSendButtonDisabled_canBeStarted', () => {
    // Mock canBeStarted
    element.canBeStarted = true;
    element.draftCommentThreads = [];
    element.patchsetLevelDraftMessage = '';
    element.reviewersMutated = false;
    element.labelsChanged = false;
    element.includeComments = false;
    element.disabled = false;
    element.commentEditing = false;
    element.account = makeAccount();
    assert.isFalse(element.computeSendButtonDisabled());
  });

  test('computeSendButtonDisabled_allFalse', () => {
    // Mock everything false
    element.canBeStarted = false;
    element.draftCommentThreads = [];
    element.patchsetLevelDraftMessage = '';
    element.reviewersMutated = false;
    element.labelsChanged = false;
    element.includeComments = false;
    element.disabled = false;
    element.commentEditing = false;
    element.account = makeAccount();
    assert.isTrue(element.computeSendButtonDisabled());
  });

  test('computeSendButtonDisabled_draftCommentsSend', () => {
    // Mock nonempty comment draft array; with sending comments.
    element.canBeStarted = false;
    element.draftCommentThreads = [{...createCommentThread([createComment()])}];
    element.patchsetLevelDraftMessage = '';
    element.reviewersMutated = false;
    element.labelsChanged = false;
    element.includeComments = true;
    element.disabled = false;
    element.commentEditing = false;
    element.account = makeAccount();
    assert.isFalse(element.computeSendButtonDisabled());
  });

  test('computeSendButtonDisabled_draftCommentsDoNotSend', () => {
    // Mock nonempty comment draft array; without sending comments.
    element.canBeStarted = false;
    element.draftCommentThreads = [{...createCommentThread([createComment()])}];
    element.patchsetLevelDraftMessage = '';
    element.reviewersMutated = false;
    element.labelsChanged = false;
    element.includeComments = false;
    element.disabled = false;
    element.commentEditing = false;
    element.account = makeAccount();

    assert.isTrue(element.computeSendButtonDisabled());
  });

  test('computeSendButtonDisabled_changeMessage', () => {
    // Mock nonempty change message.
    element.canBeStarted = false;
    element.draftCommentThreads = [{...createCommentThread([createComment()])}];
    element.patchsetLevelDraftMessage = 'test';
    element.reviewersMutated = false;
    element.labelsChanged = false;
    element.includeComments = false;
    element.disabled = false;
    element.commentEditing = false;
    element.account = makeAccount();

    assert.isFalse(element.computeSendButtonDisabled());
  });

  test('computeSendButtonDisabledreviewersChanged', () => {
    // Mock reviewers mutated.
    element.canBeStarted = false;
    element.draftCommentThreads = [{...createCommentThread([createComment()])}];
    element.patchsetLevelDraftMessage = '';
    element.reviewersMutated = true;
    element.labelsChanged = false;
    element.includeComments = false;
    element.disabled = false;
    element.commentEditing = false;
    element.account = makeAccount();

    assert.isFalse(element.computeSendButtonDisabled());
  });

  test('computeSendButtonDisabled_labelsChanged', () => {
    // Mock labels changed.
    element.canBeStarted = false;
    element.draftCommentThreads = [{...createCommentThread([createComment()])}];
    element.patchsetLevelDraftMessage = '';
    element.reviewersMutated = false;
    element.labelsChanged = true;
    element.includeComments = false;
    element.disabled = false;
    element.commentEditing = false;
    element.account = makeAccount();

    assert.isFalse(element.computeSendButtonDisabled());
  });

  test('computeSendButtonDisabled_dialogDisabled', () => {
    // Whole dialog is disabled.
    element.canBeStarted = false;
    element.draftCommentThreads = [{...createCommentThread([createComment()])}];
    element.patchsetLevelDraftMessage = '';
    element.reviewersMutated = false;
    element.labelsChanged = true;
    element.includeComments = false;
    element.disabled = true;
    element.commentEditing = false;
    element.account = makeAccount();

    assert.isTrue(element.computeSendButtonDisabled());
  });

  test('computeSendButtonDisabled_existingVote', async () => {
    const account = createAccountWithId();
    (
      element.change!.labels![StandardLabels.CODE_REVIEW]! as DetailedLabelInfo
    ).all = [account];
    element.canBeStarted = false;
    element.draftCommentThreads = [{...createCommentThread([createComment()])}];
    element.patchsetLevelDraftMessage = '';
    element.reviewersMutated = false;
    element.labelsChanged = false;
    element.includeComments = false;
    element.disabled = false;
    element.commentEditing = false;
    element.account = account;

    // User has already voted.
    assert.isFalse(element.computeSendButtonDisabled());
  });

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

    queryAndAssert<GrButton>(element, 'gr-button.send').click();
    assert.isFalse(sendStub.called);

    element.draftCommentThreads = [
      {
        ...createCommentThread([
          {
            ...createDraft(),
            path: 'test',
            line: 1,
            patch_set: 1 as RevisionPatchSetNum,
          },
        ]),
      },
    ];
    await element.updateComplete;

    queryAndAssert<GrButton>(element, 'gr-button.send').click();
    assert.isTrue(sendStub.called);
  });

  suite('patchset level comment using GrComment', () => {
    setup(async () => {
      element.account = createAccountWithId(1);
      element.requestUpdate();
      await element.updateComplete;
    });

    test('renders GrComment', () => {
      assert.dom.equal(
        query(element, '.patchsetLevelContainer'),
        /* HTML */ `
          <div class="patchsetLevelContainer resolved">
            <gr-endpoint-decorator name="reply-text">
              <gr-comment
                hide-header=""
                id="patchsetLevelComment"
                permanent-editing-mode=""
              >
              </gr-comment>
              <gr-endpoint-param name="change"> </gr-endpoint-param>
            </gr-endpoint-decorator>
          </div>
        `
      );
    });

    test('send button updates state as text is typed in patchset comment', async () => {
      assert.isTrue(element.computeSendButtonDisabled());

      queryAndAssert<GrComment>(element, '#patchsetLevelComment').messageText =
        'hello';
      await waitUntil(() => element.patchsetLevelDraftMessage === 'hello');

      assert.isFalse(element.computeSendButtonDisabled());

      queryAndAssert<GrComment>(element, '#patchsetLevelComment').messageText =
        '';
      await waitUntil(() => element.patchsetLevelDraftMessage === '');

      assert.isTrue(element.computeSendButtonDisabled());
    });

    test('sending patchset level comment', async () => {
      const patchsetLevelComment = queryAndAssert<GrComment>(
        element,
        '#patchsetLevelComment'
      );
      const autoSaveStub = sinon
        .stub(patchsetLevelComment, 'save')
        .returns(Promise.resolve());

      patchsetLevelComment.messageText = 'hello world';
      await waitUntil(
        () => element.patchsetLevelDraftMessage === 'hello world'
      );

      const saveReviewPromise = interceptSaveReview();

      assert.deepEqual(autoSaveStub.callCount, 0);

      queryAndAssert<GrButton>(element, '.send').click();

      const review = await saveReviewPromise;

      assert.deepEqual(autoSaveStub.callCount, 1);

      assert.deepEqual(review, {
        drafts: 'PUBLISH_ALL_REVISIONS',
        labels: {
          'Code-Review': 0,
          Verified: 0,
        },
        reviewers: [],
        add_to_attention_set: [
          {reason: '<GERRIT_ACCOUNT_1> replied on the change', user: 999},
        ],
        remove_from_attention_set: [],
        ignore_automatic_attention_set_rules: true,
      });
    });

    test('comment is auto saved when dialog is canceled', async () => {
      const patchsetLevelComment = queryAndAssert<GrComment>(
        element,
        '#patchsetLevelComment'
      );
      const autoSaveStub = sinon
        .stub(patchsetLevelComment, 'save')
        .returns(Promise.resolve());

      patchsetLevelComment.messageText = 'hello world';

      await waitUntil(
        () => element.patchsetLevelDraftMessage === 'hello world'
      );
      assert.deepEqual(autoSaveStub.callCount, 0);

      patchsetLevelComment.messageText = '';
      queryAndAssert<GrButton>(element, '#cancelButton').click();

      await waitUntil(() => autoSaveStub.callCount === 1);

      assert.deepEqual(patchsetLevelComment.messageText, '');
    });

    test('replies to patchset level comments are not filtered out', async () => {
      const draft = {...createDraft(), in_reply_to: '1' as UrlEncodedCommentId};
      commentsModel.setState({
        drafts: {
          'abc.txt': [draft],
        },
        discardedDrafts: [],
      });
      await waitUntil(() => element.draftCommentThreads.length === 1);

      // patchset level draft as a reply is not loaded in patchsetLevel comment
      assert.equal(element.patchsetLevelDraftMessage, '');

      assert.deepEqual(element.draftCommentThreads[0].comments[0], draft);
    });
  });

  suite('mention users', () => {
    setup(async () => {
      stubFlags('isEnabled')
        .withArgs(KnownExperimentId.MENTION_USERS)
        .returns(true);
      element.account = createAccountWithId(1);
      element.requestUpdate();
      await element.updateComplete;
    });

    test('mentioned user in resolved draft is added to CC', async () => {
      const account = {
        ...createAccountWithEmail('abcd@def.com' as EmailAddress),
        _account_id: 1234 as AccountId,
        registered_on: '2015-03-12 18:32:08.000000000' as Timestamp,
      };
      stubRestApi('getAccountDetails').returns(Promise.resolve(account));
      const draft = {
        ...createDraft(),
        message: 'hey @abcd@def take a look at this',
      };
      commentsModel.setState({
        comments: {},
        robotComments: {},
        drafts: {
          a: [draft],
        },
        portedComments: {},
        portedDrafts: {},
        discardedDrafts: [],
      });

      element.draftCommentThreads = [createCommentThread([draft])];
      await waitUntil(() => element.mentionedUsers.length > 0);

      await element.updateComplete;

      assert.deepEqual(element.mentionedUsers, [account]);
      assert.deepEqual(element.ccs, [account]);

      // owner(999) is added since (accountId = 1) replied to the change
      assert.sameMembers([...element.newAttentionSet], [999 as AccountId]);
    });

    test('mentioned user in unresolved draft is added to CC and AttentionSet', async () => {
      const account = {
        ...createAccountWithEmail('abcd@def.com' as EmailAddress),
        _account_id: 1234 as AccountId,
        registered_on: '2015-03-12 18:32:08.000000000' as Timestamp,
      };
      stubRestApi('getAccountDetails').returns(Promise.resolve(account));
      const draft = {
        ...createDraft(),
        message: 'hey @abcd@def.com take a look at this',
        unresolved: true,
      };
      commentsModel.setState({
        comments: {},
        robotComments: {},
        drafts: {
          a: [draft],
        },
        portedComments: {},
        portedDrafts: {},
        discardedDrafts: [],
      });
      element.draftCommentThreads = [createCommentThread([draft])];
      await waitUntil(
        () => element.mentionedUsersInUnresolvedDrafts.length > 0
      );

      await element.updateComplete;

      assert.deepEqual(element.mentionedUsers, [account]);
      assert.deepEqual(element.ccs, [account]);

      // owner(999) is added since (accountId = 1) replied to the change
      assert.sameMembers(
        [...element.newAttentionSet],
        [999 as AccountId, 1234 as AccountId]
      );
    });

    test('mention user can be manually removed from attention set', async () => {
      stubRestApi('getAccountDetails').returns(
        Promise.resolve({
          ...createAccountWithEmail('abcd@def.com' as EmailAddress),
          _account_id: 1234 as AccountId,
          registered_on: '2015-03-12 18:32:08.000000000' as Timestamp,
        })
      );
      const draft = {
        ...createDraft(),
        message: 'hey @abcd@def.com take a look at this',
        unresolved: true,
      };
      commentsModel.setState({
        comments: {},
        robotComments: {},
        drafts: {
          a: [draft],
        },
        portedComments: {},
        portedDrafts: {},
        discardedDrafts: [],
      });
      element.draftCommentThreads = [createCommentThread([draft])];
      await waitUntil(
        () => element.mentionedUsersInUnresolvedDrafts.length > 0
      );

      await element.updateComplete;

      // owner(999) is added since (accountId = 1) replied to the change
      assert.sameMembers(
        [...element.newAttentionSet],
        [999 as AccountId, 1234 as AccountId]
      );

      const modifyButton = queryAndAssert<GrButton>(
        element,
        '.edit-attention-button'
      );
      modifyButton.click();
      await element.updateComplete;

      const accountsChips = Array.from(
        queryAll<GrAccountLabel>(element, '.attention-detail gr-account-label')
      );
      assert.deepEqual(accountsChips[1].account, {
        email: 'abcd@def.com' as EmailAddress,
        registered_on: '2015-03-12 18:32:08.000000000' as Timestamp,
        _account_id: 1234 as AccountId,
      } as AccountInfo);
      accountsChips[1].click();

      await element.updateComplete;

      assert.sameMembers([...element.newAttentionSet], [999 as AccountId]);
    });

    test('mention user who is already CCed', async () => {
      const account = {
        ...createAccountWithEmail('abcd@def.com' as EmailAddress),
        _account_id: 1234 as AccountId,
        registered_on: '2015-03-12 18:32:08.000000000' as Timestamp,
      };
      stubRestApi('getAccountDetails').returns(Promise.resolve(account));

      commentsModel.setState({
        comments: {},
        robotComments: {},
        drafts: {
          a: [
            {
              ...createDraft(),
              message: 'hey @abcd@def.com take a look at this',
              unresolved: true,
            },
          ],
        },
        portedComments: {},
        portedDrafts: {},
        discardedDrafts: [],
      });

      await element.updateComplete;
      await waitUntil(() => element.mentionedUsers.length > 0);

      assert.deepEqual(element.ccs, [account]);
      assert.deepEqual(element.mentionedUsers, [account]);
      element._ccs = [account];

      await element.updateComplete;

      assert.deepEqual(element.mentionedUsers, [account]);
      assert.deepEqual(element.ccs, [account]);
    });

    test('mention user who is already a reviewer', async () => {
      const account = {
        ...createAccountWithEmail('abcd@def.com' as EmailAddress),
        _account_id: 1234 as AccountId,
        registered_on: '2015-03-12 18:32:08.000000000' as Timestamp,
      };
      stubRestApi('getAccountDetails').returns(Promise.resolve(account));
      commentsModel.setState({
        comments: {},
        robotComments: {},
        drafts: {
          a: [
            {
              ...createDraft(),
              message: 'hey @abcd@def.com take a look at this',
              unresolved: true,
            },
          ],
        },
        portedComments: {},
        portedDrafts: {},
        discardedDrafts: [],
      });

      await element.updateComplete;
      await waitUntil(() => element.mentionedUsers.length > 0);

      assert.deepEqual(element.mentionedUsers, [account]);

      // ensure updates to reviewers is reflected to mentionedUsers property
      element.reviewers = [account];

      await element.updateComplete;

      // overall ccs is empty since we filter out existing reviewers
      assert.deepEqual(element.ccs, []);
      assert.deepEqual(element.mentionedUsers, [account]);
      assert.deepEqual(element.reviewers, [account]);
    });
  });

  test('setPluginMessage', async () => {
    element.setPluginMessage('foo');
    await element.updateComplete;
    assert.equal(queryAndAssert(element, '#pluginMessage').textContent, 'foo');
  });
});
