/**
 * @license
 * Copyright 2020 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import '../../../test/common-test-setup';
import './gr-change-metadata';

import {ChangeRole, GrChangeMetadata} from './gr-change-metadata';
import {
  createServerInfo,
  createUserConfig,
  createParsedChange,
  createAccountWithId,
  createCommitInfoWithRequiredCommit,
  createWebLinkInfo,
  createGerritInfo,
  createGitPerson,
  createCommit,
  createRevision,
  createAccountDetailWithId,
  createConfig,
} from '../../../test/test-data-generators';
import {
  ChangeStatus,
  SubmitType,
  GpgKeyInfoStatus,
  InheritedBooleanInfoConfiguredValue,
} from '../../../constants/constants';
import {
  EmailAddress,
  AccountId,
  CommitId,
  ServerInfo,
  RevisionInfo,
  ParentCommitInfo,
  TopicName,
  RevisionPatchSetNum,
  NumericChangeId,
  LabelValueToDescriptionMap,
  Hashtag,
  CommitInfo,
} from '../../../types/common';
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 {
  queryAndAssert,
  stubRestApi,
  waitUntilCalled,
} from '../../../test/test-utils';
import {ParsedChangeInfo} from '../../../types/types';
import {GrLinkedChip} from '../../shared/gr-linked-chip/gr-linked-chip';
import {GrButton} from '../../shared/gr-button/gr-button';
import {nothing} from 'lit';
import {fixture, html, assert} from '@open-wc/testing';
import {EventType} from '../../../types/events';
import {testResolver} from '../../../test/common-test-setup';
import {pluginLoaderToken} from '../../shared/gr-js-api-interface/gr-plugin-loader';

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

  setup(async () => {
    stubRestApi('getLoggedIn').returns(Promise.resolve(false));
    stubRestApi('getConfig').returns(
      Promise.resolve({
        ...createServerInfo(),
        user: {
          ...createUserConfig(),
          anonymouscowardname: 'test coward name',
        },
      })
    );
    element = await fixture(html`<gr-change-metadata></gr-change-metadata>`);
    element.change = createParsedChange();
    await element.updateComplete;
  });

  test('renders', async () => {
    await element.updateComplete;
    assert.shadowDom.equal(
      element,
      /* HTML */ `<div>
      <div class="metadata-header">
        <h3 class="heading-3 metadata-title">Change Info</h3>
        <gr-button
          class="show-all-button"
          link=""
          role="button"
          tabindex="0"
          aria-disabled="false"
        >
          Show all <gr-icon icon="expand_more"></gr-icon>
          <gr-icon hidden="" icon="expand_less"></gr-icon>
        </gr-button>
      </div>
      <section class="hideDisplay">
        <span class="title">
          <gr-tooltip-content
            has-tooltip=""
            title="Last update of (meta)data for this change."
          >
            Updated
          </gr-tooltip-content>
        </span>
        <span class="value">
          <gr-date-formatter showyesterday="" withtooltip="">
          </gr-date-formatter>
        </span>
      </section>
      <section>
        <span class="title">
          <gr-tooltip-content
            has-tooltip=""
            title="This user created or uploaded the first patchset of this change."
          >
            Owner
          </gr-tooltip-content>
        </span>
        <span class="value">
          <gr-account-chip highlightattention=""
            ><gr-vote-chip circle-shape="" slot="vote-chip"> </gr-vote-chip
          ></gr-account-chip>
        </span>
      </section>
      <section>
        <span class="title">
          <gr-tooltip-content
            has-tooltip=""
            title="This user wrote the code change."
          >
            Author
          </gr-tooltip-content>
        </span>
        <span class="value">
          <gr-account-chip><gr-vote-chip circle-shape="" slot="vote-chip"></gr-vote-chip
          ></gr-account-chip>
        </span>
      </section>
      <section>
        <span class="title">
          <gr-tooltip-content
            has-tooltip=""
            title="This user committed the code change to the Git repository (typically to the local Git repo before uploading)."
          >
            Committer
          </gr-tooltip-content>
        </span>
        <span class="value">
          <gr-account-chip><gr-vote-chip circle-shape="" slot="vote-chip"></gr-account-chip>
        </span>
      </section>
      <section>
        <span class="title"> Reviewers </span>
        <span class="value">
          <gr-reviewer-list reviewers-only=""> </gr-reviewer-list>
        </span>
      </section>
      <section class="hideDisplay">
        <span class="title"> CC </span>
        <span class="value">
          <gr-reviewer-list ccs-only=""> </gr-reviewer-list>
        </span>
      </section>
      <section>
          <span class="title">
            Repo | Branch
          </span>
          <span class="value">
            <a href="/q/project:test-project">
              test-project
            </a>
            |
            <a href="/q/project:test-project+branch:test-branch+status:open">
              test-branch
            </a>
          </span>
        </section>
      <section class="hideDisplay">
        <span class="title">Parent</span>
        <span class="value">
          <ol  class="nonMerge notCurrent parentList"></ol>
        </span>
      </section>
      <section class="hideDisplay strategy">
        <span class="title"> Strategy </span> <span class="value"> </span>
      </section>
      <section class="hashtag hideDisplay">
        <span class="title"> Hashtags </span>
        <span class="value"> </span>
      </section>
      <div class="separatedSection">
      <gr-submit-requirements></gr-submit-requirements>
      </div>
      <gr-endpoint-decorator name="change-metadata-item">
        <gr-endpoint-param name="labels"> </gr-endpoint-param>
        <gr-endpoint-param name="change"> </gr-endpoint-param>
        <gr-endpoint-param name="revision"> </gr-endpoint-param>
      </gr-endpoint-decorator>
    </div>`
    );
  });

  test('computeMergedCommitInfo', () => {
    const dummyRevs: {[revisionId: string]: RevisionInfo} = {
      1: createRevision(1),
      2: createRevision(2),
    };
    assert.deepEqual(
      element.computeMergedCommitInfo('0' as CommitId, dummyRevs),
      undefined
    );
    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] as unknown as CommitInfo);
    assert.deepEqual(commit, dummyRevs[2].commit);
  });

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

  test('hide strategy for closed change', async () => {
    element.change = {
      ...createParsedChange(),
      status: ChangeStatus.MERGED,
      labels: {},
    };
    await element.updateComplete;
    assert.isNull(element.shadowRoot?.querySelector('.strategy'));
  });

  test('weblinks hidden when no weblinks', async () => {
    element.commitInfo = createCommitInfoWithRequiredCommit();
    element.serverConfig = createServerInfo();
    await element.updateComplete;
    assert.isNull(element.webLinks);
  });

  test('weblinks hidden when only gitiles weblink', async () => {
    element.commitInfo = {
      ...createCommitInfoWithRequiredCommit(),
      web_links: [{...createWebLinkInfo(), name: 'gitiles', url: '#'}],
    };
    element.serverConfig = createServerInfo();
    await element.updateComplete;
    assert.isNull(element.webLinks);
    assert.equal(element.computeWebLinks().length, 0);
  });

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

  test('weblinks are visible when other weblinks', async () => {
    element.commitInfo = {
      ...createCommitInfoWithRequiredCommit(),
      web_links: [{...createWebLinkInfo(), name: 'test', url: '#'}],
    };
    await element.updateComplete;
    const webLinks = element.webLinks!;
    assert.isFalse(webLinks.hasAttribute('hidden'));
    assert.equal(element.computeWebLinks().length, 1);
  });

  test('weblinks are visible when gitiles and other weblinks', async () => {
    element.commitInfo = {
      ...createCommitInfoWithRequiredCommit(),
      web_links: [
        {...createWebLinkInfo(), name: 'test', url: '#'},
        {...createWebLinkInfo(), name: 'gitiles', url: '#'},
      ],
    };
    await element.updateComplete;
    const webLinks = element.webLinks!;
    assert.isFalse(webLinks.hasAttribute('hidden'));
    // Only the non-gitiles weblink is returned.
    assert.equal(element.computeWebLinks().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', () => {
        element.change = change;
        assert.deepEqual(element.getNonOwnerRole(ChangeRole.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;
        element.change = change;
        assert.isNotOk(element.getNonOwnerRole(ChangeRole.UPLOADER));
      });

      test('computeShowRoleClass show uploader', () => {
        element.change = change;
        assert.notEqual(element.renderNonOwner(ChangeRole.UPLOADER), nothing);
      });

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

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

      test('getNonOwnerRole is null if committer is same as uploader', () => {
        element.change = change;
        assert.isNotOk(element.getNonOwnerRole(ChangeRole.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;
        element.change = change;
        assert.isNotOk(element.getNonOwnerRole(ChangeRole.COMMITTER));
      });

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

    suite('role=author', () => {
      test('getNonOwnerRole for author', () => {
        element.change = change;
        assert.deepEqual(element.getNonOwnerRole(ChangeRole.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;
        element.change = change;
        assert.isNotOk(element.getNonOwnerRole(ChangeRole.AUTHOR));
      });

      test('getNonOwnerRole null for author with no commit', () => {
        delete change!.revisions.rev1.commit;
        element.change = change;
        assert.isNotOk(element.getNonOwnerRole(ChangeRole.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,
      };
      element.repoConfig = {
        ...createConfig(),
        enable_signed_push: {
          configured_value: 'TRUE' as InheritedBooleanInfoConfiguredValue,
          value: 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'],
        },
      };
      element.change = change;
      element.serverConfig = serverConfig;
      const result = element.computePushCertificateValidation();
      assert.equal(
        result?.message,
        'Push certificate is invalid:\n' +
          'No public keys found for key ID E5E20E52'
      );
      assert.equal(result?.icon, 'close');
      assert.equal(result?.class, 'invalid');
    });

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

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

    test('computePushCertificateValidation returns undefined', () => {
      element.change = change;
      delete serverConfig!.receive!.enable_signed_push;
      element.serverConfig = serverConfig;
      assert.isUndefined(element.computePushCertificateValidation());
    });

    test('isEnabledSignedPushOnRepo', () => {
      change!.revisions.rev1!.push_certificate = {
        certificate: 'Push certificate',
        key: {
          status: GpgKeyInfoStatus.TRUSTED,
        },
      };
      element.change = change;
      element.serverConfig = serverConfig;
      element.repoConfig!.enable_signed_push!.configured_value =
        InheritedBooleanInfoConfiguredValue.INHERIT;
      element.repoConfig!.enable_signed_push!.inherited_value = true;
      assert.isTrue(element.isEnabledSignedPushOnRepo());

      element.repoConfig!.enable_signed_push!.inherited_value = false;
      assert.isFalse(element.isEnabledSignedPushOnRepo());

      element.repoConfig!.enable_signed_push!.configured_value =
        InheritedBooleanInfoConfiguredValue.TRUE;
      assert.isTrue(element.isEnabledSignedPushOnRepo());

      element.repoConfig = undefined;
      assert.isFalse(element.isEnabledSignedPushOnRepo());
    });
  });

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

  test('currentParents', async () => {
    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);
    await element.updateComplete;
    assert.equal(element.currentParents[0].commit, '222');
    element.revision = revision('333' as CommitId);
    await element.updateComplete;
    assert.equal(element.currentParents[0].commit, '333');
    element.revision = undefined;
    await element.updateComplete;
    assert.equal(element.currentParents[0].commit, '111');
    element.change = createParsedChange();
    await element.updateComplete;
    assert.deepEqual(element.currentParents, []);
  });

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

  test('showAddTopic', () => {
    const change = createParsedChange();
    element.change = undefined;
    element.settingTopic = false;
    element.topicReadOnly = false;
    assert.isTrue(element.showAddTopic());
    // do not show for 'readonly'
    element.change = undefined;
    element.settingTopic = false;
    element.topicReadOnly = true;
    assert.isFalse(element.showAddTopic());
    element.change = change;
    element.settingTopic = false;
    element.topicReadOnly = false;
    assert.isTrue(element.showAddTopic());
    element.change = change;
    element.settingTopic = true;
    element.topicReadOnly = false;
    assert.isFalse(element.showAddTopic());
    change.topic = 'foo' as TopicName;
    element.change = change;
    element.settingTopic = true;
    element.topicReadOnly = false;
    assert.isFalse(element.showAddTopic());
    element.change = change;
    element.settingTopic = false;
    element.topicReadOnly = false;
    assert.isFalse(element.showAddTopic());
  });

  test('showTopicChip', async () => {
    const change = createParsedChange();
    element.change = change;
    element.settingTopic = true;
    await element.updateComplete;
    assert.isFalse(element.showTopicChip());
    element.change = change;
    element.settingTopic = false;
    await element.updateComplete;
    assert.isFalse(element.showTopicChip());
    element.change = change;
    element.settingTopic = true;
    await element.updateComplete;
    assert.isFalse(element.showTopicChip());
    change.topic = 'foo' as TopicName;
    element.change = change;
    element.settingTopic = true;
    await element.updateComplete;
    assert.isFalse(element.showTopicChip());
    element.change = change;
    element.settingTopic = false;
    await element.updateComplete;
    assert.isTrue(element.showTopicChip());
  });

  test('showCherryPickOf', async () => {
    element.change = undefined;
    await element.updateComplete;
    assert.isFalse(element.showCherryPickOf());
    const change = createParsedChange();
    element.change = change;
    await element.updateComplete;
    assert.isFalse(element.showCherryPickOf());
    change.cherry_pick_of_change = 123 as NumericChangeId;
    change.cherry_pick_of_patch_set = 1 as RevisionPatchSetNum;
    element.change = change;
    await element.updateComplete;
    assert.isTrue(element.showCherryPickOf());
  });

  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;
      element.mutable = mutable;
      element.change = change;
      assert.isTrue(element.computeTopicReadOnly());
      mutable = true;
      element.mutable = mutable;
      assert.isTrue(element.computeTopicReadOnly());
      change.actions!.topic!.enabled = true;
      element.mutable = mutable;
      element.change = change;
      assert.isFalse(element.computeTopicReadOnly());
      mutable = false;
      element.mutable = mutable;
      assert.isTrue(element.computeTopicReadOnly());
    });

    test('topic read only hides delete button', async () => {
      element.account = createAccountDetailWithId();
      element.change = change;
      await element.updateComplete;
      const chip = queryAndAssert<GrLinkedChip>(element, 'gr-linked-chip');
      const button = queryAndAssert<GrButton>(chip, 'gr-button');
      assert.isTrue(button.hasAttribute('hidden'));
    });

    test('topic not read only does not hide delete button', async () => {
      element.account = createAccountDetailWithId();
      change.actions!.topic!.enabled = true;
      element.change = change;
      await element.updateComplete;
      const chip = queryAndAssert<GrLinkedChip>(element, 'gr-linked-chip');
      const button = queryAndAssert<GrButton>(chip, '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', async () => {
      await element.updateComplete;
      let mutable = false;
      element.change = change;
      element.mutable = mutable;
      await element.updateComplete;
      assert.isTrue(element.computeHashtagReadOnly());
      mutable = true;
      element.change = change;
      element.mutable = mutable;
      await element.updateComplete;
      assert.isTrue(element.computeHashtagReadOnly());
      change.actions!.hashtags!.enabled = true;
      element.change = change;
      element.mutable = mutable;
      await element.updateComplete;
      assert.isFalse(element.computeHashtagReadOnly());
      mutable = false;
      element.change = change;
      element.mutable = mutable;
      await element.updateComplete;
      assert.isTrue(element.computeHashtagReadOnly());
    });

    test('hashtag read only hides delete button', async () => {
      element.account = createAccountDetailWithId();
      element.change = change;
      await element.updateComplete;
      assert.isTrue(element.mutable, 'Mutable');
      assert.isFalse(
        element.change.actions?.hashtags?.enabled,
        'hashtags disabled'
      );
      assert.isTrue(element.hashtagReadOnly, 'hashtag read only');
      const chip = queryAndAssert<GrLinkedChip>(element, 'gr-linked-chip');
      const button = queryAndAssert<GrButton>(chip, 'gr-button');
      assert.isTrue(button.hasAttribute('hidden'), 'button hidden');
    });

    test('hashtag not read only does not hide delete button', async () => {
      await element.updateComplete;
      element.account = createAccountDetailWithId();
      change.actions!.hashtags!.enabled = true;
      element.change = change;
      await element.updateComplete;
      const chip = queryAndAssert<GrLinkedChip>(element, 'gr-linked-chip');
      const button = queryAndAssert<GrButton>(chip, 'gr-button');
      assert.isFalse(button.hasAttribute('hidden'));
    });
  });

  suite('remove reviewer votes', () => {
    setup(async () => {
      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: [],
      };
      await element.updateComplete;
    });

    test('changing topic', async () => {
      const newTopic = 'the new topic' as TopicName;
      const setChangeTopicStub = stubRestApi('setChangeTopic').returns(
        Promise.resolve(newTopic)
      );
      const alertStub = sinon.stub();
      element.addEventListener(EventType.SHOW_ALERT, alertStub);

      element.handleTopicChanged(new CustomEvent('test', {detail: newTopic}));

      assert.isTrue(
        setChangeTopicStub.calledWith(42 as NumericChangeId, newTopic)
      );
      await setChangeTopicStub.lastCall.returnValue;
      await waitUntilCalled(alertStub, 'alertStub');
      assert.deepEqual(alertStub.lastCall.args[0].detail, {
        message: 'Saving topic and reloading ...',
        showDismiss: true,
      });
    });

    test('topic removal', async () => {
      const newTopic = 'the new topic' as TopicName;
      const setChangeTopicStub = stubRestApi('setChangeTopic').returns(
        Promise.resolve(newTopic)
      );
      const alertStub = sinon.stub();
      element.addEventListener(EventType.SHOW_ALERT, alertStub);
      await element.updateComplete;
      const chip = queryAndAssert<GrLinkedChip>(element, 'gr-linked-chip');
      const remove = queryAndAssert<GrButton>(chip, '#remove');

      remove.click();

      assert.isTrue(chip?.disabled);
      assert.isTrue(setChangeTopicStub.calledWith(42 as NumericChangeId));
      await setChangeTopicStub.lastCall.returnValue;
      await waitUntilCalled(alertStub, 'alertStub');
      assert.deepEqual(alertStub.lastCall.args[0].detail, {
        message: 'Removing topic and reloading ...',
        showDismiss: true,
      });
    });

    test('changing hashtag', async () => {
      await element.updateComplete;
      const newHashtag: Hashtag[] = ['new hashtag' as Hashtag];
      const setChangeHashtagStub = stubRestApi('setChangeHashtag').returns(
        Promise.resolve(newHashtag)
      );
      const alertStub = sinon.stub();
      element.addEventListener(EventType.SHOW_ALERT, alertStub);
      element.handleHashtagChanged(
        new CustomEvent('test', {detail: 'new hashtag'})
      );
      assert.isTrue(
        setChangeHashtagStub.calledWith(42 as NumericChangeId, {
          add: ['new hashtag' as Hashtag],
        })
      );
      await setChangeHashtagStub.lastCall.returnValue;
      await waitUntilCalled(alertStub, 'alertStub');
      assert.deepEqual(alertStub.lastCall.args[0].detail, {
        message: 'Saving hashtag and reloading ...',
        showDismiss: true,
      });
    });
  });

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

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

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

  suite('plugin endpoints', () => {
    setup(async () => {
      element = await fixture(html`<gr-change-metadata></gr-change-metadata>`);
      element.change = createParsedChange();
      element.revision = createRevision();
      await element.updateComplete;
    });

    test('endpoint params', async () => {
      interface MetadataGrEndpointDecorator extends GrEndpointDecorator {
        plugin: PluginApi;
        change: ParsedChangeInfo;
        revision: RevisionInfo;
      }
      let plugin: PluginApi;
      window.Gerrit.install(
        p => {
          plugin = p;
        },
        '0.1',
        'http://some/plugins/url.js'
      );
      await element.updateComplete;
      const hookEl = (await plugin!
        .hook('change-metadata-item')
        .getLastAttached()) as MetadataGrEndpointDecorator;
      testResolver(pluginLoaderToken).loadPlugins([]);
      await element.updateComplete;
      assert.strictEqual(hookEl.plugin, plugin!);
      assert.strictEqual(hookEl.change, element.change);
      assert.strictEqual(hookEl.revision, element.revision);
    });
  });
});
