mirror of
https://github.com/Unleash/unleash.git
synced 2025-03-27 00:19:39 +01:00
feat: add support for cdnPrefix for static assets (#1191)
This commit is contained in:
parent
2b59a4219a
commit
26b7da8b5c
@ -63,6 +63,7 @@ Object {
|
||||
"secureHeaders": false,
|
||||
"server": Object {
|
||||
"baseUriPath": "",
|
||||
"cdnPrefix": undefined,
|
||||
"enableRequestLogger": false,
|
||||
"gracefulShutdownEnable": true,
|
||||
"gracefulShutdownTimeout": 1000,
|
||||
|
@ -11,32 +11,32 @@ jest.mock(
|
||||
},
|
||||
);
|
||||
|
||||
const getApp = require('./app');
|
||||
const getApp = require('./app').default;
|
||||
|
||||
test('should not throw when valid config', () => {
|
||||
test('should not throw when valid config', async () => {
|
||||
const config = createTestConfig();
|
||||
const app = getApp(config, {}, {});
|
||||
const app = await getApp(config, {}, {});
|
||||
expect(typeof app.listen).toBe('function');
|
||||
});
|
||||
|
||||
test('should call preHook', () => {
|
||||
test('should call preHook', async () => {
|
||||
let called = 0;
|
||||
const config = createTestConfig({
|
||||
preHook: () => {
|
||||
called++;
|
||||
},
|
||||
});
|
||||
getApp(config, {}, {});
|
||||
await getApp(config, {}, {});
|
||||
expect(called).toBe(1);
|
||||
});
|
||||
|
||||
test('should call preRouterHook', () => {
|
||||
test('should call preRouterHook', async () => {
|
||||
let called = 0;
|
||||
const config = createTestConfig({
|
||||
preRouterHook: () => {
|
||||
called++;
|
||||
},
|
||||
});
|
||||
getApp(config, {}, {});
|
||||
await getApp(config, {}, {});
|
||||
expect(called).toBe(1);
|
||||
});
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { publicFolder } from 'unleash-frontend';
|
||||
import fs from 'fs';
|
||||
import express, { Application, RequestHandler } from 'express';
|
||||
import cors from 'cors';
|
||||
import compression from 'compression';
|
||||
@ -22,23 +21,19 @@ import ossAuthentication from './middleware/oss-authentication';
|
||||
import noAuthentication from './middleware/no-authentication';
|
||||
import secureHeaders from './middleware/secure-headers';
|
||||
|
||||
import { rewriteHTML } from './util/rewriteHTML';
|
||||
import { loadIndexHTML } from './util/load-index-html';
|
||||
|
||||
export default function getApp(
|
||||
export default async function getApp(
|
||||
config: IUnleashConfig,
|
||||
stores: IUnleashStores,
|
||||
services: IUnleashServices,
|
||||
unleashSession?: RequestHandler,
|
||||
): Application {
|
||||
): Promise<Application> {
|
||||
const app = express();
|
||||
|
||||
const baseUriPath = config.server.baseUriPath || '';
|
||||
|
||||
let indexHTML = fs
|
||||
.readFileSync(path.join(publicFolder, 'index.html'))
|
||||
.toString();
|
||||
|
||||
indexHTML = rewriteHTML(indexHTML, baseUriPath);
|
||||
let indexHTML = await loadIndexHTML(config, publicFolder);
|
||||
|
||||
app.set('trust proxy', true);
|
||||
app.disable('x-powered-by');
|
||||
@ -68,7 +63,7 @@ export default function getApp(
|
||||
app.use(secureHeaders(config));
|
||||
app.use(express.urlencoded({ extended: true }));
|
||||
app.use(favicon(path.join(publicFolder, 'favicon.ico')));
|
||||
|
||||
app.use(baseUriPath, favicon(path.join(publicFolder, 'favicon.ico')));
|
||||
app.use(baseUriPath, express.static(publicFolder, { index: false }));
|
||||
|
||||
if (config.enableOAS) {
|
||||
@ -151,4 +146,3 @@ export default function getApp(
|
||||
});
|
||||
return app;
|
||||
}
|
||||
module.exports = getApp;
|
||||
|
@ -107,6 +107,7 @@ const defaultServerOption: IServerOption = {
|
||||
host: process.env.HTTP_HOST,
|
||||
port: safeNumber(process.env.HTTP_PORT || process.env.PORT, 4242),
|
||||
baseUriPath: formatBaseUri(process.env.BASE_URI_PATH),
|
||||
cdnPrefix: process.env.CDN_PREFIX,
|
||||
unleashUrl: process.env.UNLEASH_URL || 'http://localhost:4242',
|
||||
serverMetrics: true,
|
||||
keepAliveTimeout: minutesToMilliseconds(1),
|
||||
|
@ -8,7 +8,7 @@ import getApp from '../app';
|
||||
import User from '../types/user';
|
||||
import sessionDb from './session-db';
|
||||
|
||||
function getSetup(preRouterHook) {
|
||||
async function getSetup(preRouterHook) {
|
||||
const base = `/random${Math.round(Math.random() * 1000)}`;
|
||||
const config = createTestConfig({
|
||||
server: { baseUriPath: base },
|
||||
@ -23,7 +23,7 @@ function getSetup(preRouterHook) {
|
||||
const stores = createStores();
|
||||
const services = createServices(stores, config);
|
||||
const unleashSession = sessionDb(config, undefined);
|
||||
const app = getApp(config, stores, services, unleashSession);
|
||||
const app = await getApp(config, stores, services, unleashSession);
|
||||
|
||||
return {
|
||||
base,
|
||||
@ -31,17 +31,17 @@ function getSetup(preRouterHook) {
|
||||
};
|
||||
}
|
||||
|
||||
test('should return 401 when missing user', () => {
|
||||
test('should return 401 when missing user', async () => {
|
||||
expect.assertions(0);
|
||||
const { base, request } = getSetup(() => {});
|
||||
const { base, request } = await getSetup(() => {});
|
||||
|
||||
return request.get(`${base}/api/protectedResource`).expect(401);
|
||||
});
|
||||
|
||||
test('should return 200 when user exists', () => {
|
||||
test('should return 200 when user exists', async () => {
|
||||
expect.assertions(0);
|
||||
const user = new User({ id: 1, email: 'some@mail.com' });
|
||||
const { base, request } = getSetup((app) =>
|
||||
const { base, request } = await getSetup((app) =>
|
||||
app.use((req, res, next) => {
|
||||
req.user = user;
|
||||
next();
|
||||
|
@ -10,7 +10,7 @@ const uiConfig = {
|
||||
slogan: 'hello',
|
||||
};
|
||||
|
||||
function getSetup() {
|
||||
async function getSetup() {
|
||||
const base = `/random${Math.round(Math.random() * 1000)}`;
|
||||
const config = createTestConfig({
|
||||
server: { baseUriPath: base },
|
||||
@ -19,7 +19,7 @@ function getSetup() {
|
||||
const stores = createStores();
|
||||
const services = createServices(stores, config);
|
||||
|
||||
const app = getApp(config, stores, services);
|
||||
const app = await getApp(config, stores, services);
|
||||
|
||||
return {
|
||||
base,
|
||||
@ -36,8 +36,8 @@ let request;
|
||||
let base;
|
||||
let destroy;
|
||||
|
||||
beforeEach(() => {
|
||||
const setup = getSetup();
|
||||
beforeEach(async () => {
|
||||
const setup = await getSetup();
|
||||
request = setup.request;
|
||||
base = setup.base;
|
||||
destroy = setup.destroy;
|
||||
|
@ -5,7 +5,7 @@ import { createServices } from '../../services';
|
||||
import permissions from '../../../test/fixtures/permissions';
|
||||
import getApp from '../../app';
|
||||
|
||||
function getSetup() {
|
||||
async function getSetup() {
|
||||
const base = `/random${Math.round(Math.random() * 1000)}`;
|
||||
const perms = permissions();
|
||||
const config = createTestConfig({
|
||||
@ -15,7 +15,7 @@ function getSetup() {
|
||||
const stores = createStores();
|
||||
|
||||
const services = createServices(stores, config);
|
||||
const app = getApp(config, stores, services);
|
||||
const app = await getApp(config, stores, services);
|
||||
|
||||
return {
|
||||
base,
|
||||
@ -32,8 +32,8 @@ let base;
|
||||
let request;
|
||||
let destroy;
|
||||
|
||||
beforeEach(() => {
|
||||
const setup = getSetup();
|
||||
beforeEach(async () => {
|
||||
const setup = await getSetup();
|
||||
base = setup.base;
|
||||
request = setup.request;
|
||||
destroy = setup.destroy;
|
||||
|
@ -5,7 +5,7 @@ import { createServices } from '../../services';
|
||||
import permissions from '../../../test/fixtures/permissions';
|
||||
import getApp from '../../app';
|
||||
|
||||
function getSetup() {
|
||||
async function getSetup() {
|
||||
const base = `/random${Math.round(Math.random() * 1000)}`;
|
||||
const stores = createStores();
|
||||
const perms = permissions();
|
||||
@ -15,7 +15,7 @@ function getSetup() {
|
||||
});
|
||||
|
||||
const services = createServices(stores, config);
|
||||
const app = getApp(config, stores, services);
|
||||
const app = await getApp(config, stores, services);
|
||||
|
||||
return {
|
||||
base,
|
||||
@ -23,9 +23,9 @@ function getSetup() {
|
||||
};
|
||||
}
|
||||
|
||||
test('should render html preview of template', () => {
|
||||
test('should render html preview of template', async () => {
|
||||
expect.assertions(0);
|
||||
const { request, base } = getSetup();
|
||||
const { request, base } = await getSetup();
|
||||
return request
|
||||
.get(
|
||||
`${base}/api/admin/email/preview/html/reset-password?name=Test%20Test`,
|
||||
@ -35,9 +35,9 @@ test('should render html preview of template', () => {
|
||||
.expect((res) => 'Test Test' in res.body);
|
||||
});
|
||||
|
||||
test('should render text preview of template', () => {
|
||||
test('should render text preview of template', async () => {
|
||||
expect.assertions(0);
|
||||
const { request, base } = getSetup();
|
||||
const { request, base } = await getSetup();
|
||||
return request
|
||||
.get(
|
||||
`${base}/api/admin/email/preview/text/reset-password?name=Test%20Test`,
|
||||
@ -47,9 +47,9 @@ test('should render text preview of template', () => {
|
||||
.expect((res) => 'Test Test' in res.body);
|
||||
});
|
||||
|
||||
test('Requesting a non-existing template should yield 404', () => {
|
||||
test('Requesting a non-existing template should yield 404', async () => {
|
||||
expect.assertions(0);
|
||||
const { request, base } = getSetup();
|
||||
const { request, base } = await getSetup();
|
||||
return request
|
||||
.get(`${base}/api/admin/email/preview/text/some-non-existing-template`)
|
||||
.expect(404);
|
||||
|
@ -6,21 +6,21 @@ import createStores from '../../../test/fixtures/store';
|
||||
|
||||
import getApp from '../../app';
|
||||
|
||||
function getSetup() {
|
||||
async function getSetup() {
|
||||
const base = `/random${Math.round(Math.random() * 1000)}`;
|
||||
const stores = createStores();
|
||||
const config = createTestConfig({
|
||||
server: { baseUriPath: base },
|
||||
});
|
||||
const services = createServices(stores, config);
|
||||
const app = getApp(config, stores, services);
|
||||
const app = await getApp(config, stores, services);
|
||||
|
||||
return { base, eventStore: stores.eventStore, request: supertest(app) };
|
||||
}
|
||||
|
||||
test('should get empty events list via admin', () => {
|
||||
test('should get empty events list via admin', async () => {
|
||||
expect.assertions(1);
|
||||
const { request, base } = getSetup();
|
||||
const { request, base } = await getSetup();
|
||||
return request
|
||||
.get(`${base}/api/admin/events`)
|
||||
.expect('Content-Type', /json/)
|
||||
|
@ -5,14 +5,14 @@ import getApp from '../../app';
|
||||
import { createTestConfig } from '../../../test/config/test-config';
|
||||
import { createServices } from '../../services';
|
||||
|
||||
function getSetup() {
|
||||
async function getSetup() {
|
||||
const stores = createStores();
|
||||
const perms = permissions();
|
||||
const config = createTestConfig({
|
||||
preRouterHook: perms.hook,
|
||||
});
|
||||
const services = createServices(stores, config);
|
||||
const app = getApp(config, stores, services);
|
||||
const app = await getApp(config, stores, services);
|
||||
|
||||
return {
|
||||
request: supertest(app),
|
||||
@ -30,8 +30,8 @@ let stores;
|
||||
let request;
|
||||
let destroy;
|
||||
|
||||
beforeEach(() => {
|
||||
const setup = getSetup();
|
||||
beforeEach(async () => {
|
||||
const setup = await getSetup();
|
||||
stores = setup.stores;
|
||||
request = setup.request;
|
||||
destroy = setup.destroy;
|
||||
|
@ -7,7 +7,7 @@ import { createServices } from '../../services';
|
||||
|
||||
let destroy;
|
||||
|
||||
function getSetup() {
|
||||
async function getSetup() {
|
||||
const randomBase = `/random${Math.round(Math.random() * 1000)}`;
|
||||
const perms = permissions();
|
||||
const stores = createStores();
|
||||
@ -16,7 +16,7 @@ function getSetup() {
|
||||
preRouterHook: perms.hook,
|
||||
});
|
||||
const services = createServices(stores, config);
|
||||
const app = getApp(config, stores, services);
|
||||
const app = await getApp(config, stores, services);
|
||||
|
||||
destroy = () => {
|
||||
services.versionService.destroy();
|
||||
@ -36,8 +36,8 @@ afterEach(() => {
|
||||
destroy();
|
||||
});
|
||||
|
||||
test('add version numbers for /strategies', () => {
|
||||
const { request, base } = getSetup();
|
||||
test('add version numbers for /strategies', async () => {
|
||||
const { request, base } = await getSetup();
|
||||
return request
|
||||
.get(`${base}/api/admin/strategies`)
|
||||
.expect('Content-Type', /json/)
|
||||
@ -47,8 +47,8 @@ test('add version numbers for /strategies', () => {
|
||||
});
|
||||
});
|
||||
|
||||
test('require a name when creating a new strategy', () => {
|
||||
const { request, base } = getSetup();
|
||||
test('require a name when creating a new strategy', async () => {
|
||||
const { request, base } = await getSetup();
|
||||
return request
|
||||
.post(`${base}/api/admin/strategies`)
|
||||
.send({})
|
||||
@ -60,8 +60,8 @@ test('require a name when creating a new strategy', () => {
|
||||
});
|
||||
});
|
||||
|
||||
test('require parameters array when creating a new stratey', () => {
|
||||
const { request, base } = getSetup();
|
||||
test('require parameters array when creating a new strategy', async () => {
|
||||
const { request, base } = await getSetup();
|
||||
return request
|
||||
.post(`${base}/api/admin/strategies`)
|
||||
.send({ name: 'TestStrat' })
|
||||
@ -74,15 +74,15 @@ test('require parameters array when creating a new stratey', () => {
|
||||
});
|
||||
|
||||
test('create a new strategy with empty parameters', async () => {
|
||||
const { request, base } = getSetup();
|
||||
const { request, base } = await getSetup();
|
||||
return request
|
||||
.post(`${base}/api/admin/strategies`)
|
||||
.send({ name: 'TestStrat', parameters: [] })
|
||||
.expect(201);
|
||||
});
|
||||
|
||||
test('not be possible to override name', () => {
|
||||
const { request, base, strategyStore } = getSetup();
|
||||
test('not be possible to override name', async () => {
|
||||
const { request, base, strategyStore } = await getSetup();
|
||||
strategyStore.createStrategy({ name: 'Testing', parameters: [] });
|
||||
|
||||
return request
|
||||
@ -91,8 +91,8 @@ test('not be possible to override name', () => {
|
||||
.expect(409);
|
||||
});
|
||||
|
||||
test('update strategy', () => {
|
||||
const { request, base, strategyStore } = getSetup();
|
||||
test('update strategy', async () => {
|
||||
const { request, base, strategyStore } = await getSetup();
|
||||
const name = 'AnotherStrat';
|
||||
strategyStore.createStrategy({ name, parameters: [] });
|
||||
|
||||
@ -102,8 +102,8 @@ test('update strategy', () => {
|
||||
.expect(200);
|
||||
});
|
||||
|
||||
test('not update unknown strategy', () => {
|
||||
const { request, base } = getSetup();
|
||||
test('not update unknown strategy', async () => {
|
||||
const { request, base } = await getSetup();
|
||||
const name = 'UnknownStrat';
|
||||
return request
|
||||
.put(`${base}/api/admin/strategies/${name}`)
|
||||
@ -111,8 +111,8 @@ test('not update unknown strategy', () => {
|
||||
.expect(404);
|
||||
});
|
||||
|
||||
test('validate format when updating strategy', () => {
|
||||
const { request, base, strategyStore } = getSetup();
|
||||
test('validate format when updating strategy', async () => {
|
||||
const { request, base, strategyStore } = await getSetup();
|
||||
const name = 'AnotherStrat';
|
||||
strategyStore.createStrategy({ name, parameters: [] });
|
||||
|
||||
@ -122,16 +122,16 @@ test('validate format when updating strategy', () => {
|
||||
.expect(400);
|
||||
});
|
||||
|
||||
test('editable=false will stop delete request', () => {
|
||||
test('editable=false will stop delete request', async () => {
|
||||
jest.spyOn(global.console, 'error').mockImplementation(() => jest.fn());
|
||||
const { request, base } = getSetup();
|
||||
const { request, base } = await getSetup();
|
||||
const name = 'default';
|
||||
return request.delete(`${base}/api/admin/strategies/${name}`).expect(500);
|
||||
});
|
||||
|
||||
test('editable=false will stop edit request', () => {
|
||||
test('editable=false will stop edit request', async () => {
|
||||
jest.spyOn(global.console, 'error').mockImplementation(() => jest.fn());
|
||||
const { request, base } = getSetup();
|
||||
const { request, base } = await getSetup();
|
||||
const name = 'default';
|
||||
return request
|
||||
.put(`${base}/api/admin/strategies/${name}`)
|
||||
@ -139,8 +139,8 @@ test('editable=false will stop edit request', () => {
|
||||
.expect(500);
|
||||
});
|
||||
|
||||
test('editable=true will allow delete request', () => {
|
||||
const { request, base, strategyStore } = getSetup();
|
||||
test('editable=true will allow delete request', async () => {
|
||||
const { request, base, strategyStore } = await getSetup();
|
||||
const name = 'deleteStrat';
|
||||
strategyStore.createStrategy({ name, parameters: [] });
|
||||
|
||||
@ -150,8 +150,8 @@ test('editable=true will allow delete request', () => {
|
||||
.expect(200);
|
||||
});
|
||||
|
||||
test('editable=true will allow edit request', () => {
|
||||
const { request, base, strategyStore } = getSetup();
|
||||
test('editable=true will allow edit request', async () => {
|
||||
const { request, base, strategyStore } = await getSetup();
|
||||
const name = 'editStrat';
|
||||
strategyStore.createStrategy({ name, parameters: [] });
|
||||
|
||||
@ -162,7 +162,7 @@ test('editable=true will allow edit request', () => {
|
||||
});
|
||||
|
||||
test('deprecating a strategy works', async () => {
|
||||
const { request, base, strategyStore } = getSetup();
|
||||
const { request, base, strategyStore } = await getSetup();
|
||||
const name = 'editStrat';
|
||||
strategyStore.createStrategy({ name, parameters: [] });
|
||||
|
||||
@ -177,8 +177,8 @@ test('deprecating a strategy works', async () => {
|
||||
.expect((res) => expect(res.body.deprecated).toBe(true));
|
||||
});
|
||||
|
||||
test('deprecating a non-existent strategy yields 404', () => {
|
||||
const { request, base } = getSetup();
|
||||
test('deprecating a non-existent strategy yields 404', async () => {
|
||||
const { request, base } = await getSetup();
|
||||
return request
|
||||
.post(`${base}/api/admin/strategies/non-existent-strategy/deprecate`)
|
||||
.set('Content-Type', 'application/json')
|
||||
@ -186,7 +186,7 @@ test('deprecating a non-existent strategy yields 404', () => {
|
||||
});
|
||||
|
||||
test('reactivating a strategy works', async () => {
|
||||
const { request, base, strategyStore } = getSetup();
|
||||
const { request, base, strategyStore } = await getSetup();
|
||||
const name = 'editStrat';
|
||||
strategyStore.createStrategy({ name, parameters: [] });
|
||||
|
||||
@ -201,16 +201,16 @@ test('reactivating a strategy works', async () => {
|
||||
.expect((res) => expect(res.body.deprecated).toBe(false));
|
||||
});
|
||||
|
||||
test('reactivating a non-existent strategy yields 404', () => {
|
||||
const { request, base } = getSetup();
|
||||
test('reactivating a non-existent strategy yields 404', async () => {
|
||||
const { request, base } = await getSetup();
|
||||
return request
|
||||
.post(`${base}/api/admin/strategies/non-existent-strategy/reactivate`)
|
||||
.set('Content-Type', 'application/json')
|
||||
.expect(404);
|
||||
});
|
||||
test("deprecating 'default' strategy will yield 403", () => {
|
||||
test("deprecating 'default' strategy will yield 403", async () => {
|
||||
jest.spyOn(global.console, 'error').mockImplementation(() => jest.fn());
|
||||
const { request, base } = getSetup();
|
||||
const { request, base } = await getSetup();
|
||||
return request
|
||||
.post(`${base}/api/admin/strategies/default/deprecate`)
|
||||
.set('Content-Type', 'application/json')
|
||||
|
@ -5,7 +5,7 @@ import getApp from '../../app';
|
||||
import { createTestConfig } from '../../../test/config/test-config';
|
||||
import { createServices } from '../../services';
|
||||
|
||||
function getSetup() {
|
||||
async function getSetup() {
|
||||
const base = `/random${Math.round(Math.random() * 1000)}`;
|
||||
const stores = createStores();
|
||||
const perms = permissions();
|
||||
@ -14,7 +14,7 @@ function getSetup() {
|
||||
preRouterHook: perms.hook,
|
||||
});
|
||||
const services = createServices(stores, config);
|
||||
const app = getApp(config, stores, services);
|
||||
const app = await getApp(config, stores, services);
|
||||
|
||||
return {
|
||||
base,
|
||||
@ -34,8 +34,8 @@ let tagStore;
|
||||
let request;
|
||||
let destroy;
|
||||
|
||||
beforeEach(() => {
|
||||
const setup = getSetup();
|
||||
beforeEach(async () => {
|
||||
const setup = await getSetup();
|
||||
base = setup.base;
|
||||
tagStore = setup.tagStore;
|
||||
request = setup.request;
|
||||
|
@ -23,7 +23,7 @@ async function getSetup() {
|
||||
server: { baseUriPath: base },
|
||||
});
|
||||
const services = createServices(stores, config);
|
||||
const app = getApp(config, stores, services);
|
||||
const app = await getApp(config, stores, services);
|
||||
return {
|
||||
base,
|
||||
userStore: stores.userStore,
|
||||
|
@ -11,7 +11,7 @@ test('should enable prometheus', async () => {
|
||||
const config = createTestConfig();
|
||||
const services = createServices(stores, config);
|
||||
|
||||
const app = getApp(config, stores, services);
|
||||
const app = await getApp(config, stores, services);
|
||||
|
||||
const request = supertest(app);
|
||||
|
||||
|
@ -7,7 +7,7 @@ import FeatureController from './feature';
|
||||
import { createTestConfig } from '../../../test/config/test-config';
|
||||
import { secondsToMilliseconds } from 'date-fns';
|
||||
|
||||
function getSetup() {
|
||||
async function getSetup() {
|
||||
const base = `/random${Math.round(Math.random() * 1000)}`;
|
||||
const stores = createStores();
|
||||
const config = createTestConfig({
|
||||
@ -15,7 +15,7 @@ function getSetup() {
|
||||
});
|
||||
const services = createServices(stores, config);
|
||||
|
||||
const app = getApp(config, stores, services);
|
||||
const app = await getApp(config, stores, services);
|
||||
|
||||
return {
|
||||
base,
|
||||
@ -35,8 +35,8 @@ let request;
|
||||
let destroy;
|
||||
let featureToggleClientStore;
|
||||
|
||||
beforeEach(() => {
|
||||
const setup = getSetup();
|
||||
beforeEach(async () => {
|
||||
const setup = await getSetup();
|
||||
base = setup.base;
|
||||
request = setup.request;
|
||||
featureToggleClientStore = setup.featureToggleClientStore;
|
||||
|
@ -7,12 +7,12 @@ import { createServices } from '../../services';
|
||||
import { IUnleashStores } from '../../types';
|
||||
import { IUnleashOptions } from '../../server-impl';
|
||||
|
||||
function getSetup(opts?: IUnleashOptions) {
|
||||
async function getSetup(opts?: IUnleashOptions) {
|
||||
const stores = createStores();
|
||||
|
||||
const config = createTestConfig(opts);
|
||||
const services = createServices(stores, config);
|
||||
const app = getApp(config, stores, services);
|
||||
const app = await getApp(config, stores, services);
|
||||
|
||||
return {
|
||||
request: supertest(app),
|
||||
@ -29,8 +29,8 @@ let request;
|
||||
let stores: IUnleashStores;
|
||||
let destroy;
|
||||
|
||||
beforeEach(() => {
|
||||
const setup = getSetup();
|
||||
beforeEach(async () => {
|
||||
const setup = await getSetup();
|
||||
request = setup.request;
|
||||
stores = setup.stores;
|
||||
destroy = setup.destroy;
|
||||
@ -83,7 +83,7 @@ test('should accept client metrics with yes/no', () => {
|
||||
});
|
||||
|
||||
test('should accept client metrics with yes/no with metricsV2', async () => {
|
||||
const testRunner = getSetup({
|
||||
const testRunner = await getSetup({
|
||||
experimental: { metricsV2: { enabled: true } },
|
||||
});
|
||||
await testRunner.request
|
||||
|
@ -5,11 +5,11 @@ import getLogger from '../../../test/fixtures/no-logger';
|
||||
import getApp from '../../app';
|
||||
import { createServices } from '../../services';
|
||||
|
||||
function getSetup() {
|
||||
async function getSetup() {
|
||||
const stores = createStores();
|
||||
const config = createTestConfig();
|
||||
const services = createServices(stores, config);
|
||||
const app = getApp(config, stores, services);
|
||||
const app = await getApp(config, stores, services);
|
||||
|
||||
return {
|
||||
request: supertest(app),
|
||||
@ -23,8 +23,8 @@ function getSetup() {
|
||||
}
|
||||
let request;
|
||||
let destroy;
|
||||
beforeEach(() => {
|
||||
const setup = getSetup();
|
||||
beforeEach(async () => {
|
||||
const setup = await getSetup();
|
||||
request = setup.request;
|
||||
destroy = setup.destroy;
|
||||
});
|
||||
|
@ -7,11 +7,11 @@ import getLogger from '../../test/fixtures/no-logger';
|
||||
import getApp from '../app';
|
||||
import { IUnleashStores } from '../types';
|
||||
|
||||
function getSetup() {
|
||||
async function getSetup() {
|
||||
const stores = createStores();
|
||||
const config = createTestConfig();
|
||||
const services = createServices(stores, config);
|
||||
const app = getApp(config, stores, services);
|
||||
const app = await getApp(config, stores, services);
|
||||
|
||||
return {
|
||||
request: supertest(app),
|
||||
@ -26,8 +26,8 @@ function getSetup() {
|
||||
let request;
|
||||
let destroy;
|
||||
let stores;
|
||||
beforeEach(() => {
|
||||
const setup = getSetup();
|
||||
beforeEach(async () => {
|
||||
const setup = await getSetup();
|
||||
request = setup.request;
|
||||
destroy = setup.destroy;
|
||||
stores = setup.stores;
|
||||
@ -38,7 +38,7 @@ afterEach(() => {
|
||||
getLogger.setMuteError(false);
|
||||
});
|
||||
|
||||
test('should give 500 when db is failing', () => {
|
||||
test('should give 500 when db is failing', async () => {
|
||||
jest.spyOn(global.console, 'error').mockImplementation(() => jest.fn());
|
||||
const config = createTestConfig();
|
||||
const failingStores: Partial<IUnleashStores> = {
|
||||
@ -54,7 +54,7 @@ test('should give 500 when db is failing', () => {
|
||||
// @ts-ignore
|
||||
const services = createServices(failingStores, config);
|
||||
// @ts-ignore
|
||||
const app = getApp(createTestConfig(), failingStores, services);
|
||||
const app = await getApp(createTestConfig(), failingStores, services);
|
||||
request = supertest(app);
|
||||
getLogger.setMuteError(true);
|
||||
expect.assertions(2);
|
||||
|
@ -4,14 +4,14 @@ import createStores from '../../test/fixtures/store';
|
||||
import getApp from '../app';
|
||||
import { createServices } from '../services';
|
||||
|
||||
function getSetup() {
|
||||
async function getSetup() {
|
||||
const base = `/random${Math.round(Math.random() * 1000)}`;
|
||||
const stores = createStores();
|
||||
const config = createTestConfig({
|
||||
server: { baseUriPath: base },
|
||||
});
|
||||
const services = createServices(stores, config);
|
||||
const app = getApp(config, stores, services);
|
||||
const app = await getApp(config, stores, services);
|
||||
|
||||
return {
|
||||
base,
|
||||
@ -27,8 +27,8 @@ function getSetup() {
|
||||
let base;
|
||||
let request;
|
||||
let destroy;
|
||||
beforeEach(() => {
|
||||
const setup = getSetup();
|
||||
beforeEach(async () => {
|
||||
const setup = await getSetup();
|
||||
base = setup.base;
|
||||
request = setup.request;
|
||||
destroy = setup.destroy;
|
||||
|
@ -57,7 +57,7 @@ async function createApp(
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
config.server.secret = secret;
|
||||
}
|
||||
const app = getApp(config, stores, services, unleashSession);
|
||||
const app = await getApp(config, stores, services, unleashSession);
|
||||
|
||||
if (typeof config.eventHook === 'function') {
|
||||
addEventHook(config.eventHook, stores.eventStore);
|
||||
|
@ -70,6 +70,7 @@ export interface IServerOption {
|
||||
keepAliveTimeout: number;
|
||||
headersTimeout: number;
|
||||
baseUriPath: string;
|
||||
cdnPrefix?: string;
|
||||
unleashUrl: string;
|
||||
serverMetrics: boolean;
|
||||
enableRequestLogger: boolean;
|
||||
|
24
src/lib/util/load-index-html.ts
Normal file
24
src/lib/util/load-index-html.ts
Normal file
@ -0,0 +1,24 @@
|
||||
import fs from 'fs';
|
||||
import { IUnleashConfig } from '../server-impl';
|
||||
import { rewriteHTML } from './rewriteHTML';
|
||||
import path from 'path';
|
||||
import fetch from 'node-fetch';
|
||||
|
||||
export async function loadIndexHTML(
|
||||
config: IUnleashConfig,
|
||||
publicFolder: string,
|
||||
): Promise<string> {
|
||||
const { cdnPrefix, baseUriPath = '' } = config.server;
|
||||
|
||||
let indexHTML: string;
|
||||
if (cdnPrefix) {
|
||||
const res = await fetch(`${cdnPrefix}/index.html`);
|
||||
indexHTML = await res.text();
|
||||
} else {
|
||||
indexHTML = fs
|
||||
.readFileSync(path.join(publicFolder, 'index.html'))
|
||||
.toString();
|
||||
}
|
||||
|
||||
return rewriteHTML(indexHTML, baseUriPath, cdnPrefix);
|
||||
}
|
@ -1,7 +1,15 @@
|
||||
export const rewriteHTML = (input: string, rewriteValue: string): string => {
|
||||
export const rewriteHTML = (
|
||||
input: string,
|
||||
rewriteValue: string,
|
||||
cdnPrefix?: string,
|
||||
): string => {
|
||||
let result = input;
|
||||
result = result.replace(/::baseUriPath::/gi, rewriteValue);
|
||||
result = result.replace(/\/static/gi, `${rewriteValue}/static`);
|
||||
result = result.replace(/::cdnPrefix::/gi, cdnPrefix || '');
|
||||
result = result.replace(
|
||||
/\/static/gi,
|
||||
`${cdnPrefix || rewriteValue}/static`,
|
||||
);
|
||||
|
||||
return result;
|
||||
};
|
||||
|
@ -20,6 +20,7 @@ process.nextTick(async () => {
|
||||
baseUriPath: '',
|
||||
// keepAliveTimeout: 1,
|
||||
gracefulShutdownEnable: true,
|
||||
// cdnPrefix: 'https://cdn.getunleash.io/unleash/v4.4.1',
|
||||
},
|
||||
logLevel: LogLevel.debug,
|
||||
enableOAS: true,
|
||||
|
@ -25,7 +25,3 @@ export function createTestConfig(config?: IUnleashOptions): IUnleashConfig {
|
||||
const options = mergeAll<IUnleashOptions>([testConfig, config]);
|
||||
return createConfig(options);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
createTestConfig,
|
||||
};
|
||||
|
@ -18,12 +18,12 @@ export interface IUnleashTest {
|
||||
services: IUnleashServices;
|
||||
}
|
||||
|
||||
function createApp(
|
||||
async function createApp(
|
||||
stores,
|
||||
adminAuthentication = IAuthType.NONE,
|
||||
preHook?: Function,
|
||||
customOptions?: any,
|
||||
): IUnleashTest {
|
||||
): Promise<IUnleashTest> {
|
||||
const config = createTestConfig({
|
||||
authentication: {
|
||||
type: adminAuthentication,
|
||||
@ -38,7 +38,7 @@ function createApp(
|
||||
const unleashSession = sessionDb(config, undefined);
|
||||
const emitter = new EventEmitter();
|
||||
emitter.setMaxListeners(0);
|
||||
const app = getApp(config, stores, services, unleashSession);
|
||||
const app = await getApp(config, stores, services, unleashSession);
|
||||
const request = supertest.agent(app);
|
||||
|
||||
const destroy = async () => {
|
||||
|
@ -7246,7 +7246,7 @@ universalify@^0.1.0, universalify@^0.1.2:
|
||||
resolved "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz"
|
||||
integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==
|
||||
|
||||
unleash-frontend@4.4.1:
|
||||
unleash-frontend@v4.4.1:
|
||||
version "4.4.1"
|
||||
resolved "https://registry.yarnpkg.com/unleash-frontend/-/unleash-frontend-4.4.1.tgz#753008e8a1a25b204edf23595261635f030b8590"
|
||||
integrity sha512-hyVd56nbWkFdyEeCeHMVZjKlQyWu82QqzGT6IDKzYJruYpIk00/9dm7zycziZIwzu7GXfKkI4J6fnm6Ge7mB5g==
|
||||
|
Loading…
Reference in New Issue
Block a user