diff --git a/src/lib/app.ts b/src/lib/app.ts
index 0025fcf61e..c587082806 100644
--- a/src/lib/app.ts
+++ b/src/lib/app.ts
@@ -23,6 +23,7 @@ import demoAuthentication from './middleware/demo-authentication';
import ossAuthentication from './middleware/oss-authentication';
import noAuthentication from './middleware/no-authentication';
import secureHeaders from './middleware/secure-headers';
+import { rewriteHTML } from './util/rewriteHTML';
export default function getApp(
config: IUnleashConfig,
@@ -38,8 +39,7 @@ export default function getApp(
.readFileSync(path.join(publicFolder, 'index.html'))
.toString();
- indexHTML = indexHTML.replace(/::baseUriPath::/gi, baseUriPath);
- indexHTML = indexHTML.replace(/\/static/gi, `${baseUriPath}/static`);
+ indexHTML = rewriteHTML(indexHTML, baseUriPath);
app.set('trust proxy', true);
app.disable('x-powered-by');
diff --git a/src/lib/util/rewriteHTML.test.ts b/src/lib/util/rewriteHTML.test.ts
new file mode 100644
index 0000000000..54dd557929
--- /dev/null
+++ b/src/lib/util/rewriteHTML.test.ts
@@ -0,0 +1,67 @@
+import { rewriteHTML } from './rewriteHTML';
+import test from 'ava';
+
+const input = `
+
+
+
+
+
+
+
+
+
+ Unleash - Enterprise ready feature toggles
+
+
+
+
+
+
+
+
+`;
+
+test('rewriteHTML substitutes meta tag with existing rewrite value', t => {
+ const result = rewriteHTML(input, '/hosted');
+ t.true(result.includes(``));
+});
+
+test('rewriteHTML substitutes meta tag with empty value', t => {
+ const result = rewriteHTML(input, '');
+ t.true(result.includes(``));
+});
+
+test('rewriteHTML substitutes asset paths correctly with baseUriPath', t => {
+ const result = rewriteHTML(input, '/hosted');
+ t.true(
+ result.includes(
+ ``,
+ ),
+ );
+ t.true(
+ result.includes(
+ ` `,
+ ),
+ );
+});
+
+test('rewriteHTML substitutes asset paths correctly without baseUriPath', t => {
+ const result = rewriteHTML(input, '');
+ t.true(
+ result.includes(
+ ``,
+ ),
+ );
+ t.true(
+ result.includes(
+ ` `,
+ ),
+ );
+});
diff --git a/src/lib/util/rewriteHTML.ts b/src/lib/util/rewriteHTML.ts
new file mode 100644
index 0000000000..641c71ac64
--- /dev/null
+++ b/src/lib/util/rewriteHTML.ts
@@ -0,0 +1,7 @@
+export const rewriteHTML = (input: string, rewriteValue: string): string => {
+ let result = input;
+ result = result.replace(/::baseUriPath::/gi, rewriteValue);
+ result = result.replace(/\/static/gi, `${rewriteValue}/static`);
+
+ return result;
+};
diff --git a/src/test/e2e/helpers/test-helper.js b/src/test/e2e/helpers/test-helper.js
index 8ce8af1a78..e338a91e1c 100644
--- a/src/test/e2e/helpers/test-helper.js
+++ b/src/test/e2e/helpers/test-helper.js
@@ -9,7 +9,12 @@ const { createTestConfig } = require('../../config/test-config');
const { IAuthType } = require('../../../lib/types/option');
const { createServices } = require('../../../lib/services');
-function createApp(stores, adminAuthentication = IAuthType.NONE, preHook) {
+function createApp(
+ stores,
+ adminAuthentication = IAuthType.NONE,
+ preHook,
+ customOptions,
+) {
const config = createTestConfig({
authentication: {
type: adminAuthentication,
@@ -18,6 +23,7 @@ function createApp(stores, adminAuthentication = IAuthType.NONE, preHook) {
server: {
unleashUrl: 'http://localhost:4242',
},
+ ...customOptions,
});
const services = createServices(stores, config);
// TODO: use create from server-impl instead?
@@ -39,4 +45,14 @@ module.exports = {
const app = createApp(stores, IAuthType.CUSTOM, preHook);
return supertest.agent(app);
},
+ async setupAppWithBaseUrl(stores) {
+ const app = createApp(stores, undefined, undefined, {
+ server: {
+ unleashUrl: 'http://localhost:4242',
+ basePathUri: '/hosted',
+ },
+ });
+
+ return supertest.agent(app);
+ },
};
diff --git a/src/test/e2e/routes/routes.test.ts b/src/test/e2e/routes/routes.test.ts
new file mode 100644
index 0000000000..c170e8953c
--- /dev/null
+++ b/src/test/e2e/routes/routes.test.ts
@@ -0,0 +1,40 @@
+import test, { before } from 'ava';
+import { setupAppWithBaseUrl } from '../helpers/test-helper';
+
+import dbInit from '../helpers/database-init';
+
+let db;
+let stores;
+
+before(async () => {
+ db = await dbInit('custom_auth_serial');
+ stores = db.stores;
+});
+
+test.after.always(async () => {
+ await db.destroy();
+});
+
+test('hitting a baseUri path returns HTML document', async t => {
+ t.plan(0);
+ const request = await setupAppWithBaseUrl(stores);
+ await request
+ .get('/hosted')
+ .expect(200)
+ .expect('Content-Type', 'text/html; charset=utf-8');
+});
+
+test('hitting an api path that does not exist returns 404', async t => {
+ t.plan(0);
+ const request = await setupAppWithBaseUrl(stores);
+ await request.get('/hosted/api/i-dont-exist').expect(404);
+});
+
+test('hitting a non-api returns HTML document', async t => {
+ t.plan(0);
+ const request = await setupAppWithBaseUrl(stores);
+ await request
+ .get('/hosted/i-dont-exist')
+ .expect(200)
+ .expect('Content-Type', 'text/html; charset=utf-8');
+});