@toolbox-sdk/core
Version:
JavaScript Base SDK for interacting with the Toolbox service
98 lines (77 loc) • 3.53 kB
text/typescript
// Copyright 2025 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import {GoogleAuth} from 'google-auth-library';
type GetGoogleIdToken = (url: string) => Promise<string>;
describe('getGoogleIdToken', () => {
const mockUrl = 'https://example.com';
const mockToken = 'mock-id-token';
let getGoogleIdToken: GetGoogleIdToken;
let MockedGoogleAuth: jest.MockedClass<typeof GoogleAuth>;
let mockGetIdTokenClient: jest.Mock;
let mockFetchIdToken: jest.Mock;
beforeEach(() => {
jest.resetModules();
mockFetchIdToken = jest.fn();
mockGetIdTokenClient = jest.fn();
jest.mock('google-auth-library', () => {
return {
GoogleAuth: jest.fn().mockImplementation(() => ({
getIdTokenClient: mockGetIdTokenClient,
})),
};
});
// With the mocks fully configured, dynamically require the modules.
// This ensures our code runs against the fresh mocks we just set up.
const authMethods = require('../src/toolbox_core/authMethods');
const {GoogleAuth: GA} = require('google-auth-library');
getGoogleIdToken = authMethods.getGoogleIdToken;
MockedGoogleAuth = GA;
mockGetIdTokenClient.mockResolvedValue({
idTokenProvider: {fetchIdToken: mockFetchIdToken},
});
mockFetchIdToken.mockResolvedValue(mockToken);
});
it('should return a Bearer token on successful fetch', async () => {
const token = await getGoogleIdToken(mockUrl);
expect(token).toBe(`Bearer ${mockToken}`);
expect(MockedGoogleAuth).toHaveBeenCalledTimes(1);
expect(mockGetIdTokenClient).toHaveBeenCalledWith(mockUrl);
expect(mockGetIdTokenClient).toHaveBeenCalledTimes(1);
expect(mockFetchIdToken).toHaveBeenCalledWith(mockUrl);
expect(mockFetchIdToken).toHaveBeenCalledTimes(1);
});
it('should propagate errors from getIdTokenClient', async () => {
const errorMessage = 'Failed to get ID token client';
mockGetIdTokenClient.mockRejectedValue(new Error(errorMessage));
await expect(getGoogleIdToken(mockUrl)).rejects.toThrow(errorMessage);
});
it('should propagate errors from fetchIdToken', async () => {
const errorMessage = 'Failed to fetch ID token';
mockFetchIdToken.mockRejectedValue(new Error(errorMessage));
await expect(getGoogleIdToken(mockUrl)).rejects.toThrow(errorMessage);
});
it('should fetch the token only once when called multiple times', async () => {
const token1 = await getGoogleIdToken(mockUrl);
const token2 = await getGoogleIdToken(mockUrl);
await getGoogleIdToken(mockUrl);
expect(token1).toBe(`Bearer ${mockToken}`);
expect(token2).toBe(`Bearer ${mockToken}`);
// `GoogleAuth` constructor was only ever called once.
expect(MockedGoogleAuth).toHaveBeenCalledTimes(1);
// The client is only fetched once.
expect(mockGetIdTokenClient).toHaveBeenCalledTimes(1);
// With our current mock, the token fetching method is called each time.
expect(mockFetchIdToken).toHaveBeenCalledTimes(3);
});
});