import { SecretsManagerClient, GetSecretValueCommand } from '@aws-sdk/client-secrets-manager' import { SSMClient, GetParameterCommand } from '@aws-sdk/client-ssm' import { expect } from 'chai' import EnvironmentVar, { EnvironmentType } from '../../src/Config/EnvironmentVar.js' import { mockAwsClient, mockAwsCommand, mockAwsResult } from '../AwsSdkTest.utils.js' const SSMMock = mockAwsClient(SSMClient) const SecretsManagerMock = mockAwsClient(SecretsManagerClient) function testRemoteEnv(mock, type, command) { describe(`Optional ${type} environment`, () => { // reset mock beforeEach(() => { mock.reset() }) test('Does not accept sync resolve', async () => { mock.on(mockAwsCommand(command)).resolves( mockAwsResult({ ...(type == EnvironmentType.PlainRemote ? { Parameter: { Value: undefined, }, } : { SecretString: undefined, }), }) ) let err = null try { const env = new EnvironmentVar('abc', type, true) env.syncResolve() } catch (e) { err = e } expect(err).is.not.null expect(err?.['message']).is.not.null }) test('Optional value with null value', async () => { mock.on(mockAwsCommand(command)).resolves( mockAwsResult({ ...(type == EnvironmentType.PlainRemote ? { Parameter: { Value: undefined, }, } : { SecretString: undefined, }), }) ) const env = new EnvironmentVar('abc', type, true) const token = await env.resolve() expect(token).is.undefined }) test('Optional value with empty response', async () => { mock.on(mockAwsCommand(command)).resolves(mockAwsResult({})) const env = new EnvironmentVar('abc', type, true) const token = await env.resolve() expect(token).is.undefined }) test('Optional value with valid response', async () => { const value = 'abc' mock.on(mockAwsCommand(command)).resolves( mockAwsResult({ ...(type == EnvironmentType.PlainRemote ? { Parameter: { Value: value, }, } : { SecretString: value, }), }) ) const env = new EnvironmentVar(value, type, true) const token = await env.resolve() expect(token).is.not.undefined expect(token).to.be.equals(value) }) test('Optional value rejection', async () => { const value = 'abc' mock.on(mockAwsCommand(command)).rejects(new Error('failed!')) const env = new EnvironmentVar(value, type, true) const token = await env.resolve() expect(token).is.undefined }) }) describe(`Required ${type} environment`, () => { // reset mock beforeEach(() => { mock.reset() }) test('Does not accept sync resolve', async () => { mock.on(mockAwsCommand(command)).resolves( mockAwsResult({ ...(type == EnvironmentType.PlainRemote ? { Parameter: { Value: undefined, }, } : { SecretString: undefined, }), }) ) let err = null try { const env = new EnvironmentVar('abc', type) env.syncResolve() } catch (e) { err = e } expect(err).is.not.null expect(err?.['message']).is.not.null }) test('Required fails when null', async () => { mock.on(mockAwsCommand(command)).resolves( mockAwsResult({ ...(type == EnvironmentType.PlainRemote ? { Parameter: { Value: undefined, }, } : { SecretString: undefined, }), }) ) let err = null try { const env = new EnvironmentVar('abc', type) await env.resolve() } catch (e) { err = e } console.log(err) expect(err).is.not.null expect(err?.['message']).is.not.null }) test('Required fails when empty response', async () => { mock.on(mockAwsCommand(command)).resolves(mockAwsResult({})) let err = null try { const env = new EnvironmentVar('abc', type) await env.resolve() } catch (e) { err = e } expect(err).is.not.null expect(err?.['message']).is.not.null }) test('Required value with valid response', async () => { const value = 'abc' mock.on(mockAwsCommand(command)).resolves( mockAwsResult({ ...(type == EnvironmentType.PlainRemote ? { Parameter: { Value: value, }, } : { SecretString: value, }), }) ) const env = new EnvironmentVar(value, type) const token = await env.resolve() expect(token).is.not.undefined expect(token).to.be.equals(value) }) test('Required value rejection', async () => { mock.on(mockAwsCommand(command)).rejects(new Error('failed!')) let err = null try { const env = new EnvironmentVar('abc', type) await env.resolve() } catch (e) { err = e } expect(err).is.not.null expect(err?.['message']).is.not.null }) }) } /* Remote envs test */ testRemoteEnv(SSMMock, EnvironmentType.PlainRemote, GetParameterCommand) testRemoteEnv(SecretsManagerMock, EnvironmentType.SecureRemote, GetSecretValueCommand) describe('Optional Local environment', () => { test('Does accept async resolve', async () => { const env = new EnvironmentVar('PATH123', EnvironmentType.Local, true) const v = await env.resolve() expect(v).is.undefined }) test('Optional value with null value', async () => { const env = new EnvironmentVar('PATH123', EnvironmentType.Local, true) const token = env.syncResolve() expect(token).is.undefined }) test('Optional value with valid value', async () => { const key = 'PATH' const env = new EnvironmentVar(key, EnvironmentType.Local, true) const token = env.syncResolve() expect(token).is.not.undefined expect(token).to.be.equals(process.env[key]) }) }) describe('Required local environment', () => { test('Does accept async resolve', async () => { const key = 'PATH' const env = new EnvironmentVar(key, EnvironmentType.Local) const v = await env.resolve() expect(v).is.not.null expect(v).to.be.equals(process.env[key]) }) test('Required fails when null', async () => { let err = null try { const env = new EnvironmentVar('PATH123', EnvironmentType.Local) env.syncResolve() } catch (e) { err = e } console.log(err) expect(err).is.not.null expect(err?.['message']).is.not.null }) test('Required value with valid value', async () => { const key = 'PATH' const env = new EnvironmentVar(key, EnvironmentType.Local) const v = env.syncResolve() expect(v).is.not.null expect(v).to.be.equals(process.env[key]) }) }) export {}