diff --git a/src/static/helpers/fetchHelper.test.ts b/src/static/helpers/fetchHelper.test.ts index f88a07dc..e893a42e 100644 --- a/src/static/helpers/fetchHelper.test.ts +++ b/src/static/helpers/fetchHelper.test.ts @@ -8,7 +8,7 @@ import nock from 'nock'; import {Response} from 'node-fetch'; import * as environment from './environment'; import ClientConfig from '../clientConfig'; -import {doFetch} from './fetchHelper'; +import {doFetch, transferParams, ParameterKey} from './fetchHelper'; describe('doFetch', () => { const basePath = 'https://short_code.api.commercecloud.salesforce.com'; @@ -139,3 +139,121 @@ describe('doFetch', () => { ); }); }); + +describe('transferParams', () => { + const optionParams: Record = { + // organizationId and siteId are not defined here + id: 'id', + inventoryIds: 'inventoryIds', + expand: ['expand1', 'expand2'], + allImages: true, + perPricebook: true, + select: 'select', + currency: 'currency', + locale: 'locale', + }; + + const configParameters = { + shortCode: 'short_code', + organizationId: 'organization_id', + clientId: 'client_id', + siteId: 'site_id', + }; + + const getProductRequired = ['organizationId', 'id']; + + const currentParamKeys: Array = [ + { + parameterName: 'organizationId', + isQueryParameter: false, + }, + { + parameterName: 'id', + isQueryParameter: false, + }, + { + parameterName: 'inventoryIds', + isQueryParameter: true, + }, + { + parameterName: 'expand', + isQueryParameter: true, + }, + { + parameterName: 'allImages', + isQueryParameter: true, + }, + { + parameterName: 'perPricebook', + isQueryParameter: true, + }, + { + parameterName: 'select', + isQueryParameter: true, + }, + { + parameterName: 'currency', + isQueryParameter: true, + }, + { + parameterName: 'locale', + isQueryParameter: true, + }, + { + parameterName: 'siteId', + isQueryParameter: true, + }, + ]; + + test('transferParams successfully populates the query and path parameters object', () => { + const queryParameters = {}; + const pathParameters = {}; + + transferParams({ + optionParams, + configParams: configParameters, + queryParams: queryParameters, + pathParams: pathParameters, + paramKeys: currentParamKeys, + requiredParamKeys: getProductRequired, + }); + + const expectedQueryParameters = { + allImages: true, + currency: 'currency', + expand: ['expand1', 'expand2'], + inventoryIds: 'inventoryIds', + locale: 'locale', + perPricebook: true, + siteId: 'site_id', + select: 'select', + }; + + const expectedPathParameters = { + id: 'id', + organizationId: 'organization_id', + }; + + expect(queryParameters).toEqual(expectedQueryParameters); + expect(pathParameters).toEqual(expectedPathParameters); + }); + + test('transferParams throws error when required parameter is not passed', () => { + const queryParameters = {}; + const pathParameters = {}; + + // remove id from optionParams + const {id, ...newOptionParams} = optionParams; + + expect(() => + transferParams({ + optionParams: newOptionParams, + configParams: configParameters, + queryParams: queryParameters, + pathParams: pathParameters, + paramKeys: currentParamKeys, + requiredParamKeys: getProductRequired, + }) + ).toThrowError('Missing required parameter: id'); + }); +}); diff --git a/src/static/helpers/fetchHelper.ts b/src/static/helpers/fetchHelper.ts index 7b9cbd92..21a57cfe 100644 --- a/src/static/helpers/fetchHelper.ts +++ b/src/static/helpers/fetchHelper.ts @@ -68,3 +68,51 @@ export const doFetch = async ( return (text ? JSON.parse(text) : {}) as unknown | Response; } }; + +export type ParameterKey = { + parameterName: string; + required?: boolean; + isQueryParameter?: boolean; + isPathParameter?: boolean; +}; + +/** + * Transfers parameters from option and config objects to the query parameters object + * based on a list of parameter keys + * + * @param options - The options object + * @param options.optionParams - The options parameters object (higher priority) + * @param options.configParams - The config parameters object (lower priority) + * @param options.queryParams - The query parameters object to populate + * @param options.pathParams - The path parameters object to populate + * @param options.paramKeys - Array of parameter keys to process + * @param options.paramKeys - Array of parameter keys to process + */ +export const transferParams = (options: { + optionParams: Record; + configParams: Record; + queryParams: Record; + pathParams: Record; + paramKeys: Array; + requiredParamKeys: readonly string[]; +}): void => { + const { + optionParams, + configParams, + queryParams, + paramKeys, + pathParams, + requiredParamKeys, + } = options; + paramKeys.forEach(paramKey => { + const currentParams = paramKey.isQueryParameter ? queryParams : pathParams; + const key = paramKey.parameterName; + if (optionParams[key] !== undefined) { + currentParams[key] = optionParams[key]; + } else if (configParams[key] !== undefined) { + currentParams[key] = configParams[key]; + } else if (requiredParamKeys.includes(key)) { + throw new Error(`Missing required parameter: ${paramKey.parameterName}`); + } + }); +};