Files
OmniRoute/tests/unit/sync-env.test.mjs
Diego Rodrigues de Sa e Souza 515674b6cf chore(release): v3.6.1 — OAuth env repair + i18n fix (#1117)
* chore: bump to v3.6.1

* fix(i18n): add missing provider messages across locales (#1111)

Integrated into release/v3.6.1 — adds missing filterModels, modelsActive, showModel, hideModel i18n keys across all 32 locales

* fix: add Repair env action for OAuth providers (#1116)

Integrated into release/v3.6.1 — adds OAuth env repair feature with full 33-language i18n support and backupPath security fix

* chore(release): v3.6.1 — OAuth env repair + i18n fix

* fix: add targetFormat openai-responses to gpt-5.4 and gpt-5.4-mini (#1114)

* fix: add targetFormat openai-responses to gpt-5.4 and gpt-5.4-mini (#1114)

* chore: force CI trigger

---------

Co-authored-by: diegosouzapw <diegosouzapw@users.noreply.github.com>
Co-authored-by: Ilham Ramadhan <28677129+rilham97@users.noreply.github.com>
Co-authored-by: Artёm <470045+yart@users.noreply.github.com>
2026-04-10 12:19:15 -03:00

138 lines
5.1 KiB
JavaScript

import test from "node:test";
import assert from "node:assert/strict";
import fs from "node:fs";
import os from "node:os";
import path from "node:path";
const { syncEnv } = await import("../../scripts/sync-env.mjs");
function createTempRoot() {
return fs.mkdtempSync(path.join(os.tmpdir(), "omniroute-sync-env-"));
}
function writeEnvExample(rootDir) {
fs.writeFileSync(
path.join(rootDir, ".env.example"),
[
"JWT_SECRET=",
"API_KEY_SECRET=",
"STORAGE_ENCRYPTION_KEY=",
"MACHINE_ID_SALT=",
"CLAUDE_OAUTH_CLIENT_ID=claude-default",
"CODEX_OAUTH_CLIENT_ID=codex-default",
"# COMMENTED_KEY=skip-me",
"",
].join("\n"),
"utf8"
);
}
function writeOauthEnvExample(rootDir) {
fs.writeFileSync(
path.join(rootDir, ".env.example"),
[
"# ═══════════════════════════════════════════════════",
"# OAUTH PROVIDER CREDENTIALS",
"# ═══════════════════════════════════════════════════",
"CLAUDE_OAUTH_CLIENT_ID=claude-default",
"CODEX_OAUTH_CLIENT_ID=codex-default",
"# ─────────────────────────────────────────────────────────────────────────────",
"# Provider User-Agent Overrides (optional — customize per-provider UA headers)",
"# ─────────────────────────────────────────────────────────────────────────────",
"JWT_SECRET=should-not-be-copied",
"",
].join("\n"),
"utf8"
);
}
test("syncEnv creates .env from .env.example and generates blank secrets", () => {
const rootDir = createTempRoot();
try {
writeEnvExample(rootDir);
const result = syncEnv({ rootDir, quiet: true });
const envContent = fs.readFileSync(path.join(rootDir, ".env"), "utf8");
assert.deepEqual(result, { created: true, added: 6 });
assert.match(envContent, /^JWT_SECRET=.{32,}$/m);
assert.match(envContent, /^API_KEY_SECRET=.{32,}$/m);
assert.match(envContent, /^STORAGE_ENCRYPTION_KEY=.{32,}$/m);
assert.match(envContent, /^MACHINE_ID_SALT=omniroute-/m);
assert.match(envContent, /^CLAUDE_OAUTH_CLIENT_ID=claude-default$/m);
assert.match(envContent, /^CODEX_OAUTH_CLIENT_ID=codex-default$/m);
assert.doesNotMatch(envContent, /^COMMENTED_KEY=/m);
} finally {
fs.rmSync(rootDir, { recursive: true, force: true });
}
});
test("syncEnv appends only missing keys and preserves existing values", () => {
const rootDir = createTempRoot();
try {
writeEnvExample(rootDir);
fs.writeFileSync(
path.join(rootDir, ".env"),
[
"JWT_SECRET=my-custom-secret-that-should-stay",
"CLAUDE_OAUTH_CLIENT_ID=custom-claude",
"",
].join("\n"),
"utf8"
);
const result = syncEnv({ rootDir, quiet: true });
const envContent = fs.readFileSync(path.join(rootDir, ".env"), "utf8");
assert.deepEqual(result, { created: false, added: 4 });
assert.match(envContent, /^JWT_SECRET=my-custom-secret-that-should-stay$/m);
assert.match(envContent, /^CLAUDE_OAUTH_CLIENT_ID=custom-claude$/m);
assert.match(envContent, /^API_KEY_SECRET=.{32,}$/m);
assert.match(envContent, /^STORAGE_ENCRYPTION_KEY=.{32,}$/m);
assert.match(envContent, /^MACHINE_ID_SALT=omniroute-/m);
assert.match(envContent, /^CODEX_OAUTH_CLIENT_ID=codex-default$/m);
assert.match(envContent, /Auto-added by sync-env/);
} finally {
fs.rmSync(rootDir, { recursive: true, force: true });
}
});
test("syncEnv is idempotent when .env is already complete", () => {
const rootDir = createTempRoot();
try {
writeEnvExample(rootDir);
syncEnv({ rootDir, quiet: true });
const before = fs.readFileSync(path.join(rootDir, ".env"), "utf8");
const result = syncEnv({ rootDir, quiet: true });
const after = fs.readFileSync(path.join(rootDir, ".env"), "utf8");
assert.deepEqual(result, { created: false, added: 0 });
assert.equal(after, before);
} finally {
fs.rmSync(rootDir, { recursive: true, force: true });
}
});
test("syncEnv oauth scope only copies oauth defaults", () => {
const rootDir = createTempRoot();
try {
writeOauthEnvExample(rootDir);
const result = syncEnv({ rootDir, quiet: true, scope: "oauth" });
const envContent = fs.readFileSync(path.join(rootDir, ".env"), "utf8");
assert.deepEqual(result, { created: true, added: 2 });
assert.match(envContent, /^CLAUDE_OAUTH_CLIENT_ID=claude-default$/m);
assert.match(envContent, /^CODEX_OAUTH_CLIENT_ID=codex-default$/m);
assert.doesNotMatch(envContent, /^JWT_SECRET=/m);
assert.doesNotMatch(envContent, /^Provider User-Agent Overrides/m);
} finally {
fs.rmSync(rootDir, { recursive: true, force: true });
}
});