Skip to content
This repository has been archived by the owner on May 3, 2024. It is now read-only.

fix(module-map): missing baseUrl to module map on server #206

Merged
merged 7 commits into from
Jun 24, 2020
Merged
1 change: 1 addition & 0 deletions __tests__/server/middleware/createRequestStore.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ jest.mock('holocron', () => {
holocron.getModuleMap.mockImplementation(() => fromJS({
modules: {
'test-root': {
baseUrl: 'https://example.com/cdn/test-root/2.2.2/',
node: {
url: 'https://example.com/cdn/test-root/2.2.2/test-root.node.js',
integrity: '4y45hr',
Expand Down
1 change: 1 addition & 0 deletions __tests__/server/middleware/sendHtml.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ describe('sendHtml', () => {
setClientModuleMapCache({
modules: {
'test-root': {
baseUrl: 'https://example.com/cdn/test-root/2.2.2/',
node: {
url: 'https://example.com/cdn/test-root/2.2.2/test-root.node.js',
integrity: '4y45hr',
Expand Down
78 changes: 78 additions & 0 deletions __tests__/server/utils/addBaseUrlToModuleMap.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/*
* Copyright 2019 American Express Travel Related Services Company, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/

import addBaseUrlToModuleMap from '../../../src/server/utils/addBaseUrlToModuleMap';

const moduleMap = {
modules: {
'module-a': {
node: {
url: 'https://example.com/cdn/module-a/1.0.0/module-a.node.js',
integrity: '234',
},
browser: {
url: 'https://example.com/cdn/module-a/1.0.0/module-a.browser.js',
integrity: '353',
},
legacyBrowser: {
url: 'https://example.com/cdn/module-a/1.0.0/module-a.legacy.browser.js',
integrity: '0087',
},
},
'module-b': {
node: {
url: 'https://example.com/cdn/module-b/1.0.0/module-b.node.js',
integrity: '0322380',
},
browser: {
url: 'https://example.com/cdn/module-b/1.0.0/module-b.browser.js',
integrity: 'sd3o23098',
},
legacyBrowser: {
url: 'https://example.com/cdn/module-b/1.0.0/module-b.legacy.browser.js',
integrity: 'flj23032',
},
},
},
};

describe('addBaseUrlToModuleMap', () => {
it('creates a "baseUrl" entry for each module and returns a module map including the new key', () => {
const updatedModuleMap = addBaseUrlToModuleMap(moduleMap);
Object.keys(updatedModuleMap.modules).forEach((moduleName) => {
const module = updatedModuleMap.modules[moduleName];
expect(module.baseUrl).toBe(`https://example.com/cdn/${moduleName}/1.0.0/`);
});
});

it('does not override the baseUrl key if already present in the module map', () => {
const moduleMapWithBaseUrl = {
...moduleMap,
modules: {
...moduleMap.modules,
'module-a': {
...moduleMap.modules['module-a'],
baseUrl: 'https://example.com/languages/module-a/1.0.0/',
},
},
};
const updatedModuleMap = addBaseUrlToModuleMap(moduleMapWithBaseUrl);
const moduleA = updatedModuleMap.modules['module-a'];
const moduleB = updatedModuleMap.modules['module-b'];
expect(moduleA.baseUrl).toBe('https://example.com/languages/module-a/1.0.0/');
expect(moduleB.baseUrl).toBe('https://example.com/cdn/module-b/1.0.0/');
});
});
10 changes: 0 additions & 10 deletions __tests__/server/utils/clientModuleMapCache.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,16 +62,6 @@ describe('clientModuleMapCache', () => {
expect(Object.keys(moduleMapCache)).toEqual(cacheKeys);
});

it('creates a "baseUrl" entry for each module and returns a module map including the addition', () => {
// conflicting eslint rules here
// eslint-disable-next-line max-len
cacheKeys.forEach((cacheKey) => Object.keys(moduleMapCache[cacheKey].modules).forEach((moduleName) => {
const module = moduleMapCache[cacheKey].modules[moduleName];
expect(module.baseUrl).toBe(`https://example.com/cdn/${moduleName}/1.0.0/`);
})
);
});

it('only includes values for a single bundle per module in each map', () => {
// conflicting eslint rules here
// eslint-disable-next-line max-len
Expand Down
3 changes: 2 additions & 1 deletion __tests__/server/utils/loadModules.spec.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { CONFIGURATION_KEY } from '../../../src/server/utils/onModuleLoad';
import loadModules from '../../../src/server/utils/loadModules';
import { updateCSP } from '../../../src/server/middleware/csp';
import { setClientModuleMapCache, getClientModuleMapCache } from '../../../src/server/utils/clientModuleMapCache';
import addBaseUrlToModuleMap from '../../../src/server/utils/addBaseUrlToModuleMap';

// This named export exists only on the mock
// eslint-disable-next-line import/named
Expand Down Expand Up @@ -95,7 +96,7 @@ describe('loadModules', () => {
it('updates the holocron module registry', async () => {
await loadModules();
expect(updateModuleRegistry).toHaveBeenCalledWith({
moduleMap,
moduleMap: addBaseUrlToModuleMap(moduleMap),
batchModulesToUpdate: require('../../../src/server/utils/batchModulesToUpdate').default,
getModulesToUpdate: require('../../../src/server/utils/getModulesToUpdate').default,
onModuleLoad: require('../../../src/server/utils/onModuleLoad').default,
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

32 changes: 32 additions & 0 deletions src/server/utils/addBaseUrlToModuleMap.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* Copyright 2020 American Express Travel Related Services Company, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/

/* The baseUrl key in the module map is used by one-app-ducks to construct
the language pack URL pointing at the location of the language pack */
const addBaseUrlToModuleMap = (moduleMap) => ({
...moduleMap,
modules: Object.entries(moduleMap.modules).reduce((acc, [moduleName, moduleBundles]) => (
{
...acc,
[moduleName]: {
...moduleBundles,
baseUrl: moduleBundles.baseUrl ? moduleBundles.baseUrl : moduleBundles.node.url.replace(/[^/]+\.js$/i, ''),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this option should be documented

},
}
), {}),
});

export default addBaseUrlToModuleMap;
4 changes: 3 additions & 1 deletion src/server/utils/clientModuleMapCache.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,16 @@

let cache = {};

/* Filters bundle types so only the required client moduleBundleType is returned
in ../server/middleware/sendHtml.js and reducing the html payload size */
function filterBundles(moduleMap, moduleBundleType) {
return {
...moduleMap,
modules: Object.entries(moduleMap.modules).reduce((acc, [moduleName, moduleBundles]) => (
{
...acc,
[moduleName]: {
baseUrl: moduleBundles[moduleBundleType].url.replace(/[^/]+\.js$/i, ''),
baseUrl: moduleBundles.baseUrl,
[moduleBundleType]: moduleBundles[moduleBundleType],
},
}
Expand Down
3 changes: 2 additions & 1 deletion src/server/utils/loadModules.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,11 @@ import getModulesToUpdate from './getModulesToUpdate';
import { getServerStateConfig } from './stateConfig';
import { setClientModuleMapCache } from './clientModuleMapCache';
import { updateCSP } from '../middleware/csp';
import addBaseUrlToModuleMap from './addBaseUrlToModuleMap';

const loadModules = async () => {
const moduleMapResponse = await fetch(process.env.HOLOCRON_MODULE_MAP_URL);
const moduleMap = await moduleMapResponse.json();
const moduleMap = addBaseUrlToModuleMap(await moduleMapResponse.json());
const serverConfig = getServerStateConfig();

const loadedModules = await updateModuleRegistry({
Expand Down