/**
 * @license
 * Copyright 2016 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import * as sinon from 'sinon';
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 {FlowInput} from '../../api/rest-api';
import {
  AccountDetailInfo,
  BasePatchSetNum,
  ChangeInfo,
  ChangeMessageId,
  CommentInfo,
  CommentInput,
  DashboardId,
  EDIT,
  Hashtag,
  ListChangesOption,
  NumericChangeId,
  PARENT,
  ParsedJSON,
  PatchSetNum,
  RepoName,
  RevisionPatchSetNum,
  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';

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

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

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

  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 CommentInfo);
    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 CommentInfo);
    assert.deepEqual(obj.comments[1], {
      message: '¯\\_(ツ)_/¯',
      path: 'sieve.go',
      updated: '2017-02-04 22:33:28.000000000' as Timestamp,
    } as CommentInfo);
  });

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

  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('getChange', () => {
    const changeNum = 555 as NumericChangeId;
    const repo = 'test-repo' as RepoName;

    test('getChange with known project', async () => {
      element._projectLookup[changeNum] = Promise.resolve(repo);
      const promise = mockPromise<ParsedJSON>();
      const stub = sinon
        .stub(element._restApiHelper, 'fetchJSON')
        .returns(promise);

      const change = element.getChange(
        changeNum,
        undefined,
        listChangesOptionsToHex(ListChangesOption.DETAILED_ACCOUNTS)
      );
      promise.resolve({...createChange()} as unknown as ParsedJSON);

      await change;

      assert.isTrue(stub.called);
      assert.equal(stub.args[0][0].url, '/changes/test-repo~555');
      assert.deepEqual(stub.args[0][0].params, {
        O: listChangesOptionsToHex(ListChangesOption.DETAILED_ACCOUNTS),
      });
    });

    test('getChange with unknown projecgt', async () => {
      const promise = mockPromise<ParsedJSON>();
      const stub = sinon
        .stub(element._restApiHelper, 'fetchJSON')
        .returns(promise);

      const change = element.getChange(
        changeNum,
        undefined,
        listChangesOptionsToHex(ListChangesOption.DETAILED_ACCOUNTS)
      );
      promise.resolve({...createChange()} as unknown as ParsedJSON);

      await change;

      assert.isTrue(stub.called);
      assert.equal(stub.args[0][0].url, '/changes/');
      assert.deepEqual(stub.args[0][0].params, {
        O: listChangesOptionsToHex(ListChangesOption.DETAILED_ACCOUNTS),
        q: 'change:555',
      });
    });
  });

  suite('getChanges populates _projectLookup', () => {
    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('getDetailedChangesWithActions with SUBMIT_REQUIREMENTS', async () => {
    const expectedQueryOptions = listChangesOptionsToHex(
      ListChangesOption.CHANGE_ACTIONS,
      ListChangesOption.CURRENT_REVISION,
      ListChangesOption.DETAILED_LABELS,
      ListChangesOption.SUBMIT_REQUIREMENTS
    );
    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, expectedQueryOptions);
        return Promise.resolve([]);
      });
    await element.getDetailedChangesWithActions([c1._number, c2._number], true);
    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('generateAccountAuthToken', async () => {
    const fetchStub = sinon
      .stub(element._restApiHelper, 'fetchJSON')
      .resolves();
    await element.generateAccountAuthToken('token1', '3d');
    assert.isTrue(fetchStub.calledOnce);
    assert.deepEqual(
      JSON.parse(fetchStub.lastCall.args[0].fetchOptions?.body as string),
      {id: 'token1', lifetime: '3d'}
    );
  });

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

  suite('getFixPreview', () => {
    const fixReplacementInfo = createFixReplacementInfo();
    let fetchJSONStub: sinon.SinonStub;

    setup(() => {
      element.addRepoNameToCache(123 as NumericChangeId, TEST_PROJECT_NAME);
      fetchJSONStub = sinon
        .stub(element._restApiHelper, 'fetchJSON')
        .resolves({} as unknown as ParsedJSON);
    });

    test('getFixPreview caches results', async () => {
      await element.getFixPreview(123 as NumericChangeId, 1 as PatchSetNum, [
        fixReplacementInfo,
      ]);
      assert.isTrue(fetchJSONStub.calledOnce);

      // Call again with same params
      await element.getFixPreview(123 as NumericChangeId, 1 as PatchSetNum, [
        fixReplacementInfo,
      ]);
      // Should not call fetchJSON again
      assert.isTrue(fetchJSONStub.calledOnce);
    });

    test('getFixPreview does not cache for different params', async () => {
      await element.getFixPreview(123 as NumericChangeId, 1 as PatchSetNum, [
        fixReplacementInfo,
      ]);
      assert.isTrue(fetchJSONStub.calledOnce);

      // Call with different patchNum
      await element.getFixPreview(123 as NumericChangeId, 2 as PatchSetNum, [
        fixReplacementInfo,
      ]);
      assert.isTrue(fetchJSONStub.calledTwice);
    });
  });

  suite('flow api', () => {
    const changeNum = 123 as NumericChangeId;
    const flowId = 'test-flow-id';
    let fetchJSONStub: sinon.SinonStub;
    let fetchStub: sinon.SinonStub;

    setup(() => {
      element.addRepoNameToCache(changeNum, TEST_PROJECT_NAME);
      fetchJSONStub = sinon
        .stub(element._restApiHelper, 'fetchJSON')
        .resolves();
      fetchStub = sinon.stub(element._restApiHelper, 'fetch').resolves();
    });

    test('getFlow', async () => {
      await element.getFlow(changeNum, flowId);
      assert.isTrue(fetchJSONStub.calledOnce);
      assert.equal(
        fetchJSONStub.lastCall.args[0].url,
        `/changes/test-project~${changeNum}/flows/${flowId}`
      );
    });

    test('listFlows', async () => {
      await element.listFlows(changeNum);
      assert.isTrue(fetchJSONStub.calledOnce);
      assert.equal(
        fetchJSONStub.lastCall.args[0].url,
        `/changes/test-project~${changeNum}/flows`
      );
    });

    test('getIfFlowsIsEnabled', async () => {
      await element.getIfFlowsIsEnabled(changeNum);
      assert.isTrue(fetchJSONStub.calledOnce);
      assert.equal(
        fetchJSONStub.lastCall.args[0].url,
        `/changes/test-project~${changeNum}/is-flows-enabled`
      );
    });

    test('createFlow', async () => {
      const flow: FlowInput = {
        stage_expressions: [{condition: 'branch:refs/heads/main'}],
      };
      await element.createFlow(changeNum, flow);
      assert.isTrue(fetchJSONStub.calledOnce);
      assert.equal(
        fetchJSONStub.lastCall.args[0].url,
        `/changes/test-project~${changeNum}/flows`
      );
      assert.equal(fetchJSONStub.lastCall.args[0].fetchOptions.method, 'POST');
      assert.deepEqual(
        JSON.parse(fetchJSONStub.lastCall.args[0].fetchOptions.body),
        flow
      );
    });

    test('deleteFlow', async () => {
      await element.deleteFlow(changeNum, flowId);
      assert.isTrue(fetchStub.calledOnce);
      assert.equal(
        fetchStub.lastCall.args[0].url,
        `/changes/test-project~${changeNum}/flows/${flowId}`
      );
      assert.equal(fetchStub.lastCall.args[0].fetchOptions!.method, 'DELETE');
    });
  });
});
