Commit ba49bf7c authored by Paul Slaughter's avatar Paul Slaughter 2️⃣ Committed by Tomas Vik (OOO back on 2026-08-31)
Browse files

feat(web-ide): Use auth provider if available

parent 6c1cc807
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ module.exports = {
  Uri,
  authentication: {
    getSession: jest.fn(),
    onDidChangeSessions: jest.fn(),
  },
  comments: {
    createCommentController: jest.fn(),
+55 −0
Original line number Diff line number Diff line
import { NoopAuthentication } from '../auth/noop_authentication';
import { DefaultApiClient } from '../../common/gitlab/api/api_client';
import { createApiClient } from './factory';
import { MediatorCommandsApiClient } from './mediator_commands_api_client';
import { createFakePartial } from '../../common/test_utils/create_fake_partial';
import { Authentication } from '../auth';

jest.mock('../../common/gitlab/api/api_client');

const TEST_INSTANCE_URL = 'http://localhost:3000';
const TEST_AUTHENTICATION: Authentication = createFakePartial<Authentication>({
  getSession: () => ({
    accessToken: 'test-token',
    account: {
      id: 'test-id',
      label: 'test-label',
    },
    id: 'test-id',
    scopes: ['api'],
  }),
});

describe('browser/api/factory', () => {
  describe('createApiClient', () => {
    it('when auth does not have accessToken, creates MediatorCommandsApiClient', () => {
      const client = createApiClient(TEST_INSTANCE_URL, new NoopAuthentication());

      expect(client).toBeInstanceOf(MediatorCommandsApiClient);
    });

    it('when auth has accessToken, creates DefaultApiClient', () => {
      const client = createApiClient(TEST_INSTANCE_URL, TEST_AUTHENTICATION);

      expect(client).toBeInstanceOf(DefaultApiClient);
      expect(DefaultApiClient).toHaveBeenCalledWith({
        instanceUrl: TEST_INSTANCE_URL,
        authProvider: {
          getAuthHeaders: expect.any(Function),
        },
      });
    });

    it('when auth has accessToken, authProvider.getAuthHeaders returns correct headers', async () => {
      createApiClient(TEST_INSTANCE_URL, TEST_AUTHENTICATION);

      const headers = await jest
        .mocked(DefaultApiClient)
        .mock.calls[0]?.[0]?.authProvider?.getAuthHeaders();

      expect(headers).toEqual({
        Authorization: 'Bearer test-token',
      });
    });
  });
});
+25 −0
Original line number Diff line number Diff line
import type { ApiClient } from '../../common/gitlab/api/api_client';
import type { Authentication } from '../auth';
import { DefaultApiClient } from '../../common/gitlab/api/api_client';
import { MediatorCommandsApiClient } from './mediator_commands_api_client';

export const createApiClient = (instanceUrl: string, authentication: Authentication): ApiClient => {
  // note: We only need to check this once here to know if we support auth tokens or not
  const hasAuthToken = Boolean(authentication.getSession().accessToken);

  if (hasAuthToken) {
    return new DefaultApiClient({
      instanceUrl,
      authProvider: {
        async getAuthHeaders() {
          // note: It's important that we *refetch* `getSession` here, to make sure we have the latest.
          return {
            Authorization: `Bearer ${authentication.getSession().accessToken}`,
          };
        },
      },
    });
  }

  return new MediatorCommandsApiClient();
};
+1 −0
Original line number Diff line number Diff line
export * from './factory';
+58 −0
Original line number Diff line number Diff line
import * as vscode from 'vscode';
import { MediatorCommandsApiClient } from './mediator_commands_api_client';
import {
  ApiRequest,
  COMMAND_FETCH_FROM_API,
  COMMAND_MEDIATOR_TOKEN,
} from '../../common/platform/web_ide';

const TEST_REQUEST: ApiRequest<string> = {
  type: 'rest',
  method: 'GET',
  path: '/test',
};
const TEST_RESPONSE = 'test-response';
const TEST_MEDIATOR_TOKEN = 'test-mediator-token';

describe('MediatorCommandsApiClient', () => {
  let subject: MediatorCommandsApiClient;

  beforeEach(() => {
    jest.spyOn(vscode.commands, 'executeCommand').mockImplementation(async key => {
      if (key === COMMAND_MEDIATOR_TOKEN) {
        return TEST_MEDIATOR_TOKEN;
      }
      if (key === COMMAND_FETCH_FROM_API) {
        return TEST_RESPONSE;
      }

      return undefined;
    });

    subject = new MediatorCommandsApiClient();
  });

  describe('fetchFromApi', () => {
    it('passes request to mediator command', async () => {
      const actual = await subject.fetchFromApi(TEST_REQUEST);

      expect(actual).toBe(TEST_RESPONSE);
      expect(vscode.commands.executeCommand).toHaveBeenCalledWith(
        COMMAND_FETCH_FROM_API,
        TEST_MEDIATOR_TOKEN,
        TEST_REQUEST,
      );
    });

    it('requests mediator token only once', async () => {
      await subject.fetchFromApi(TEST_REQUEST);
      await subject.fetchFromApi(TEST_REQUEST);

      const mediatorCalls = jest
        .mocked(vscode.commands.executeCommand)
        .mock.calls.filter(([key]) => key === COMMAND_MEDIATOR_TOKEN);

      expect(mediatorCalls).toEqual([[COMMAND_MEDIATOR_TOKEN]]);
    });
  });
});
Loading