/**
 * @license
 * Copyright (C) 2020 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';
import '../../core/gr-router/gr-router';
import './gr-change-metadata';
import {GerritNav} from '../../core/gr-navigation/gr-navigation';
import {getPluginLoader} from '../../shared/gr-js-api-interface/gr-plugin-loader';
import {_testOnly_initGerritPluginApi} from '../../shared/gr-js-api-interface/gr-gerrit';
import {GrChangeMetadata} from './gr-change-metadata';
import {
  createServerInfo,
  createUserConfig,
  createParsedChange,
  createAccountWithId,
  createRequirement,
  createCommitInfoWithRequiredCommit,
  createWebLinkInfo,
  createGerritInfo,
  createGitPerson,
  createCommit,
  createRevision,
  createAccountDetailWithId,
  createChangeConfig,
} from '../../../test/test-data-generators';
import {
  ChangeStatus,
  SubmitType,
  RequirementStatus,
  GpgKeyInfoStatus,
} from '../../../constants/constants';
import {
  EmailAddress,
  AccountId,
  CommitId,
  ServerInfo,
  RevisionInfo,
  ParentCommitInfo,
  TopicName,
  ElementPropertyDeepChange,
  PatchSetNum,
  NumericChangeId,
  LabelValueToDescriptionMap,
  Hashtag,
} from '../../../types/common';
import {SinonStubbedMember} from 'sinon/pkg/sinon-esm';
import {RestApiService} from '../../../services/gr-rest-api/gr-rest-api';
import {tap} from '@polymer/iron-test-helpers/mock-interactions';
import {GrEditableLabel} from '../../shared/gr-editable-label/gr-editable-label';
import {PluginApi} from '../../../api/plugin';
import {GrEndpointDecorator} from '../../plugins/gr-endpoint-decorator/gr-endpoint-decorator';
import {stubRestApi} from '../../../test/test-utils';
import {ParsedChangeInfo} from '../../../types/types';

const basicFixture = fixtureFromElement('gr-change-metadata');

const pluginApi = _testOnly_initGerritPluginApi();

suite('gr-change-metadata tests', () => {
  let element: GrChangeMetadata;

  setup(() => {
    stubRestApi('getLoggedIn').returns(Promise.resolve(false));
    stubRestApi('getConfig').returns(
      Promise.resolve({
        ...createServerInfo(),
        user: {
          ...createUserConfig(),
          anonymous_coward_name: 'test coward name',
        },
      })
    );
    element = basicFixture.instantiate();
  });

  test('_computeMergedCommitInfo', () => {
    const dummyRevs: {[revisionId: string]: RevisionInfo} = {
      1: createRevision(1),
      2: createRevision(2),
    };
    assert.deepEqual(
      element._computeMergedCommitInfo('0' as CommitId, dummyRevs),
      {}
    );
    assert.deepEqual(
      element._computeMergedCommitInfo('1' as CommitId, dummyRevs),
      dummyRevs[1].commit
    );

    // Regression test for issue 5337.
    const commit = element._computeMergedCommitInfo('2' as CommitId, dummyRevs);
    assert.notDeepEqual(commit, dummyRevs[2]);
    assert.deepEqual(commit, dummyRevs[2].commit);
  });

  test('computed fields', () => {
    assert.isFalse(
      element._computeHideStrategy({
        ...createParsedChange(),
        status: ChangeStatus.NEW,
      })
    );
    assert.isTrue(
      element._computeHideStrategy({
        ...createParsedChange(),
        status: ChangeStatus.MERGED,
      })
    );
    assert.isTrue(
      element._computeHideStrategy({
        ...createParsedChange(),
        status: ChangeStatus.ABANDONED,
      })
    );
    assert.equal(
      element._computeStrategy({
        ...createParsedChange(),
        submit_type: SubmitType.CHERRY_PICK,
      }),
      'Cherry Pick'
    );
    assert.equal(
      element._computeStrategy({
        ...createParsedChange(),
        submit_type: SubmitType.REBASE_ALWAYS,
      }),
      'Rebase Always'
    );
  });

  test('computed fields requirements', () => {
    assert.isFalse(
      element._computeShowRequirements({
        ...createParsedChange(),
        status: ChangeStatus.MERGED,
      })
    );
    assert.isFalse(
      element._computeShowRequirements({
        ...createParsedChange(),
        status: ChangeStatus.ABANDONED,
      })
    );

    // No labels and no requirements: submit status is useless
    assert.isFalse(
      element._computeShowRequirements({
        ...createParsedChange(),
        status: ChangeStatus.NEW,
        labels: {},
      })
    );

    // Work in Progress: submit status should be present
    assert.isTrue(
      element._computeShowRequirements({
        ...createParsedChange(),
        status: ChangeStatus.NEW,
        labels: {},
        work_in_progress: true,
      })
    );

    // We have at least one reason to display Submit Status
    assert.isTrue(
      element._computeShowRequirements({
        ...createParsedChange(),
        status: ChangeStatus.NEW,
        labels: {
          Verified: {
            approved: createAccountWithId(),
          },
        },
        requirements: [],
      })
    );
    assert.isTrue(
      element._computeShowRequirements({
        ...createParsedChange(),
        status: ChangeStatus.NEW,
        labels: {},
        requirements: [
          {
            ...createRequirement(),
            fallbackText: 'Resolve all comments',
            status: RequirementStatus.OK,
          },
        ],
      })
    );
  });

  test('show strategy for open change', () => {
    element.change = {
      ...createParsedChange(),
      status: ChangeStatus.NEW,
      submit_type: SubmitType.CHERRY_PICK,
      labels: {},
    };
    flush();
    const strategy = element.shadowRoot?.querySelector('.strategy');
    assert.ok(strategy);
    assert.isFalse(strategy?.hasAttribute('hidden'));
    assert.equal(strategy?.children[1].innerHTML, 'Cherry Pick');
  });

  test('hide strategy for closed change', () => {
    element.change = {
      ...createParsedChange(),
      status: ChangeStatus.MERGED,
      labels: {},
    };
    flush();
    assert.isTrue(
      element.shadowRoot?.querySelector('.strategy')?.hasAttribute('hidden')
    );
  });

  test('weblinks use GerritNav interface', () => {
    const weblinksStub = sinon
      .stub(GerritNav, '_generateWeblinks')
      .returns([{name: 'stubb', url: '#s'}]);
    element.commitInfo = createCommitInfoWithRequiredCommit();
    element.serverConfig = createServerInfo();
    flush();
    const webLinks = element.$.webLinks;
    assert.isTrue(weblinksStub.called);
    assert.isFalse(webLinks.hasAttribute('hidden'));
    assert.equal(element._computeWebLinks(element.commitInfo)?.length, 1);
  });

  test('weblinks hidden when no weblinks', () => {
    element.commitInfo = createCommitInfoWithRequiredCommit();
    element.serverConfig = createServerInfo();
    flush();
    const webLinks = element.$.webLinks;
    assert.isTrue(webLinks.hasAttribute('hidden'));
  });

  test('weblinks hidden when only gitiles weblink', () => {
    element.commitInfo = {
      ...createCommitInfoWithRequiredCommit(),
      web_links: [{...createWebLinkInfo(), name: 'gitiles', url: '#'}],
    };
    element.serverConfig = createServerInfo();
    flush();
    const webLinks = element.$.webLinks;
    assert.isTrue(webLinks.hasAttribute('hidden'));
    assert.equal(element._computeWebLinks(element.commitInfo), null);
  });

  test('weblinks hidden when sole weblink is set as primary', () => {
    const browser = 'browser';
    element.commitInfo = {
      ...createCommitInfoWithRequiredCommit(),
      web_links: [{...createWebLinkInfo(), name: browser, url: '#'}],
    };
    element.serverConfig = {
      ...createServerInfo(),
      gerrit: {
        ...createGerritInfo(),
        primary_weblink_name: browser,
      },
    };
    flush();
    const webLinks = element.$.webLinks;
    assert.isTrue(webLinks.hasAttribute('hidden'));
  });

  test('weblinks are visible when other weblinks', () => {
    const router = document.createElement('gr-router');
    sinon
      .stub(GerritNav, '_generateWeblinks')
      .callsFake(router._generateWeblinks.bind(router));

    element.commitInfo = {
      ...createCommitInfoWithRequiredCommit(),
      web_links: [{...createWebLinkInfo(), name: 'test', url: '#'}],
    };
    flush();
    const webLinks = element.$.webLinks;
    assert.isFalse(webLinks.hasAttribute('hidden'));
    assert.equal(element._computeWebLinks(element.commitInfo)?.length, 1);
    // With two non-gitiles weblinks, there are two returned.
    element.commitInfo = {
      ...createCommitInfoWithRequiredCommit(),
      web_links: [
        {...createWebLinkInfo(), name: 'test', url: '#'},
        {...createWebLinkInfo(), name: 'test2', url: '#'},
      ],
    };
    assert.equal(element._computeWebLinks(element.commitInfo)?.length, 2);
  });

  test('weblinks are visible when gitiles and other weblinks', () => {
    const router = document.createElement('gr-router');
    sinon
      .stub(GerritNav, '_generateWeblinks')
      .callsFake(router._generateWeblinks.bind(router));

    element.commitInfo = {
      ...createCommitInfoWithRequiredCommit(),
      web_links: [
        {...createWebLinkInfo(), name: 'test', url: '#'},
        {...createWebLinkInfo(), name: 'gitiles', url: '#'},
      ],
    };
    flush();
    const webLinks = element.$.webLinks;
    assert.isFalse(webLinks.hasAttribute('hidden'));
    // Only the non-gitiles weblink is returned.
    assert.equal(element._computeWebLinks(element.commitInfo)?.length, 1);
  });

  suite('_getNonOwnerRole', () => {
    let change: ParsedChangeInfo | undefined;

    setup(() => {
      change = {
        ...createParsedChange(),
        owner: {
          ...createAccountWithId(),
          email: 'abc@def' as EmailAddress,
          _account_id: 1019328 as AccountId,
        },
        revisions: {
          rev1: {
            ...createRevision(),
            uploader: {
              ...createAccountWithId(),
              email: 'ghi@def' as EmailAddress,
              _account_id: 1011123 as AccountId,
            },
            commit: {
              ...createCommit(),
              author: {...createGitPerson(), email: 'jkl@def' as EmailAddress},
              committer: {
                ...createGitPerson(),
                email: 'ghi@def' as EmailAddress,
              },
            },
          },
        },
        current_revision: 'rev1' as CommitId,
      };
    });

    suite('role=uploader', () => {
      test('_getNonOwnerRole for uploader', () => {
        assert.deepEqual(
          element._getNonOwnerRole(change, element._CHANGE_ROLE.UPLOADER),
          {
            ...createAccountWithId(),
            email: 'ghi@def' as EmailAddress,
            _account_id: 1011123 as AccountId,
          }
        );
      });

      test('_getNonOwnerRole that it does not return uploader', () => {
        // Set the uploader email to be the same as the owner.
        change!.revisions.rev1.uploader!._account_id = 1019328 as AccountId;
        assert.isNotOk(
          element._getNonOwnerRole(change, element._CHANGE_ROLE.UPLOADER)
        );
      });

      test('_computeShowRoleClass show uploader', () => {
        assert.equal(
          element._computeShowRoleClass(change, element._CHANGE_ROLE.UPLOADER),
          ''
        );
      });

      test('_computeShowRoleClass hide uploader', () => {
        // Set the uploader email to be the same as the owner.
        change!.revisions.rev1.uploader!._account_id = 1019328 as AccountId;
        assert.equal(
          element._computeShowRoleClass(change, element._CHANGE_ROLE.UPLOADER),
          'hideDisplay'
        );
      });
    });

    suite('role=committer', () => {
      test('_getNonOwnerRole for committer', () => {
        change!.revisions.rev1.uploader!.email = 'ghh@def' as EmailAddress;
        assert.deepEqual(
          element._getNonOwnerRole(change, element._CHANGE_ROLE.COMMITTER),
          {...createGitPerson(), email: 'ghi@def' as EmailAddress}
        );
      });

      test('_getNonOwnerRole is null if committer is same as uploader', () => {
        assert.isNotOk(
          element._getNonOwnerRole(change, element._CHANGE_ROLE.COMMITTER)
        );
      });

      test('_getNonOwnerRole that it does not return committer', () => {
        // Set the committer email to be the same as the owner.
        change!.revisions.rev1.commit!.committer.email = 'abc@def' as EmailAddress;
        assert.isNotOk(
          element._getNonOwnerRole(change, element._CHANGE_ROLE.COMMITTER)
        );
      });

      test('_getNonOwnerRole null for committer with no commit', () => {
        delete change!.revisions.rev1.commit;
        assert.isNotOk(
          element._getNonOwnerRole(change, element._CHANGE_ROLE.COMMITTER)
        );
      });
    });

    suite('role=author', () => {
      test('_getNonOwnerRole for author', () => {
        assert.deepEqual(
          element._getNonOwnerRole(change, element._CHANGE_ROLE.AUTHOR),
          {...createGitPerson(), email: 'jkl@def' as EmailAddress}
        );
      });

      test('_getNonOwnerRole that it does not return author', () => {
        // Set the author email to be the same as the owner.
        change!.revisions.rev1.commit!.author.email = 'abc@def' as EmailAddress;
        assert.isNotOk(
          element._getNonOwnerRole(change, element._CHANGE_ROLE.AUTHOR)
        );
      });

      test('_getNonOwnerRole null for author with no commit', () => {
        delete change!.revisions.rev1.commit;
        assert.isNotOk(
          element._getNonOwnerRole(change, element._CHANGE_ROLE.AUTHOR)
        );
      });
    });
  });

  suite('Push Certificate Validation', () => {
    let serverConfig: ServerInfo | undefined;
    let change: ParsedChangeInfo | undefined;

    setup(() => {
      serverConfig = {
        ...createServerInfo(),
        receive: {
          enable_signed_push: 'true',
        },
      };
      change = {
        ...createParsedChange(),
        revisions: {
          rev1: {
            ...createRevision(1),
            push_certificate: {
              certificate: 'Push certificate',
              key: {
                status: GpgKeyInfoStatus.BAD,
                problems: ['No public keys found for key ID E5E20E52'],
              },
            },
          },
        },
        current_revision: 'rev1' as CommitId,
        status: ChangeStatus.NEW,
        labels: {},
        mergeable: true,
      };
    });

    test('Push Certificate Validation test BAD', () => {
      change!.revisions.rev1!.push_certificate = {
        certificate: 'Push certificate',
        key: {
          status: GpgKeyInfoStatus.BAD,
          problems: ['No public keys found for key ID E5E20E52'],
        },
      };
      const result = element._computePushCertificateValidation(
        serverConfig,
        change
      );
      assert.equal(
        result?.message,
        'Push certificate is invalid:\n' +
          'No public keys found for key ID E5E20E52'
      );
      assert.equal(result?.icon, 'gr-icons:close');
      assert.equal(result?.class, 'invalid');
    });

    test('Push Certificate Validation test TRUSTED', () => {
      change!.revisions.rev1!.push_certificate = {
        certificate: 'Push certificate',
        key: {
          status: GpgKeyInfoStatus.TRUSTED,
        },
      };
      const result = element._computePushCertificateValidation(
        serverConfig,
        change
      );
      assert.equal(
        result?.message,
        'Push certificate is valid and key is trusted'
      );
      assert.equal(result?.icon, 'gr-icons:check');
      assert.equal(result?.class, 'trusted');
    });

    test('Push Certificate Validation is missing test', () => {
      change!.revisions.rev1! = createRevision(1);
      const result = element._computePushCertificateValidation(
        serverConfig,
        change
      );
      assert.equal(
        result?.message,
        'This patch set was created without a push certificate'
      );
      assert.equal(result?.icon, 'gr-icons:help');
      assert.equal(result?.class, 'help');
    });
  });

  test('_computeParents', () => {
    const parents: ParentCommitInfo[] = [
      {...createCommit(), commit: '123' as CommitId, subject: 'abc'},
    ];
    const revision: RevisionInfo = {
      ...createRevision(1),
      commit: {...createCommit(), parents},
    };
    assert.equal(element._computeParents(undefined, revision), parents);
    const change = (current_revision: CommitId): ParsedChangeInfo => {
      return {
        ...createParsedChange(),
        current_revision,
        revisions: {456: revision},
      };
    };
    const change_bad_revision = change('789' as CommitId);
    assert.deepEqual(
      element._computeParents(change_bad_revision, createRevision()),
      []
    );
    const change_no_commit: ParsedChangeInfo = {
      ...createParsedChange(),
      current_revision: '456' as CommitId,
      revisions: {456: createRevision()},
    };
    assert.deepEqual(element._computeParents(change_no_commit, undefined), []);
    const change_good = change('456' as CommitId);
    assert.equal(element._computeParents(change_good, undefined), parents);
  });

  test('_currentParents', () => {
    const revision = (parent: CommitId): RevisionInfo => {
      return {
        ...createRevision(),
        commit: {
          ...createCommit(),
          parents: [{...createCommit(), commit: parent, subject: 'abc'}],
        },
      };
    };
    element.change = {
      ...createParsedChange(),
      current_revision: '456' as CommitId,
      revisions: {456: revision('111' as CommitId)},
      owner: {},
    };
    element.revision = revision('222' as CommitId);
    assert.equal(element._currentParents[0].commit, '222');
    element.revision = revision('333' as CommitId);
    assert.equal(element._currentParents[0].commit, '333');
    element.revision = undefined;
    assert.equal(element._currentParents[0].commit, '111');
    element.change = createParsedChange();
    assert.deepEqual(element._currentParents, []);
  });

  test('_computeParentsLabel', () => {
    const parent: ParentCommitInfo = {
      ...createCommit(),
      commit: 'abc123' as CommitId,
      subject: 'My parent commit',
    };
    assert.equal(element._computeParentsLabel([parent]), 'Parent');
    assert.equal(element._computeParentsLabel([parent, parent]), 'Parents');
  });

  test('_computeParentListClass', () => {
    const parent: ParentCommitInfo = {
      ...createCommit(),
      commit: 'abc123' as CommitId,
      subject: 'My parent commit',
    };
    assert.equal(
      element._computeParentListClass([parent], true),
      'parentList nonMerge current'
    );
    assert.equal(
      element._computeParentListClass([parent], false),
      'parentList nonMerge notCurrent'
    );
    assert.equal(
      element._computeParentListClass([parent, parent], false),
      'parentList merge notCurrent'
    );
    assert.equal(
      element._computeParentListClass([parent, parent], true),
      'parentList merge current'
    );
  });

  test('_showAddTopic', () => {
    const changeRecord: ElementPropertyDeepChange<
      GrChangeMetadata,
      'change'
    > = {
      base: {...createParsedChange()},
      path: '',
      value: undefined,
    };
    assert.isTrue(element._showAddTopic(undefined, false));
    assert.isTrue(element._showAddTopic(changeRecord, false));
    assert.isFalse(element._showAddTopic(changeRecord, true));
    changeRecord.base!.topic = 'foo' as TopicName;
    assert.isFalse(element._showAddTopic(changeRecord, true));
    assert.isFalse(element._showAddTopic(changeRecord, false));
  });

  test('_showTopicChip', () => {
    const changeRecord: ElementPropertyDeepChange<
      GrChangeMetadata,
      'change'
    > = {
      base: {...createParsedChange()},
      path: '',
      value: undefined,
    };
    assert.isFalse(element._showTopicChip(undefined, false));
    assert.isFalse(element._showTopicChip(changeRecord, false));
    assert.isFalse(element._showTopicChip(changeRecord, true));
    changeRecord.base!.topic = 'foo' as TopicName;
    assert.isFalse(element._showTopicChip(changeRecord, true));
    assert.isTrue(element._showTopicChip(changeRecord, false));
  });

  test('_showCherryPickOf', () => {
    const changeRecord: ElementPropertyDeepChange<
      GrChangeMetadata,
      'change'
    > = {
      base: {...createParsedChange()},
      path: '',
      value: undefined,
    };
    assert.isFalse(element._showCherryPickOf(undefined));
    assert.isFalse(element._showCherryPickOf(changeRecord));
    changeRecord.base!.cherry_pick_of_change = 123 as NumericChangeId;
    changeRecord.base!.cherry_pick_of_patch_set = 1 as PatchSetNum;
    assert.isTrue(element._showCherryPickOf(changeRecord));
  });

  suite('Topic removal', () => {
    let change: ParsedChangeInfo;
    setup(() => {
      change = {
        ...createParsedChange(),
        actions: {
          topic: {enabled: false},
        },
        topic: 'the topic' as TopicName,
        status: ChangeStatus.NEW,
        submit_type: SubmitType.CHERRY_PICK,
        labels: {
          test: {
            all: [{_account_id: 1 as AccountId, name: 'bojack', value: 1}],
            default_value: 0,
            values: ([] as unknown) as LabelValueToDescriptionMap,
          },
        },
        removable_reviewers: [],
      };
    });

    test('_computeTopicReadOnly', () => {
      let mutable = false;
      assert.isTrue(element._computeTopicReadOnly(mutable, change));
      mutable = true;
      assert.isTrue(element._computeTopicReadOnly(mutable, change));
      change!.actions!.topic!.enabled = true;
      assert.isFalse(element._computeTopicReadOnly(mutable, change));
      mutable = false;
      assert.isTrue(element._computeTopicReadOnly(mutable, change));
    });

    test('topic read only hides delete button', () => {
      element.account = createAccountDetailWithId();
      element.change = change;
      flush();
      const button = element!
        .shadowRoot!.querySelector('gr-linked-chip')!
        .shadowRoot!.querySelector('gr-button');
      assert.isTrue(button?.hasAttribute('hidden'));
    });

    test('topic not read only does not hide delete button', () => {
      element.account = createAccountDetailWithId();
      change.actions!.topic!.enabled = true;
      element.change = change;
      flush();
      const button = element!
        .shadowRoot!.querySelector('gr-linked-chip')!
        .shadowRoot!.querySelector('gr-button');
      assert.isFalse(button?.hasAttribute('hidden'));
    });
  });

  suite('Hashtag removal', () => {
    let change: ParsedChangeInfo;
    setup(() => {
      change = {
        ...createParsedChange(),
        actions: {
          hashtags: {enabled: false},
        },
        hashtags: ['test-hashtag' as Hashtag],
        labels: {
          test: {
            all: [{_account_id: 1 as AccountId, name: 'bojack', value: 1}],
            default_value: 0,
            values: ([] as unknown) as LabelValueToDescriptionMap,
          },
        },
        removable_reviewers: [],
      };
    });

    test('_computeHashtagReadOnly', () => {
      flush();
      let mutable = false;
      assert.isTrue(element._computeHashtagReadOnly(mutable, change));
      mutable = true;
      assert.isTrue(element._computeHashtagReadOnly(mutable, change));
      change!.actions!.hashtags!.enabled = true;
      assert.isFalse(element._computeHashtagReadOnly(mutable, change));
      mutable = false;
      assert.isTrue(element._computeHashtagReadOnly(mutable, change));
    });

    test('hashtag read only hides delete button', () => {
      flush();
      element.account = createAccountDetailWithId();
      element.change = change;
      flush();
      const button = element!
        .shadowRoot!.querySelector('gr-linked-chip')!
        .shadowRoot!.querySelector('gr-button');
      assert.isTrue(button?.hasAttribute('hidden'));
    });

    test('hashtag not read only does not hide delete button', () => {
      flush();
      element.account = createAccountDetailWithId();
      change!.actions!.hashtags!.enabled = true;
      element.change = change;
      flush();
      const button = element!
        .shadowRoot!.querySelector('gr-linked-chip')!
        .shadowRoot!.querySelector('gr-button');
      assert.isFalse(button?.hasAttribute('hidden'));
    });
  });

  suite('remove reviewer votes', () => {
    setup(() => {
      sinon.stub(element, '_computeTopicReadOnly').returns(true);
      element.change = {
        ...createParsedChange(),
        topic: 'the topic' as TopicName,
        labels: {
          test: {
            all: [{_account_id: 1 as AccountId, name: 'bojack', value: 1}],
            default_value: 0,
            values: ([] as unknown) as LabelValueToDescriptionMap,
          },
        },
        removable_reviewers: [],
      };
      flush();
    });

    suite('assignee field', () => {
      const dummyAccount = createAccountWithId();
      const change: ParsedChangeInfo = {
        ...createParsedChange(),
        actions: {
          assignee: {enabled: false},
        },
        assignee: dummyAccount,
      };
      let deleteStub: SinonStubbedMember<RestApiService['deleteAssignee']>;
      let setStub: SinonStubbedMember<RestApiService['setAssignee']>;

      setup(() => {
        deleteStub = stubRestApi('deleteAssignee');
        setStub = stubRestApi('setAssignee');
        element.serverConfig = {
          ...createServerInfo(),
          change: {
            ...createChangeConfig(),
            enable_assignee: true,
          },
        };
      });

      test('changing change recomputes _assignee', () => {
        assert.isFalse(!!element._assignee?.length);
        const change = element.change;
        change!.assignee = dummyAccount;
        element._changeChanged(change);
        assert.deepEqual(element?._assignee?.[0], dummyAccount);
      });

      test('modifying _assignee calls API', () => {
        assert.isFalse(!!element._assignee?.length);
        element.set('_assignee', [dummyAccount]);
        assert.isTrue(setStub.calledOnce);
        assert.deepEqual(element.change!.assignee, dummyAccount);
        element.set('_assignee', [dummyAccount]);
        assert.isTrue(setStub.calledOnce);
        element.set('_assignee', []);
        assert.isTrue(deleteStub.calledOnce);
        assert.equal(element.change!.assignee, undefined);
        element.set('_assignee', []);
        assert.isTrue(deleteStub.calledOnce);
      });

      test('_computeAssigneeReadOnly', () => {
        let mutable = false;
        assert.isTrue(element._computeAssigneeReadOnly(mutable, change));
        mutable = true;
        assert.isTrue(element._computeAssigneeReadOnly(mutable, change));
        change.actions!.assignee!.enabled = true;
        assert.isFalse(element._computeAssigneeReadOnly(mutable, change));
        mutable = false;
        assert.isTrue(element._computeAssigneeReadOnly(mutable, change));
      });
    });

    test('changing topic', () => {
      const newTopic = 'the new topic' as TopicName;
      const setChangeTopicStub = stubRestApi('setChangeTopic').returns(
        Promise.resolve(newTopic)
      );
      element._handleTopicChanged(new CustomEvent('test', {detail: newTopic}));
      const topicChangedSpy = sinon.spy();
      element.addEventListener('topic-changed', topicChangedSpy);
      assert.isTrue(
        setChangeTopicStub.calledWith(42 as NumericChangeId, newTopic)
      );
      return setChangeTopicStub.lastCall.returnValue.then(() => {
        assert.equal(element.change!.topic, newTopic);
        assert.isTrue(topicChangedSpy.called);
      });
    });

    test('topic removal', () => {
      const newTopic = 'the new topic' as TopicName;
      const setChangeTopicStub = stubRestApi('setChangeTopic').returns(
        Promise.resolve(newTopic)
      );
      const chip = element.shadowRoot!.querySelector('gr-linked-chip');
      const remove = chip!.$.remove;
      const topicChangedSpy = sinon.spy();
      element.addEventListener('topic-changed', topicChangedSpy);
      tap(remove);
      assert.isTrue(chip?.disabled);
      assert.isTrue(setChangeTopicStub.calledWith(42 as NumericChangeId));
      return setChangeTopicStub.lastCall.returnValue.then(() => {
        assert.isFalse(chip?.disabled);
        assert.equal(element.change!.topic, '' as TopicName);
        assert.isTrue(topicChangedSpy.called);
      });
    });

    test('changing hashtag', () => {
      flush();
      element._newHashtag = 'new hashtag' as Hashtag;
      const newHashtag: Hashtag[] = ['new hashtag' as Hashtag];
      const setChangeHashtagStub = stubRestApi('setChangeHashtag').returns(
        Promise.resolve(newHashtag)
      );
      element._handleHashtagChanged();
      assert.isTrue(
        setChangeHashtagStub.calledWith(42 as NumericChangeId, {
          add: ['new hashtag' as Hashtag],
        })
      );
      return setChangeHashtagStub.lastCall.returnValue.then(() => {
        assert.equal(element.change!.hashtags, newHashtag);
      });
    });
  });

  test('editTopic', () => {
    element.account = createAccountDetailWithId();
    element.change = {
      ...createParsedChange(),
      actions: {topic: {enabled: true}},
    };
    flush();

    const label = element.shadowRoot!.querySelector(
      '.topicEditableLabel'
    ) as GrEditableLabel;
    assert.ok(label);
    const openStub = sinon.stub(label, 'open');
    element.editTopic();
    flush();

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

  suite('plugin endpoints', () => {
    test('endpoint params', async () => {
      element.change = createParsedChange();
      element.revision = createRevision();
      interface MetadataGrEndpointDecorator extends GrEndpointDecorator {
        plugin: PluginApi;
        change: ParsedChangeInfo;
        revision: RevisionInfo;
      }
      let hookEl: MetadataGrEndpointDecorator;
      let plugin: PluginApi;
      pluginApi.install(
        p => {
          plugin = p;
          plugin
            .hook('change-metadata-item')
            .getLastAttached()
            .then(el => (hookEl = el as MetadataGrEndpointDecorator));
        },
        '0.1',
        'http://some/plugins/url.js'
      );
      getPluginLoader().loadPlugins([]);
      await flush();
      assert.strictEqual(hookEl!.plugin, plugin!);
      assert.strictEqual(hookEl!.change, element.change);
      assert.strictEqual(hookEl!.revision, element.revision);
    });
  });
});
