evOo-local/apps/api/src/env.test.ts
Claude 105a3094b1
refactor: remove the trading bot status integration
With the sidebar trading indicator gone, the only remaining consumer of
the trading bot status was a banner in General settings that reused the
same component. evOo is a personal assistant; a status proxy and poller
for one external trading service, configured through service-specific
TRADING_BOT_URL and VITE_TRADING_BOT_URL variables, does not belong in
the core product.

Remove the settings banner and its prop plumbing, the web poller, the
indicator component, the /api/trading-bot/status proxy, the shared core
contract, the env loading and both variables from .env.example, together
with their tests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MRtGG9ARfqqhma3t85Ro2u
2026-10-03 13:08:58 +00:00

215 lines
7.3 KiB
TypeScript

import { describe, expect, it } from "vitest";
import { loadEnv } from "./env.js";
const base = {
DATABASE_URL: "postgres://rakazo:rakazo@127.0.0.1:5433/rakazo",
NODE_ENV: "test",
};
describe("loadEnv", () => {
it("defaults the product path to Pi, Docker, and Graphile Worker", () => {
const env = loadEnv(base);
expect(env.agentRuntime).toBe("pi");
expect(env.sandboxProvider).toBe("docker");
expect(env.wakeupDriver).toBe("graphile");
expect(env.apiHost).toBe("127.0.0.1");
expect(env.nodeEnv).toBe("test");
});
it("defaults Pi JSONL session recording to off", () => {
expect(loadEnv(base).piSessionRecording).toBe(false);
expect(loadEnv({ ...base, PI_SESSION_RECORDING: "false" }).piSessionRecording).toBe(false);
expect(loadEnv({ ...base, PI_SESSION_RECORDING: "1" }).piSessionRecording).toBe(false);
expect(loadEnv({ ...base, PI_SESSION_RECORDING: "true" }).piSessionRecording).toBe(true);
});
it("keeps explicit emulator settings for pnpm test", () => {
const env = loadEnv({
...base,
AGENT_RUNTIME: "scripted",
SANDBOX_PROVIDER: "fake",
WAKEUP_DRIVER: "memory",
});
expect(env.agentRuntime).toBe("scripted");
expect(env.sandboxProvider).toBe("fake");
expect(env.wakeupDriver).toBe("memory");
});
it("keeps the onboarding scan off the host unless a scan home is configured", () => {
expect(loadEnv(base).onboardingScanHome).toBeUndefined();
expect(loadEnv({ ...base, ONBOARDING_SCAN_HOME: " /srv/home " }).onboardingScanHome).toBe(
"/srv/home",
);
});
it("loads an optional integrations catalog mirror", () => {
expect(loadEnv(base).integrationsCatalogUrl).toBeUndefined();
expect(
loadEnv({ ...base, INTEGRATIONS_CATALOG_URL: " https://catalog.example.test/feed " })
.integrationsCatalogUrl,
).toBe("https://catalog.example.test/feed");
});
it("falls back to none when a remote provider key is missing", () => {
expect(
loadEnv({
...base,
SANDBOX_PROVIDER: "e2b",
}).sandboxProvider,
).toBe("none");
expect(
loadEnv({
...base,
SANDBOX_PROVIDER: "none",
}).sandboxProvider,
).toBe("none");
expect(
loadEnv({
...base,
SANDBOX_PROVIDER: "",
}).sandboxProvider,
).toBe("none");
});
it("loads provider-specific Daytona configuration", () => {
const env = loadEnv({
...base,
SANDBOX_PROVIDER: "daytona",
DAYTONA_API_KEY: "test-daytona-key",
DAYTONA_API_URL: "https://daytona.test/api",
DAYTONA_TARGET: "test-target",
});
expect(env).toMatchObject({
sandboxProvider: "daytona",
daytonaApiKey: "test-daytona-key",
daytonaApiUrl: "https://daytona.test/api",
daytonaTarget: "test-target",
});
});
it("loads provider-specific Box configuration", () => {
const env = loadEnv({
...base,
SANDBOX_PROVIDER: "box",
BOX_API_KEY: "test-box-key",
BOX_API_URL: "https://box.test/api/v1",
});
expect(env).toMatchObject({
sandboxProvider: "box",
boxApiKey: "test-box-key",
boxApiUrl: "https://box.test/api/v1",
});
});
it("throws when production omits secrets", () => {
expect(() =>
loadEnv({
DATABASE_URL: base.DATABASE_URL,
NODE_ENV: "production",
}),
).toThrow(/BETTER_AUTH_SECRET/);
});
it("throws when production uses placeholder secrets", () => {
expect(() =>
loadEnv({
DATABASE_URL: base.DATABASE_URL,
NODE_ENV: "production",
BETTER_AUTH_SECRET: "dev-secret-change-me-please-32chars",
ENCRYPTION_KEY: "real-encryption-key-value",
SANDBOX_SUPERVISOR_TOKEN: "real-supervisor-token-with-enough-length",
SCREEN_PROXY_SECRET: "real-screen-proxy-secret-with-enough-length",
}),
).toThrow(/BETTER_AUTH_SECRET/);
});
it("loads real secrets in production", () => {
const env = loadEnv({
DATABASE_URL: base.DATABASE_URL,
NODE_ENV: "production",
BETTER_AUTH_SECRET: "prod-auth-secret-with-enough-length",
ENCRYPTION_KEY: "prod-encryption-key-with-enough-length",
SCREEN_PROXY_SECRET: "prod-screen-proxy-secret-with-enough-length",
SANDBOX_PROVIDER: "e2b",
API_HOST: "0.0.0.0",
});
expect(env.authSecret).toBe("prod-auth-secret-with-enough-length");
expect(env.encryptionKey).toBe("prod-encryption-key-with-enough-length");
expect(env.sandboxSupervisorToken).toBeUndefined();
expect(env.screenProxySecret).toBe("prod-screen-proxy-secret-with-enough-length");
expect(env.apiHost).toBe("0.0.0.0");
});
it("falls back to none in production when Docker has no supervisor token", () => {
const env = loadEnv({
DATABASE_URL: base.DATABASE_URL,
NODE_ENV: "production",
BETTER_AUTH_SECRET: "prod-auth-secret-with-enough-length",
ENCRYPTION_KEY: "prod-encryption-key-with-enough-length",
SCREEN_PROXY_SECRET: "prod-screen-proxy-secret-with-enough-length",
SANDBOX_PROVIDER: "docker",
});
expect(env.sandboxProvider).toBe("none");
expect(env.sandboxSupervisorToken).toBeUndefined();
});
it("requires a dedicated supervisor token when Docker stays selected", () => {
expect(() =>
loadEnv({
DATABASE_URL: base.DATABASE_URL,
NODE_ENV: "production",
BETTER_AUTH_SECRET: "prod-auth-secret-with-enough-length",
ENCRYPTION_KEY: "prod-encryption-key-with-enough-length",
SCREEN_PROXY_SECRET: "prod-screen-proxy-secret-with-enough-length",
SANDBOX_PROVIDER: "docker",
SANDBOX_SUPERVISOR_TOKEN: "too-short",
}),
).toThrow(/SANDBOX_SUPERVISOR_TOKEN/);
});
it("exposes a deployed git revision when GIT_SHA is set", () => {
expect(loadEnv(base).gitSha).toBeUndefined();
expect(loadEnv({ ...base, GIT_SHA: " 3c6e209 " }).gitSha).toBe("3c6e209");
expect(loadEnv({ ...base, RAKAZO_GIT_SHA: "abc1234" }).gitSha).toBe("abc1234");
});
it("loads optional updater sidecar wiring without requiring the token at boot", () => {
expect(loadEnv(base).updaterUrl).toBeUndefined();
expect(loadEnv(base).updaterToken).toBeUndefined();
const env = loadEnv({
...base,
RAKAZO_UPDATER_URL: " http://updater:7092 ",
RAKAZO_UPDATER_TOKEN: " fake-review-updater-token-000000000000 ",
});
expect(env.updaterUrl).toBe("http://updater:7092");
expect(env.updaterToken).toBe("fake-review-updater-token-000000000000");
});
it("loads SMTP configuration and keeps the email emulator out of production", () => {
expect(
loadEnv({
...base,
SMTP_URL: " smtps://user:secret@smtp.example.test:465 ",
EMAIL_FROM: " Rakazo <no-reply@example.test> ",
EMAIL_EMULATOR: "true",
}),
).toMatchObject({
smtpUrl: "smtps://user:secret@smtp.example.test:465",
emailFrom: "Rakazo <no-reply@example.test>",
emailEmulator: true,
});
expect(
loadEnv({
...base,
NODE_ENV: "production",
BETTER_AUTH_SECRET: "prod-auth-secret-with-enough-length",
ENCRYPTION_KEY: "prod-encryption-key-with-enough-length",
SCREEN_PROXY_SECRET: "prod-screen-proxy-secret-with-enough-length",
SANDBOX_PROVIDER: "none",
EMAIL_EMULATOR: "true",
}).emailEmulator,
).toBe(false);
expect(loadEnv({ ...base, NODE_ENV: "development" }).nodeEnv).toBe("development");
});
});