|
| 1 | +import { afterEach, expect, it, vi } from 'vitest'; |
| 2 | +import { mkdtempSync, renameSync, readFileSync, rmSync, symlinkSync, writeFileSync } from 'node:fs'; |
| 3 | +import { tmpdir } from 'node:os'; |
| 4 | +import { join } from 'node:path'; |
| 5 | +import { isolatedGitEnvironment } from '../scripts/git-environment.ts'; |
| 6 | +import { createDemo } from '../scripts/demo.ts'; |
| 7 | +const roots: string[] = []; |
| 8 | +afterEach(() => { vi.unstubAllEnvs(); roots.splice(0).forEach(root => rmSync(root, { recursive: true, force: true })); }); |
| 9 | +function root() { const path = mkdtempSync(join(tmpdir(), 'codeboost-demo-')); roots.push(path); return path; } |
| 10 | +it('rejects existing demo configs redirected outside their fixture', () => { |
| 11 | + const base = root(), directory = join(base, 'demo'), config = createDemo(directory); |
| 12 | + expect(createDemo(directory)).toEqual(config); |
| 13 | + for (const key of ['repository', 'database'] as const) { |
| 14 | + writeFileSync(join(directory, 'review.json'), JSON.stringify({ ...config, [key]: join(base, 'outside') })); |
| 15 | + expect(() => createDemo(directory)).toThrow(/fixture/i); |
| 16 | + } |
| 17 | +}); |
| 18 | +it('rejects symlinked demo roots, configs, repositories and databases', () => { |
| 19 | + const base = root(), directory = join(base, 'demo'); createDemo(directory); |
| 20 | + symlinkSync(directory, join(base, 'alias')); |
| 21 | + expect(() => createDemo(join(base, 'alias'))).toThrow(/fixture/i); |
| 22 | + for (const name of ['review.json', 'retry-service', 'review.sqlite']) { |
| 23 | + const path = join(directory, name), backup = join(base, name); |
| 24 | + // Move each object out of the fixture and replace it with a symlink. |
| 25 | + renameSync(path, backup); symlinkSync(backup, path); |
| 26 | + expect(() => createDemo(directory)).toThrow(/fixture/i); |
| 27 | + rmSync(path); renameSync(backup, path); |
| 28 | + } |
| 29 | +}); |
| 30 | +it('scrubs inherited Git repository and config environment in demo commands', () => { |
| 31 | + const base = root(); |
| 32 | + vi.stubEnv('GIT_DIR', join(base, 'outside.git')); |
| 33 | + vi.stubEnv('GIT_WORK_TREE', join(base, 'outside')); |
| 34 | + vi.stubEnv('GIT_CONFIG_COUNT', '1'); |
| 35 | + vi.stubEnv('GIT_CONFIG_KEY_0', 'init.defaultBranch'); |
| 36 | + vi.stubEnv('GIT_CONFIG_VALUE_0', 'inherited'); |
| 37 | + const config = createDemo(join(base, 'demo')); |
| 38 | + expect(readFileSync(join(config.repository, 'retry.ts'), 'utf8')).toContain('Math.min'); |
| 39 | +}); |
| 40 | + |
| 41 | +it('scrubs Git environment names case-insensitively for Windows', () => { |
| 42 | + vi.stubEnv('git_dir', '/outside'); vi.stubEnv('Git_Work_Tree', '/outside'); |
| 43 | + const env = isolatedGitEnvironment(); |
| 44 | + expect(env).not.toHaveProperty('git_dir'); expect(env).not.toHaveProperty('Git_Work_Tree'); |
| 45 | + expect(env.GIT_CONFIG_NOSYSTEM).toBe('1'); |
| 46 | +}); |
0 commit comments