@shopify/slate-env
Version:
Manages the environment variables which are needed by Slate to interact with Shopify servers.
342 lines (288 loc) • 10.7 kB
JavaScript
/* eslint-disable no-process-env */
const fs = require('fs');
const path = require('path');
const glob = require('glob');
const dotenv = require('dotenv');
const slateEnv = require('../index');
const config = require('../slate-env.config');
const envPath = path.resolve(config.envRootDir, config.envDefaultFileName);
const TEST_ENV = {
[config.envNameVar]: 'production',
[config.envStoreVar]: 'test-shop.myshopify.com',
[config.envPasswordVar]: '123456789',
[config.envThemeIdVar]: '987654321',
[config.envIgnoreFilesVar]: 'config/settings_data.json',
};
function setVars(vars) {
for (const key in vars) {
if (vars.hasOwnProperty(key)) {
process.env[key] = vars[key];
}
}
}
function clearVars(vars) {
for (const key in vars) {
if (vars.hasOwnProperty(key)) {
delete process.env[key];
}
}
}
afterEach(() => {
clearVars(TEST_ENV);
glob.sync(`${envPath}*`).forEach(file => fs.unlinkSync(file));
});
describe('Slate Env', () => {
describe('clear()', () => {
beforeEach(() => {
setVars(TEST_ENV);
});
test('Clears all the values assigned to Slate environment variables', () => {
slateEnv.clear();
for (const key in TEST_ENV) {
if (TEST_ENV.hasOwnProperty(key)) {
expect(process.env[key]).toBe('');
}
}
});
});
describe('getSlateEnv()', () => {
beforeEach(() => {
setVars(TEST_ENV);
});
test('returns object containing all env variables without current values', () => {
expect(slateEnv.getSlateEnv()).toEqual(TEST_ENV);
});
});
describe('getEmptySlateEnv()', () => {
test('returns object containing all env file variables with empty values', () => {
const EMPTY_TEST_VARS = Object.assign({}, TEST_ENV);
for (const key in EMPTY_TEST_VARS) {
if (EMPTY_TEST_VARS.hasOwnProperty(key)) {
EMPTY_TEST_VARS[key] = '';
}
}
expect(slateEnv.getEmptySlateEnv()).toEqual(EMPTY_TEST_VARS);
});
});
describe('create()', () => {
describe('generates an .env file', () => {
test('with empty config values', () => {
slateEnv.create();
const envParsed = dotenv.parse(fs.readFileSync(envPath, 'utf8'));
expect(envParsed).toEqual({
[config.envStoreVar]: '',
[config.envPasswordVar]: '',
[config.envThemeIdVar]: '',
[config.envIgnoreFilesVar]: '',
});
});
test('with specified config values', () => {
const env = slateEnv.getEmptySlateEnv();
const store = 'test-shop.myshopify.com';
env[config.envStoreVar] = store;
slateEnv.create({values: env});
const envParsed = dotenv.parse(fs.readFileSync(envPath, 'utf8'));
expect(envParsed).toHaveProperty(config.envStoreVar, store);
});
test('with invalid config values ommited', () => {
const env = slateEnv.getEmptySlateEnv();
const store = 'test-shop.myshopify.com';
const invalidKey = 'INVALID_VARIABLE';
const invalidValue = 'some value';
env[config.envStoreVar] = store;
env[invalidKey] = invalidValue;
slateEnv.create({values: env});
const envParsed = dotenv.parse(fs.readFileSync(envPath, 'utf8'));
expect(envParsed).toHaveProperty(config.envStoreVar, store);
expect(envParsed).not.toHaveProperty(invalidKey, invalidValue);
});
test('when a valid name is provided', () => {
const name = 'production';
const namedEnvPath = envPath.concat(`.${name}`);
slateEnv.create({name});
expect(fs.existsSync(namedEnvPath)).toBeTruthy();
});
test('when no name is provided', () => {
slateEnv.create();
expect(fs.existsSync(envPath)).toBeTruthy();
});
test('when an empty name ("") is provided', () => {
slateEnv.create({}, '');
expect(fs.existsSync(envPath)).toBeTruthy();
});
test('when a whitespace name (" ") is provided', () => {
slateEnv.create({}, ' ');
expect(fs.existsSync(envPath)).toBeTruthy();
});
});
});
describe('assign()', () => {
beforeEach(() => {
slateEnv.create({values: TEST_ENV});
slateEnv.create({values: TEST_ENV, name: 'production'});
});
test('reads default env file and assigns values to environment variables', () => {
slateEnv.assign();
expect(process.env[config.envStoreVar]).toBe(
TEST_ENV[config.envStoreVar],
);
});
test('reads named env file and assigns values to environment variables', () => {
slateEnv.assign('production');
expect(process.env[config.envStoreVar]).toBe(
TEST_ENV[config.envStoreVar],
);
});
test('does not overwrite an environment variable if it already has a value', () => {
const store = 'other-value.myshopify.com';
process.env[config.envStoreVar] = store;
slateEnv.assign();
expect(process.env[config.envStoreVar]).toBe(store);
});
test("throw an error if a name is provided and the env file doesn't exist", () => {
expect(() => slateEnv.assign('nope')).toThrow();
});
});
describe('getEnvName()', () => {
describe('if a env name is specified', () => {
beforeEach(() => {
slateEnv.create({values: TEST_ENV, name: 'production'});
slateEnv.assign('production');
});
test('returns the name of the environment', () => {
expect(slateEnv.getEnvNameValue()).toBe('production');
});
});
describe('if a env name is not specified', () => {
test(`returns the name '${
config.envDefaultEnvName
}' if the default env file is present`, () => {
slateEnv.create(TEST_ENV);
slateEnv.assign();
expect(slateEnv.getEnvNameValue()).toBe(config.envDefaultEnvName);
});
test(`returns the name '${
config.envExternalEnvName
}' if the default env file is not present`, () => {
slateEnv.assign();
expect(slateEnv.getEnvNameValue()).toBe(config.envExternalEnvName);
});
});
});
describe('getStoreValue()', () => {
test('returns the value of the environment variable that references the store URL', () => {
process.env[config.envStoreVar] = TEST_ENV[config.envStoreVar];
expect(slateEnv.getStoreValue()).toBe(TEST_ENV[config.envStoreVar]);
});
test('returns an empty string if the value is undefined', () => {
expect(slateEnv.getStoreValue()).toBe('');
});
});
describe('getPasswordValue()', () => {
test('returns the value of the environment variable that references the store API password', () => {
process.env[config.envPasswordVar] = TEST_ENV[config.envPasswordVar];
expect(slateEnv.getPasswordValue()).toBe(TEST_ENV[config.envPasswordVar]);
});
test('returns an empty string if the value is undefined', () => {
expect(slateEnv.getPasswordValue()).toBe('');
});
});
describe('getThemeIdValue()', () => {
test('returns the value of the environment variable that references the store theme ID', () => {
process.env[config.envThemeIdVar] = TEST_ENV[config.envThemeIdVar];
expect(slateEnv.getThemeIdValue()).toBe(TEST_ENV[config.envThemeIdVar]);
});
test('returns an empty string if the value is undefined', () => {
expect(slateEnv.getThemeIdValue()).toBe('');
});
});
describe('getIgnoreFilesValue()', () => {
test('returns the value of the environment variable that references a list of files to ignore', () => {
process.env[config.envIgnoreFilesVar] =
TEST_ENV[config.envIgnoreFilesVar];
expect(slateEnv.getIgnoreFilesValue()).toBe(
TEST_ENV[config.envIgnoreFilesVar],
);
});
test('returns an empty string if the value is undefined', () => {
expect(slateEnv.getIgnoreFilesValue()).toBe('');
});
});
describe('validate()', () => {
describe('returns an object with an .isValid prop', () => {
test('that is true if no validation .errors is empty', () => {
setVars(TEST_ENV);
const result = slateEnv.validate();
expect(result).toHaveProperty('isValid', true);
expect(result.errors).toBeDefined();
expect(result.errors).toHaveLength(0);
});
test('that is false validation .errors is not empty', () => {
const result = slateEnv.validate();
expect(result).toHaveProperty('isValid', false);
expect(result.errors).toBeDefined();
expect(result.errors.length).toBeGreaterThan(0);
});
});
describe('returns errors if', () => {
test('the store URL environment variable is empty', () => {
setVars(
Object.assign({}, TEST_ENV, {
[config.envStoreVar]: '',
}),
);
const result = slateEnv.validate();
expect(result.errors).toHaveLength(1);
});
test('the store URL environment variable is not a .myshopify.com or myshopify.io URL', () => {
['shop1.myshopify.com', 'shop1.myshopify.io', 'shop1'].forEach(
value => {
setVars(
Object.assign({}, TEST_ENV, {
[config.envStoreVar]: value,
}),
);
const result = slateEnv.validate();
expect(result.errors).toHaveLength(value === 'shop1' ? 1 : 0);
},
);
});
test('the store API password environment variable is empty', () => {
setVars(
Object.assign({}, TEST_ENV, {
[config.envPasswordVar]: '',
}),
);
const result = slateEnv.validate();
expect(result.errors).toHaveLength(1);
});
test('the store API password environment variable has invalid characters', () => {
setVars(
Object.assign({}, TEST_ENV, {
[config.envPasswordVar]: '8h1j-dnjn8',
}),
);
const result = slateEnv.validate();
expect(result.errors).toHaveLength(1);
});
test('the store Theme ID environment variable is empty', () => {
setVars(
Object.assign({}, TEST_ENV, {
[config.envThemeIdVar]: '',
}),
);
const result = slateEnv.validate();
expect(result.errors).toHaveLength(1);
});
test("the store Theme ID environment variable is not 'live' or a string of numbers", () => {
setVars(
Object.assign({}, TEST_ENV, {
[config.envThemeIdVar]: 'ds7dsh8d',
}),
);
const result = slateEnv.validate();
expect(result.errors).toHaveLength(1);
});
});
});
});