LibreChat/packages/api/src/utils/key.test.ts

98 lines
3.2 KiB
TypeScript
Raw Normal View History

import fs from 'fs';
import path from 'path';
import axios from 'axios';
import { loadServiceKey } from './key';
jest.mock('fs');
jest.mock('axios');
jest.mock('@librechat/data-schemas', () => ({
logger: {
error: jest.fn(),
},
}));
describe('loadServiceKey', () => {
const mockServiceKey = {
type: 'service_account',
project_id: 'test-project',
private_key_id: 'test-key-id',
private_key: '-----BEGIN PRIVATE KEY-----\ntest-key\n-----END PRIVATE KEY-----',
client_email: 'test@test-project.iam.gserviceaccount.com',
client_id: '123456789',
auth_uri: 'https://accounts.google.com/o/oauth2/auth',
token_uri: 'https://oauth2.googleapis.com/token',
auth_provider_x509_cert_url: 'https://www.googleapis.com/oauth2/v1/certs',
client_x509_cert_url:
'https://www.googleapis.com/robot/v1/metadata/x509/test%40test-project.iam.gserviceaccount.com',
};
beforeEach(() => {
jest.clearAllMocks();
});
it('should return null if keyPath is empty', async () => {
const result = await loadServiceKey('');
expect(result).toBeNull();
});
it('should parse stringified JSON directly', async () => {
const jsonString = JSON.stringify(mockServiceKey);
const result = await loadServiceKey(jsonString);
expect(result).toEqual(mockServiceKey);
});
it('should parse stringified JSON with leading/trailing whitespace', async () => {
const jsonString = ` ${JSON.stringify(mockServiceKey)} `;
const result = await loadServiceKey(jsonString);
expect(result).toEqual(mockServiceKey);
});
it('should load from file path', async () => {
const filePath = '/path/to/service-key.json';
(fs.readFileSync as jest.Mock).mockReturnValue(JSON.stringify(mockServiceKey));
const result = await loadServiceKey(filePath);
expect(fs.readFileSync).toHaveBeenCalledWith(path.resolve(filePath), 'utf8');
expect(result).toEqual(mockServiceKey);
});
it('should load from URL', async () => {
const url = 'https://example.com/service-key.json';
(axios.get as jest.Mock).mockResolvedValue({ data: mockServiceKey });
const result = await loadServiceKey(url);
expect(axios.get).toHaveBeenCalledWith(url);
expect(result).toEqual(mockServiceKey);
});
it('should handle invalid JSON string', async () => {
const invalidJson = '{ invalid json }';
const result = await loadServiceKey(invalidJson);
expect(result).toBeNull();
});
it('should handle file read errors', async () => {
const filePath = '/path/to/nonexistent.json';
(fs.readFileSync as jest.Mock).mockImplementation(() => {
throw new Error('File not found');
});
const result = await loadServiceKey(filePath);
expect(result).toBeNull();
});
it('should handle URL fetch errors', async () => {
const url = 'https://example.com/service-key.json';
(axios.get as jest.Mock).mockRejectedValue(new Error('Network error'));
const result = await loadServiceKey(url);
expect(result).toBeNull();
});
it('should validate service key format', async () => {
const invalidServiceKey = { invalid: 'key' };
const result = await loadServiceKey(JSON.stringify(invalidServiceKey));
expect(result).toEqual(invalidServiceKey); // It returns the object as-is, validation is minimal
});
});