UNPKG

@tywalk/pcf-helper

Version:

Command line helper for building and publishing PCF controls to Dataverse.

173 lines (172 loc) 8.47 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const fs_1 = __importDefault(require("fs")); const os_1 = __importDefault(require("os")); const path_1 = __importDefault(require("path")); const configUtil_1 = require("../util/configUtil"); jest.mock('fs'); jest.mock('os'); jest.mock('@tywalk/color-logger', () => ({ __esModule: true, default: { log: jest.fn(), warn: jest.fn(), error: jest.fn(), debug: jest.fn(), }, })); const mockFs = fs_1.default; const mockOs = os_1.default; /** * Wires fs.existsSync/readFileSync to a map of path → file contents. Any path * not in the map behaves as if the file does not exist. */ function setFakeFiles(files) { mockFs.existsSync.mockImplementation((p) => Object.prototype.hasOwnProperty.call(files, p.toString())); mockFs.readFileSync.mockImplementation((p, _encoding) => { const key = p.toString(); if (!(key in files)) throw new Error(`ENOENT: ${key}`); return files[key]; }); } describe('configUtil', () => { const HOME = '/home/tester'; const CWD = '/workspace/proj'; beforeEach(() => { jest.clearAllMocks(); mockOs.homedir.mockReturnValue(HOME); jest.spyOn(process, 'cwd').mockReturnValue(CWD); }); afterEach(() => { jest.restoreAllMocks(); }); describe('path helpers', () => { it('resolves the global config under the user home directory', () => { expect((0, configUtil_1.getGlobalConfigPath)()).toBe(path_1.default.join(HOME, '.pcf-helper', 'config.json')); }); it('resolves the project config at the provided cwd', () => { expect((0, configUtil_1.getProjectConfigPath)('/some/cwd')).toBe(path_1.default.join('/some/cwd', 'pcf-helper.config.json')); }); }); describe('loadPcfHelperConfig', () => { it('returns empty merged config when neither file exists', () => { setFakeFiles({}); const loaded = (0, configUtil_1.loadPcfHelperConfig)(); expect(loaded.sources).toEqual([]); expect(loaded.merged.profiles).toEqual({}); expect(loaded.merged.defaultProfile).toBeUndefined(); }); it('loads only from project when global is missing', () => { var _a, _b; const projectCfg = { defaultProfile: 'dev', profiles: { dev: { environment: 'DevOrg' } }, }; setFakeFiles({ [path_1.default.join(CWD, 'pcf-helper.config.json')]: JSON.stringify(projectCfg), }); const loaded = (0, configUtil_1.loadPcfHelperConfig)(); expect(loaded.sources).toHaveLength(1); expect(loaded.merged.defaultProfile).toBe('dev'); expect((_b = (_a = loaded.merged.profiles) === null || _a === void 0 ? void 0 : _a.dev) === null || _b === void 0 ? void 0 : _b.environment).toBe('DevOrg'); }); it('merges profiles by name — project value wins on collision', () => { var _a, _b, _c, _d; const globalCfg = { profiles: { dev: { environment: 'GlobalDev', publisherName: 'GlobalPub' }, prod: { environment: 'GlobalProd' }, }, }; const projectCfg = { profiles: { dev: { environment: 'ProjectDev' }, // overrides }, }; setFakeFiles({ [path_1.default.join(HOME, '.pcf-helper', 'config.json')]: JSON.stringify(globalCfg), [path_1.default.join(CWD, 'pcf-helper.config.json')]: JSON.stringify(projectCfg), }); const loaded = (0, configUtil_1.loadPcfHelperConfig)(); // Project dev beats global dev (whole-object replacement by design) expect((_b = (_a = loaded.merged.profiles) === null || _a === void 0 ? void 0 : _a.dev) === null || _b === void 0 ? void 0 : _b.environment).toBe('ProjectDev'); // Global-only profile is still present expect((_d = (_c = loaded.merged.profiles) === null || _c === void 0 ? void 0 : _c.prod) === null || _d === void 0 ? void 0 : _d.environment).toBe('GlobalProd'); }); it('projects defaultProfile wins over global defaultProfile', () => { setFakeFiles({ [path_1.default.join(HOME, '.pcf-helper', 'config.json')]: JSON.stringify({ defaultProfile: 'a' }), [path_1.default.join(CWD, 'pcf-helper.config.json')]: JSON.stringify({ defaultProfile: 'b' }), }); expect((0, configUtil_1.loadPcfHelperConfig)().merged.defaultProfile).toBe('b'); }); it('treats malformed JSON as empty and does not throw', () => { setFakeFiles({ [path_1.default.join(CWD, 'pcf-helper.config.json')]: 'not json {{{', }); const loaded = (0, configUtil_1.loadPcfHelperConfig)(); expect(loaded.merged.profiles).toEqual({}); }); it('merges top-level session blocks field-by-field', () => { var _a, _b; setFakeFiles({ [path_1.default.join(HOME, '.pcf-helper', 'config.json')]: JSON.stringify({ session: { remoteEnvironmentUrl: 'https://global', startWatch: true }, }), [path_1.default.join(CWD, 'pcf-helper.config.json')]: JSON.stringify({ session: { remoteEnvironmentUrl: 'https://project' }, }), }); const loaded = (0, configUtil_1.loadPcfHelperConfig)(); expect((_a = loaded.merged.session) === null || _a === void 0 ? void 0 : _a.remoteEnvironmentUrl).toBe('https://project'); expect((_b = loaded.merged.session) === null || _b === void 0 ? void 0 : _b.startWatch).toBe(true); }); }); describe('resolveProfile', () => { const merged = { defaultProfile: 'dev', profiles: { dev: { environment: 'DevOrg' }, prod: { environment: 'ProdOrg' }, }, }; it('returns the requested profile by name', () => { const { name, profile } = (0, configUtil_1.resolveProfile)('prod', merged); expect(name).toBe('prod'); expect(profile === null || profile === void 0 ? void 0 : profile.environment).toBe('ProdOrg'); }); it('falls back to defaultProfile when no name is given', () => { const { name, profile } = (0, configUtil_1.resolveProfile)(undefined, merged); expect(name).toBe('dev'); expect(profile === null || profile === void 0 ? void 0 : profile.environment).toBe('DevOrg'); }); it('returns an empty result when no name and no default', () => { const { name, profile } = (0, configUtil_1.resolveProfile)(undefined, { profiles: {} }); expect(name).toBeUndefined(); expect(profile).toBeUndefined(); }); it('throws a helpful error when the named profile is missing', () => { expect(() => (0, configUtil_1.resolveProfile)('nope', merged)).toThrow(/Profile "nope" not found/); }); }); describe('mergeSessionConfig', () => { it('layers later values over earlier values', () => { const merged = (0, configUtil_1.mergeSessionConfig)({ remoteEnvironmentUrl: 'low', startWatch: false }, { remoteEnvironmentUrl: 'mid' }, { startWatch: true }); expect(merged.remoteEnvironmentUrl).toBe('mid'); expect(merged.startWatch).toBe(true); }); it('skips undefined layers', () => { const merged = (0, configUtil_1.mergeSessionConfig)(undefined, { remoteEnvironmentUrl: 'only' }, undefined); expect(merged.remoteEnvironmentUrl).toBe('only'); }); it('ignores undefined fields in a layer (does not wipe lower values)', () => { const merged = (0, configUtil_1.mergeSessionConfig)({ remoteEnvironmentUrl: 'keep' }, { remoteEnvironmentUrl: undefined, startWatch: true }); expect(merged.remoteEnvironmentUrl).toBe('keep'); expect(merged.startWatch).toBe(true); }); }); });