@pallad/app-env
Version:
Detects environment (production, staging, test, development, ci) and helps making decision based on that
201 lines (200 loc) • 8.04 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const conditional_type_checks_1 = require("conditional-type-checks");
const Factory_1 = require("../Factory");
const Builder_1 = require("../Builder");
describe('Factory', () => {
const factory = new Factory_1.Factory({});
describe('creating', () => {
it('environment names are converted to lowercase', () => {
const config = new Factory_1.Factory({
envName: ['FOO', 'BAR'],
});
expect(config.isValidEnvName('foo'))
.toBe(true);
expect(config.isValidEnvName('bar'))
.toBe(true);
});
});
describe('create', () => {
const PRODUCTION = factory.create('production');
const DEVELOPMENT = factory.create('development');
const TEST = factory.create('test');
const STAGING = factory.create('staging');
const CI = factory.create('ci');
const PREVIEW = factory.create('preview');
it.each([
['staging', { isStaging: true }],
['test', { isTest: true }],
['development', { isDevelopment: true }],
['production', { isProduction: true }],
['ci', { isCi: true }],
['ci', { isCI: true }],
['preview', { isPreview: true }],
])('for env: %s', (env, expectedIsState) => {
const info = factory.create(env);
expect(info)
.toMatchObject({
name: env,
isProduction: false,
isStaging: false,
isDevelopment: false,
isTest: false,
...expectedIsState
});
expect(info.is(env))
.toEqual(true);
});
const VALUE = 'FOO';
const VALUE_2 = 'BAR';
describe.each([
[PRODUCTION, DEVELOPMENT],
[DEVELOPMENT, PRODUCTION],
[TEST, DEVELOPMENT],
[STAGING, DEVELOPMENT],
[CI, DEVELOPMENT],
[PREVIEW, DEVELOPMENT],
])('forEnv returns value only for given environment', (env, oppositeEnv) => {
it('uses provided value if matches env', () => {
expect(env.forEnv(env.name)(VALUE)).toEqual(VALUE);
expect(oppositeEnv.forEnv(env.name)(VALUE)).toBeUndefined();
});
it('uses fallback value if provided', () => {
expect(env.forEnv(env.name)(VALUE, VALUE_2)).toEqual(VALUE);
expect(oppositeEnv.forEnv(env.name)(VALUE, VALUE_2)).toEqual(VALUE_2);
});
});
it('it builder creates builder for environment', () => {
expect(TEST.build())
.toEqual(new Builder_1.Builder(TEST));
expect(PRODUCTION.build())
.toEqual(new Builder_1.Builder(PRODUCTION));
});
});
describe('getEnvNameFromProcess', () => {
it('using default keys: APP_ENV, NODE_ENV', () => {
expect(factory.getEnvNameFromProcess({ APP_ENV: 'production' }))
.toEqual('production');
expect(factory.getEnvNameFromProcess({ NODE_ENV: 'production' }))
.toEqual('production');
});
describe('fallbacks', () => {
it('to CI if APP_ENV, NODE_ENV are invalid as CI is detected', () => {
expect(factory.getEnvNameFromProcess({
APP_ENV: 'foo',
NODE_ENV: 'bar',
CI: 'true'
}))
.toEqual('ci');
});
it('to development if APP_ENV, NODE_ENV are invalid as CI is not detected', () => {
expect(factory.getEnvNameFromProcess({
APP_ENV: 'foo',
NODE_ENV: 'bar',
}))
.toEqual('development');
});
it('to NODE_ENV if APP_ENV is not provided', () => {
expect(factory.getEnvNameFromProcess({
NODE_ENV: 'staging',
CI: 'true',
}))
.toEqual('staging');
});
it('to CI if missing and CI is detected', () => {
expect(factory.getEnvNameFromProcess({ CI: 'true' }))
.toEqual('ci');
});
it('to development if missing and not CI', () => {
expect(factory.getEnvNameFromProcess({}))
.toEqual('development');
});
it('to development if CI is detected but not supported', () => {
const factory = new Factory_1.Factory({
envName: ['test', 'development']
});
expect(factory.getEnvNameFromProcess({
CI: 'true'
}))
.toEqual('development');
});
it('throws an error if none of provided env is valid and CI and development are not supported', () => {
const factory = new Factory_1.Factory({
envName: ['foo', 'bar']
});
expect(() => {
factory.getEnvNameFromProcess({});
}).toThrowErrorMatchingInlineSnapshot(`"No environment name found in config. Supported environment names: foo, bar. Environment variables considered: ["APP_ENV","NODE_ENV"]"`);
});
});
describe('CI', () => {
it('might be provided in APP_ENV', () => {
expect(factory.getEnvNameFromProcess({ APP_ENV: 'ci' }))
.toEqual('ci');
});
it('might be provided in NODE_ENV', () => {
expect(factory.getEnvNameFromProcess({ NODE_ENV: 'ci' }))
.toEqual('ci');
});
it.each([
['CI'],
['CONTINUOUS_INTEGRATION'],
['BUILD_NUMBER'],
['RUN_ID']
])('to CI if ENV variable %s is present', envName => {
expect(factory.getEnvNameFromProcess({ [envName]: '1' }))
.toEqual('ci');
});
});
it('using provided keys', () => {
const env = {
APP_ENV: 'test',
NODE_ENV: 'production'
};
const factory = new Factory_1.Factory({
envNameEnvKeys: ['NODE_ENV']
});
expect(factory.getEnvNameFromProcess(env))
.toEqual('production');
});
describe('using process.env', () => {
let env;
beforeEach(() => {
env = process.env;
process.env = {
...env,
APP_ENV: 'staging'
};
});
afterAll(() => {
process.env = env;
});
it('as default', () => {
expect(factory.getEnvNameFromProcess())
.toEqual('staging');
});
});
});
describe('environment id', () => {
const factory = new Factory_1.Factory({
validateEnvId: envId => {
return envId === 'foo' || envId === 'bar';
}
});
it('validation function prevents using invalid env id', () => {
expect(factory.isValidEnvId('foo')).toBe(true);
expect(factory.isValidEnvId('bar')).toBe(true);
});
it('prevents creating info with invalid env id', () => {
expect(factory.createFromProcessEnv({ APP_ENV_ID: 'test' }))
.toHaveProperty('id', undefined);
});
it('creates info with valid env id', () => {
expect(factory.createFromProcessEnv({ APP_ENV_ID: 'foo' }))
.toHaveProperty('id', 'foo');
});
it('types', () => {
(0, conditional_type_checks_1.assert)(true);
});
});
});