Skip to content

Commit

Permalink
Merge branch 'develop' into 1617-fetch-store-name-from-graphql-at-bui…
Browse files Browse the repository at this point in the history
…ld-time
  • Loading branch information
dpatil-magento authored Mar 9, 2021
2 parents 8b183a9 + c483b3a commit b2b724f
Show file tree
Hide file tree
Showing 13 changed files with 326 additions and 15 deletions.
17 changes: 17 additions & 0 deletions packages/pwa-buildpack/envVarDefinitions.json
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,23 @@
}
]
},
{
"name": "Custom HTTPS certificates",
"variables": [
{
"name": "CUSTOM_HTTPS_KEY",
"type": "str",
"desc": "Absolute path to the custom HTTPS certificate key file.",
"default": ""
},
{
"name": "CUSTOM_HTTPS_CERT",
"type": "str",
"desc": "Absolute path to the custom HTTPS certificate cert file.",
"default": ""
}
]
},
{
"name": "Express compression settings",
"variables": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,18 @@ BUILDBUS_DEPS_ADDITIONAL=
#
################################################################################
#### Custom HTTPS certificates #################################################
#
# Absolute path to the custom HTTPS certificate key file.
# - Default when not set:
CUSTOM_HTTPS_KEY=
#
# Absolute path to the custom HTTPS certificate cert file.
# - Default when not set:
CUSTOM_HTTPS_CERT=
#
################################################################################
#### Express compression settings ##############################################
#
# Specify if express server compression needs to be enabled. Defaults to false if not provided.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,44 @@ UPWARD server running.",
}
`;

exports[`should throw a warning if key and cert paths are provided but cert doesnt exist 1`] = `
Object {
"error": Array [],
"info": Array [
"PORT is set in environment: 1234",
"NODE_ENV=production, will not attempt to use custom host or port",
"Launching UPWARD server
",
],
"success": Array [
"
UPWARD server running.",
],
"warn": Array [
"Custom key and cert paths provided but files not found, creating HTTP server.",
],
}
`;

exports[`should throw a warning if key and cert paths are provided but key doesnt exist 1`] = `
Object {
"error": Array [],
"info": Array [
"PORT is set in environment: 1234",
"NODE_ENV=production, will not attempt to use custom host or port",
"Launching UPWARD server
",
],
"success": Array [
"
UPWARD server running.",
],
"warn": Array [
"Custom key and cert paths provided but files not found, creating HTTP server.",
],
}
`;

exports[`should throw error if unable to load env 1`] = `[Error: Can not load environment config!]`;

exports[`should throw error if unable to load env 2`] = `
Expand Down Expand Up @@ -154,6 +192,24 @@ UPWARD server running.",
}
`;

exports[`should use custom https if key and cert paths provided from the env 1`] = `
Object {
"error": Array [],
"info": Array [
"Custom key and cert paths provided, creating HTTPS server.",
"PORT is set in environment: 1234",
"NODE_ENV=production, will not attempt to use custom host or port",
"Launching UPWARD server
",
],
"success": Array [
"
UPWARD server running.",
],
"warn": Array [],
}
`;

exports[`should use env.PORT if provided 1`] = `
Object {
"error": Array [],
Expand Down
100 changes: 100 additions & 0 deletions packages/pwa-buildpack/lib/Utilities/__tests__/serve.spec.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
jest.mock('fs');
const { existsSync, readFileSync } = require('fs');

const { createUpwardServer } = require('@magento/upward-js');
const compression = require('compression');
const serve = require('../serve');
Expand Down Expand Up @@ -67,6 +70,7 @@ const getImageServiceConfig = jest.fn().mockReturnValue({});
const getCustomOriginConfig = jest.fn().mockReturnValue({
enabled: false
});
const getcustomHttpsConfig = jest.fn().mockReturnValue({});

const getSectionData = sectionName => {
if (sectionName === 'stagingServer') {
Expand All @@ -79,6 +83,8 @@ const getSectionData = sectionName => {
return getImageServiceConfig();
} else if (sectionName === 'customOrigin') {
return getCustomOriginConfig();
} else if (sectionName === 'customHttps') {
return getcustomHttpsConfig();
} else {
return {};
}
Expand Down Expand Up @@ -115,6 +121,11 @@ beforeEach(() => {
);
});

afterEach(() => {
existsSync.mockReset();
readFileSync.mockReset();
});

test('should create upward server', async () => {
const server = await serve('pwa-buildpack');

Expand Down Expand Up @@ -284,3 +295,92 @@ test('should log error if configureHost throws error', async () => {

expect(logs).toMatchSnapshot();
});

test('should use custom https if key and cert paths provided from the env', async () => {
const key = 'path/to/key';
const cert = 'path/to/cert';
getcustomHttpsConfig.mockReturnValueOnce({
key,
cert
});
// mock that files exist
existsSync.mockReturnValue(true);
readFileSync
.mockReturnValueOnce('key_for_https')
.mockReturnValueOnce('cert_for_https');
await serve('pwa-buildpack');

// check if files exist
expect(existsSync).toBeCalledTimes(2);
expect(existsSync.mock.calls[0][0]).toBe(key);
expect(existsSync.mock.calls[1][0]).toBe(cert);

// check if both files are also read
expect(readFileSync).toBeCalledTimes(2);
expect(readFileSync.mock.calls[0]).toEqual([key, 'utf8']);
expect(readFileSync.mock.calls[1]).toEqual([cert, 'utf8']);

// upward server should now have custom key and cert
expect(createUpwardServer.mock.calls[0][0].https).toEqual({
key: 'key_for_https',
cert: 'cert_for_https'
});
// logs info that creating HTTPS server with custom cert and key
expect(logs).toMatchSnapshot();
});

test('should throw a warning if key and cert paths are provided but key doesnt exist', async () => {
const key = 'path/to/key';
const cert = 'path/to/cert';
getcustomHttpsConfig.mockReturnValueOnce({
key,
cert
});
existsSync.mockReturnValueOnce(false);

await serve('pwa-buildpack');

// will be called only once and fail on the if statement
expect(existsSync).toBeCalledTimes(1);

// should not try to read files
expect(readFileSync).not.toBeCalled();
expect(logs.warn.length).toBe(1);
expect(logs).toMatchSnapshot();
expect(createUpwardServer.mock.calls[0][0].https).toBe(undefined);
});

test('should throw a warning if key and cert paths are provided but cert doesnt exist', async () => {
const key = 'path/to/key';
const cert = 'path/to/cert';
getcustomHttpsConfig.mockReturnValueOnce({
key,
cert
});
existsSync.mockReturnValueOnce(true).mockReturnValueOnce(false);

await serve('pwa-buildpack');

// will be called twice and fail on the if statement
expect(existsSync).toBeCalledTimes(2);

// should not try to read files
expect(readFileSync).not.toBeCalled();
expect(logs.warn.length).toBe(1);
expect(logs).toMatchSnapshot();
expect(createUpwardServer.mock.calls[0][0].https).toBe(undefined);
});

test('should not try to read custom key and cert if one of them is missing', async () => {
const key = 'path/to/key';
getcustomHttpsConfig.mockReturnValueOnce({
key,
cert: undefined
});

await serve('pwa-buildpack');

expect(existsSync).not.toBeCalled();
expect(readFileSync).not.toBeCalled();
expect(createUpwardServer.mock.calls[0][0].https).toBe(undefined);
});
24 changes: 23 additions & 1 deletion packages/pwa-buildpack/lib/Utilities/serve.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
const loadEnvironment = require('../Utilities/loadEnvironment');
const path = require('path');
const { existsSync, readFileSync } = require('fs');
const compression = require('compression');

module.exports = async function serve(dirname) {
Expand All @@ -12,6 +13,7 @@ module.exports = async function serve(dirname) {
const prettyLogger = require('../util/pretty-logger');
const addImgOptMiddleware = require('./addImgOptMiddleware');
const stagingServerSettings = config.section('stagingServer');
const customHttpsSettings = config.section('customHttps');

process.chdir(path.join(dirname, 'dist'));

Expand Down Expand Up @@ -41,6 +43,24 @@ module.exports = async function serve(dirname) {
}
);

if (customHttpsSettings.key && customHttpsSettings.cert) {
const { key, cert } = customHttpsSettings;
if (existsSync(key) && existsSync(cert)) {
prettyLogger.info(
'Custom key and cert paths provided, creating HTTPS server.'
);
const ssl = {
key: readFileSync(key, 'utf8'),
cert: readFileSync(cert, 'utf8')
};
upwardServerOptions.https = ssl;
} else {
prettyLogger.warn(
'Custom key and cert paths provided but files not found, creating HTTP server.'
);
}
}

let envPort;
/**
* null and undefined are represented as strings in the env
Expand Down Expand Up @@ -86,8 +106,10 @@ module.exports = async function serve(dirname) {
})
);
upwardServerOptions.host = hostname;
upwardServerOptions.https = ssl;
upwardServerOptions.port = envPort || ports.staging || 0;
if (!upwardServerOptions.https) {
upwardServerOptions.https = ssl;
}
} catch (e) {
prettyLogger.error(
'Could not configure or access custom host. Using loopback...',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
const getModuleRules = require('../configureWebpack/getModuleRules');

describe('css', async () => {
const helper = {
mode: 'development',
paths: {
src: 'unit_test'
},
hasFlag: () => [],
babelRootMode: 'unit_test',
transformRequests: {
babel: {},
source: {}
}
};
const isStyleLoaderRule = rule => {
return rule.loader === 'style-loader';
};
const injectTypeIs = value => {
return rule => rule.options.injectType === value;
};
const injectTypeIsStyleTag = injectTypeIs('styleTag');
const injectTypeIsSingletonStyleTag = injectTypeIs('singletonStyleTag');

test('style loader inject type is "styleTag" in development', async () => {
// Arrange.

// Act.
const rules = await getModuleRules(helper);

// Assert.
// Promise.all returns an array of result objects.
const cssRule = rules[2];

const { oneOf } = cssRule;
oneOf.forEach(rule => {
const { use } = rule;
const allInjectTypesAreCorrect = use
.filter(isStyleLoaderRule)
.every(injectTypeIsStyleTag);

expect(allInjectTypesAreCorrect).toBe(true);
});
});

test('style loader inject type is "singletonStyleTag" not in development', async () => {
// Arrange.
const myHelper = {
...helper,
mode: 'production'
};

// Act.
const rules = await getModuleRules(myHelper);

// Assert.
// Promise.all returns an array of result objects.
const cssRule = rules[2];

const { oneOf } = cssRule;
oneOf.forEach(rule => {
const { use } = rule;
const allInjectTypesAreCorrect = use
.filter(isStyleLoaderRule)
.every(injectTypeIsSingletonStyleTag);

expect(allInjectTypesAreCorrect).toBe(true);
});
});
});
Loading

0 comments on commit b2b724f

Please sign in to comment.