1
0
mirror of https://github.com/Unleash/unleash.git synced 2024-11-01 19:07:38 +01:00
unleash.unleash/src/lib/create-config.test.ts
Gastón Fournier 149bc8aab2
chore: remove optimal 304 flag (#3665)
## About the changes
This PR removes the optimal304 flag after being tested in production.
We're keeping the existing configuration that allows users to disable
cache mainly because it's useful for testing.
2023-05-05 09:18:04 +02:00

474 lines
15 KiB
TypeScript

import { createConfig } from './create-config';
import { ApiTokenType } from './types/models/api-token';
test('should create default config', async () => {
const config = createConfig({
db: {
host: 'localhost',
port: 4242,
user: 'unleash',
password: 'password',
database: 'unleash_db',
},
server: {
port: 4242,
},
});
expect(config).toMatchSnapshot();
});
test('should add initApiToken for admin token from options', async () => {
const token = {
environment: '*',
project: '*',
secret: '*:*.some-random-string',
type: ApiTokenType.ADMIN,
tokenName: 'admin',
};
const config = createConfig({
db: {
host: 'localhost',
port: 4242,
user: 'unleash',
password: 'password',
database: 'unleash_db',
},
server: {
port: 4242,
},
authentication: {
initApiTokens: [token],
},
});
expect(config.authentication.initApiTokens).toHaveLength(1);
expect(config.authentication.initApiTokens[0].environment).toBe(
token.environment,
);
expect(config.authentication.initApiTokens[0].project).toBe(token.project);
expect(config.authentication.initApiTokens[0].type).toBe(
ApiTokenType.ADMIN,
);
});
test('should add initApiToken for client token from options', async () => {
const token = {
environment: 'development',
project: 'default',
secret: 'default:development.some-random-string',
type: ApiTokenType.CLIENT,
tokenName: 'admin',
};
const config = createConfig({
db: {
host: 'localhost',
port: 4242,
user: 'unleash',
password: 'password',
database: 'unleash_db',
},
server: {
port: 4242,
},
authentication: {
initApiTokens: [token],
},
});
expect(config.authentication.initApiTokens).toHaveLength(1);
expect(config.authentication.initApiTokens[0].environment).toBe(
token.environment,
);
expect(config.authentication.initApiTokens[0].project).toBe(token.project);
expect(config.authentication.initApiTokens[0].type).toBe(
ApiTokenType.CLIENT,
);
});
test('should add initApiToken for admin token from env var', async () => {
process.env.INIT_ADMIN_API_TOKENS = '*:*.some-token1, *:*.some-token2';
const config = createConfig({
db: {
host: 'localhost',
port: 4242,
user: 'unleash',
password: 'password',
database: 'unleash_db',
},
server: {
port: 4242,
},
});
expect(config.authentication.initApiTokens).toHaveLength(2);
expect(config.authentication.initApiTokens[0].environment).toBe('*');
expect(config.authentication.initApiTokens[0].project).toBe('*');
expect(config.authentication.initApiTokens[0].type).toBe(
ApiTokenType.ADMIN,
);
expect(config.authentication.initApiTokens[1].secret).toBe(
'*:*.some-token2',
);
delete process.env.INIT_ADMIN_API_TOKENS;
});
test('should validate initApiToken for admin token from env var', async () => {
process.env.INIT_ADMIN_API_TOKENS = 'invalidProject:*:some-token1';
expect(() => createConfig({})).toThrow(
'Admin token cannot be scoped to single project',
);
delete process.env.INIT_ADMIN_API_TOKENS;
});
test('should validate initApiToken for client token from env var', async () => {
process.env.INIT_CLIENT_API_TOKENS = '*:*:some-token1';
expect(() => createConfig({})).toThrow(
'Client token cannot be scoped to all environments',
);
delete process.env.INIT_CLIENT_API_TOKENS;
});
test('should merge initApiToken from options and env vars', async () => {
process.env.INIT_ADMIN_API_TOKENS = '*:*.some-token1, *:*.some-token2';
process.env.INIT_CLIENT_API_TOKENS = 'default:development.some-token1';
const token = {
environment: '*',
project: '*',
secret: '*:*.some-random-string',
type: ApiTokenType.ADMIN,
tokenName: 'admin',
};
const config = createConfig({
db: {
host: 'localhost',
port: 4242,
user: 'unleash',
password: 'password',
database: 'unleash_db',
},
server: {
port: 4242,
},
authentication: {
initApiTokens: [token],
},
});
expect(config.authentication.initApiTokens).toHaveLength(4);
delete process.env.INIT_CLIENT_API_TOKENS;
delete process.env.INIT_ADMIN_API_TOKENS;
});
test('should add initApiToken for client token from env var', async () => {
process.env.INIT_CLIENT_API_TOKENS =
'default:development.some-token1, default:development.some-token2';
const config = createConfig({
db: {
host: 'localhost',
port: 4242,
user: 'unleash',
password: 'password',
database: 'unleash_db',
},
server: {
port: 4242,
},
});
expect(config.authentication.initApiTokens).toHaveLength(2);
expect(config.authentication.initApiTokens[0].environment).toBe(
'development',
);
expect(config.authentication.initApiTokens[0].project).toBe('default');
expect(config.authentication.initApiTokens[0].type).toBe(
ApiTokenType.CLIENT,
);
expect(config.authentication.initApiTokens[0].secret).toBe(
'default:development.some-token1',
);
delete process.env.INIT_CLIENT_API_TOKENS;
});
test('should handle cases where no env var specified for tokens', async () => {
const token = {
environment: '*',
project: '*',
secret: '*:*.some-random-string',
type: ApiTokenType.ADMIN,
tokenName: 'admin',
};
const config = createConfig({
db: {
host: 'localhost',
port: 4242,
user: 'unleash',
password: 'password',
database: 'unleash_db',
},
server: {
port: 4242,
},
authentication: {
initApiTokens: [token],
},
});
expect(config.authentication.initApiTokens).toHaveLength(1);
});
test('should load environment overrides from env var', async () => {
process.env.ENABLED_ENVIRONMENTS = 'default,production';
const config = createConfig({
db: {
host: 'localhost',
port: 4242,
user: 'unleash',
password: 'password',
database: 'unleash_db',
},
server: {
port: 4242,
},
authentication: {
initApiTokens: [],
},
});
expect(config.environmentEnableOverrides).toHaveLength(2);
expect(config.environmentEnableOverrides).toContain('production');
delete process.env.ENABLED_ENVIRONMENTS;
});
test('should yield an empty list when no environment overrides are specified', async () => {
const config = createConfig({
db: {
host: 'localhost',
port: 4242,
user: 'unleash',
password: 'password',
database: 'unleash_db',
},
server: {
port: 4242,
},
authentication: {
initApiTokens: [],
},
});
expect(config.environmentEnableOverrides).toStrictEqual([]);
});
test('should yield all empty lists when no additionalCspAllowedDomains are set', async () => {
const config = createConfig({});
expect(config.additionalCspAllowedDomains).toBeDefined();
expect(config.additionalCspAllowedDomains.defaultSrc).toStrictEqual([]);
expect(config.additionalCspAllowedDomains.fontSrc).toStrictEqual([]);
expect(config.additionalCspAllowedDomains.styleSrc).toStrictEqual([]);
expect(config.additionalCspAllowedDomains.scriptSrc).toStrictEqual([]);
expect(config.additionalCspAllowedDomains.imgSrc).toStrictEqual([]);
expect(config.additionalCspAllowedDomains.connectSrc).toStrictEqual([]);
});
test('If additionalCspAllowedDomains is set in config map, passes through', async () => {
const config = createConfig({
additionalCspAllowedDomains: {
defaultSrc: ['googlefonts.com'],
fontSrc: [],
styleSrc: [],
scriptSrc: [],
imgSrc: [],
connectSrc: [],
},
});
expect(config.additionalCspAllowedDomains).toBeDefined();
expect(config.additionalCspAllowedDomains.defaultSrc).toStrictEqual([
'googlefonts.com',
]);
expect(config.additionalCspAllowedDomains.fontSrc).toStrictEqual([]);
expect(config.additionalCspAllowedDomains.styleSrc).toStrictEqual([]);
expect(config.additionalCspAllowedDomains.scriptSrc).toStrictEqual([]);
expect(config.additionalCspAllowedDomains.imgSrc).toStrictEqual([]);
expect(config.additionalCspAllowedDomains.connectSrc).toStrictEqual([]);
});
test('Can set partial additionalCspDomains', () => {
const config = createConfig({
additionalCspAllowedDomains: {
defaultSrc: ['googlefonts.com'],
},
});
expect(config.additionalCspAllowedDomains).toBeDefined();
expect(config.additionalCspAllowedDomains.defaultSrc).toStrictEqual([
'googlefonts.com',
]);
expect(config.additionalCspAllowedDomains.fontSrc).toStrictEqual([]);
expect(config.additionalCspAllowedDomains.styleSrc).toStrictEqual([]);
expect(config.additionalCspAllowedDomains.scriptSrc).toStrictEqual([]);
expect(config.additionalCspAllowedDomains.imgSrc).toStrictEqual([]);
});
test.each([
['CSP_ALLOWED_DEFAULT', 'googlefonts.com', 'defaultSrc'],
['CSP_ALLOWED_FONT', 'googlefonts.com', 'fontSrc'],
['CSP_ALLOWED_STYLE', 'googlefonts.com', 'styleSrc'],
['CSP_ALLOWED_SCRIPT', 'googlefonts.com', 'scriptSrc'],
['CSP_ALLOWED_IMG', 'googlefonts.com', 'imgSrc'],
['CSP_ALLOWED_CONNECT', 'googlefonts.com', 'connectSrc'],
])(
'When %s is set to %s. %s should include passed in domain',
(env, domain, key) => {
process.env[env] = domain;
const config = createConfig({});
expect(config.additionalCspAllowedDomains[key][0]).toBe(domain);
Object.keys(config.additionalCspAllowedDomains)
.filter((objKey) => objKey !== key)
.forEach((otherKey) => {
expect(
config.additionalCspAllowedDomains[otherKey],
).toStrictEqual([]);
});
delete process.env[env];
},
);
test('When multiple CSP environment variables are set, respects them all', () => {
process.env.CSP_ALLOWED_DEFAULT = 'googlefonts.com';
process.env.CSP_ALLOWED_IMG = 'googlefonts.com';
process.env.CSP_ALLOWED_SCRIPT = 'plausible.getunleash.io';
process.env.CSP_ALLOWED_CONNECT = 'plausible.getunleash.io';
const config = createConfig({});
expect(config.additionalCspAllowedDomains.imgSrc).toStrictEqual([
'googlefonts.com',
]);
expect(config.additionalCspAllowedDomains.defaultSrc).toStrictEqual([
'googlefonts.com',
]);
expect(config.additionalCspAllowedDomains.scriptSrc).toStrictEqual([
'plausible.getunleash.io',
]);
expect(config.additionalCspAllowedDomains.connectSrc).toStrictEqual([
'plausible.getunleash.io',
]);
delete process.env.CSP_ALLOWED_DEFAULT;
delete process.env.CSP_ALLOWED_IMG;
delete process.env.CSP_ALLOWED_SCRIPT;
delete process.env.CSP_ALLOWED_CONNECT;
});
test('Supports multiple domains comma separated in environment variables', () => {
process.env.CSP_ALLOWED_SCRIPT = 'plausible.getunleash.io,googlefonts.com';
const config = createConfig({});
expect(config.additionalCspAllowedDomains.scriptSrc).toStrictEqual([
'plausible.getunleash.io',
'googlefonts.com',
]);
});
test('Should enable client feature caching with .6 seconds max age by default', () => {
const config = createConfig({});
expect(config.clientFeatureCaching.enabled).toBe(true);
expect(config.clientFeatureCaching.maxAge).toBe(3600000);
});
test('Should use overrides from options for client feature caching', () => {
const config = createConfig({
clientFeatureCaching: {
enabled: false,
maxAge: 120,
},
});
expect(config.clientFeatureCaching.enabled).toBe(false);
expect(config.clientFeatureCaching.maxAge).toBe(120);
});
test('Should be able to set client features caching using environment variables', () => {
process.env.CLIENT_FEATURE_CACHING_ENABLED = 'false';
process.env.CLIENT_FEATURE_CACHING_MAXAGE = '120';
const config = createConfig({});
expect(config.clientFeatureCaching.enabled).toBe(false);
expect(config.clientFeatureCaching.maxAge).toBe(120);
delete process.env.CLIENT_FEATURE_CACHING_ENABLED;
delete process.env.CLIENT_FEATURE_CACHING_MAXAGE;
});
test('Environment variables for client features caching takes priority over options', () => {
process.env.CLIENT_FEATURE_CACHING_MAXAGE = '120';
const config = createConfig({
clientFeatureCaching: {
maxAge: 180,
},
});
expect(config.clientFeatureCaching.enabled).toBe(true);
expect(config.clientFeatureCaching.maxAge).toBe(120);
});
test('Environment variables for frontend CORS origins takes priority over options', async () => {
const create = (frontendApiOrigins?): string[] => {
return createConfig({
frontendApiOrigins,
}).frontendApiOrigins;
};
expect(create()).toEqual(['*']);
expect(create([])).toEqual([]);
expect(create(['*'])).toEqual(['*']);
expect(create(['https://example.com'])).toEqual(['https://example.com']);
expect(() => create(['a'])).toThrow('Invalid origin: a');
process.env.UNLEASH_FRONTEND_API_ORIGINS = '';
expect(create()).toEqual([]);
process.env.UNLEASH_FRONTEND_API_ORIGINS = '*';
expect(create()).toEqual(['*']);
process.env.UNLEASH_FRONTEND_API_ORIGINS = 'https://example.com, *';
expect(create()).toEqual(['https://example.com', '*']);
process.env.UNLEASH_FRONTEND_API_ORIGINS = 'b';
expect(() => create(['a'])).toThrow('Invalid origin: b');
delete process.env.UNLEASH_FRONTEND_API_ORIGINS;
expect(create()).toEqual(['*']);
});
test('baseUriPath defaults to the empty string', async () => {
let config = createConfig({});
expect(config.server.baseUriPath).toBe('');
});
test('BASE_URI_PATH defined in env is passed through', async () => {
process.env.BASE_URI_PATH = '/demo';
let config = createConfig({});
expect(config.server.baseUriPath).toBe('/demo');
delete process.env.BASE_URI_PATH;
});
test('environment variable takes precedence over configured variable', async () => {
process.env.BASE_URI_PATH = '/demo';
let config = createConfig({
server: {
baseUriPath: '/other',
},
});
expect(config.server.baseUriPath).toBe('/demo');
delete process.env.BASE_URI_PATH;
});
test.each(['demo', '/demo', '/demo/'])(
'Trailing and leading slashes gets normalized for base path %s',
async (path) => {
let config = createConfig({
server: {
baseUriPath: path,
},
});
expect(config.server.baseUriPath).toBe('/demo');
},
);