|
15 | 15 | */ |
16 | 16 |
|
17 | 17 | import { describe, expect, it } from '@jest/globals'; |
| 18 | +import path from 'path'; |
18 | 19 | import { checkPermissionSecret, validateCommandData } from './runCmd'; |
19 | 20 |
|
20 | 21 | describe('checkPermissionSecret', () => { |
@@ -220,3 +221,68 @@ describe('validateCommandData', () => { |
220 | 221 | ).toBe(true); |
221 | 222 | }); |
222 | 223 | }); |
| 224 | + |
| 225 | +describe('runScript', () => { |
| 226 | + const originalArgv = process.argv; |
| 227 | + const originalExit = process.exit; |
| 228 | + const originalConsoleError = console.error; |
| 229 | + const originalResourcesPath = process.resourcesPath; |
| 230 | + |
| 231 | + let exitMock: jest.Mock; |
| 232 | + let consoleErrorMock: jest.Mock; |
| 233 | + beforeEach(() => { |
| 234 | + jest.resetModules(); |
| 235 | + // @ts-ignore this is fine for tests |
| 236 | + process.resourcesPath = '/resources'; |
| 237 | + jest.mock('./plugin-management', () => ({ |
| 238 | + defaultPluginsDir: jest.fn(() => '/plugins/default'), |
| 239 | + defaultUserPluginsDir: jest.fn(() => '/plugins/user'), |
| 240 | + })); |
| 241 | + |
| 242 | + exitMock = jest.fn() as any; |
| 243 | + // @ts-expect-error overriding for test |
| 244 | + process.exit = exitMock; |
| 245 | + consoleErrorMock = jest.fn(); |
| 246 | + console.error = consoleErrorMock; |
| 247 | + }); |
| 248 | + |
| 249 | + afterEach(() => { |
| 250 | + process.argv = originalArgv; |
| 251 | + process.exit = originalExit; |
| 252 | + console.error = originalConsoleError; |
| 253 | + // @ts-ignore |
| 254 | + process.resourcesPath = originalResourcesPath; |
| 255 | + jest.unmock('./plugin-management'); |
| 256 | + jest.restoreAllMocks(); |
| 257 | + }); |
| 258 | + |
| 259 | + const testScriptImport = async (scriptPath: string) => { |
| 260 | + const resolvedPath = path.resolve(scriptPath); |
| 261 | + process.argv = ['node', resolvedPath]; |
| 262 | + jest.doMock(resolvedPath, () => ({}), { virtual: true }); |
| 263 | + const runCmdModule = await import('./runCmd'); |
| 264 | + runCmdModule.runScript(); |
| 265 | + expect(exitMock).not.toHaveBeenCalled(); |
| 266 | + }; |
| 267 | + |
| 268 | + it('imports the script when path is inside defaultPluginsDir', () => |
| 269 | + testScriptImport('/plugins/default/my-script.js')); |
| 270 | + |
| 271 | + it('imports the script when path is inside defaultUserPluginsDir', () => |
| 272 | + testScriptImport('/plugins/user/my-script.js')); |
| 273 | + |
| 274 | + it('imports the script when path is inside static .plugins dir', () => |
| 275 | + testScriptImport('/resources/.plugins/my-script.js')); |
| 276 | + |
| 277 | + it('exits with error when script is outside allowed directories', async () => { |
| 278 | + const scriptPath = path.resolve('/not-allowed/my-script.js'); |
| 279 | + process.argv = ['node', scriptPath]; |
| 280 | + jest.doMock(scriptPath, () => ({}), { virtual: true }); |
| 281 | + |
| 282 | + const runCmdModule = await import('./runCmd'); |
| 283 | + runCmdModule.runScript(); |
| 284 | + |
| 285 | + expect(consoleErrorMock).toHaveBeenCalledTimes(1); |
| 286 | + expect(exitMock).toHaveBeenCalledWith(1); |
| 287 | + }); |
| 288 | +}); |
0 commit comments