gcp-monorepo-secret-manager
Version:
A Google Cloud Secret Manager utility for managing environment variables across different environments and services within a monorepo.
150 lines • 6.43 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const loadConfig_1 = require("../loadConfig");
const initSecretManagerClient_1 = require("../initSecretManagerClient");
const fs = __importStar(require("fs"));
const path = __importStar(require("path"));
const dotenv_1 = __importDefault(require("dotenv"));
// Mock the dependencies
jest.mock('../initSecretManagerClient');
jest.mock('fs');
jest.mock('dotenv');
jest.mock('path');
const mockFs = fs;
const mockPath = path;
const mockDotenv = dotenv_1.default;
const mockInitSecretManagerClient = initSecretManagerClient_1.initSecretManagerClient;
describe('loadConfig', () => {
const mockClient = {
accessSecretVersion: jest.fn()
};
beforeEach(() => {
jest.clearAllMocks();
mockInitSecretManagerClient.mockReturnValue(mockClient);
mockPath.resolve.mockReturnValue('/path/to/.env');
mockDotenv.config.mockReturnValue({ parsed: {}, error: undefined });
// Mock process.env
process.env.ENV = 'STG';
});
afterEach(() => {
delete process.env.ENV;
});
it('should use existing .env file if it exists', async () => {
mockFs.existsSync.mockReturnValue(true);
await (0, loadConfig_1.loadConfig)({
serviceName: 'test-service',
projectId: 'test-project'
});
expect(mockFs.existsSync).toHaveBeenCalledWith('/path/to/.env');
expect(mockDotenv.config).toHaveBeenCalledWith({ path: '/path/to/.env' });
expect(mockInitSecretManagerClient).not.toHaveBeenCalled();
});
it('should fetch from Secret Manager when .env file does not exist', async () => {
mockFs.existsSync.mockReturnValue(false);
const mockSecretData = 'NODE_ENV=staging\nENV=STG\nPORT=3000';
mockClient.accessSecretVersion.mockResolvedValue([{
payload: {
data: Buffer.from(mockSecretData)
}
}]);
await (0, loadConfig_1.loadConfig)({
serviceName: 'test-service',
projectId: 'test-project'
});
expect(mockInitSecretManagerClient).toHaveBeenCalled();
expect(mockClient.accessSecretVersion).toHaveBeenCalledWith({
name: 'projects/test-project/secrets/TEST-SERVICE_ENV_FILE/versions/latest'
});
expect(mockFs.writeFileSync).toHaveBeenCalledWith('/path/to/.env', mockSecretData);
});
it('should use custom secret name when provided', async () => {
mockFs.existsSync.mockReturnValue(false);
mockClient.accessSecretVersion.mockResolvedValue([{
payload: {
data: Buffer.from('NODE_ENV=staging\nENV=STG')
}
}]);
await (0, loadConfig_1.loadConfig)({
serviceName: 'test-service',
projectId: 'test-project',
secretName: 'custom-secret'
});
expect(mockClient.accessSecretVersion).toHaveBeenCalledWith({
name: 'projects/test-project/secrets/custom-secret/versions/latest'
});
});
it('should check required environment variables', async () => {
mockFs.existsSync.mockReturnValue(true);
// Mock process.env to not have the required variable
delete process.env.REQUIRED_VAR;
await expect((0, loadConfig_1.loadConfig)({
serviceName: 'test-service',
projectId: 'test-project',
requiredEnvVars: ['REQUIRED_VAR']
})).rejects.toThrow('Missing required environment variables: REQUIRED_VAR');
});
it('should pass when all required environment variables are present', async () => {
mockFs.existsSync.mockReturnValue(true);
// Mock process.env to have the required variable
process.env.REQUIRED_VAR = 'test-value';
await expect((0, loadConfig_1.loadConfig)({
serviceName: 'test-service',
projectId: 'test-project',
requiredEnvVars: ['REQUIRED_VAR']
})).resolves.toBeUndefined();
});
it('should throw error when ENV is not set after loading', async () => {
mockFs.existsSync.mockReturnValue(true);
// Mock process.env to not have ENV
delete process.env.ENV;
await expect((0, loadConfig_1.loadConfig)({
serviceName: 'test-service',
projectId: 'test-project'
})).rejects.toThrow('ENV is not set');
});
it('should handle errors from Secret Manager', async () => {
mockFs.existsSync.mockReturnValue(false);
mockClient.accessSecretVersion.mockRejectedValue(new Error('Secret not found'));
await expect((0, loadConfig_1.loadConfig)({
serviceName: 'test-service',
projectId: 'test-project'
})).rejects.toThrow('Failed to initialize config for test-service from Secret Manager');
});
});
//# sourceMappingURL=loadConfig.test.js.map