From 816dce60ed0613ffdd10094b769728cae52e45f2 Mon Sep 17 00:00:00 2001 From: Antoine Arlaud Date: Thu, 29 Feb 2024 14:05:33 +0100 Subject: [PATCH] fix: interpolate reflected cfg values --- lib/common/config/config.ts | 22 ++++- lib/common/config/universal.ts | 28 ++++-- .../relay-response-body-universal.test.ts | 89 ++++++++++++------- 3 files changed, 99 insertions(+), 40 deletions(-) diff --git a/lib/common/config/config.ts b/lib/common/config/config.ts index 4080d0e94..9bf9b1d75 100644 --- a/lib/common/config/config.ts +++ b/lib/common/config/config.ts @@ -34,12 +34,14 @@ export const findProjectRoot = (startDir: string): string | null => { return null; }; -export const loadBrokerConfig = () => { +export const loadBrokerConfig = (localConfigForTest?) => { dotenv.config({ path: path.join(process.cwd(), '.env'), }); try { - const localConfig = loadConfig(findProjectRoot(__dirname) ?? process.cwd()); + const localConfig = localConfigForTest + ? localConfigForTest + : loadConfig(findProjectRoot(__dirname) ?? process.cwd()); expand(process.env); config = Object.assign({}, camelify(localConfig), camelify(process.env)); // for each in config.brokerClientConfiguration.common.default check if process env exist and if it does, @@ -186,6 +188,22 @@ function expand(obj: Record): Record { return obj; } +export const expandPlaceholderValuesInFlatList = ( + objectToExpand: Object, + referenceConfig: Object, +) => { + for (const key of Object.keys(objectToExpand)) { + if ( + typeof objectToExpand[key] == 'string' && + objectToExpand[key].startsWith('$') + ) { + objectToExpand[key] = + referenceConfig[objectToExpand[key].replace('$', '')]; + } + } + return objectToExpand; +}; + export const expandConfigObjectRecursively = ( objToExpand: Object, referenceConfig: Object, diff --git a/lib/common/config/universal.ts b/lib/common/config/universal.ts index e18631850..1a056dd6b 100644 --- a/lib/common/config/universal.ts +++ b/lib/common/config/universal.ts @@ -1,6 +1,6 @@ import { log as logger } from '../../logs/logger'; import { ConnectionConfig } from '../../client/types/config'; -import { getConfig } from './config'; +import { expandPlaceholderValuesInFlatList, getConfig } from './config'; export const getConfigForType = (type: string) => { const config = getConfig(); @@ -63,10 +63,16 @@ export const getConfigForIdentifier = (identifier: string, config) => { // `Unable to find configuration type for ${identifier}. Please review config.`, // ); } - return { + const configToOverload = { ...(connectionType ? getConfigForType(connectionType) : {}), - ...(connectionKey ? config.connections[connectionKey] : {}), + ...(connectionKey + ? expandPlaceholderValuesInFlatList( + config.connections[connectionKey], + config.connections[connectionKey], + ) + : {}), }; + return configToOverload; }; export const overloadConfigWithConnectionSpecificConfig = ( @@ -74,10 +80,18 @@ export const overloadConfigWithConnectionSpecificConfig = ( localConfig, ) => { const config = getConfig(); - return { - ...localConfig, - ...getConfigForIdentifier(connectionIdentifier, config), - }; + let overloadedConfig = Object.assign( + {}, + { + ...localConfig, + ...getConfigForIdentifier(connectionIdentifier, config), + }, + ); + overloadedConfig = expandPlaceholderValuesInFlatList( + overloadedConfig, + overloadedConfig, + ); + return overloadedConfig; }; const findConnectionWithIdentifier = (connections: Object, identifier) => { diff --git a/test/unit/relay-response-body-universal.test.ts b/test/unit/relay-response-body-universal.test.ts index 18f5c3d34..e49104783 100644 --- a/test/unit/relay-response-body-universal.test.ts +++ b/test/unit/relay-response-body-universal.test.ts @@ -1,14 +1,17 @@ const PORT = 8001; process.env.BROKER_SERVER_URL = `http://localhost:${PORT}`; -jest.mock('../../lib/common/http/request'); +jest.mock('../../lib/common/relay/requestsHelper'); import { WebSocketConnection } from '../../lib/client/types/client'; -import { makeRequestToDownstream } from '../../lib/common/http/request'; +import { loadBrokerConfig } from '../../lib/common/config/config'; +import { loadAllFilters } from '../../lib/common/filter/filtersAsync'; +import { makeLegacyRequest } from '../../lib/common/relay/requestsHelper'; // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore // eslint-disable-next-line @typescript-eslint/no-unused-vars -const mockedFn = makeRequestToDownstream.mockImplementation((data) => { +const mockedFn = makeLegacyRequest.mockImplementation((data, emit) => { + emit(); // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore return data; @@ -37,20 +40,27 @@ const dummyWebsocketHandler: WebSocketConnection = { send: () => {}, serverId: '0', socket: {}, - supportedIntegrationType: 'github', transport: '', url: '', on: () => {}, readyState: 3, + supportedIntegrationType: 'github', }; -const dummyLoadedFilters = { - private: () => { - return { url: '/', auth: '', stream: true }; - }, - public: () => { - return { url: '/', auth: '', stream: true }; - }, +const dummyLoadedFilters = new Map(); +dummyLoadedFilters['github'] = { + private: [ + { + method: 'any', + url: '/*', + }, + ], + public: [ + { + method: 'any', + url: '/*', + }, + ], }; describe('body relay', () => { @@ -63,21 +73,33 @@ describe('body relay', () => { jest.clearAllMocks(); }); - it('relay swaps body values found in BROKER_VAR_SUB', (done) => { + it('relay swaps body values found in BROKER_VAR_SUB', () => { expect.hasAssertions(); const brokerToken = 'test-broker'; const config = { universalBrokerEnabled: true, + brokerType: 'client', connections: { myconn: { identifier: brokerToken, - HOST: 'localhost', + HOST: '$HOST2', PORT: '8001', + HOST2: 'localhost', + type: 'github', }, }, + brokerClientConfiguration: { + common: { + default: {}, + required: {}, + }, + github: { default: {} }, + }, }; + loadBrokerConfig(config); + const options: LoadedClientOpts | LoadedServerOpts = { filters: { private: [ @@ -90,16 +112,14 @@ describe('body relay', () => { }, config, port: 8001, - loadedFilters: dummyLoadedFilters, + loadedFilters: loadAllFilters(dummyLoadedFilters, config), }; - const route = relay(options, dummyWebsocketHandler)(brokerToken); const body = { BROKER_VAR_SUB: ['url'], url: '${HOST}:${PORT}/webhook', }; - route( { url: '/', @@ -110,34 +130,43 @@ describe('body relay', () => { headers: {}, }, () => { - expect(makeRequestToDownstream).toHaveBeenCalledTimes(1); + expect(makeLegacyRequest).toHaveBeenCalledTimes(1); const arg = mockedFn.mock.calls[0][0]; - expect(JSON.parse(arg.body).url).toEqual( - `${config.connections.myconn.HOST}:${config.connections.myconn.PORT}/webhook`, + const url = JSON.parse(arg.body).url; + expect(url).toEqual( + `${config.connections.myconn.HOST2}:${config.connections.myconn.PORT}/webhook`, ); - - done(); }, ); }); - it('relay does NOT swap body values found in BROKER_VAR_SUB if disabled', (done) => { + it('relay does NOT swaps body values found in BROKER_VAR_SUB if disable substition true', () => { expect.hasAssertions(); const brokerToken = 'test-broker'; const config = { + disableBodyVarsSubstitution: true, universalBrokerEnabled: true, + brokerType: 'client', connections: { myconn: { identifier: brokerToken, - HOST: 'localhost', + HOST: '$HOST2', PORT: '8001', + HOST2: 'localhost', + type: 'github', }, }, - disableBodyVarsSubstitution: true, - brokerServerUrl: 'http://localhost:8001', + brokerClientConfiguration: { + common: { + default: {}, + required: {}, + }, + github: { default: {} }, + }, }; + loadBrokerConfig(config); const options: LoadedClientOpts | LoadedServerOpts = { filters: { @@ -151,7 +180,7 @@ describe('body relay', () => { }, config, port: 8001, - loadedFilters: dummyLoadedFilters, + loadedFilters: loadAllFilters(dummyLoadedFilters, config), }; const route = relay(options, dummyWebsocketHandler)(brokerToken); @@ -159,7 +188,6 @@ describe('body relay', () => { BROKER_VAR_SUB: ['url'], url: '${HOST}:${PORT}/webhook', }; - route( { url: '/', @@ -170,11 +198,10 @@ describe('body relay', () => { headers: {}, }, () => { - expect(makeRequestToDownstream).toHaveBeenCalledTimes(1); + expect(makeLegacyRequest).toHaveBeenCalledTimes(1); const arg = mockedFn.mock.calls[0][0]; - expect(JSON.parse(arg.body).url).toEqual('${HOST}:${PORT}/webhook'); - - done(); + const url = JSON.parse(arg.body).url; + expect(url).toEqual('${HOST}:${PORT}/webhook'); }, ); });