Files
claude-task-master/tests/integration/init-config.test.js
Eyal Toledano 2819be51d3 feat: Implement TaskMaster AI Gateway integration with enhanced UX
- Fix Zod schema conversion, update headers, add premium telemetry display, improve user auth flow, and standardize email fields

Functionally complete on this end, mostly polish around user experience and need to add in profile, upgrade/downgrade, etc.

But the AI commands are working off the gateway.
2025-06-01 19:37:12 -04:00

254 lines
7.8 KiB
JavaScript

import fs from "fs";
import path from "path";
import { execSync } from "child_process";
import { jest } from "@jest/globals";
import { fileURLToPath } from "url";
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
describe("TaskMaster Init Configuration Tests", () => {
const testProjectDir = path.join(__dirname, "../../test-init-project");
const configPath = path.join(testProjectDir, ".taskmasterconfig");
const envPath = path.join(testProjectDir, ".env");
beforeEach(() => {
// Clear all mocks and reset modules to prevent interference from other tests
jest.clearAllMocks();
jest.resetAllMocks();
jest.resetModules();
// Clean up test directory
if (fs.existsSync(testProjectDir)) {
execSync(`rm -rf "${testProjectDir}"`);
}
fs.mkdirSync(testProjectDir, { recursive: true });
process.chdir(testProjectDir);
});
afterEach(() => {
// Clean up after tests
process.chdir(__dirname);
if (fs.existsSync(testProjectDir)) {
execSync(`rm -rf "${testProjectDir}"`);
}
// Clear mocks again
jest.clearAllMocks();
jest.resetAllMocks();
});
describe("getUserId functionality", () => {
it("should read userId from config.account.userId", async () => {
// Create config with userId in account section
const config = {
account: {
mode: "byok",
userId: "test-user-123",
},
};
fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
// Import and test getUserId
const { getUserId } = await import(
"../../scripts/modules/config-manager.js"
);
const userId = getUserId(testProjectDir);
expect(userId).toBe("test-user-123");
});
it("should set default userId if none exists", async () => {
// Create config without userId
const config = {
account: {
mode: "byok",
},
};
fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
const { getUserId } = await import(
"../../scripts/modules/config-manager.js"
);
const userId = getUserId(testProjectDir);
// Should set default userId
expect(userId).toBe("1234567890");
// Verify it was written to config
const savedConfig = JSON.parse(fs.readFileSync(configPath, "utf8"));
expect(savedConfig.account.userId).toBe("1234567890");
});
it("should return existing userId even if it's the default value", async () => {
// Create config with default userId already set
const config = {
account: {
mode: "byok",
userId: "1234567890",
},
};
fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
const { getUserId } = await import(
"../../scripts/modules/config-manager.js"
);
const userId = getUserId(testProjectDir);
// Should return the existing userId (even if it's the default)
expect(userId).toBe("1234567890");
});
});
describe("Init process integration", () => {
it("should store mode (byok/hosted) in config", () => {
// Test that mode gets stored correctly
const config = {
account: {
mode: "hosted",
userId: "test-user-789",
},
};
fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
// Read config back
const savedConfig = JSON.parse(fs.readFileSync(configPath, "utf8"));
expect(savedConfig.account.mode).toBe("hosted");
expect(savedConfig.account.userId).toBe("test-user-789");
});
it("should store API key in .env file (NOT config)", () => {
// Create .env with API key
const envContent =
"TASKMASTER_SERVICE_ID=test-api-key-123\nOTHER_VAR=value\n";
fs.writeFileSync(envPath, envContent);
// Test that API key is in .env
const envFileContent = fs.readFileSync(envPath, "utf8");
expect(envFileContent).toContain(
"TASKMASTER_SERVICE_ID=test-api-key-123"
);
// Test that API key is NOT in config
const config = {
account: {
mode: "byok",
userId: "test-user-abc",
},
};
fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
const configContent = fs.readFileSync(configPath, "utf8");
expect(configContent).not.toContain("test-api-key-123");
expect(configContent).not.toContain("apiKey");
});
});
describe("Telemetry configuration", () => {
it("should get API key from .env file", async () => {
// Create .env with API key
const envContent = "TASKMASTER_SERVICE_ID=env-api-key-456\n";
fs.writeFileSync(envPath, envContent);
// Test reading API key from .env
const { resolveEnvVariable } = await import(
"../../scripts/modules/utils.js"
);
const apiKey = resolveEnvVariable(
"TASKMASTER_SERVICE_ID",
null,
testProjectDir
);
expect(apiKey).toBe("env-api-key-456");
});
it("should prioritize environment variables", async () => {
// Clean up any existing env var first
delete process.env.TASKMASTER_SERVICE_ID;
// Set environment variable
process.env.TASKMASTER_SERVICE_ID = "process-env-key";
// Also create .env file
const envContent = "TASKMASTER_SERVICE_ID=file-env-key\n";
fs.writeFileSync(envPath, envContent);
const { resolveEnvVariable } = await import(
"../../scripts/modules/utils.js"
);
// Test with explicit projectRoot to avoid caching issues
const apiKey = resolveEnvVariable("TASKMASTER_SERVICE_ID");
// Should prioritize process.env over .env file
expect(apiKey).toBe("process-env-key");
// Clean up
delete process.env.TASKMASTER_SERVICE_ID;
});
});
describe("Config structure consistency", () => {
it("should maintain consistent structure for both BYOK and hosted modes", () => {
// Test BYOK mode structure
const byokConfig = {
account: {
mode: "byok",
userId: "byok-user-123",
telemetryEnabled: false,
},
};
fs.writeFileSync(configPath, JSON.stringify(byokConfig, null, 2));
let config = JSON.parse(fs.readFileSync(configPath, "utf8"));
expect(config.account.mode).toBe("byok");
expect(config.account.userId).toBe("byok-user-123");
expect(config.account.telemetryEnabled).toBe(false);
// Test hosted mode structure
const hostedConfig = {
account: {
mode: "hosted",
userId: "hosted-user-456",
telemetryEnabled: true,
},
};
fs.writeFileSync(configPath, JSON.stringify(hostedConfig, null, 2));
config = JSON.parse(fs.readFileSync(configPath, "utf8"));
expect(config.account.mode).toBe("hosted");
expect(config.account.userId).toBe("hosted-user-456");
expect(config.account.telemetryEnabled).toBe(true);
});
it("should use consistent userId location (config.account.userId)", async () => {
const config = {
account: {
mode: "byok",
userId: "consistent-user-789",
},
global: {
logLevel: "info",
},
};
fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
// Clear any cached modules to ensure fresh import
jest.resetModules();
const { getUserId } = await import(
"../../scripts/modules/config-manager.js"
);
const userId = getUserId(testProjectDir);
expect(userId).toBe("consistent-user-789");
// Verify it's in account section, not root
const savedConfig = JSON.parse(fs.readFileSync(configPath, "utf8"));
expect(savedConfig.account.userId).toBe("consistent-user-789");
expect(savedConfig.userId).toBeUndefined(); // Should NOT be in root
});
});
});