AikidoSec-safe-chain/packages/safe-chain/src/shell-integration/setup-ci.spec.js
2026-04-14 11:30:29 -07:00

151 lines
5.3 KiB
JavaScript

import { describe, it, beforeEach, afterEach, mock } from "node:test";
import assert from "node:assert";
import { tmpdir } from "node:os";
import fs from "node:fs";
import path from "path";
describe("Setup CI shell integration", () => {
let mockShimsDir;
let mockTemplateDir;
let setupCi;
let mockHomeDir;
let mockPlatform;
beforeEach(async () => {
mockPlatform = "linux";
// Create temporary directories for testing
mockHomeDir = path.join(tmpdir(), `test-home-${Date.now()}`);
mockShimsDir = path.join(mockHomeDir, ".safe-chain", "shims");
mockTemplateDir = path.join(tmpdir(), `test-templates-${Date.now()}`);
// Create template directories and files
fs.mkdirSync(path.join(mockTemplateDir, "path-wrappers", "templates"), { recursive: true });
fs.writeFileSync(
path.join(mockTemplateDir, "path-wrappers", "templates", "unix-wrapper.template.sh"),
"#!/bin/bash\n# Template for {{PACKAGE_MANAGER}}\n_safe_chain_shims=$(CDPATH= cd -- \"$(dirname -- \"$0\")\" 2>/dev/null && pwd -P)\nexec {{AIKIDO_COMMAND}} \"$@\"\n",
"utf-8"
);
fs.writeFileSync(
path.join(mockTemplateDir, "path-wrappers", "templates", "windows-wrapper.template.cmd"),
"@echo off\nset \"SHIM_DIR=%~dp0\"\n{{AIKIDO_COMMAND}} %*\n",
"utf-8"
);
// Mock the ui module
mock.module("../environment/userInteraction.js", {
namedExports: {
ui: {
writeInformation: () => {},
emptyLine: () => {},
writeError: () => {},
},
},
});
// Mock the helpers module
mock.module("./helpers.js", {
namedExports: {
knownAikidoTools: [
{ tool: "npm", aikidoCommand: "aikido-npm" },
{ tool: "yarn", aikidoCommand: "aikido-yarn" },
],
getPackageManagerList: () => "npm, yarn",
},
});
mock.module("../config/safeChainDir.js", {
namedExports: {
getShimsDir: () => mockShimsDir,
getBinDir: () => path.join(mockHomeDir, ".safe-chain", "bin"),
getPathWrapperTemplatePath: (_moduleUrl, fileName) =>
path.join(mockTemplateDir, "path-wrappers", "templates", fileName),
},
});
// Mock os module
mock.module("os", {
namedExports: {
homedir: () => mockHomeDir,
platform: () => mockPlatform,
EOL: "\n",
},
});
// Import setupCi module after mocking
setupCi = (await import("./setup-ci.js")).setupCi;
});
afterEach(() => {
// Clean up test directories
if (fs.existsSync(mockShimsDir)) {
fs.rmSync(mockShimsDir, { recursive: true, force: true });
}
if (fs.existsSync(mockHomeDir)) {
fs.rmSync(mockHomeDir, { recursive: true, force: true });
}
if (fs.existsSync(mockTemplateDir)) {
fs.rmSync(mockTemplateDir, { recursive: true, force: true });
}
// Reset mocks
mock.reset();
mockPlatform = "linux";
});
describe("setupCi", () => {
it("should create shims directory and Unix shims", async () => {
await setupCi();
// Check if shims directory was created
assert.ok(fs.existsSync(mockShimsDir), "Shims directory should exist");
// Check if npm shim was created
const npmShimPath = path.join(mockShimsDir, "npm");
assert.ok(fs.existsSync(npmShimPath), "npm shim should exist");
// Check if yarn shim was created
const yarnShimPath = path.join(mockShimsDir, "yarn");
assert.ok(fs.existsSync(yarnShimPath), "yarn shim should exist");
// Check content of npm shim
const npmShimContent = fs.readFileSync(npmShimPath, "utf-8");
assert.ok(npmShimContent.includes("aikido-npm"), "npm shim should contain aikido-npm");
assert.ok(npmShimContent.includes("#!/bin/bash"), "npm shim should have bash shebang");
assert.ok(
npmShimContent.includes("_safe_chain_shims=$(CDPATH= cd -- \"$(dirname -- \"$0\")\" 2>/dev/null && pwd -P)"),
"npm shim should derive the shims directory from its own location",
);
});
it("should create Windows .cmd shims on win32 platform", async () => {
// Change platform for this test
mockPlatform = "win32";
await setupCi();
// Check if shims directory was created
assert.ok(fs.existsSync(mockShimsDir), "Shims directory should exist");
// Check if .cmd files were created instead of Unix scripts
const npmShimPath = path.join(mockShimsDir, "npm.cmd");
assert.ok(fs.existsSync(npmShimPath), "npm.cmd shim should exist");
const yarnShimPath = path.join(mockShimsDir, "yarn.cmd");
assert.ok(fs.existsSync(yarnShimPath), "yarn.cmd shim should exist");
// Check content of npm.cmd shim
const npmShimContent = fs.readFileSync(npmShimPath, "utf-8");
assert.ok(npmShimContent.includes("aikido-npm"), "npm.cmd should contain aikido-npm");
assert.ok(npmShimContent.includes("@echo off"), "npm.cmd should have Windows batch header");
assert.ok(npmShimContent.includes("%*"), "npm.cmd should use Windows argument passing");
assert.ok(
npmShimContent.includes('set "SHIM_DIR=%~dp0"'),
"npm.cmd should derive the shims directory from its own location",
);
// Verify Unix shims were NOT created
const unixNpmShim = path.join(mockShimsDir, "npm");
assert.ok(!fs.existsSync(unixNpmShim), "Unix npm shim should not exist on Windows");
});
});
});