1import { expect, it } from "@effect/vitest";
2import * as ConfigProvider from "effect/ConfigProvider";
3import * as Effect from "effect/Effect";
4import * as Option from "effect/Option";
5
6import {
7 legacyManagedEndpointCleanupModeConfig,
8 legacyTunnelGraceMinutesConfig,
9 managedEndpointCleanupModeConfig,
10} from "./Config.ts";
11
12it.effect.each([
13 { name: "missing", env: {}, expected: "off" },
14 { name: "empty", env: { RELAY_TUNNEL_CLEANUP_MODE: "" }, expected: "off" },
15 { name: "whitespace", env: { RELAY_TUNNEL_CLEANUP_MODE: " \t" }, expected: "off" },
16 { name: "off", env: { RELAY_TUNNEL_CLEANUP_MODE: "off" }, expected: "off" },
17 {
18 name: "dry-run",
19 env: { RELAY_TUNNEL_CLEANUP_MODE: "dry-run" },
20 expected: "dry-run",
21 },
22 { name: "enabled", env: { RELAY_TUNNEL_CLEANUP_MODE: "enabled" }, expected: "enabled" },
23] as const)("loads $name cleanup mode as $expected", ({ env, expected }) =>
24 Effect.gen(function* () {
25 const provider = ConfigProvider.fromEnv({ env });
26 expect(yield* managedEndpointCleanupModeConfig.parse(provider)).toBe(expected);
27 }),
28);
29
30it.effect("rejects an invalid cleanup mode", () =>
31 Effect.gen(function* () {
32 const provider = ConfigProvider.fromEnv({
33 env: { RELAY_TUNNEL_CLEANUP_MODE: "delete-everything" },
34 });
35 const error = yield* Effect.flip(managedEndpointCleanupModeConfig.parse(provider));
36
37 expect(error._tag).toBe("ConfigError");
38 expect(error.message).toContain('Expected "off" | "dry-run" | "enabled"');
39 }),
40);
41
42it.effect("reads the legacy cleanup mode independently of the main one", () =>
43 Effect.gen(function* () {
44 const provider = ConfigProvider.fromEnv({
45 env: { RELAY_TUNNEL_CLEANUP_MODE: "enabled", RELAY_LEGACY_TUNNEL_CLEANUP_MODE: "dry-run" },
46 });
47 expect(yield* managedEndpointCleanupModeConfig.parse(provider)).toBe("enabled");
48 expect(yield* legacyManagedEndpointCleanupModeConfig.parse(provider)).toBe("dry-run");
49 expect(
50 yield* legacyManagedEndpointCleanupModeConfig.parse(ConfigProvider.fromEnv({ env: {} })),
51 ).toBe("off");
52 }),
53);
54
55it.effect.each([
56 { name: "missing", env: {}, expected: Option.none() },
57 {
58 name: "positive",
59 env: { RELAY_LEGACY_TUNNEL_GRACE_MINUTES: "10" },
60 expected: Option.some(10),
61 },
62] as const)("loads a $name legacy grace override", ({ env, expected }) =>
63 Effect.gen(function* () {
64 const minutes = yield* legacyTunnelGraceMinutesConfig.parse(ConfigProvider.fromEnv({ env }));
65 expect(minutes).toEqual(expected);
66 }),
67);
68
69it.effect.each(["0", "-10"])("rejects a grace override of %s minutes", (value) =>
70 Effect.gen(function* () {
71 const error = yield* Effect.flip(
72 legacyTunnelGraceMinutesConfig.parse(
73 ConfigProvider.fromEnv({ env: { RELAY_LEGACY_TUNNEL_GRACE_MINUTES: value } }),
74 ),
75 );
76 expect(error._tag).toBe("ConfigError");
77 }),
78);