Some checks failed
L'intégration Forgejo (« Créer un ticket » depuis un message de contact, issue #81) restait invisible en prod Docker : `docker-compose.yml` ne listait pas `FORGEJO_BASE_URL` / `FORGEJO_TOKEN` / `FORGEJO_REPO` dans le bloc `environment:` du service `app`, et `**/.env` est `.dockerignore`d — le process API ne voyait donc jamais ces variables, `ForgejoService.isConfigured()` renvoyait `false` et le bouton restait masqué sur `/admin/messages`. - `docker-compose.yml` : les 3 `FORGEJO_*` passées au conteneur via `${VAR:-}`, même forme que `ADMIN_JWT_SECRET` / `INTERNAL_WORKER_SECRET`. - `config/env.ts` : `blankAsUnset` sur les 3 champs — `${VAR:-}` arrive comme `""` quand le `.env` du stack laisse la variable vide ; sans ça une valeur vide ferait échouer `.url()` / la regex `owner/repo` et planter `envSchema.parse()` au boot. Même parade que `COOKIE_SECURE`. `envSchema` exporté pour le test. - `.env.example` (racine) : documente les 3 variables au niveau compose. - `apps/api/test/env.test.ts` : blanc = absent, + non-régression sur une valeur non vide mais mal formée. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
59 lines
2.2 KiB
TypeScript
59 lines
2.2 KiB
TypeScript
import { expect } from "chai";
|
|
import { envSchema } from "../src/config/env.js";
|
|
|
|
/**
|
|
* Pure schema test — no DB, no `process.env`. Covers `blankAsUnset` on the
|
|
* `FORGEJO_*` trio: `docker-compose.yml` forwards every optional var as
|
|
* `${FOO:-}`, which the container receives as `""` (not an absent key) when
|
|
* the stack's `.env` leaves it blank. Those three must read a blank value
|
|
* as "not configured" and still boot, rather than trip `FORGEJO_BASE_URL`'s
|
|
* `.url()` / `FORGEJO_REPO`'s regex and abort `parse()` at startup.
|
|
*/
|
|
describe("envSchema — FORGEJO_* blank handling", () => {
|
|
// The only two vars with no default and no `.optional()`.
|
|
const base = {
|
|
JWT_SECRET: "x".repeat(32),
|
|
INTENT_SERVICE_SECRET: "y".repeat(32),
|
|
};
|
|
|
|
it("treats blank FORGEJO_* values as unset instead of failing validation", () => {
|
|
const parsed = envSchema.parse({
|
|
...base,
|
|
FORGEJO_BASE_URL: "",
|
|
FORGEJO_TOKEN: "",
|
|
FORGEJO_REPO: "",
|
|
});
|
|
|
|
expect(parsed.FORGEJO_BASE_URL).to.equal(undefined);
|
|
expect(parsed.FORGEJO_TOKEN).to.equal(undefined);
|
|
expect(parsed.FORGEJO_REPO).to.equal(undefined);
|
|
});
|
|
|
|
it("treats a fully absent FORGEJO_* trio the same way", () => {
|
|
const parsed = envSchema.parse({ ...base });
|
|
expect(parsed.FORGEJO_BASE_URL).to.equal(undefined);
|
|
expect(parsed.FORGEJO_TOKEN).to.equal(undefined);
|
|
expect(parsed.FORGEJO_REPO).to.equal(undefined);
|
|
});
|
|
|
|
it("still passes through and validates non-blank FORGEJO_* values", () => {
|
|
const parsed = envSchema.parse({
|
|
...base,
|
|
FORGEJO_BASE_URL: "https://git.example.com",
|
|
FORGEJO_TOKEN: "a-token",
|
|
FORGEJO_REPO: "owner/repo",
|
|
});
|
|
|
|
expect(parsed.FORGEJO_BASE_URL).to.equal("https://git.example.com");
|
|
expect(parsed.FORGEJO_TOKEN).to.equal("a-token");
|
|
expect(parsed.FORGEJO_REPO).to.equal("owner/repo");
|
|
});
|
|
|
|
it("still rejects a non-blank but malformed FORGEJO_BASE_URL", () => {
|
|
expect(() => envSchema.parse({ ...base, FORGEJO_BASE_URL: "git.example.com" })).to.throw();
|
|
});
|
|
|
|
it("still rejects a non-blank but malformed FORGEJO_REPO", () => {
|
|
expect(() => envSchema.parse({ ...base, FORGEJO_REPO: "not-a-repo" })).to.throw();
|
|
});
|
|
});
|