/**
 * @license
 * Copyright 2016 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import '../../test/common-test-setup';
import {
  addListenerForTest,
  assertFails,
  makePrefixedJSON,
  MockPromise,
  mockPromise,
  waitEventLoop,
} from '../../test/test-utils';
import {GrReviewerUpdatesParser} from '../../elements/shared/gr-rest-api-interface/gr-reviewer-updates-parser';
import {listChangesOptionsToHex} from '../../utils/change-util';
import {
  createAccountDetailWithId,
  createAccountWithId,
  createChange,
  createComment,
  createEditInfo,
  createFixReplacementInfo,
  createParsedChange,
  createServerInfo,
  TEST_PROJECT_NAME,
} from '../../test/test-data-generators';
import {CURRENT} from '../../utils/patch-set-util';
import {GrRestApiServiceImpl} from './gr-rest-api-impl';
import {
  CommentSide,
  createDefaultEditPrefs,
  HttpMethod,
} from '../../constants/constants';
import {
  AccountDetailInfo,
  BasePatchSetNum,
  ChangeInfo,
  ChangeMessageId,
  CommentInfo,
  CommentInput,
  DashboardId,
  EDIT,
  Hashtag,
  ListChangesOption,
  NumericChangeId,
  PARENT,
  ParsedJSON,
  PatchSetNum,
  RepoName,
  RevisionPatchSetNum,
  RobotCommentInfo,
  Timestamp,
  UrlEncodedCommentId,
} from '../../types/common';
import {assert} from '@open-wc/testing';
import {AuthService} from '../gr-auth/gr-auth';
import {GrAuthMock} from '../gr-auth/gr-auth_mock';
import {FlagsServiceImplementation} from '../flags/flags_impl';

const EXPECTED_QUERY_OPTIONS = listChangesOptionsToHex(
  ListChangesOption.CHANGE_ACTIONS,
  // Current actions can be costly to calculate (e.g submit action)
  // They are not used in bulk actions.
  // ListChangesOption.CURRENT_ACTIONS,
  ListChangesOption.CURRENT_REVISION,
  ListChangesOption.DETAILED_LABELS,
  ListChangesOption.SUBMIT_REQUIREMENTS
);

suite('gr-rest-api-service-impl tests', () => {
  let element: GrRestApiServiceImpl;
  let authService: AuthService;

  let ctr = 0;
  let originalCanonicalPath: string | undefined;

  setup(() => {
    // Modify CANONICAL_PATH to effectively reset cache.
    ctr += 1;
    originalCanonicalPath = window.CANONICAL_PATH;
    window.CANONICAL_PATH = `test${ctr}`;

    const testJSON = ')]}\'\n{"hello": "bonjour"}';
    sinon.stub(window, 'fetch').resolves(new Response(testJSON));
    // fake auth
    authService = new GrAuthMock();
    sinon.stub(authService, 'authCheck').resolves(true);
    element = new GrRestApiServiceImpl(
      authService,
      new FlagsServiceImplementation()
    );

    element._projectLookup = {};
  });

  teardown(() => {
    window.CANONICAL_PATH = originalCanonicalPath;
  });

  test('parent diff comments are properly grouped', async () => {
    element.addRepoNameToCache(42 as NumericChangeId, TEST_PROJECT_NAME);
    sinon.stub(element._restApiHelper, 'fetchJSON').resolves({
      '/COMMIT_MSG': [],
      'sieve.go': [
        {
          updated: '2017-02-03 22:32:28.000000000',
          message: 'this isn’t quite right',
        },
        {
          side: CommentSide.PARENT,
          message: 'how did this work in the first place?',
          updated: '2017-02-03 22:33:28.000000000',
        },
      ],
    } as unknown as ParsedJSON);
    const obj = await element._getDiffComments(
      42 as NumericChangeId,
      '/comments',
      undefined,
      PARENT,
      1 as PatchSetNum,
      'sieve.go'
    );
    assert.equal(obj.baseComments.length, 1);
    assert.deepEqual(obj.baseComments[0], {
      side: CommentSide.PARENT,
      message: 'how did this work in the first place?',
      path: 'sieve.go',
      updated: '2017-02-03 22:33:28.000000000' as Timestamp,
    } as RobotCommentInfo);
    assert.equal(obj.comments.length, 1);
    assert.deepEqual(obj.comments[0], {
      message: 'this isn’t quite right',
      path: 'sieve.go',
      updated: '2017-02-03 22:32:28.000000000' as Timestamp,
    } as RobotCommentInfo);
  });

  test('_setRange', () => {
    const comments: CommentInfo[] = [
      {
        id: '1' as UrlEncodedCommentId,
        side: CommentSide.PARENT,
        message: 'how did this work in the first place?',
        updated: '2017-02-03 22:32:28.000000000' as Timestamp,
        range: {
          start_line: 1,
          start_character: 1,
          end_line: 2,
          end_character: 1,
        },
      },
      {
        id: '2' as UrlEncodedCommentId,
        in_reply_to: '1' as UrlEncodedCommentId,
        message: 'this isn’t quite right',
        updated: '2017-02-03 22:33:28.000000000' as Timestamp,
      },
    ];
    const expectedResult: CommentInfo = {
      id: '2' as UrlEncodedCommentId,
      in_reply_to: '1' as UrlEncodedCommentId,
      message: 'this isn’t quite right',
      updated: '2017-02-03 22:33:28.000000000' as Timestamp,
      range: {
        start_line: 1,
        start_character: 1,
        end_line: 2,
        end_character: 1,
      },
    };
    const comment = comments[1];
    assert.deepEqual(element._setRange(comments, comment), expectedResult);
  });

  test('_setRanges', () => {
    const comments: CommentInfo[] = [
      {
        id: '3' as UrlEncodedCommentId,
        in_reply_to: '2' as UrlEncodedCommentId,
        message: 'this isn’t quite right either',
        updated: '2017-02-03 22:34:28.000000000' as Timestamp,
      },
      {
        id: '2' as UrlEncodedCommentId,
        in_reply_to: '1' as UrlEncodedCommentId,
        message: 'this isn’t quite right',
        updated: '2017-02-03 22:33:28.000000000' as Timestamp,
      },
      {
        id: '1' as UrlEncodedCommentId,
        side: CommentSide.PARENT,
        message: 'how did this work in the first place?',
        updated: '2017-02-03 22:32:28.000000000' as Timestamp,
        range: {
          start_line: 1,
          start_character: 1,
          end_line: 2,
          end_character: 1,
        },
      },
    ];
    const expectedResult: CommentInfo[] = [
      {
        id: '1' as UrlEncodedCommentId,
        side: CommentSide.PARENT,
        message: 'how did this work in the first place?',
        updated: '2017-02-03 22:32:28.000000000' as Timestamp,
        range: {
          start_line: 1,
          start_character: 1,
          end_line: 2,
          end_character: 1,
        },
      },
      {
        id: '2' as UrlEncodedCommentId,
        in_reply_to: '1' as UrlEncodedCommentId,
        message: 'this isn’t quite right',
        updated: '2017-02-03 22:33:28.000000000' as Timestamp,
        range: {
          start_line: 1,
          start_character: 1,
          end_line: 2,
          end_character: 1,
        },
      },
      {
        id: '3' as UrlEncodedCommentId,
        in_reply_to: '2' as UrlEncodedCommentId,
        message: 'this isn’t quite right either',
        updated: '2017-02-03 22:34:28.000000000' as Timestamp,
        range: {
          start_line: 1,
          start_character: 1,
          end_line: 2,
          end_character: 1,
        },
      },
    ];
    assert.deepEqual(element._setRanges(comments), expectedResult);
  });

  test('differing patch diff comments are properly grouped', async () => {
    sinon.stub(element, 'getRepoName').resolves('test' as RepoName);
    sinon.stub(element._restApiHelper, 'fetchJSON').callsFake(async request => {
      const url = request.url;
      if (url === '/changes/test~42/revisions/1/comments') {
        return {
          '/COMMIT_MSG': [],
          'sieve.go': [
            {
              message: 'this isn’t quite right',
              updated: '2017-02-03 22:32:28.000000000',
            },
            {
              side: CommentSide.PARENT,
              message: 'how did this work in the first place?',
              updated: '2017-02-03 22:33:28.000000000',
            },
          ],
        } as unknown as ParsedJSON;
      } else if (url === '/changes/test~42/revisions/2/comments') {
        return {
          '/COMMIT_MSG': [],
          'sieve.go': [
            {
              message: 'What on earth are you thinking, here?',
              updated: '2017-02-03 22:32:28.000000000',
            },
            {
              side: CommentSide.PARENT,
              message: 'Yeah not sure how this worked either?',
              updated: '2017-02-03 22:33:28.000000000',
            },
            {
              message: '¯\\_(ツ)_/¯',
              updated: '2017-02-04 22:33:28.000000000',
            },
          ],
        } as unknown as ParsedJSON;
      }
      return undefined;
    });
    const obj = await element._getDiffComments(
      42 as NumericChangeId,
      '/comments',
      undefined,
      1 as BasePatchSetNum,
      2 as PatchSetNum,
      'sieve.go'
    );
    assert.equal(obj.baseComments.length, 1);
    assert.deepEqual(obj.baseComments[0], {
      message: 'this isn’t quite right',
      path: 'sieve.go',
      updated: '2017-02-03 22:32:28.000000000' as Timestamp,
    } as RobotCommentInfo);
    assert.equal(obj.comments.length, 2);
    assert.deepEqual(obj.comments[0], {
      message: 'What on earth are you thinking, here?',
      path: 'sieve.go',
      updated: '2017-02-03 22:32:28.000000000' as Timestamp,
    } as RobotCommentInfo);
    assert.deepEqual(obj.comments[1], {
      message: '¯\\_(ツ)_/¯',
      path: 'sieve.go',
      updated: '2017-02-04 22:33:28.000000000' as Timestamp,
    } as RobotCommentInfo);
  });

  test('legacy n,z key in change url is replaced', async () => {
    const stub = sinon
      .stub(element._restApiHelper, 'fetchJSON')
      .resolves([] as unknown as ParsedJSON);
    await element.getChanges(1, undefined, 'n,z');
    assert.equal(stub.lastCall.args[0].params!.S, 0);
  });

  test('saveDiffPreferences invalidates cache line', () => {
    const cacheKey = '/accounts/self/preferences.diff';
    const fetchStub = sinon.stub(element._restApiHelper, 'fetch');
    element._cache.set(cacheKey, {tab_size: 4} as unknown as ParsedJSON);
    element.saveDiffPreferences({
      tab_size: 8,
      ignore_whitespace: 'IGNORE_NONE',
    });
    assert.isTrue(fetchStub.called);
    assert.isFalse(element._cache.has(cacheKey));
  });

  suite('queryAccounts', () => {
    let fetchStub: sinon.SinonStub;
    const testProject = 'testproject';
    const testChangeNumber = 341682;
    setup(() => {
      fetchStub = sinon
        .stub(element._restApiHelper, 'fetch')
        .resolves(new Response(makePrefixedJSON(createAccountWithId())));
      element.addRepoNameToCache(
        testChangeNumber as NumericChangeId,
        testProject as RepoName
      );
    });

    test('url with just email', async () => {
      await element.queryAccounts('bro');
      assert.isTrue(fetchStub.calledOnce);
      assert.deepEqual(fetchStub.firstCall.args[0].params, {
        o: 'DETAILS',
        q: '"bro"',
      });
    });

    test('url with email and canSee changeId', async () => {
      await element.queryAccounts(
        'bro',
        undefined,
        testChangeNumber as NumericChangeId
      );
      assert.isTrue(fetchStub.calledOnce);
      assert.deepEqual(fetchStub.firstCall.args[0].params, {
        o: 'DETAILS',
        q: `"bro" and cansee:${testProject}~${testChangeNumber}`,
      });
    });

    test('url with email and canSee changeId and isActive', async () => {
      await element.queryAccounts(
        'bro',
        undefined,
        testChangeNumber as NumericChangeId,
        true
      );
      assert.isTrue(fetchStub.calledOnce);
      assert.deepEqual(fetchStub.firstCall.args[0].params, {
        o: 'DETAILS',
        q: `"bro" and cansee:${testProject}~${testChangeNumber} and is:active`,
      });
    });
  });

  test('getAccountSuggestions using suggest query param', () => {
    const fetchStub = sinon
      .stub(element._restApiHelper, 'fetch')
      .resolves(new Response());
    element.getAccountSuggestions('user');
    assert.isTrue(fetchStub.calledOnce);
    assert.deepEqual(fetchStub.firstCall.args[0].params, {
      suggest: undefined,
      q: 'user',
    });
  });

  test('getAccount when resp is undefined clears cache', async () => {
    const cacheKey = '/accounts/self/detail';
    const account = createAccountDetailWithId();
    element._cache.set(cacheKey, account as unknown as ParsedJSON);
    const stub = sinon
      .stub(element._restApiHelper, 'fetchCacheJSON')
      .callsFake(async req => {
        req.errFn!(undefined);
        return undefined;
      });
    assert.isTrue(element._cache.has(cacheKey));

    await element.getAccount();
    assert.isTrue(stub.called);
    assert.isFalse(element._cache.has(cacheKey));
  });

  test('getAccount when status is 403 clears cache', async () => {
    const cacheKey = '/accounts/self/detail';
    const account = createAccountDetailWithId();
    element._cache.set(cacheKey, account as unknown as ParsedJSON);
    const stub = sinon
      .stub(element._restApiHelper, 'fetchCacheJSON')
      .callsFake(async req => {
        req.errFn!(new Response(undefined, {status: 403}));
        return undefined;
      });
    assert.isTrue(element._cache.has(cacheKey));

    await element.getAccount();
    assert.isTrue(stub.called);
    assert.isFalse(element._cache.has(cacheKey));
  });

  test('getAccount when resp is successful updates cache', async () => {
    const cacheKey = '/accounts/self/detail';
    const account = createAccountDetailWithId();
    const stub = sinon
      .stub(element._restApiHelper, 'fetchCacheJSON')
      .callsFake(async () => {
        element._cache.set(cacheKey, account as unknown as ParsedJSON);
        return undefined;
      });
    assert.isFalse(element._cache.has(cacheKey));

    await element.getAccount();
    assert.isTrue(stub.called);
    assert.equal(
      element._cache.get(cacheKey),
      account as unknown as ParsedJSON
    );
  });

  const preferenceSetup = function (testJSON: unknown, loggedIn: boolean) {
    sinon
      .stub(element, 'getLoggedIn')
      .callsFake(() => Promise.resolve(loggedIn));
    sinon
      .stub(element._restApiHelper, 'fetchCacheJSON')
      .callsFake(() => Promise.resolve(testJSON as ParsedJSON));
  };

  test('getPreferences returns correctly logged in', async () => {
    const testJSON = {diff_view: 'SIDE_BY_SIDE'};
    const loggedIn = true;

    preferenceSetup(testJSON, loggedIn);

    const obj = await element.getPreferences();
    assert.equal(obj!.diff_view, 'SIDE_BY_SIDE');
  });

  test('getPreferences returns correctly on larger screens logged in', async () => {
    const testJSON = {diff_view: 'UNIFIED_DIFF'};
    const loggedIn = true;

    preferenceSetup(testJSON, loggedIn);

    const obj = await element.getPreferences();
    assert.equal(obj!.diff_view, 'UNIFIED_DIFF');
  });

  test('getPreferences returns correctly on larger screens no login', async () => {
    const testJSON = {diff_view: 'UNIFIED_DIFF'};
    const loggedIn = false;

    preferenceSetup(testJSON, loggedIn);

    const obj = await element.getPreferences();
    assert.equal(obj!.diff_view, 'SIDE_BY_SIDE');
  });

  test('savePreferences normalizes download scheme', () => {
    const fetchStub = sinon
      .stub(element._restApiHelper, 'fetch')
      .resolves(new Response());
    element.savePreferences({download_scheme: 'HTTP'});
    assert.isTrue(fetchStub.called);
    assert.equal(
      JSON.parse(fetchStub.lastCall.args[0].fetchOptions?.body as string)
        .download_scheme,
      'http'
    );
  });

  test('getDiffPreferences returns correct defaults', async () => {
    sinon.stub(element, 'getLoggedIn').callsFake(() => Promise.resolve(false));

    const obj = (await element.getDiffPreferences())!;
    assert.equal(obj.context, 10);
    assert.equal(obj.cursor_blink_rate, 0);
    assert.equal(obj.font_size, 12);
    assert.equal(obj.ignore_whitespace, 'IGNORE_NONE');
    assert.equal(obj.line_length, 100);
    assert.equal(obj.line_wrapping, false);
    assert.equal(obj.show_line_endings, true);
    assert.equal(obj.show_tabs, true);
    assert.equal(obj.show_whitespace_errors, true);
    assert.equal(obj.syntax_highlighting, true);
    assert.equal(obj.tab_size, 8);
  });

  test('saveDiffPreferences set show_tabs to false', () => {
    const fetchStub = sinon.stub(element._restApiHelper, 'fetch');
    element.saveDiffPreferences({
      show_tabs: false,
      ignore_whitespace: 'IGNORE_NONE',
    });
    assert.isTrue(fetchStub.called);
    assert.equal(
      JSON.parse(fetchStub.lastCall.args[0].fetchOptions?.body as string)
        .show_tabs,
      false
    );
  });

  test('getEditPreferences returns correct defaults', async () => {
    sinon.stub(element, 'getLoggedIn').callsFake(() => Promise.resolve(false));

    const obj = (await element.getEditPreferences())!;
    assert.equal(obj.auto_close_brackets, false);
    assert.equal(obj.cursor_blink_rate, 0);
    assert.equal(obj.hide_line_numbers, false);
    assert.equal(obj.hide_top_menu, false);
    assert.equal(obj.indent_unit, 2);
    assert.equal(obj.indent_with_tabs, false);
    assert.equal(obj.key_map_type, 'DEFAULT');
    assert.equal(obj.line_length, 100);
    assert.equal(obj.line_wrapping, false);
    assert.equal(obj.match_brackets, true);
    assert.equal(obj.show_base, false);
    assert.equal(obj.show_tabs, true);
    assert.equal(obj.show_whitespace_errors, true);
    assert.equal(obj.syntax_highlighting, true);
    assert.equal(obj.tab_size, 8);
    assert.equal(obj.theme, 'DEFAULT');
  });

  test('saveEditPreferences set show_tabs to false', () => {
    const fetchStub = sinon.stub(element._restApiHelper, 'fetch');
    element.saveEditPreferences({
      ...createDefaultEditPrefs(),
      show_tabs: false,
    });
    assert.isTrue(fetchStub.called);
    assert.equal(
      JSON.parse(fetchStub.lastCall.args[0].fetchOptions?.body as string)
        .show_tabs,
      false
    );
  });

  test('confirmEmail', () => {
    const fetchStub = sinon.stub(element._restApiHelper, 'fetch').resolves();
    element.confirmEmail('foo');
    assert.isTrue(fetchStub.calledOnce);
    assert.equal(
      fetchStub.lastCall.args[0].fetchOptions?.method,
      HttpMethod.PUT
    );
    assert.equal(
      fetchStub.lastCall.args[0].url,
      '/config/server/email.confirm'
    );
    assert.deepEqual(
      JSON.parse(fetchStub.lastCall.args[0].fetchOptions?.body as string),
      {token: 'foo'}
    );
  });

  test('setPreferredAccountEmail', async () => {
    const email1 = 'email1@example.com';
    const email2 = 'email2@example.com';
    const encodedEmail = encodeURIComponent(email2);
    const sendStub = sinon.stub(element._restApiHelper, 'fetch').resolves();
    element._cache.set('/accounts/self/emails', [
      {email: email1, preferred: true},
      {email: email2, preferred: false},
    ] as unknown as ParsedJSON);

    await element.setPreferredAccountEmail(email2);
    assert.isTrue(sendStub.calledOnce);
    assert.equal(
      sendStub.lastCall.args[0].fetchOptions?.method,
      HttpMethod.PUT
    );
    assert.equal(
      sendStub.lastCall.args[0].url,
      `/accounts/self/emails/${encodedEmail}/preferred`
    );
    assert.deepEqual(element._cache.get('/accounts/self/emails'), [
      {email: email1, preferred: false},
      {email: email2, preferred: true},
    ] as unknown as ParsedJSON);
  });

  test('setAccountUsername', async () => {
    const fetchStub = sinon
      .stub(element._restApiHelper, 'fetch')
      .resolves(new Response(makePrefixedJSON('john')));
    element._cache.set(
      '/accounts/self/detail',
      createAccountDetailWithId() as unknown as ParsedJSON
    );
    await element.setAccountUsername('john');
    assert.isTrue(fetchStub.calledOnce);
    assert.equal(
      fetchStub.lastCall.args[0].fetchOptions?.method,
      HttpMethod.PUT
    );
    assert.equal(fetchStub.lastCall.args[0].url, '/accounts/self/username');
    assert.deepEqual(
      JSON.parse(fetchStub.lastCall.args[0].fetchOptions?.body as string),
      {username: 'john'}
    );
    assert.deepEqual(
      (element._cache.get(
        '/accounts/self/detail'
      ) as unknown as AccountDetailInfo)!.username,
      'john'
    );
  });

  test('setAccountUsername empty unsets field', async () => {
    const fetchStub = sinon
      .stub(element._restApiHelper, 'fetch')
      .resolves(new Response(undefined, {status: 204}));
    element._cache.set('/accounts/self/detail', {
      ...createAccountDetailWithId(),
      username: 'john',
    } as unknown as ParsedJSON);
    await element.setAccountUsername('');
    assert.isTrue(fetchStub.calledOnce);
    assert.equal(
      fetchStub.lastCall.args[0].fetchOptions?.method,
      HttpMethod.PUT
    );
    assert.isUndefined(
      (element._cache.get(
        '/accounts/self/detail'
      ) as unknown as AccountDetailInfo)!.username
    );
  });

  test('setAccountDisplayName', async () => {
    const fetchStub = sinon
      .stub(element._restApiHelper, 'fetch')
      .resolves(new Response(makePrefixedJSON('john')));
    element._cache.set(
      '/accounts/self/detail',
      createAccountDetailWithId() as unknown as ParsedJSON
    );
    await element.setAccountDisplayName('john');
    assert.isTrue(fetchStub.calledOnce);
    assert.equal(
      fetchStub.lastCall.args[0].fetchOptions?.method,
      HttpMethod.PUT
    );
    assert.equal(fetchStub.lastCall.args[0].url, '/accounts/self/displayname');
    assert.deepEqual(
      JSON.parse(fetchStub.lastCall.args[0].fetchOptions?.body as string),
      {display_name: 'john'}
    );
    assert.deepEqual(
      (element._cache.get(
        '/accounts/self/detail'
      ) as unknown as AccountDetailInfo)!.display_name,
      'john'
    );
  });

  test('setAccountDisplayName empty unsets field', async () => {
    const fetchStub = sinon
      .stub(element._restApiHelper, 'fetch')
      .resolves(new Response(undefined, {status: 204}));
    element._cache.set('/accounts/self/detail', {
      ...createAccountDetailWithId(),
      display_name: 'john',
    } as unknown as ParsedJSON);
    await element.setAccountDisplayName('');
    assert.isTrue(fetchStub.calledOnce);
    assert.equal(
      fetchStub.lastCall.args[0].fetchOptions?.method,
      HttpMethod.PUT
    );
    assert.isUndefined(
      (element._cache.get(
        '/accounts/self/detail'
      ) as unknown as AccountDetailInfo)!.display_name
    );
  });

  test('setAccountName', async () => {
    const fetchStub = sinon
      .stub(element._restApiHelper, 'fetch')
      .resolves(new Response(makePrefixedJSON('john')));
    element._cache.set(
      '/accounts/self/detail',
      createAccountDetailWithId() as unknown as ParsedJSON
    );
    await element.setAccountName('john');
    assert.isTrue(fetchStub.calledOnce);
    assert.equal(
      fetchStub.lastCall.args[0].fetchOptions?.method,
      HttpMethod.PUT
    );
    assert.equal(fetchStub.lastCall.args[0].url, '/accounts/self/name');
    assert.deepEqual(
      JSON.parse(fetchStub.lastCall.args[0].fetchOptions?.body as string),
      {name: 'john'}
    );
    assert.deepEqual(
      (element._cache.get(
        '/accounts/self/detail'
      ) as unknown as AccountDetailInfo)!.name,
      'john'
    );
  });

  test('setAccountName empty unsets field', async () => {
    const fetchStub = sinon
      .stub(element._restApiHelper, 'fetch')
      .resolves(new Response(undefined, {status: 204}));
    element._cache.set('/accounts/self/detail', {
      ...createAccountDetailWithId(),
      name: 'john',
    } as unknown as ParsedJSON);
    await element.setAccountName('');
    assert.isTrue(fetchStub.calledOnce);
    assert.equal(
      fetchStub.lastCall.args[0].fetchOptions?.method,
      HttpMethod.PUT
    );
    assert.isUndefined(
      (element._cache.get(
        '/accounts/self/detail'
      ) as unknown as AccountDetailInfo)!.name
    );
  });

  test('setAccountStatus', async () => {
    const fetchStub = sinon
      .stub(element._restApiHelper, 'fetch')
      .resolves(new Response(makePrefixedJSON('OOO')));
    element._cache.set(
      '/accounts/self/detail',
      createAccountDetailWithId() as unknown as ParsedJSON
    );
    await element.setAccountStatus('OOO');
    assert.isTrue(fetchStub.calledOnce);
    assert.equal(
      fetchStub.lastCall.args[0].fetchOptions?.method,
      HttpMethod.PUT
    );
    assert.equal(fetchStub.lastCall.args[0].url, '/accounts/self/status');
    assert.deepEqual(
      JSON.parse(fetchStub.lastCall.args[0].fetchOptions?.body as string),
      {status: 'OOO'}
    );
    assert.deepEqual(
      (element._cache.get(
        '/accounts/self/detail'
      ) as unknown as AccountDetailInfo)!.status,
      'OOO'
    );
  });

  test('setAccountStatus empty unsets field', async () => {
    const fetchStub = sinon
      .stub(element._restApiHelper, 'fetch')
      .resolves(new Response(undefined, {status: 204}));
    element._cache.set('/accounts/self/detail', {
      ...createAccountDetailWithId(),
      status: 'OOO',
    } as unknown as ParsedJSON);
    await element.setAccountStatus('');
    assert.isTrue(fetchStub.calledOnce);
    assert.equal(
      fetchStub.lastCall.args[0].fetchOptions?.method,
      HttpMethod.PUT
    );
    assert.isUndefined(
      (element._cache.get(
        '/accounts/self/detail'
      ) as unknown as AccountDetailInfo)!.status
    );
  });

  suite('draft comments', () => {
    test('_sendDiffDraftRequest pending requests tracked', async () => {
      const obj = element._pendingRequests;
      const promises: MockPromise<string>[] = [];
      sinon.stub(element, '_changeBaseURL').callsFake(() => {
        promises.push(mockPromise<string>());
        return promises[promises.length - 1];
      });
      const fetchStub = sinon
        .stub(element._restApiHelper, 'fetch')
        .resolves(new Response(undefined, {status: 201}));
      const draft: CommentInput = {
        id: 'draft-id' as UrlEncodedCommentId,
        message: 'draft message',
      };
      assert.isFalse(!!element.hasPendingDiffDrafts());

      element._sendDiffDraftRequest(
        HttpMethod.PUT,
        123 as NumericChangeId,
        1 as PatchSetNum,
        draft
      );
      assert.equal(obj.sendDiffDraft.length, 1);
      assert.isTrue(!!element.hasPendingDiffDrafts());

      element._sendDiffDraftRequest(
        HttpMethod.PUT,
        123 as NumericChangeId,
        1 as PatchSetNum,
        draft
      );
      assert.equal(obj.sendDiffDraft.length, 2);
      assert.isTrue(!!element.hasPendingDiffDrafts());

      for (const promise of promises) {
        promise.resolve('');
      }

      await element.awaitPendingDiffDrafts();
      assert.equal(obj.sendDiffDraft.length, 0);
      assert.isFalse(!!element.hasPendingDiffDrafts());

      assert.isTrue(fetchStub.called);
      assert.deepEqual(
        JSON.parse(fetchStub.lastCall.args[0].fetchOptions?.body as string),
        draft
      );
    });

    suite('_failForCreate200', () => {
      test('_sendDiffDraftRequest checks for 200 on create', async () => {
        element.addRepoNameToCache(123 as NumericChangeId, TEST_PROJECT_NAME);
        sinon.stub(element._restApiHelper, 'fetch').resolves(new Response());
        const failStub = sinon.stub(element, '_failForCreate200').resolves();
        await element._sendDiffDraftRequest(
          HttpMethod.PUT,
          123 as NumericChangeId,
          4 as PatchSetNum,
          {}
        );
        assert.isTrue(failStub.calledOnce);
      });

      test('_sendDiffDraftRequest no checks for 200 on non create', async () => {
        element.addRepoNameToCache(123 as NumericChangeId, TEST_PROJECT_NAME);
        sinon.stub(element._restApiHelper, 'fetch').resolves(new Response());
        const failStub = sinon.stub(element, '_failForCreate200').resolves();
        await element._sendDiffDraftRequest(
          HttpMethod.PUT,
          123 as NumericChangeId,
          4 as PatchSetNum,
          {
            id: '123' as UrlEncodedCommentId,
          }
        );
        assert.isFalse(failStub.called);
      });

      test('_failForCreate200 fails on 200', async () => {
        const result = new Response(undefined, {
          status: 200,
          headers: {
            'Set-CoOkiE': 'secret',
            Innocuous: 'hello',
          },
        });
        const error = await assertFails<Error>(
          element._failForCreate200(Promise.resolve(result))
        );
        assert.isOk(error);
        assert.include(error.message, 'Saving draft resulted in HTTP 200');
        assert.include(error.message, 'hello');
        assert.notInclude(error.message, 'secret');
      });

      test('_failForCreate200 does not fail on 201', () => {
        const result = new Response(undefined, {status: 201});
        return element._failForCreate200(Promise.resolve(result));
      });
    });
  });

  test('saveChangeEdit', async () => {
    element._projectLookup = {1: Promise.resolve('test' as RepoName)};
    const change_num = 1 as NumericChangeId;
    const file_name = 'index.php';
    const file_contents = '<?php';
    const fetchStub = sinon.stub(element._restApiHelper, 'fetch').resolves();
    element._cache.set(
      `/changes/${change_num}/edit/${file_name}`,
      {} as unknown as ParsedJSON
    );
    await element.saveChangeEdit(change_num, file_name, file_contents);
    assert.isTrue(fetchStub.calledOnce);
    assert.equal(
      fetchStub.lastCall.args[0].fetchOptions?.method,
      HttpMethod.PUT
    );
    assert.equal(
      fetchStub.lastCall.args[0].url,
      '/changes/test~1/edit/' + file_name
    );
    assert.equal(fetchStub.lastCall.args[0].fetchOptions?.body, file_contents);
  });

  test('putChangeCommitMessage', async () => {
    element._projectLookup = {1: Promise.resolve('test' as RepoName)};
    const change_num = 1 as NumericChangeId;
    const message = 'this is a commit message';
    const committer_email = 'test@example.com';
    const fetchStub = sinon.stub(element._restApiHelper, 'fetch').resolves();
    element._cache.set(
      `/changes/${change_num}/message`,
      {} as unknown as ParsedJSON
    );
    await element.putChangeCommitMessage(change_num, message, committer_email);
    assert.isTrue(fetchStub.calledOnce);
    assert.equal(
      fetchStub.lastCall.args[0].fetchOptions?.method,
      HttpMethod.PUT
    );
    assert.equal(fetchStub.lastCall.args[0].url, '/changes/test~1/message');
    assert.deepEqual(
      JSON.parse(fetchStub.lastCall.args[0].fetchOptions?.body as string),
      {
        message,
        committer_email,
      }
    );
  });

  test('updateIdentityInChangeEdit', async () => {
    element._projectLookup = {1: Promise.resolve('test' as RepoName)};
    const change_num = 1 as NumericChangeId;
    const name = 'user';
    const email = 'user@example.com';
    const type = 'AUTHOR';
    const fetchStub = sinon.stub(element._restApiHelper, 'fetch').resolves();
    await element.updateIdentityInChangeEdit(change_num, name, email, type);
    assert.isTrue(fetchStub.calledOnce);
    assert.equal(
      fetchStub.lastCall.args[0].fetchOptions?.method,
      HttpMethod.PUT
    );
    assert.equal(
      fetchStub.lastCall.args[0].url,
      '/changes/test~1/edit:identity'
    );
    assert.deepEqual(
      JSON.parse(fetchStub.lastCall.args[0].fetchOptions?.body as string),
      {
        email: 'user@example.com',
        name: 'user',
        type: 'AUTHOR',
      }
    );
  });

  test('deleteChangeCommitMessage', async () => {
    element._projectLookup = {1: Promise.resolve('test' as RepoName)};
    const change_num = 1 as NumericChangeId;
    const messageId = 'abc' as ChangeMessageId;
    const fetchStub = sinon.stub(element._restApiHelper, 'fetch').resolves();
    await element.deleteChangeCommitMessage(change_num, messageId);
    assert.isTrue(fetchStub.calledOnce);
    assert.equal(
      fetchStub.lastCall.args[0].fetchOptions?.method,
      HttpMethod.DELETE
    );
    assert.equal(
      fetchStub.lastCall.args[0].url,
      '/changes/test~1/messages/abc'
    );
  });

  test('startWorkInProgress', async () => {
    element.addRepoNameToCache(42 as NumericChangeId, TEST_PROJECT_NAME);
    const fetchStub = sinon
      .stub(element._restApiHelper, 'fetch')
      .resolves(new Response());
    const urlSpy = sinon.spy(element, '_changeBaseURL');
    await element.startWorkInProgress(42 as NumericChangeId);
    assert.isTrue(fetchStub.calledOnce);
    assert.isTrue(urlSpy.calledOnce);
    assert.equal(urlSpy.lastCall.args[0], 42 as NumericChangeId);
    assert.isNotOk(urlSpy.lastCall.args[1]);
    assert.equal(
      fetchStub.lastCall.args[0].fetchOptions?.method,
      HttpMethod.POST
    );
    assert.isTrue(fetchStub.lastCall.args[0].url.endsWith('/wip'));
    assert.deepEqual(
      JSON.parse(fetchStub.lastCall.args[0].fetchOptions?.body as string),
      {}
    );

    await element.startWorkInProgress(42 as NumericChangeId, 'revising...');
    assert.isTrue(fetchStub.calledTwice);
    assert.equal(urlSpy.lastCall.args[0], 42 as NumericChangeId);
    assert.isNotOk(urlSpy.lastCall.args[1]);
    assert.equal(
      fetchStub.lastCall.args[0].fetchOptions?.method,
      HttpMethod.POST
    );
    assert.isTrue(fetchStub.lastCall.args[0].url.endsWith('/wip'));
    assert.deepEqual(
      JSON.parse(fetchStub.lastCall.args[0].fetchOptions?.body as string),
      {
        message: 'revising...',
      }
    );
  });

  test('deleteComment', async () => {
    element.addRepoNameToCache(123 as NumericChangeId, TEST_PROJECT_NAME);
    const comment = createComment();
    const fetchStub = sinon
      .stub(element._restApiHelper, 'fetchJSON')
      .resolves(comment as unknown as ParsedJSON);
    const response = await element.deleteComment(
      123 as NumericChangeId,
      1 as PatchSetNum,
      '01234' as UrlEncodedCommentId,
      'removal reason'
    );
    assert.equal(response, comment);
    assert.isTrue(fetchStub.calledOnce);
    assert.equal(
      fetchStub.lastCall.args[0].fetchOptions?.method,
      HttpMethod.POST
    );
    assert.equal(
      fetchStub.lastCall.args[0].url,
      '/changes/test-project~123/revisions/1/comments/01234/delete'
    );
    assert.deepEqual(
      JSON.parse(fetchStub.lastCall.args[0].fetchOptions?.body as string),
      {
        reason: 'removal reason',
      }
    );
  });

  test('createRepo encodes name', async () => {
    const fetchStub = sinon.stub(element._restApiHelper, 'fetch').resolves();
    await element.createRepo({name: 'x/y' as RepoName});
    assert.isTrue(fetchStub.calledOnce);
    assert.equal(fetchStub.lastCall.args[0].url, '/projects/x%2Fy');
  });

  test('queryChangeFiles', async () => {
    element.addRepoNameToCache(42 as NumericChangeId, TEST_PROJECT_NAME);
    const fetchStub = sinon
      .stub(element._restApiHelper, 'fetchJSON')
      .resolves();
    await element.queryChangeFiles(42 as NumericChangeId, EDIT, 'test/path.js');
    assert.equal(
      fetchStub.lastCall.args[0].url,
      '/changes/test-project~42/revisions/edit/files?q=test%2Fpath.js'
    );
  });

  test('normal use', () => {
    const defaultQuery = '';

    assert.equal(
      element._getReposUrl('test', 25).toString(),
      [false, '/projects/?n=26&S=0&d=&m=test'].toString()
    );

    assert.equal(
      element._getReposUrl(undefined, 25).toString(),
      [false, `/projects/?n=26&S=0&d=&m=${defaultQuery}`].toString()
    );

    assert.equal(
      element._getReposUrl('test', 25, 25).toString(),
      [false, '/projects/?n=26&S=25&d=&m=test'].toString()
    );

    assert.equal(
      element._getReposUrl('inname:test', 25, 25).toString(),
      [true, '/projects/?n=26&S=25&query=inname%3Atest'].toString()
    );
  });

  test('invalidateReposCache', () => {
    const url = '/projects/?n=26&S=0&query=test';

    element._cache.set(url, {} as unknown as ParsedJSON);

    element.invalidateReposCache();

    assert.isUndefined(element._sharedFetchPromises.get(url));

    assert.isFalse(element._cache.has(url));
  });

  test('invalidateAccountsCache', () => {
    const url = '/accounts/self/detail';

    element._cache.set(url, {} as unknown as ParsedJSON);

    element.invalidateAccountsCache();

    assert.isUndefined(element._sharedFetchPromises.get(url));

    assert.isFalse(element._cache.has(url));
  });

  suite('getRepos', () => {
    const defaultQuery = '';
    let fetchCacheJSONStub: sinon.SinonStub;
    setup(() => {
      fetchCacheJSONStub = sinon
        .stub(element._restApiHelper, 'fetchCacheJSON')
        .resolves([] as unknown as ParsedJSON);
    });

    test('normal use', () => {
      element.getRepos('test', 25);
      assert.equal(
        fetchCacheJSONStub.lastCall.args[0].url,
        '/projects/?n=26&S=0&d=&m=test'
      );

      element.getRepos(undefined, 25);
      assert.equal(
        fetchCacheJSONStub.lastCall.args[0].url,
        `/projects/?n=26&S=0&d=&m=${defaultQuery}`
      );

      element.getRepos('test', 25, 25);
      assert.equal(
        fetchCacheJSONStub.lastCall.args[0].url,
        '/projects/?n=26&S=25&d=&m=test'
      );
    });

    test('with blank', () => {
      element.getRepos('test/test', 25);
      assert.equal(
        fetchCacheJSONStub.lastCall.args[0].url,
        '/projects/?n=26&S=0&d=&m=test%2Ftest'
      );
    });

    test('with hyphen', () => {
      element.getRepos('foo-bar', 25);
      assert.equal(
        fetchCacheJSONStub.lastCall.args[0].url,
        '/projects/?n=26&S=0&d=&m=foo-bar'
      );
    });

    test('with leading hyphen', () => {
      element.getRepos('-bar', 25);
      assert.equal(
        fetchCacheJSONStub.lastCall.args[0].url,
        '/projects/?n=26&S=0&d=&m=-bar'
      );
    });

    test('with trailing hyphen', () => {
      element.getRepos('foo-bar-', 25);
      assert.equal(
        fetchCacheJSONStub.lastCall.args[0].url,
        '/projects/?n=26&S=0&d=&m=foo-bar-'
      );
    });

    test('with underscore', () => {
      element.getRepos('foo_bar', 25);
      assert.equal(
        fetchCacheJSONStub.lastCall.args[0].url,
        '/projects/?n=26&S=0&d=&m=foo_bar'
      );
    });

    test('with underscore', () => {
      element.getRepos('foo_bar', 25);
      assert.equal(
        fetchCacheJSONStub.lastCall.args[0].url,
        '/projects/?n=26&S=0&d=&m=foo_bar'
      );
    });

    test('hyphen only', () => {
      element.getRepos('-', 25);
      assert.equal(
        fetchCacheJSONStub.lastCall.args[0].url,
        '/projects/?n=26&S=0&d=&m=-'
      );
    });

    test('using query', () => {
      element.getRepos('description:project', 25);
      assert.equal(
        fetchCacheJSONStub.lastCall.args[0].url,
        '/projects/?n=26&S=0&query=description%3Aproject'
      );
    });
  });

  test('_getGroupsUrl normal use', () => {
    assert.equal(element._getGroupsUrl('test', 25), '/groups/?n=26&S=0&m=test');

    assert.equal(element._getGroupsUrl('', 25), '/groups/?n=26&S=0');

    assert.equal(
      element._getGroupsUrl('test', 25, 25),
      '/groups/?n=26&S=25&m=test'
    );
  });

  test('invalidateGroupsCache', () => {
    const url = '/groups/?n=26&S=0&m=test';

    element._cache.set(url, {} as unknown as ParsedJSON);

    element.invalidateGroupsCache();

    assert.isUndefined(element._sharedFetchPromises.get(url));

    assert.isFalse(element._cache.has(url));
  });

  suite('getGroups', () => {
    let fetchCacheJSONStub: sinon.SinonStub;
    setup(() => {
      fetchCacheJSONStub = sinon.stub(element._restApiHelper, 'fetchCacheJSON');
    });

    test('normal use', () => {
      element.getGroups('test', 25);
      assert.equal(
        fetchCacheJSONStub.lastCall.args[0].url,
        '/groups/?n=26&S=0&m=test'
      );

      element.getGroups('', 25);
      assert.equal(
        fetchCacheJSONStub.lastCall.args[0].url,
        '/groups/?n=26&S=0'
      );

      element.getGroups('test', 25, 25);
      assert.equal(
        fetchCacheJSONStub.lastCall.args[0].url,
        '/groups/?n=26&S=25&m=test'
      );
    });

    test('regex', () => {
      element.getGroups('^test.*', 25);
      assert.equal(
        fetchCacheJSONStub.lastCall.args[0].url,
        '/groups/?n=26&S=0&r=%5Etest.*'
      );

      element.getGroups('^test.*', 25, 25);
      assert.equal(
        fetchCacheJSONStub.lastCall.args[0].url,
        '/groups/?n=26&S=25&r=%5Etest.*'
      );
    });
  });

  test('gerrit auth is used', () => {
    const fetchStub = sinon.stub(authService, 'fetch').resolves();
    element._restApiHelper.fetchJSON({url: 'foo'});
    assert(fetchStub.called);
  });

  test('queryAccounts does not return fetchJSON', async () => {
    const fetchJSONSpy = sinon.spy(element._restApiHelper, 'fetchJSON');
    const accts = await element.queryAccounts('');
    assert.isFalse(fetchJSONSpy.called);
    assert.equal(accts!.length, 0);
  });

  test('fetchJSON gets called by queryAccounts', async () => {
    const fetchJSONStub = sinon
      .stub(element._restApiHelper, 'fetchJSON')
      .resolves();
    await element.queryAccounts('own');
    assert.deepEqual(fetchJSONStub.lastCall.args[0].params, {
      q: '"own"',
      o: 'DETAILS',
    });
  });

  suite('getChangeDetail', () => {
    let getConfigStub: sinon.SinonStub;

    setup(() => {
      getConfigStub = sinon
        .stub(element, 'getConfig')
        .resolves(createServerInfo());
    });

    suite('change detail options', () => {
      let changeDetailStub: sinon.SinonStub;
      setup(() => {
        changeDetailStub = sinon
          .stub(element, '_getChangeDetail')
          .resolves({...createChange(), _number: 123 as NumericChangeId});
      });

      test('signed pushes disabled', async () => {
        getConfigStub.resolves({
          ...createServerInfo(),
          receive: {enable_signed_push: undefined},
        });
        const change = await element.getChangeDetail(123 as NumericChangeId);
        assert.strictEqual(123, change!._number);
        const options = changeDetailStub.firstCall.args[1];
        assert.isNotOk(
          parseInt(options, 16) & (1 << ListChangesOption.PUSH_CERTIFICATES)
        );
      });

      test('signed pushes enabled', async () => {
        getConfigStub.resolves({
          ...createServerInfo(),
          receive: {enable_signed_push: 'true'},
        });
        const change = await element.getChangeDetail(123 as NumericChangeId);
        assert.strictEqual(123, change!._number);
        const options = changeDetailStub.firstCall.args[1];
        assert.ok(
          parseInt(options, 16) & (1 << ListChangesOption.PUSH_CERTIFICATES)
        );
      });
    });

    test('GrReviewerUpdatesParser.parse is used', async () => {
      element.addRepoNameToCache(42 as NumericChangeId, TEST_PROJECT_NAME);
      const changeInfo = createParsedChange();
      const parseStub = sinon
        .stub(GrReviewerUpdatesParser, 'parse')
        .resolves(changeInfo);
      const result = await element.getChangeDetail(42 as NumericChangeId);
      assert.isTrue(parseStub.calledOnce);
      assert.equal(result, changeInfo);
    });

    test('_getChangeDetail passes params to ETags decorator', async () => {
      const changeNum = 4321 as NumericChangeId;
      element._projectLookup[changeNum] = Promise.resolve('test' as RepoName);
      const expectedUrl = `${window.CANONICAL_PATH}/changes/test~4321/detail?O=516714`;
      const optionsStub = sinon.stub(element._etags, 'getOptions');
      const collectStub = sinon.stub(element._etags, 'collect');
      sinon.stub(element._restApiHelper, 'fetch').resolves(
        new Response(
          makePrefixedJSON({
            ...createChange(),
            _number: 123 as NumericChangeId,
          })
        )
      );
      await element._getChangeDetail(changeNum, '516714');
      assert.isTrue(optionsStub.calledWithExactly(expectedUrl));
      assert.equal(collectStub.lastCall.args[0], expectedUrl);
    });

    test('_getChangeDetail calls errFn on 500', async () => {
      const errFn = sinon.stub();
      sinon.stub(element, 'getChangeActionURL').resolves('');
      sinon
        .stub(element._restApiHelper, 'fetch')
        .resolves(new Response(undefined, {status: 500}));
      await element._getChangeDetail(123 as NumericChangeId, '516714', errFn);
      assert.isTrue(errFn.called);
    });

    test('_getChangeDetail populates _projectLookup', async () => {
      sinon.stub(element, 'getChangeActionURL').resolves('');
      sinon.stub(element._restApiHelper, 'fetch').resolves(
        new Response(')]}\'{"_number":1,"project":"test"}', {
          status: 200,
        })
      );
      await element._getChangeDetail(1 as NumericChangeId, '516714');
      assert.equal(Object.keys(element._projectLookup).length, 1);
      const project = await element._projectLookup[1];
      assert.equal(project, 'test' as RepoName);
    });

    suite('_getChangeDetail ETag cache', () => {
      let requestUrl: string;
      let mockResponseSerial: string;
      let collectSpy: sinon.SinonSpy;

      setup(() => {
        requestUrl = '/foo/bar';
        const mockResponse = {foo: 'bar', baz: 42};
        mockResponseSerial = makePrefixedJSON(mockResponse);
        sinon.stub(element._restApiHelper, 'urlWithParams').returns(requestUrl);
        sinon.stub(element, 'getChangeActionURL').resolves(requestUrl);
        collectSpy = sinon.spy(element._etags, 'collect');
      });

      test('contributes to cache', async () => {
        const getPayloadSpy = sinon.spy(element._etags, 'getCachedPayload');
        sinon.stub(element._restApiHelper, 'fetch').resolves(
          new Response(mockResponseSerial, {
            status: 200,
          })
        );

        await element._getChangeDetail(123 as NumericChangeId, '516714');
        assert.isFalse(getPayloadSpy.called);
        assert.isTrue(collectSpy.calledOnce);
        const cachedResponse = element._etags.getCachedPayload(requestUrl);
        assert.equal(cachedResponse, mockResponseSerial);
      });

      test('uses cache on HTTP 304', async () => {
        const getPayloadStub = sinon.stub(element._etags, 'getCachedPayload');
        getPayloadStub.returns(mockResponseSerial);
        sinon.stub(element._restApiHelper, 'fetch').resolves(
          new Response(undefined, {
            status: 304,
          })
        );

        await element._getChangeDetail(123 as NumericChangeId, '');
        assert.isFalse(collectSpy.called);
        assert.isTrue(getPayloadStub.calledOnce);
      });
    });
  });

  test('addRepoNameToCache', async () => {
    element.addRepoNameToCache(555 as NumericChangeId, 'project' as RepoName);
    const project = await element.getRepoName(555 as NumericChangeId);
    assert.deepEqual(project, 'project' as RepoName);
  });

  suite('getRepoName', () => {
    const changeNum = 555 as NumericChangeId;
    const repo = 'test-repo' as RepoName;

    test('getChange fails to yield a project', async () => {
      const promise = mockPromise<undefined>();
      sinon.stub(element, 'getChange').returns(promise);

      const projectLookup = element.getRepoName(changeNum);
      promise.resolve(undefined);

      const err: Error = await assertFails(projectLookup);
      assert.equal(
        err.message,
        'Failed to lookup the repo for change number 555'
      );
    });

    test('getChange succeeds with project', async () => {
      const promise = mockPromise<undefined | ChangeInfo>();
      sinon.stub(element, 'getChange').returns(promise);

      const projectLookup = element.getRepoName(changeNum);
      promise.resolve({...createChange(), project: repo});

      assert.equal(await projectLookup, repo);
      assert.deepEqual(element._projectLookup, {'555': projectLookup});
    });

    test('getChange fails, but a addRepoNameToCache() call is used as fallback', async () => {
      const promise = mockPromise<undefined>();
      sinon.stub(element, 'getChange').returns(promise);

      const projectLookup = element.getRepoName(changeNum);
      element.addRepoNameToCache(changeNum, repo);
      promise.resolve(undefined);

      assert.equal(await projectLookup, repo);
    });
  });

  suite('getChanges populates _projectLookup', () => {
    test('multiple queries', async () => {
      sinon.stub(element._restApiHelper, 'fetchJSON').resolves([
        [
          {_number: 1, project: 'test'},
          {_number: 2, project: 'test'},
        ],
        [{_number: 3, project: 'test/test'}],
      ] as unknown as ParsedJSON);
      // When query instanceof Array, fetchJSON returns
      // Array<Array<Object>>.
      await element.getChangesForMultipleQueries(undefined, []);
      assert.equal(Object.keys(element._projectLookup).length, 3);
      const project1 = await element.getRepoName(1 as NumericChangeId);
      assert.equal(project1, 'test' as RepoName);
      const project2 = await element.getRepoName(2 as NumericChangeId);
      assert.equal(project2, 'test' as RepoName);
      const project3 = await element.getRepoName(3 as NumericChangeId);
      assert.equal(project3, 'test/test' as RepoName);
    });

    test('no query', async () => {
      sinon.stub(element._restApiHelper, 'fetchJSON').resolves([
        {_number: 1, project: 'test'},
        {_number: 2, project: 'test'},
        {_number: 3, project: 'test/test'},
      ] as unknown as ParsedJSON);

      // When query !instanceof Array, fetchJSON returns Array<Object>.
      await element.getChanges();
      assert.equal(Object.keys(element._projectLookup).length, 3);
      const project1 = await element.getRepoName(1 as NumericChangeId);
      assert.equal(project1, 'test' as RepoName);
      const project2 = await element.getRepoName(2 as NumericChangeId);
      assert.equal(project2, 'test' as RepoName);
      const project3 = await element.getRepoName(3 as NumericChangeId);
      assert.equal(project3, 'test/test' as RepoName);
    });
  });

  test('getDetailedChangesWithActions', async () => {
    const c1 = createChange();
    c1._number = 1 as NumericChangeId;
    const c2 = createChange();
    c2._number = 2 as NumericChangeId;
    const getChangesStub = sinon
      .stub(element, 'getChanges')
      .callsFake((changesPerPage, query, offset, options) => {
        assert.isUndefined(changesPerPage);
        assert.strictEqual(query, 'change:1 OR change:2');
        assert.isUndefined(offset);
        assert.strictEqual(options, EXPECTED_QUERY_OPTIONS);
        return Promise.resolve([]);
      });
    await element.getDetailedChangesWithActions([c1._number, c2._number]);
    assert.isTrue(getChangesStub.calledOnce);
  });

  test('setChangeTopic', async () => {
    element.addRepoNameToCache(123 as NumericChangeId, TEST_PROJECT_NAME);
    const fetchStub = sinon
      .stub(element._restApiHelper, 'fetch')
      .resolves(new Response(makePrefixedJSON('foo-bar')));
    await element.setChangeTopic(123 as NumericChangeId, 'foo-bar');
    assert.isTrue(fetchStub.calledOnce);
    assert.deepEqual(
      JSON.parse(fetchStub.lastCall.args[0].fetchOptions?.body as string),
      {topic: 'foo-bar'}
    );
  });

  test('setChangeHashtag', async () => {
    element.addRepoNameToCache(123 as NumericChangeId, TEST_PROJECT_NAME);
    const fetchStub = sinon.stub(element._restApiHelper, 'fetchJSON');
    await element.setChangeHashtag(123 as NumericChangeId, {
      add: ['foo-bar' as Hashtag],
    });
    assert.isTrue(fetchStub.calledOnce);
    assert.sameDeepMembers(
      JSON.parse(fetchStub.lastCall.args[0].fetchOptions?.body as string).add!,
      ['foo-bar']
    );
  });

  test('generateAccountHttpPassword', async () => {
    const fetchStub = sinon
      .stub(element._restApiHelper, 'fetchJSON')
      .resolves();
    await element.generateAccountHttpPassword();
    assert.isTrue(fetchStub.calledOnce);
    assert.deepEqual(
      JSON.parse(fetchStub.lastCall.args[0].fetchOptions?.body as string),
      {generate: true}
    );
  });

  suite('getChangeFiles', () => {
    test('patch only', async () => {
      element.addRepoNameToCache(123 as NumericChangeId, TEST_PROJECT_NAME);
      const fetchStub = sinon
        .stub(element._restApiHelper, 'fetchJSON')
        .resolves();
      const range = {basePatchNum: PARENT, patchNum: 2 as RevisionPatchSetNum};
      await element.getChangeFiles(123 as NumericChangeId, range);
      assert.isTrue(fetchStub.calledOnce);
      assert.equal(
        fetchStub.lastCall.args[0].url,
        '/changes/test-project~123/revisions/2/files'
      );
      assert.isNotOk(fetchStub.lastCall.args[0].params);
    });

    test('simple range', async () => {
      element.addRepoNameToCache(123 as NumericChangeId, TEST_PROJECT_NAME);
      const fetchStub = sinon
        .stub(element._restApiHelper, 'fetchJSON')
        .resolves();
      const range = {
        basePatchNum: 4 as BasePatchSetNum,
        patchNum: 5 as RevisionPatchSetNum,
      };
      await element.getChangeFiles(123 as NumericChangeId, range);
      assert.isTrue(fetchStub.calledOnce);
      assert.equal(
        fetchStub.lastCall.args[0].url,
        '/changes/test-project~123/revisions/5/files'
      );
      assert.isOk(fetchStub.lastCall.args[0].params);
      assert.equal(fetchStub.lastCall.args[0].params!.base, 4);
      assert.isNotOk(fetchStub.lastCall.args[0].params!.parent);
    });

    test('parent index', async () => {
      element.addRepoNameToCache(123 as NumericChangeId, TEST_PROJECT_NAME);
      const fetchStub = sinon
        .stub(element._restApiHelper, 'fetchJSON')
        .resolves();
      const range = {
        basePatchNum: -3 as BasePatchSetNum,
        patchNum: 5 as RevisionPatchSetNum,
      };
      await element.getChangeFiles(123 as NumericChangeId, range);
      assert.isTrue(fetchStub.calledOnce);
      assert.equal(
        fetchStub.lastCall.args[0].url,
        '/changes/test-project~123/revisions/5/files'
      );
      assert.isOk(fetchStub.lastCall.args[0].params);
      assert.isNotOk(fetchStub.lastCall.args[0].params!.base);
      assert.equal(fetchStub.lastCall.args[0].params!.parent, 3);
    });
  });

  suite('getDiff', () => {
    test('patchOnly', async () => {
      element.addRepoNameToCache(123 as NumericChangeId, TEST_PROJECT_NAME);
      const fetchStub = sinon
        .stub(element._restApiHelper, 'fetchJSON')
        .resolves();
      await element.getDiff(
        123 as NumericChangeId,
        PARENT,
        2 as PatchSetNum,
        'foo/bar.baz'
      );
      assert.isTrue(fetchStub.calledOnce);
      assert.equal(
        fetchStub.lastCall.args[0].url,
        '/changes/test-project~123/revisions/2/files/foo%2Fbar.baz/diff'
      );
      assert.isOk(fetchStub.lastCall.args[0].params);
      assert.isNotOk(fetchStub.lastCall.args[0].params!.parent);
      assert.isNotOk(fetchStub.lastCall.args[0].params!.base);
    });

    test('simple range', async () => {
      element.addRepoNameToCache(123 as NumericChangeId, TEST_PROJECT_NAME);
      const fetchStub = sinon
        .stub(element._restApiHelper, 'fetchJSON')
        .resolves();
      await element.getDiff(
        123 as NumericChangeId,
        4 as PatchSetNum,
        5 as PatchSetNum,
        'foo/bar.baz'
      );
      assert.isTrue(fetchStub.calledOnce);
      assert.equal(
        fetchStub.lastCall.args[0].url,
        '/changes/test-project~123/revisions/5/files/foo%2Fbar.baz/diff'
      );
      assert.isOk(fetchStub.lastCall.args[0].params);
      assert.isNotOk(fetchStub.lastCall.args[0].params!.parent);
      assert.equal(fetchStub.lastCall.args[0].params!.base, 4);
    });

    test('parent index', async () => {
      element.addRepoNameToCache(123 as NumericChangeId, TEST_PROJECT_NAME);
      const fetchStub = sinon
        .stub(element._restApiHelper, 'fetchJSON')
        .resolves();
      await element.getDiff(
        123 as NumericChangeId,
        -3 as PatchSetNum,
        5 as PatchSetNum,
        'foo/bar.baz'
      );
      assert.isTrue(fetchStub.calledOnce);
      assert.equal(
        fetchStub.lastCall.args[0].url,
        '/changes/test-project~123/revisions/5/files/foo%2Fbar.baz/diff'
      );
      assert.isOk(fetchStub.lastCall.args[0].params);
      assert.isNotOk(fetchStub.lastCall.args[0].params!.base);
      assert.equal(fetchStub.lastCall.args[0].params!.parent, 3);
    });
  });

  test('getDashboard', () => {
    const fetchCacheJSONStub = sinon.stub(
      element._restApiHelper,
      'fetchCacheJSON'
    );
    element.getDashboard(
      'gerrit/project' as RepoName,
      'default:main' as DashboardId
    );
    assert.isTrue(fetchCacheJSONStub.calledOnce);
    assert.equal(
      fetchCacheJSONStub.lastCall.args[0].url,
      '/projects/gerrit%2Fproject/dashboards/default%3Amain'
    );
  });

  test('getFileContent', async () => {
    element.addRepoNameToCache(1 as NumericChangeId, TEST_PROJECT_NAME);
    sinon.stub(element._restApiHelper, 'fetch').callsFake(() =>
      Promise.resolve(
        new Response(makePrefixedJSON('new content'), {
          status: 200,
          headers: {
            'X-FYI-Content-Type': 'text/java',
          },
        })
      )
    );

    const edit = await element.getFileContent(
      1 as NumericChangeId,
      'tst/path',
      'EDIT' as PatchSetNum
    );

    assert.deepEqual(edit, {
      content: 'new content',
      type: 'text/java',
      ok: true,
    });

    const normal = await element.getFileContent(
      1 as NumericChangeId,
      'tst/path',
      '3' as PatchSetNum
    );
    assert.deepEqual(normal, {
      content: 'new content',
      type: 'text/java',
      ok: true,
    });
  });

  test('getFileContent suppresses 404s', async () => {
    const res404 = new Response(undefined, {status: 404});
    const res500 = new Response(undefined, {status: 500});
    const spy = sinon.spy();
    addListenerForTest(document, 'server-error', spy);
    const authStub = sinon.stub(authService, 'fetch').resolves(res404);
    sinon.stub(element, '_changeBaseURL').resolves('');
    await element.getFileContent(
      1 as NumericChangeId,
      'tst/path',
      1 as PatchSetNum
    );
    await waitEventLoop();
    assert.isFalse(spy.called);
    authStub.reset();
    authStub.resolves(res500);
    await element.getFileContent(
      1 as NumericChangeId,
      'tst/path',
      1 as PatchSetNum
    );
    assert.isTrue(spy.called);
    assert.notEqual(spy.lastCall.args[0].detail.response.status, 404);
  });

  test('getChangeFilesOrEditFiles is edit-sensitive', async () => {
    const getChangeFilesStub = sinon
      .stub(element, 'getChangeFiles')
      .resolves({});
    const getChangeEditFilesStub = sinon
      .stub(element, 'getChangeEditFiles')
      .resolves({files: {}});

    await element.getChangeOrEditFiles(1 as NumericChangeId, {
      basePatchNum: PARENT,
      patchNum: EDIT,
    });
    assert.isTrue(getChangeEditFilesStub.calledOnce);
    assert.isFalse(getChangeFilesStub.called);
    await element.getChangeOrEditFiles(1 as NumericChangeId, {
      basePatchNum: PARENT,
      patchNum: 1 as RevisionPatchSetNum,
    });
    assert.isTrue(getChangeEditFilesStub.calledOnce);
    assert.isTrue(getChangeFilesStub.calledOnce);
  });

  test('getChangeEdit not logged in returns undefined', async () => {
    element.addRepoNameToCache(123 as NumericChangeId, TEST_PROJECT_NAME);
    sinon.stub(element, 'getLoggedIn').resolves(false);
    const fetchSpy = sinon.spy(element._restApiHelper, 'fetch');
    const edit = await element.getChangeEdit(123 as NumericChangeId);
    assert.isUndefined(edit);
    assert.isFalse(fetchSpy.called);
  });

  test('getChangeEdit no edit patchset returns undefined', async () => {
    element.addRepoNameToCache(123 as NumericChangeId, TEST_PROJECT_NAME);
    sinon.stub(element, 'getLoggedIn').resolves(true);
    sinon
      .stub(element._restApiHelper, 'fetch')
      .resolves(new Response(undefined, {status: 204}));
    const edit = await element.getChangeEdit(123 as NumericChangeId);
    assert.isUndefined(edit);
  });

  test('getChangeEdit returns edit patchset', async () => {
    element.addRepoNameToCache(123 as NumericChangeId, TEST_PROJECT_NAME);
    sinon.stub(element, 'getLoggedIn').resolves(true);
    const expected = createEditInfo();
    sinon
      .stub(element._restApiHelper, 'fetch')
      .resolves(new Response(makePrefixedJSON(expected)));
    const edit = await element.getChangeEdit(123 as NumericChangeId);
    assert.deepEqual(edit, expected);
  });

  test('ported comment errors do not trigger error dialog', () => {
    const change = createChange();
    const handler = sinon.stub();
    addListenerForTest(document, 'server-error', handler);
    sinon.stub(element._restApiHelper, 'fetchJSON').resolves({
      ok: false,
    } as unknown as ParsedJSON);

    element.getPortedComments(change._number, CURRENT);

    assert.isFalse(handler.called);
  });

  test('ported drafts are not requested user is not logged in', () => {
    const change = createChange();
    element.addRepoNameToCache(change._number, TEST_PROJECT_NAME);
    sinon.stub(element, 'getLoggedIn').resolves(false);
    const getChangeURLAndFetchStub = sinon.stub(
      element._restApiHelper,
      'fetchJSON'
    );

    element.getPortedDrafts(change._number, CURRENT);

    assert.isFalse(getChangeURLAndFetchStub.called);
  });

  test('saveChangeStarred', async () => {
    element.addRepoNameToCache(123 as NumericChangeId, 'test' as RepoName);
    element.addRepoNameToCache(456 as NumericChangeId, 'test' as RepoName);
    const fetchStub = sinon.stub(element._restApiHelper, 'fetch').resolves();

    await element.saveChangeStarred(123 as NumericChangeId, true);
    assert.isTrue(fetchStub.calledOnce);
    assert.deepEqual(fetchStub.lastCall.args[0], {
      fetchOptions: {method: HttpMethod.PUT},
      url: '/accounts/self/starred.changes/test~123',
      anonymizedUrl: '/accounts/self/starred.changes/*',
    });

    await element.saveChangeStarred(456 as NumericChangeId, false);
    assert.isTrue(fetchStub.calledTwice);
    assert.deepEqual(fetchStub.lastCall.args[0], {
      fetchOptions: {method: HttpMethod.DELETE},
      url: '/accounts/self/starred.changes/test~456',
      anonymizedUrl: '/accounts/self/starred.changes/*',
    });
  });
  suite('applyFixSuggestion', () => {
    const fixReplacementInfo = createFixReplacementInfo();
    let fetchStub: sinon.SinonStub;
    setup(() => {
      element.addRepoNameToCache(123 as NumericChangeId, TEST_PROJECT_NAME);
      fetchStub = sinon
        .stub(element._restApiHelper, 'fetch')
        .resolves(new Response(makePrefixedJSON({})));
    });
    test('applyFixSuggestion without targetPatchNum', async () => {
      await element.applyFixSuggestion(
        123 as NumericChangeId,
        1 as PatchSetNum,
        [fixReplacementInfo]
      );
      assert.isTrue(fetchStub.calledOnce);
      assert.equal(
        fetchStub.lastCall.args[0].url,
        '/changes/test-project~123/revisions/1/fix:apply'
      );
      const body = JSON.parse(fetchStub.lastCall.args[0].fetchOptions.body);
      assert.isTrue(
        Object.keys(body).length === 1 &&
          body.fix_replacement_infos.length === 1
      );
      assert.deepEqual(body.fix_replacement_infos[0], fixReplacementInfo);
    });

    test('applyFixSuggestion with same patchNum and targetPatchNum', async () => {
      const fixReplacementInfo = createFixReplacementInfo();
      await element.applyFixSuggestion(
        123 as NumericChangeId,
        1 as PatchSetNum,
        [fixReplacementInfo],
        1 as PatchSetNum
      );
      assert.isTrue(fetchStub.calledOnce);
      assert.equal(
        fetchStub.lastCall.args[0].url,
        '/changes/test-project~123/revisions/1/fix:apply'
      );
      const body = JSON.parse(fetchStub.lastCall.args[0].fetchOptions.body);
      assert.isTrue(Object.keys(body).length === 1);
      assert.deepEqual(body.fix_replacement_infos[0], fixReplacementInfo);
    });

    test('applyFixSuggestion with targetPatchNum', async () => {
      const fixReplacementInfo = createFixReplacementInfo();
      await element.applyFixSuggestion(
        123 as NumericChangeId,
        1 as PatchSetNum,
        [fixReplacementInfo],
        2 as PatchSetNum
      );
      assert.isTrue(fetchStub.calledOnce);
      assert.equal(
        fetchStub.lastCall.args[0].url,
        '/changes/test-project~123/revisions/2/fix:apply'
      );
      const body = JSON.parse(fetchStub.lastCall.args[0].fetchOptions.body);
      assert.isTrue(Object.keys(body).length === 2);
      assert.deepEqual(body.fix_replacement_infos[0], fixReplacementInfo);
      assert.deepEqual(body.original_patchset_for_fix, 1);
    });
  });
});
