1 |
|
2 | const fs = require('fs');
|
3 | const path = require('path');
|
4 | const glob = require('glob');
|
5 | const dotenv = require('dotenv');
|
6 | const slateEnv = require('../index');
|
7 | const config = require('../slate-env.config');
|
8 |
|
9 | const envPath = path.resolve(config.envRootDir, config.envDefaultFileName);
|
10 |
|
11 | const TEST_ENV = {
|
12 | [config.envNameVar]: 'production',
|
13 | [config.envStoreVar]: 'test-shop.myshopify.com',
|
14 | [config.envPasswordVar]: '123456789',
|
15 | [config.envThemeIdVar]: '987654321',
|
16 | [config.envIgnoreFilesVar]: 'config/settings_data.json',
|
17 | [config.envUserEmail]: 'test@email.com',
|
18 | };
|
19 |
|
20 | function setVars(vars) {
|
21 | for (const key in vars) {
|
22 | if (vars.hasOwnProperty(key)) {
|
23 | process.env[key] = vars[key];
|
24 | }
|
25 | }
|
26 | }
|
27 |
|
28 | function clearVars(vars) {
|
29 | for (const key in vars) {
|
30 | if (vars.hasOwnProperty(key)) {
|
31 | delete process.env[key];
|
32 | }
|
33 | }
|
34 | }
|
35 |
|
36 | afterEach(() => {
|
37 | clearVars(TEST_ENV);
|
38 | glob.sync(`${envPath}*`).forEach((file) => fs.unlinkSync(file));
|
39 | });
|
40 |
|
41 | describe('Slate Env', () => {
|
42 | describe('clear()', () => {
|
43 | beforeEach(() => {
|
44 | setVars(TEST_ENV);
|
45 | });
|
46 |
|
47 | test('Clears all the values assigned to Slate environment variables', () => {
|
48 | slateEnv.clear();
|
49 |
|
50 | for (const key in TEST_ENV) {
|
51 | if (TEST_ENV.hasOwnProperty(key)) {
|
52 | expect(process.env[key]).toBe('');
|
53 | }
|
54 | }
|
55 | });
|
56 | });
|
57 |
|
58 | describe('getSlateEnv()', () => {
|
59 | beforeEach(() => {
|
60 | setVars(TEST_ENV);
|
61 | });
|
62 |
|
63 | test('returns object containing all env variables without current values', () => {
|
64 | expect(slateEnv.getSlateEnv()).toEqual(TEST_ENV);
|
65 | });
|
66 | });
|
67 |
|
68 | describe('getDefaultSlateEnv', () => {
|
69 | test('returns an object which contains the default variables and values of an env file', () => {
|
70 | const emptyTestVars = {
|
71 | [config.envStoreVar]: '',
|
72 | [config.envPasswordVar]: '',
|
73 | [config.envThemeIdVar]: '',
|
74 | [config.envIgnoreFilesVar]: '',
|
75 | };
|
76 |
|
77 | expect(slateEnv.getDefaultSlateEnv()).toEqual(emptyTestVars);
|
78 | });
|
79 | });
|
80 |
|
81 | describe('getEmptySlateEnv()', () => {
|
82 | test('returns object containing all env file variables with empty values', () => {
|
83 | const emptyTestVars = Object.assign({}, TEST_ENV);
|
84 |
|
85 | for (const key in emptyTestVars) {
|
86 | if (emptyTestVars.hasOwnProperty(key)) {
|
87 | emptyTestVars[key] = '';
|
88 | }
|
89 | }
|
90 |
|
91 | expect(slateEnv.getEmptySlateEnv()).toEqual(emptyTestVars);
|
92 | });
|
93 | });
|
94 |
|
95 | describe('create()', () => {
|
96 | describe('generates an .env file', () => {
|
97 | test('with empty config values', () => {
|
98 | slateEnv.create();
|
99 |
|
100 | const envParsed = dotenv.parse(fs.readFileSync(envPath, 'utf8'));
|
101 |
|
102 | expect(envParsed).toEqual({
|
103 | [config.envStoreVar]: '',
|
104 | [config.envPasswordVar]: '',
|
105 | [config.envThemeIdVar]: '',
|
106 | [config.envIgnoreFilesVar]: '',
|
107 | });
|
108 | });
|
109 |
|
110 | test('with specified config values', () => {
|
111 | const env = slateEnv.getEmptySlateEnv();
|
112 | const store = 'test-shop.myshopify.com';
|
113 |
|
114 | env[config.envStoreVar] = store;
|
115 | slateEnv.create({values: env});
|
116 |
|
117 | const envParsed = dotenv.parse(fs.readFileSync(envPath, 'utf8'));
|
118 |
|
119 | expect(envParsed).toHaveProperty(config.envStoreVar, store);
|
120 | });
|
121 |
|
122 | test('with invalid config values ommited', () => {
|
123 | const env = slateEnv.getEmptySlateEnv();
|
124 | const store = 'test-shop.myshopify.com';
|
125 | const invalidKey = 'INVALID_VARIABLE';
|
126 | const invalidValue = 'some value';
|
127 |
|
128 | env[config.envStoreVar] = store;
|
129 | env[invalidKey] = invalidValue;
|
130 | slateEnv.create({values: env});
|
131 |
|
132 | const envParsed = dotenv.parse(fs.readFileSync(envPath, 'utf8'));
|
133 |
|
134 | expect(envParsed).toHaveProperty(config.envStoreVar, store);
|
135 | expect(envParsed).not.toHaveProperty(invalidKey, invalidValue);
|
136 | });
|
137 |
|
138 | test('when a valid name is provided', () => {
|
139 | const name = 'production';
|
140 | const namedEnvPath = envPath.concat(`.${name}`);
|
141 |
|
142 | slateEnv.create({name});
|
143 | expect(fs.existsSync(namedEnvPath)).toBeTruthy();
|
144 | });
|
145 |
|
146 | test('when no name is provided', () => {
|
147 | slateEnv.create();
|
148 | expect(fs.existsSync(envPath)).toBeTruthy();
|
149 | });
|
150 |
|
151 | test('when an empty name ("") is provided', () => {
|
152 | slateEnv.create({}, '');
|
153 | expect(fs.existsSync(envPath)).toBeTruthy();
|
154 | });
|
155 |
|
156 | test('when a whitespace name (" ") is provided', () => {
|
157 | slateEnv.create({}, ' ');
|
158 | expect(fs.existsSync(envPath)).toBeTruthy();
|
159 | });
|
160 | });
|
161 | });
|
162 |
|
163 | describe('assign()', () => {
|
164 | beforeEach(() => {
|
165 | slateEnv.create({values: TEST_ENV});
|
166 | slateEnv.create({values: TEST_ENV, name: 'production'});
|
167 | });
|
168 |
|
169 | test('reads default env file and assigns values to environment variables', () => {
|
170 | slateEnv.assign();
|
171 | expect(process.env[config.envStoreVar]).toBe(
|
172 | TEST_ENV[config.envStoreVar],
|
173 | );
|
174 | });
|
175 |
|
176 | test('reads named env file and assigns values to environment variables', () => {
|
177 | slateEnv.assign('production');
|
178 | expect(process.env[config.envStoreVar]).toBe(
|
179 | TEST_ENV[config.envStoreVar],
|
180 | );
|
181 | });
|
182 |
|
183 | test('does not overwrite an environment variable if it already has a value', () => {
|
184 | const store = 'other-value.myshopify.com';
|
185 | process.env[config.envStoreVar] = store;
|
186 | slateEnv.assign();
|
187 |
|
188 | expect(process.env[config.envStoreVar]).toBe(store);
|
189 | });
|
190 |
|
191 | test("throw an error if a name is provided and the env file doesn't exist", () => {
|
192 | expect(() => slateEnv.assign('nope')).toThrow();
|
193 | });
|
194 | });
|
195 |
|
196 | describe('getEnvName()', () => {
|
197 | describe('if a env name is specified', () => {
|
198 | beforeEach(() => {
|
199 | slateEnv.create({values: TEST_ENV, name: 'production'});
|
200 | slateEnv.assign('production');
|
201 | });
|
202 |
|
203 | test('returns the name of the environment', () => {
|
204 | expect(slateEnv.getEnvNameValue()).toBe('production');
|
205 | });
|
206 | });
|
207 |
|
208 | describe('if a env name is not specified', () => {
|
209 | test(`returns the name '${
|
210 | config.envDefaultEnvName
|
211 | }' if the default env file is present`, () => {
|
212 | slateEnv.create(TEST_ENV);
|
213 | slateEnv.assign();
|
214 | expect(slateEnv.getEnvNameValue()).toBe(config.envDefaultEnvName);
|
215 | });
|
216 | test(`returns the name '${
|
217 | config.envExternalEnvName
|
218 | }' if the default env file is not present`, () => {
|
219 | slateEnv.assign();
|
220 | expect(slateEnv.getEnvNameValue()).toBe(config.envExternalEnvName);
|
221 | });
|
222 | });
|
223 | });
|
224 |
|
225 | describe('getStoreValue()', () => {
|
226 | test('returns the value of the environment variable that references the store URL', () => {
|
227 | process.env[config.envStoreVar] = TEST_ENV[config.envStoreVar];
|
228 | expect(slateEnv.getStoreValue()).toBe(TEST_ENV[config.envStoreVar]);
|
229 | });
|
230 |
|
231 | test('returns an empty string if the value is undefined', () => {
|
232 | expect(slateEnv.getStoreValue()).toBe('');
|
233 | });
|
234 | });
|
235 |
|
236 | describe('getPasswordValue()', () => {
|
237 | test('returns the value of the environment variable that references the store API password', () => {
|
238 | process.env[config.envPasswordVar] = TEST_ENV[config.envPasswordVar];
|
239 | expect(slateEnv.getPasswordValue()).toBe(TEST_ENV[config.envPasswordVar]);
|
240 | });
|
241 |
|
242 | test('returns an empty string if the value is undefined', () => {
|
243 | expect(slateEnv.getPasswordValue()).toBe('');
|
244 | });
|
245 | });
|
246 |
|
247 | describe('getThemeIdValue()', () => {
|
248 | test('returns the value of the environment variable that references the store theme ID', () => {
|
249 | process.env[config.envThemeIdVar] = TEST_ENV[config.envThemeIdVar];
|
250 | expect(slateEnv.getThemeIdValue()).toBe(TEST_ENV[config.envThemeIdVar]);
|
251 | });
|
252 |
|
253 | test('returns an empty string if the value is undefined', () => {
|
254 | expect(slateEnv.getThemeIdValue()).toBe('');
|
255 | });
|
256 | });
|
257 |
|
258 | describe('getIgnoreFilesValue()', () => {
|
259 | test('returns the value of the environment variable that references a list of files to ignore', () => {
|
260 | process.env[config.envIgnoreFilesVar] =
|
261 | TEST_ENV[config.envIgnoreFilesVar];
|
262 | expect(slateEnv.getIgnoreFilesValue()).toBe(
|
263 | TEST_ENV[config.envIgnoreFilesVar],
|
264 | );
|
265 | });
|
266 |
|
267 | test('returns an empty string if the value is undefined', () => {
|
268 | expect(slateEnv.getIgnoreFilesValue()).toBe('');
|
269 | });
|
270 | });
|
271 |
|
272 | describe('validate()', () => {
|
273 | describe('returns an object with an .isValid prop', () => {
|
274 | test('that is true if no validation .errors is empty', () => {
|
275 | setVars(TEST_ENV);
|
276 | const result = slateEnv.validate();
|
277 | expect(result).toHaveProperty('isValid', true);
|
278 | expect(result.errors).toBeDefined();
|
279 | expect(result.errors).toHaveLength(0);
|
280 | });
|
281 |
|
282 | test('that is false validation .errors is not empty', () => {
|
283 | const result = slateEnv.validate();
|
284 | expect(result).toHaveProperty('isValid', false);
|
285 | expect(result.errors).toBeDefined();
|
286 | expect(result.errors.length).toBeGreaterThan(0);
|
287 | });
|
288 | });
|
289 | describe('returns errors if', () => {
|
290 | test('the store URL environment variable is empty', () => {
|
291 | setVars(
|
292 | Object.assign({}, TEST_ENV, {
|
293 | [config.envStoreVar]: '',
|
294 | }),
|
295 | );
|
296 | const result = slateEnv.validate();
|
297 | expect(result.errors).toHaveLength(1);
|
298 | });
|
299 |
|
300 | test('the store URL environment variable is not a .myshopify.com or myshopify.io URL', () => {
|
301 | ['shop1.myshopify.com', 'shop1.myshopify.io', 'shop1'].forEach(
|
302 | (value) => {
|
303 | setVars(
|
304 | Object.assign({}, TEST_ENV, {
|
305 | [config.envStoreVar]: value,
|
306 | }),
|
307 | );
|
308 | const result = slateEnv.validate();
|
309 | expect(result.errors).toHaveLength(value === 'shop1' ? 1 : 0);
|
310 | },
|
311 | );
|
312 | });
|
313 |
|
314 | test('the store API password environment variable is empty', () => {
|
315 | setVars(
|
316 | Object.assign({}, TEST_ENV, {
|
317 | [config.envPasswordVar]: '',
|
318 | }),
|
319 | );
|
320 | const result = slateEnv.validate();
|
321 | expect(result.errors).toHaveLength(1);
|
322 | });
|
323 |
|
324 | test('the store API password environment variable has invalid characters', () => {
|
325 | setVars(
|
326 | Object.assign({}, TEST_ENV, {
|
327 | [config.envPasswordVar]: '8h1j-dnjn8',
|
328 | }),
|
329 | );
|
330 | const result = slateEnv.validate();
|
331 | expect(result.errors).toHaveLength(1);
|
332 | });
|
333 |
|
334 | test('the store Theme ID environment variable is empty', () => {
|
335 | setVars(
|
336 | Object.assign({}, TEST_ENV, {
|
337 | [config.envThemeIdVar]: '',
|
338 | }),
|
339 | );
|
340 | const result = slateEnv.validate();
|
341 | expect(result.errors).toHaveLength(1);
|
342 | });
|
343 |
|
344 | test("the store Theme ID environment variable is not 'live' or a string of numbers", () => {
|
345 | setVars(
|
346 | Object.assign({}, TEST_ENV, {
|
347 | [config.envThemeIdVar]: 'ds7dsh8d',
|
348 | }),
|
349 | );
|
350 | const result = slateEnv.validate();
|
351 | expect(result.errors).toHaveLength(1);
|
352 | });
|
353 | });
|
354 | });
|
355 | });
|