/**
 * @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 '../../plugins/gr-plugin-types';
import {GrEndpointDecorator} from '../../plugins/gr-endpoint-decorator/gr-endpoint-decorator';
import {stubRestApi} from '../../../test/test-utils.js';
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('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'},
              committer: {...createGitPerson(), email: 'ghi@def'},
            },
          },
        },
        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'}
        );
      });

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

      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';
        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', done => {
      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.html'
      );
      getPluginLoader().loadPlugins([]);
      flush(() => {
        assert.strictEqual(hookEl!.plugin, plugin);
        assert.strictEqual(hookEl!.change, element.change);
        assert.strictEqual(hookEl!.revision, element.revision);
        done();
      });
    });
  });
});
