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'); +});