mirror of
https://github.com/nexu-io/open-design.git
synced 2026-06-01 03:14:35 +07:00
* Optimize Windows packaged web output * Fix packaged contracts runtime build * Optimize Windows packaged size pruning * Prune Windows root Next payload * Remove Windows bundled Node runtime * Prune Windows standalone duplicate Next * Add tools-pack cache foundation * Cache Windows packaged build layers * Cache Windows workspace builds * Cache Electron-ready Windows app * Split Windows tools-pack module * Cache Windows dir build outputs * Split Windows pack build modules * Document Windows NSIS smoke namespace limits * Move Windows NSIS smoke note to agents guide * Optimize Windows beta packaging * Bump packaged beta base version * Improve Windows installer namespace UX * Improve Windows tools-pack cache keys * Stabilize Windows beta cache version keys * Cache Windows workspace build outputs * Optimize windows release beta cache layers * Cache windows release dependencies * Trim windows release cache before save * Refresh windows tools-pack cache key * Improve windows installer preflight prompts * Fallback NSIS installer strings to English * Fix Windows installer cleanup and preflight * Improve Windows NSIS state logging * Fix system NSIS Persian language alias * Use long-path removal for Windows uninstall * Fix mac tools-pack tests on Windows * Address Windows packaging review feedback * Fix Windows installer cache namespace isolation * Include web output mode in Windows tarball cache key * Use unique Windows release cache save keys
125 lines
3.9 KiB
TypeScript
125 lines
3.9 KiB
TypeScript
import { test } from 'vitest';
|
|
import assert from 'node:assert/strict';
|
|
import { mkdirSync, mkdtempSync, writeFileSync, rmSync, symlinkSync, realpathSync } from 'node:fs';
|
|
import { tmpdir } from 'node:os';
|
|
import { join } from 'node:path';
|
|
import { validateLinkedDirs } from '../src/linked-dirs.js';
|
|
|
|
/** Resolve macOS /var -> /private/var etc. so assertions match realpathSync. */
|
|
function real(p: string): string {
|
|
try { return realpathSync(p); } catch { return p; }
|
|
}
|
|
|
|
function blockedSystemDir(): string {
|
|
return real(process.platform === 'win32' ? (process.env.SystemRoot ?? 'C:\\Windows') : '/etc');
|
|
}
|
|
|
|
test('rejects non-array input', () => {
|
|
assert.equal(validateLinkedDirs('not-array').error, 'linkedDirs must be an array');
|
|
assert.equal(validateLinkedDirs(null).error, 'linkedDirs must be an array');
|
|
});
|
|
|
|
test('rejects non-string entries', () => {
|
|
assert.equal(validateLinkedDirs([123]).error, 'each linked dir must be a non-empty string');
|
|
assert.equal(validateLinkedDirs(['']).error, 'each linked dir must be a non-empty string');
|
|
});
|
|
|
|
test('rejects relative paths', () => {
|
|
const result = validateLinkedDirs(['relative/path']);
|
|
assert.ok(result.error);
|
|
assert.ok(result.error.includes('absolute path'));
|
|
});
|
|
|
|
test('rejects non-existent directories', () => {
|
|
const result = validateLinkedDirs(['/no/such/directory/ever']);
|
|
assert.ok(result.error);
|
|
assert.ok(result.error!.includes('does not exist'));
|
|
});
|
|
|
|
test('rejects files (non-directories)', () => {
|
|
const tmp = mkdtempSync(join(tmpdir(), 'od-linked-'));
|
|
const file = join(tmp, 'file.txt');
|
|
writeFileSync(file, 'test');
|
|
try {
|
|
const result = validateLinkedDirs([file]);
|
|
assert.ok(result.error);
|
|
assert.ok(result.error!.includes('not a directory'));
|
|
} finally {
|
|
rmSync(tmp, { recursive: true });
|
|
}
|
|
});
|
|
|
|
test('rejects filesystem root', () => {
|
|
const result = validateLinkedDirs(['/']);
|
|
assert.ok(result.error);
|
|
assert.ok(result.error.includes('system directory'));
|
|
});
|
|
|
|
test('rejects blocked system directories', () => {
|
|
const result = validateLinkedDirs([blockedSystemDir()]);
|
|
assert.ok(result.error);
|
|
assert.ok(result.error.includes('system directory'));
|
|
});
|
|
|
|
test('rejects symlink pointing to blocked directory', () => {
|
|
const tmp = mkdtempSync(join(tmpdir(), 'od-linked-'));
|
|
const link = join(tmp, 'etc-link');
|
|
try {
|
|
symlinkSync(blockedSystemDir(), link, process.platform === 'win32' ? 'junction' : 'dir');
|
|
const result = validateLinkedDirs([link]);
|
|
assert.ok(result.error);
|
|
assert.ok(result.error.includes('system directory'));
|
|
} finally {
|
|
rmSync(tmp, { recursive: true });
|
|
}
|
|
});
|
|
|
|
test('accepts valid directories and normalizes paths', () => {
|
|
const tmp = mkdtempSync(join(tmpdir(), 'od-linked-'));
|
|
try {
|
|
const result = validateLinkedDirs([tmp]);
|
|
assert.ok(!result.error);
|
|
assert.deepEqual(result.dirs, [real(tmp)]);
|
|
} finally {
|
|
rmSync(tmp, { recursive: true });
|
|
}
|
|
});
|
|
|
|
test('deduplicates entries', () => {
|
|
const tmp = mkdtempSync(join(tmpdir(), 'od-linked-'));
|
|
try {
|
|
const result = validateLinkedDirs([tmp, tmp]);
|
|
assert.ok(!result.error);
|
|
assert.equal(result.dirs!.length, 1);
|
|
} finally {
|
|
rmSync(tmp, { recursive: true });
|
|
}
|
|
});
|
|
|
|
test('resolves and normalizes paths', () => {
|
|
const tmp = mkdtempSync(join(tmpdir(), 'od-linked-'));
|
|
const inner = join(tmp, 'inner');
|
|
mkdirSync(inner);
|
|
try {
|
|
const result = validateLinkedDirs([join(tmp, 'inner', '..') + '/']);
|
|
assert.ok(!result.error);
|
|
assert.deepEqual(result.dirs, [real(tmp)]);
|
|
} finally {
|
|
rmSync(tmp, { recursive: true });
|
|
}
|
|
});
|
|
|
|
test('resolves symlinks to real paths', () => {
|
|
const tmp = mkdtempSync(join(tmpdir(), 'od-linked-'));
|
|
const inner = join(tmp, 'inner');
|
|
const link = join(tmp, 'link');
|
|
mkdirSync(inner);
|
|
try {
|
|
symlinkSync(inner, link);
|
|
const result = validateLinkedDirs([link]);
|
|
assert.ok(!result.error);
|
|
assert.deepEqual(result.dirs, [real(inner)]);
|
|
} finally {
|
|
rmSync(tmp, { recursive: true });
|
|
}
|
|
});
|