/**
 * @license
 * Copyright 2016 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import '../../test/common-test-setup';
import {
  addListenerForTest,
  assertFails,
  MockPromise,
  mockPromise,
  waitEventLoop,
} from '../../test/test-utils';
import {GrReviewerUpdatesParser} from '../../elements/shared/gr-rest-api-interface/gr-reviewer-updates-parser';
import {
  ListChangesOption,
  listChangesOptionsToHex,
} from '../../utils/change-util';
import {
  createAccountDetailWithId,
  createChange,
  createComment,
  createGerritInfo,
  createParsedChange,
  createServerInfo,
} from '../../test/test-data-generators';
import {CURRENT} from '../../utils/patch-set-util';
import {
  parsePrefixedJSON,
  readResponsePayload,
  JSON_PREFIX,
} from '../../elements/shared/gr-rest-api-interface/gr-rest-apis/gr-rest-api-helper';
import {GrRestApiServiceImpl} from './gr-rest-api-impl';
import {
  CommentSide,
  createDefaultEditPrefs,
  HttpMethod,
} from '../../constants/constants';
import {
  BasePatchSetNum,
  ChangeInfo,
  ChangeMessageId,
  CommentInfo,
  DashboardId,
  DiffPreferenceInput,
  EDIT,
  EditPreferencesInfo,
  Hashtag,
  HashtagsInput,
  NumericChangeId,
  PARENT,
  ParsedJSON,
  PatchSetNum,
  PreferencesInfo,
  RepoName,
  RevisionId,
  RevisionPatchSetNum,
  RobotCommentInfo,
  ServerInfo,
  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 {getBaseUrl} from '../../utils/url-util';

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

    element._projectLookup = {};
  });

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

  test('parent diff comments are properly grouped', async () => {
    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, 'getFromProjectLookup').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('server error', async () => {
    const getResponseObjectStub = sinon.stub(element, 'getResponseObject');
    sinon
      .stub(authService, 'fetch')
      .resolves(new Response(undefined, {status: 502}));
    const serverErrorEventPromise = new Promise(resolve => {
      addListenerForTest(document, 'server-error', resolve);
    });
    const response = await element._restApiHelper.fetchJSON({url: ''});
    assert.isUndefined(response);
    assert.isTrue(getResponseObjectStub.notCalled);
    await serverErrorEventPromise;
  });

  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 sendStub = sinon.stub(element._restApiHelper, 'send');
    element._cache.set(cacheKey, {tab_size: 4} as unknown as ParsedJSON);
    element.saveDiffPreferences({
      tab_size: 8,
      ignore_whitespace: 'IGNORE_NONE',
    });
    assert.isTrue(sendStub.called);
    assert.isFalse(element._cache.has(cacheKey));
  });

  suite('getAccountSuggestions', () => {
    let fetchStub: sinon.SinonStub;
    setup(() => {
      fetchStub = sinon
        .stub(element._restApiHelper, 'fetch')
        .resolves(new Response());
    });

    test('url with just email', () => {
      element.getSuggestedAccounts('bro');
      assert.isTrue(fetchStub.calledOnce);
      assert.equal(
        fetchStub.firstCall.args[0].url,
        `${getBaseUrl()}/accounts/?o=DETAILS&q=%22bro%22`
      );
    });

    test('url with email and canSee changeId', () => {
      element.getSuggestedAccounts('bro', undefined, 341682 as NumericChangeId);
      assert.isTrue(fetchStub.calledOnce);
      assert.equal(
        fetchStub.firstCall.args[0].url,
        `${getBaseUrl()}/accounts/?o=DETAILS&q=%22bro%22%20and%20cansee%3A341682`
      );
    });

    test('url with email and canSee changeId and isActive', () => {
      element.getSuggestedAccounts(
        'bro',
        undefined,
        341682 as NumericChangeId,
        true
      );
      assert.isTrue(fetchStub.calledOnce);
      assert.equal(
        fetchStub.firstCall.args[0].url,
        `${getBaseUrl()}/accounts/?o=DETAILS&q=%22bro%22%20and%20cansee%3A341682%20and%20is%3Aactive`
      );
    });
  });

  test('getAccount when resp is undefined clears cache', async () => {
    const cacheKey = '/accounts/self/detail';
    const account = createAccountDetailWithId();
    element._cache.set(cacheKey, account);
    const stub = sinon
      .stub(element._restApiHelper, 'fetchCacheURL')
      .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);
    const stub = sinon
      .stub(element._restApiHelper, 'fetchCacheURL')
      .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, 'fetchCacheURL')
      .callsFake(async () => {
        element._cache.set(cacheKey, account);
        return undefined;
      });
    assert.isFalse(element._cache.has(cacheKey));

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

  const preferenceSetup = function (testJSON: unknown, loggedIn: boolean) {
    sinon
      .stub(element, 'getLoggedIn')
      .callsFake(() => Promise.resolve(loggedIn));
    sinon
      .stub(element._restApiHelper, 'fetchCacheURL')
      .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('savPreferences normalizes download scheme', () => {
    const sendStub = sinon
      .stub(element._restApiHelper, 'send')
      .resolves(new Response());
    element.savePreferences({download_scheme: 'HTTP'});
    assert.isTrue(sendStub.called);
    assert.equal(
      (sendStub.lastCall.args[0].body as Partial<PreferencesInfo>)
        .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 sendStub = sinon.stub(element._restApiHelper, 'send');
    element.saveDiffPreferences({
      show_tabs: false,
      ignore_whitespace: 'IGNORE_NONE',
    });
    assert.isTrue(sendStub.called);
    assert.equal(
      (sendStub.lastCall.args[0].body as Partial<DiffPreferenceInput>)
        .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 sendStub = sinon.stub(element._restApiHelper, 'send');
    element.saveEditPreferences({
      ...createDefaultEditPrefs(),
      show_tabs: false,
    });
    assert.isTrue(sendStub.called);
    assert.equal(
      (sendStub.lastCall.args[0].body as EditPreferencesInfo).show_tabs,
      false
    );
  });

  test('confirmEmail', () => {
    const sendStub = sinon.spy(element._restApiHelper, 'send');
    element.confirmEmail('foo');
    assert.isTrue(sendStub.calledOnce);
    assert.equal(sendStub.lastCall.args[0].method, HttpMethod.PUT);
    assert.equal(sendStub.lastCall.args[0].url, '/config/server/email.confirm');
    assert.deepEqual(sendStub.lastCall.args[0].body, {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, 'send').resolves();
    element._cache.set('/accounts/self/emails', [
      {email: email1, preferred: true},
      {email: email2, preferred: false},
    ]);

    await element.setPreferredAccountEmail(email2);
    assert.isTrue(sendStub.calledOnce);
    assert.equal(sendStub.lastCall.args[0].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},
    ]);
  });

  test('setAccountStatus', async () => {
    const sendStub = sinon
      .stub(element._restApiHelper, 'send')
      .resolves('OOO' as unknown as ParsedJSON);
    element._cache.set('/accounts/self/detail', createAccountDetailWithId());
    await element.setAccountStatus('OOO');
    assert.isTrue(sendStub.calledOnce);
    assert.equal(sendStub.lastCall.args[0].method, HttpMethod.PUT);
    assert.equal(sendStub.lastCall.args[0].url, '/accounts/self/status');
    assert.deepEqual(sendStub.lastCall.args[0].body, {status: 'OOO'});
    assert.deepEqual(
      element._cache.get('/accounts/self/detail')!.status,
      'OOO'
    );
  });

  suite('draft comments', () => {
    test('_sendDiffDraftRequest pending requests tracked', async () => {
      const obj = element._pendingRequests;
      sinon
        .stub(element, '_getChangeURLAndSend')
        .callsFake(() => mockPromise());
      assert.notOk(element.hasPendingDiffDrafts());

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

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

      for (const promise of obj.sendDiffDraft) {
        (promise as MockPromise<void>).resolve();
      }

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

    suite('_failForCreate200', () => {
      test('_sendDiffDraftRequest checks for 200 on create', async () => {
        const sendPromise = Promise.resolve({} as unknown as ParsedJSON);
        sinon.stub(element, '_getChangeURLAndSend').returns(sendPromise);
        const failStub = sinon.stub(element, '_failForCreate200').resolves();
        await element._sendDiffDraftRequest(
          HttpMethod.PUT,
          123 as NumericChangeId,
          4 as PatchSetNum,
          {}
        );
        assert.isTrue(failStub.calledOnce);
        assert.isTrue(failStub.calledWithExactly(sendPromise));
      });

      test('_sendDiffDraftRequest no checks for 200 on non create', async () => {
        sinon.stub(element, '_getChangeURLAndSend').resolves();
        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 sendStub = sinon
      .stub(element._restApiHelper, 'send')
      .resolves([
        change_num,
        file_name,
        file_contents,
      ] as unknown as ParsedJSON);
    sinon
      .stub(element, 'getResponseObject')
      .resolves([
        change_num,
        file_name,
        file_contents,
      ] as unknown as ParsedJSON);
    element._cache.set(
      `/changes/${change_num}/edit/${file_name}`,
      {} as unknown as ParsedJSON
    );
    await element.saveChangeEdit(change_num, file_name, file_contents);
    assert.isTrue(sendStub.calledOnce);
    assert.equal(sendStub.lastCall.args[0].method, HttpMethod.PUT);
    assert.equal(
      sendStub.lastCall.args[0].url,
      '/changes/test~1/edit/' + file_name
    );
    assert.equal(sendStub.lastCall.args[0].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 sendStub = sinon
      .stub(element._restApiHelper, 'send')
      .resolves([change_num, message] as unknown as ParsedJSON);
    sinon
      .stub(element, 'getResponseObject')
      .resolves([change_num, message] as unknown as ParsedJSON);
    element._cache.set(
      `/changes/${change_num}/message`,
      {} as unknown as ParsedJSON
    );
    await element.putChangeCommitMessage(change_num, message);
    assert.isTrue(sendStub.calledOnce);
    assert.equal(sendStub.lastCall.args[0].method, HttpMethod.PUT);
    assert.equal(sendStub.lastCall.args[0].url, '/changes/test~1/message');
    assert.deepEqual(sendStub.lastCall.args[0].body, {
      message,
    });
  });

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

  test('startWorkInProgress', () => {
    const sendStub = sinon
      .stub(element, '_getChangeURLAndSend')
      .resolves('ok' as unknown as ParsedJSON);
    element.startWorkInProgress(42 as NumericChangeId);
    assert.isTrue(sendStub.calledOnce);
    assert.equal(sendStub.lastCall.args[0].changeNum, 42 as NumericChangeId);
    assert.equal(sendStub.lastCall.args[0].method, HttpMethod.POST);
    assert.isNotOk(sendStub.lastCall.args[0].patchNum);
    assert.equal(sendStub.lastCall.args[0].endpoint, '/wip');
    assert.deepEqual(sendStub.lastCall.args[0].body, {});

    element.startWorkInProgress(42 as NumericChangeId, 'revising...');
    assert.isTrue(sendStub.calledTwice);
    assert.equal(sendStub.lastCall.args[0].changeNum, 42 as NumericChangeId);
    assert.equal(sendStub.lastCall.args[0].method, HttpMethod.POST);
    assert.isNotOk(sendStub.lastCall.args[0].patchNum);
    assert.equal(sendStub.lastCall.args[0].endpoint, '/wip');
    assert.deepEqual(sendStub.lastCall.args[0].body, {
      message: 'revising...',
    });
  });

  test('deleteComment', async () => {
    const comment = createComment();
    const sendStub = sinon
      .stub(element, '_getChangeURLAndSend')
      .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(sendStub.calledOnce);
    assert.equal(sendStub.lastCall.args[0].changeNum, 123 as NumericChangeId);
    assert.equal(sendStub.lastCall.args[0].method, HttpMethod.POST);
    assert.equal(sendStub.lastCall.args[0].patchNum, 1 as PatchSetNum);
    assert.equal(sendStub.lastCall.args[0].endpoint, '/comments/01234/delete');
    assert.deepEqual(sendStub.lastCall.args[0].body, {
      reason: 'removal reason',
    });
  });

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

  test('queryChangeFiles', async () => {
    const fetchStub = sinon.stub(element, '_getChangeURLAndFetch').resolves();
    await element.queryChangeFiles(42 as NumericChangeId, EDIT, 'test/path.js');
    assert.equal(fetchStub.lastCall.args[0].changeNum, 42 as NumericChangeId);
    assert.equal(
      fetchStub.lastCall.args[0].endpoint,
      '/files?q=test%2Fpath.js'
    );
    assert.equal(fetchStub.lastCall.args[0].revision, EDIT);
  });

  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 fetchCacheURLStub: sinon.SinonStub;
    setup(() => {
      fetchCacheURLStub = sinon
        .stub(element._restApiHelper, 'fetchCacheURL')
        .resolves([] as unknown as ParsedJSON);
    });

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

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

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

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

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

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

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

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

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

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

    test('using query', () => {
      element.getRepos('description:project', 25);
      assert.equal(
        fetchCacheURLStub.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 fetchCacheURLStub: sinon.SinonStub;
    setup(() => {
      fetchCacheURLStub = sinon.stub(element._restApiHelper, 'fetchCacheURL');
    });

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

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

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

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

      element.getGroups('^test.*', 25, 25);
      assert.equal(
        fetchCacheURLStub.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('getSuggestedAccounts does not return fetchJSON', async () => {
    const fetchJSONSpy = sinon.spy(element._restApiHelper, 'fetchJSON');
    const accts = await element.getSuggestedAccounts('');
    assert.isFalse(fetchJSONSpy.called);
    assert.equal(accts!.length, 0);
  });

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

  suite('getChangeDetail', () => {
    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 () => {
        sinon.stub(element, 'getConfig').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 () => {
        sinon.stub(element, 'getConfig').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 () => {
      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');
      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, 'fetchRawJSON')
        .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, 'fetchRawJSON').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 = JSON_PREFIX + JSON.stringify(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, 'fetchRawJSON').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, 'fetchRawJSON').resolves(
          new Response(undefined, {
            status: 304,
          })
        );

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

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

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

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

      const projectLookup = element.getFromProjectLookup(changeNum);
      promise.resolve(null);

      assert.isUndefined(await projectLookup);
    });

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

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

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

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

      const projectLookup = element.getFromProjectLookup(changeNum);
      element.setInProjectLookup(changeNum, repo);
      promise.resolve(null);

      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.getFromProjectLookup(1 as NumericChangeId);
      assert.equal(project1, 'test' as RepoName);
      const project2 = await element.getFromProjectLookup(2 as NumericChangeId);
      assert.equal(project2, 'test' as RepoName);
      const project3 = await element.getFromProjectLookup(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.getFromProjectLookup(1 as NumericChangeId);
      assert.equal(project1, 'test' as RepoName);
      const project2 = await element.getFromProjectLookup(2 as NumericChangeId);
      assert.equal(project2, 'test' as RepoName);
      const project3 = await element.getFromProjectLookup(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('_getChangeURLAndFetch', async () => {
    element._projectLookup = {1: Promise.resolve('test' as RepoName)};
    const fetchStub = sinon
      .stub(element._restApiHelper, 'fetchJSON')
      .resolves();
    const req = {
      changeNum: 1 as NumericChangeId,
      endpoint: '/test',
      revision: 1 as RevisionId,
    };
    await element._getChangeURLAndFetch(req);
    assert.equal(
      fetchStub.lastCall.args[0].url,
      '/changes/test~1/revisions/1/test'
    );
  });

  test('_getChangeURLAndSend', async () => {
    element._projectLookup = {1: Promise.resolve('test' as RepoName)};
    const sendStub = sinon.stub(element._restApiHelper, 'send').resolves();

    const req = {
      changeNum: 1 as NumericChangeId,
      method: HttpMethod.POST,
      patchNum: 1 as PatchSetNum,
      endpoint: '/test',
    };
    await element._getChangeURLAndSend(req);
    assert.isTrue(sendStub.calledOnce);
    assert.equal(sendStub.lastCall.args[0].method, HttpMethod.POST);
    assert.equal(
      sendStub.lastCall.args[0].url,
      '/changes/test~1/revisions/1/test'
    );
  });

  suite('reading responses', () => {
    test('_readResponsePayload', async () => {
      const mockObject = {foo: 'bar', baz: 'foo'} as unknown as ParsedJSON;
      const serial = JSON_PREFIX + JSON.stringify(mockObject);
      const response = new Response(serial);
      const payload = await readResponsePayload(response);
      assert.deepEqual(payload.parsed, mockObject);
      assert.equal(payload.raw, serial);
    });

    test('_parsePrefixedJSON', () => {
      const obj = {x: 3, y: {z: 4}, w: 23} as unknown as ParsedJSON;
      const serial = JSON_PREFIX + JSON.stringify(obj);
      const result = parsePrefixedJSON(serial);
      assert.deepEqual(result, obj);
    });
  });

  test('setChangeTopic', async () => {
    const sendSpy = sinon.spy(element, '_getChangeURLAndSend');
    await element.setChangeTopic(123 as NumericChangeId, 'foo-bar');
    assert.isTrue(sendSpy.calledOnce);
    assert.deepEqual(sendSpy.lastCall.args[0].body, {topic: 'foo-bar'});
  });

  test('setChangeHashtag', async () => {
    const sendSpy = sinon.spy(element, '_getChangeURLAndSend');
    await element.setChangeHashtag(123 as NumericChangeId, {
      add: ['foo-bar' as Hashtag],
    });
    assert.isTrue(sendSpy.calledOnce);
    assert.sameDeepMembers(
      (sendSpy.lastCall.args[0].body! as HashtagsInput).add!,
      ['foo-bar']
    );
  });

  test('generateAccountHttpPassword', async () => {
    const sendSpy = sinon.spy(element._restApiHelper, 'send');
    await element.generateAccountHttpPassword();
    assert.isTrue(sendSpy.calledOnce);
    assert.deepEqual(sendSpy.lastCall.args[0].body, {generate: true});
  });

  suite('getChangeFiles', () => {
    test('patch only', async () => {
      const fetchStub = sinon.stub(element, '_getChangeURLAndFetch').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].revision,
        2 as RevisionPatchSetNum
      );
      assert.isNotOk(fetchStub.lastCall.args[0].params);
    });

    test('simple range', async () => {
      const fetchStub = sinon.stub(element, '_getChangeURLAndFetch').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].revision, 5 as RevisionId);
      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 () => {
      const fetchStub = sinon.stub(element, '_getChangeURLAndFetch').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].revision, 5 as RevisionId);
      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 () => {
      const fetchStub = sinon.stub(element, '_getChangeURLAndFetch').resolves();
      await element.getDiff(
        123 as NumericChangeId,
        PARENT,
        2 as PatchSetNum,
        'foo/bar.baz'
      );
      assert.isTrue(fetchStub.calledOnce);
      assert.equal(fetchStub.lastCall.args[0].revision, 2 as RevisionId);
      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 () => {
      const fetchStub = sinon.stub(element, '_getChangeURLAndFetch').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].revision, 5 as RevisionId);
      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 () => {
      const fetchStub = sinon.stub(element, '_getChangeURLAndFetch').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].revision, 5 as RevisionId);
      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 fetchCacheURLStub = sinon.stub(
      element._restApiHelper,
      'fetchCacheURL'
    );
    element.getDashboard(
      'gerrit/project' as RepoName,
      'default:main' as DashboardId
    );
    assert.isTrue(fetchCacheURLStub.calledOnce);
    assert.equal(
      fetchCacheURLStub.lastCall.args[0].url,
      '/projects/gerrit%2Fproject/dashboards/default%3Amain'
    );
  });

  test('getFileContent', async () => {
    sinon.stub(element, '_getChangeURLAndSend').resolves(
      new Response(undefined, {
        status: 200,
        headers: {
          'X-FYI-Content-Type': 'text/java',
        },
      }) as unknown as ParsedJSON
    );

    sinon
      .stub(element, 'getResponseObject')
      .resolves('new content' as unknown as ParsedJSON);

    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('_fetch forwards request and logs', async () => {
    const logStub = sinon.stub(element._restApiHelper, '_logCall');
    const response = new Response(undefined, {status: 404});
    const url = 'my url';
    const fetchOptions = {method: 'DELETE'};
    sinon.stub(authService, 'fetch').resolves(response);
    const startTime = 123;
    sinon.stub(Date, 'now').returns(startTime);
    const req = {url, fetchOptions};
    await element._restApiHelper.fetch(req);
    assert.isTrue(logStub.calledOnce);
    assert.isTrue(logStub.calledWith(req, startTime, response.status));
  });

  test('_logCall only reports requests with anonymized URLss', async () => {
    sinon.stub(Date, 'now').returns(200);
    const handler = sinon.stub();
    addListenerForTest(document, 'gr-rpc-log', handler);

    element._restApiHelper._logCall({url: 'url'}, 100, 200);
    assert.isFalse(handler.called);

    element._restApiHelper._logCall(
      {url: 'url', anonymizedUrl: 'not url'},
      100,
      200
    );
    await waitEventLoop();
    assert.isTrue(handler.calledOnce);
  });

  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();
    sinon.stub(element, 'getLoggedIn').resolves(false);
    const getChangeURLAndFetchStub = sinon.stub(
      element,
      '_getChangeURLAndFetch'
    );

    element.getPortedDrafts(change._number, CURRENT);

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

  test('saveChangeStarred', async () => {
    sinon.stub(element, 'getFromProjectLookup').resolves('test' as RepoName);
    const sendStub = sinon.stub(element._restApiHelper, 'send').resolves();

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

    await element.saveChangeStarred(456 as NumericChangeId, false);
    assert.isTrue(sendStub.calledTwice);
    assert.deepEqual(sendStub.lastCall.args[0], {
      method: HttpMethod.DELETE,
      url: '/accounts/self/starred.changes/test~456',
      anonymizedUrl: '/accounts/self/starred.changes/*',
    });
  });

  suite('getDocsBaseUrl tests', () => {
    test('null config', async () => {
      const probePathMock = sinon.stub(element, 'probePath').resolves(true);
      const docsBaseUrl = await element.getDocsBaseUrl(undefined);
      assert.equal(
        probePathMock.lastCall.args[0],
        `${getBaseUrl()}/Documentation/index.html`
      );
      assert.equal(docsBaseUrl, `${getBaseUrl()}/Documentation`);
    });

    test('no doc config', async () => {
      const probePathMock = sinon.stub(element, 'probePath').resolves(true);
      const config: ServerInfo = {
        ...createServerInfo(),
        gerrit: createGerritInfo(),
      };
      const docsBaseUrl = await element.getDocsBaseUrl(config);
      assert.equal(
        probePathMock.lastCall.args[0],
        `${getBaseUrl()}/Documentation/index.html`
      );
      assert.equal(docsBaseUrl, `${getBaseUrl()}/Documentation`);
    });

    test('has doc config', async () => {
      const probePathMock = sinon.stub(element, 'probePath').resolves(true);
      const config: ServerInfo = {
        ...createServerInfo(),
        gerrit: {...createGerritInfo(), doc_url: 'foobar'},
      };
      const docsBaseUrl = await element.getDocsBaseUrl(config);
      assert.isFalse(probePathMock.called);
      assert.equal(docsBaseUrl, 'foobar');
    });

    test('no probe', async () => {
      const probePathMock = sinon.stub(element, 'probePath').resolves(false);
      const docsBaseUrl = await element.getDocsBaseUrl(undefined);
      assert.equal(
        probePathMock.lastCall.args[0],
        `${getBaseUrl()}/Documentation/index.html`
      );
      assert.isNotOk(docsBaseUrl);
    });
  });
});
