Skip to content

Commit 82eaa59

Browse files
committed
[exoframe-cli] Mock config during all cli tests (aside form config)
Should prevent issues with config updates causing other tests to fail
1 parent 2795c7c commit 82eaa59

File tree

2 files changed

+83
-15
lines changed

2 files changed

+83
-15
lines changed

packages/exoframe-cli/test/config.test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { afterAll, afterEach, beforeEach, expect, test, vi } from 'vitest';
55
import { getConfig, removeConfig, resetConfig, setupMocks } from './util/config.js';
66

77
// setup mocks
8-
const clearMocks = setupMocks();
8+
const clearMocks = setupMocks({ mockConfig: false });
99

1010
// timeout for IO/net
1111
const IO_TIMEOUT = 50;

packages/exoframe-cli/test/util/config.js

Lines changed: 82 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,56 @@
1+
import chalk from 'chalk';
12
import fs from 'fs';
23
import jsyaml from 'js-yaml';
34
import os from 'os';
45
import { join } from 'path';
6+
import { fileURLToPath } from 'url';
57
import { vi } from 'vitest';
68
import { fixturesFolder, testFolder } from './paths.js';
79

10+
const clone = (value) => JSON.parse(JSON.stringify(value));
11+
const createDefaultUserConfig = (addUser = true) => {
12+
const cfg = { endpoint: 'http://localhost:8080' };
13+
if (addUser) {
14+
cfg.user = { username: 'admin' };
15+
cfg.token = 'test-token';
16+
}
17+
return cfg;
18+
};
19+
20+
const configModulePath = fileURLToPath(new URL('../../src/config/index.js', import.meta.url));
21+
let mockedUserConfig = null;
22+
let mockedUserConfigDefaults = null;
23+
24+
const mockConfigModule = (addUser = true) => {
25+
mockedUserConfigDefaults = createDefaultUserConfig(addUser);
26+
mockedUserConfig = clone(mockedUserConfigDefaults);
27+
28+
const getConfig = vi.fn(async () => clone(mockedUserConfig));
29+
const updateConfig = vi.fn(async (newCfg) => {
30+
mockedUserConfig = Object.assign(mockedUserConfig, newCfg);
31+
return clone(mockedUserConfig);
32+
});
33+
const logout = vi.fn(async () => {
34+
delete mockedUserConfig.user;
35+
delete mockedUserConfig.token;
36+
});
37+
const isLoggedIn = vi.fn(async () => {
38+
const loggedIn = Boolean(mockedUserConfig.user?.username);
39+
if (!loggedIn) {
40+
console.log(chalk.red('Error: not logged in!'), 'Please, login first!');
41+
}
42+
return loggedIn;
43+
});
44+
45+
vi.doMock(configModulePath, () => ({ getConfig, updateConfig, logout, isLoggedIn }));
46+
47+
return () => {
48+
vi.doUnmock(configModulePath);
49+
mockedUserConfig = null;
50+
mockedUserConfigDefaults = null;
51+
};
52+
};
53+
854
vi.mock('ora', () => {
955
const fn = (...args) => {
1056
if (args.length > 0) {
@@ -21,33 +67,49 @@ vi.mock('ora', () => {
2167
};
2268
});
2369

24-
export const setupDeployMocks = () => {
70+
export const setupDeployMocks = ({ addUser = true, mockConfig = true } = {}) => {
2571
// mock current work dir
72+
const prevXdgConfig = process.env.XDG_CONFIG_HOME;
2673
process.env.XDG_CONFIG_HOME = join(fixturesFolder, '.config');
2774
const cwdSpy = vi.spyOn(process, 'cwd').mockImplementation(() => fixturesFolder);
2875
const osSpy = vi.spyOn(os, 'homedir').mockImplementation(() => fixturesFolder);
2976
const exitMock = vi.spyOn(process, 'exit').mockImplementation(() => {});
77+
const restoreConfigMock = mockConfig ? mockConfigModule(addUser) : null;
3078

3179
return () => {
80+
process.env.XDG_CONFIG_HOME = prevXdgConfig;
3281
cwdSpy.mockRestore();
3382
osSpy.mockRestore();
3483
exitMock.mockRestore();
84+
restoreConfigMock?.();
3585
};
3686
};
3787

38-
export const setupMocks = (addUser = true) => {
88+
const defaultSetupOptions = { addUser: true, mockConfig: true };
89+
const normalizeSetupOptions = (firstArg, maybeOptions = {}) => {
90+
if (typeof firstArg === 'object') {
91+
return { ...defaultSetupOptions, ...firstArg };
92+
}
93+
if (typeof firstArg === 'boolean') {
94+
const optionOverrides = Object.hasOwn(maybeOptions, 'mockConfig') ? { mockConfig: maybeOptions.mockConfig } : {};
95+
return { ...defaultSetupOptions, addUser: firstArg, ...optionOverrides };
96+
}
97+
return { ...defaultSetupOptions };
98+
};
99+
100+
export const setupMocks = (addUserOrOptions = true, options = {}) => {
101+
const { addUser, mockConfig } = normalizeSetupOptions(addUserOrOptions, options);
39102
// mock current work dir
40103
const cwdSpy = vi.spyOn(process, 'cwd').mockImplementation(() => testFolder);
41104
const osSpy = vi.spyOn(os, 'homedir').mockImplementation(() => testFolder);
42105

43106
let exoConfigExists = true;
44107
let exoConfig = { name: 'test' };
45-
const defaultUserConfig = { endpoint: 'http://localhost:8080' };
46-
if (addUser) {
47-
defaultUserConfig.user = { username: 'admin' };
48-
defaultUserConfig.token = 'test-token';
108+
let userConfig = null;
109+
if (!mockConfig) {
110+
userConfig = jsyaml.dump(createDefaultUserConfig(addUser));
49111
}
50-
let userConfig = jsyaml.dump(defaultUserConfig);
112+
const restoreConfigMock = mockConfig ? mockConfigModule(addUser) : null;
51113

52114
const mkdirSpy = vi.spyOn(fs.promises, 'mkdir').mockImplementation(async () => {});
53115
const statSpy = vi.spyOn(fs.promises, 'stat').mockImplementation(async (path) => {
@@ -61,7 +123,7 @@ export const setupMocks = (addUser = true) => {
61123
if ((typeof path === 'string' && path.includes('.json')) || path.href?.includes('.json')) {
62124
return Buffer.from(JSON.stringify(exoConfig));
63125
}
64-
if ((typeof path === 'string' && path.includes('.yml')) || path.href?.includes('.yml')) {
126+
if (!mockConfig && ((typeof path === 'string' && path.includes('.yml')) || path.href?.includes('.yml'))) {
65127
return Buffer.from(userConfig);
66128
}
67129
return fs.readFileSync(path);
@@ -73,7 +135,9 @@ export const setupMocks = (addUser = true) => {
73135
exoConfigExists = true;
74136
return;
75137
}
76-
userConfig = string;
138+
if (!mockConfig && path.includes('.yml')) {
139+
userConfig = string;
140+
}
77141
});
78142
const ulSpy = vi.spyOn(fs.promises, 'unlink').mockImplementation(async (path) => {
79143
// console.log('unlink', { path, string });
@@ -90,6 +154,7 @@ export const setupMocks = (addUser = true) => {
90154
rfSpy.mockRestore();
91155
wfSpy.mockRestore();
92156
ulSpy.mockRestore();
157+
restoreConfigMock?.();
93158
};
94159
};
95160

@@ -100,6 +165,9 @@ export const getConfig = async () => {
100165
};
101166

102167
export const getUserConfig = async () => {
168+
if (mockedUserConfig) {
169+
return clone(mockedUserConfig);
170+
}
103171
const xdgConfigFolder = process.env.XDG_CONFIG_HOME || join(os.homedir(), '.config');
104172
const baseFolder = join(xdgConfigFolder, 'exoframe');
105173
const configPath = join(baseFolder, 'cli.config.yml');
@@ -109,14 +177,14 @@ export const getUserConfig = async () => {
109177
};
110178

111179
export const resetUserConfig = async () => {
180+
if (mockedUserConfig && mockedUserConfigDefaults) {
181+
mockedUserConfig = clone(mockedUserConfigDefaults);
182+
return;
183+
}
112184
const xdgConfigFolder = process.env.XDG_CONFIG_HOME || join(os.homedir(), '.config');
113185
const baseFolder = join(xdgConfigFolder, 'exoframe');
114186
const configPath = join(baseFolder, 'cli.config.yml');
115-
await fs.promises.writeFile(
116-
configPath,
117-
jsyaml.dump({ endpoint: 'http://localhost:8080', user: { username: 'admin' }, token: 'test-token' }),
118-
'utf-8'
119-
);
187+
await fs.promises.writeFile(configPath, jsyaml.dump(createDefaultUserConfig(true)), 'utf-8');
120188
};
121189

122190
export const removeConfig = async () => {

0 commit comments

Comments
 (0)