test(server): scope customHome temp dir to the GITNEXUS_HOME-set cases

beforeEach created a customHome temp dir for all five tests, but the two
fallback cases never use it (one manages its own fakeHome, the other needs
none). Moved the mkdtemp/rm into a nested describe('with GITNEXUS_HOME set')
wrapping the three set-cases; the shared outer afterEach still restores
GITNEXUS_HOME and resets modules for all five.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Gergo Magyar 2026-06-18 15:57:11 +00:00
parent cec44d9059
commit 640ab43998

View file

@ -20,47 +20,56 @@ import fs from 'node:fs/promises';
*/
describe('GITNEXUS_HOME path roots', () => {
const savedHome = process.env.GITNEXUS_HOME;
// mkdtemp (not a fixed os.tmpdir() name) so a co-located process cannot
// pre-create or symlink the path before our writes land
// (CodeQL js/insecure-temporary-file).
let customHome: string;
beforeEach(async () => {
customHome = await fs.mkdtemp(path.join(os.tmpdir(), 'gitnexus-home-roots-'));
});
afterEach(async () => {
afterEach(() => {
if (savedHome === undefined) delete process.env.GITNEXUS_HOME;
else process.env.GITNEXUS_HOME = savedHome;
vi.resetModules();
await fs.rm(customHome, { recursive: true, force: true });
});
it('clone root follows GITNEXUS_HOME', async () => {
process.env.GITNEXUS_HOME = customHome;
vi.resetModules();
const { getCloneDir } = await import('../../src/server/git-clone.js');
expect(getCloneDir('my-repo')).toBe(path.resolve(customHome, 'repos', 'my-repo'));
});
// customHome is only needed by the GITNEXUS_HOME-set cases below; the two
// fallback cases manage their own (or no) temp dir, so its lifecycle lives in
// this nested block rather than a shared beforeEach.
describe('with GITNEXUS_HOME set', () => {
// mkdtemp (not a fixed os.tmpdir() name) so a co-located process cannot
// pre-create or symlink the path before our writes land
// (CodeQL js/insecure-temporary-file).
let customHome: string;
it('upload root follows GITNEXUS_HOME', async () => {
process.env.GITNEXUS_HOME = customHome;
vi.resetModules();
const { UPLOAD_ROOT, getUploadDir } = await import('../../src/server/upload-paths.js');
expect(UPLOAD_ROOT).toBe(path.resolve(customHome, 'uploads'));
expect(getUploadDir('my-repo')).toBe(path.resolve(customHome, 'uploads', 'my-repo'));
});
beforeEach(async () => {
customHome = await fs.mkdtemp(path.join(os.tmpdir(), 'gitnexus-home-roots-'));
});
it('server-mapping file is read from GITNEXUS_HOME', async () => {
process.env.GITNEXUS_HOME = customHome;
await fs.writeFile(
path.join(customHome, 'server-mapping.json'),
JSON.stringify({ 'my-repo': 'payments-service' }),
'utf-8',
);
vi.resetModules();
const { readServerMapping } = await import('../../src/core/embeddings/server-mapping.js');
expect(await readServerMapping('my-repo')).toBe('payments-service');
afterEach(async () => {
await fs.rm(customHome, { recursive: true, force: true });
});
it('clone root follows GITNEXUS_HOME', async () => {
process.env.GITNEXUS_HOME = customHome;
vi.resetModules();
const { getCloneDir } = await import('../../src/server/git-clone.js');
expect(getCloneDir('my-repo')).toBe(path.resolve(customHome, 'repos', 'my-repo'));
});
it('upload root follows GITNEXUS_HOME', async () => {
process.env.GITNEXUS_HOME = customHome;
vi.resetModules();
const { UPLOAD_ROOT, getUploadDir } = await import('../../src/server/upload-paths.js');
expect(UPLOAD_ROOT).toBe(path.resolve(customHome, 'uploads'));
expect(getUploadDir('my-repo')).toBe(path.resolve(customHome, 'uploads', 'my-repo'));
});
it('server-mapping file is read from GITNEXUS_HOME', async () => {
process.env.GITNEXUS_HOME = customHome;
await fs.writeFile(
path.join(customHome, 'server-mapping.json'),
JSON.stringify({ 'my-repo': 'payments-service' }),
'utf-8',
);
vi.resetModules();
const { readServerMapping } = await import('../../src/core/embeddings/server-mapping.js');
expect(await readServerMapping('my-repo')).toBe('payments-service');
});
});
it('falls back to ~/.gitnexus when GITNEXUS_HOME is unset', async () => {