diff --git a/apps/server/src/usage/UsageLimitSources.test.ts b/apps/server/src/usage/UsageLimitSources.test.ts new file mode 100644 index 000000000000..2b9f6c2e5d26 --- /dev/null +++ b/apps/server/src/usage/UsageLimitSources.test.ts @@ -0,0 +1,83 @@ +import { expect, it } from "@effect/vitest"; +import { ServerConfigStreamEvent, UsageLimitSourceId } from "@t3tools/contracts"; +import * as Effect from "effect/Effect"; +import * as Layer from "effect/Layer"; +import * as Schema from "effect/Schema"; +import { HttpClient } from "effect/unstable/http"; + +import * as BackgroundPolicy from "../background/BackgroundPolicy.ts"; +import * as ServerSettings from "../serverSettings.ts"; +import * as UsageLimitSources from "./UsageLimitSources.ts"; + +const encodeConfigEvent = Schema.encodeSync(ServerConfigStreamEvent); + +it.effect("keeps malformed source URLs encodable for config subscribers", () => + Effect.gen(function* () { + const sources = yield* UsageLimitSources.make; + yield* sources.refresh; + const snapshots = yield* sources.current; + expect(snapshots.map((source) => source.label)).toEqual([ + "local-hub", + "opaque-hub", + "Named hub", + "hub.test:8317", + "Usage limit source", + ]); + expect(() => + encodeConfigEvent({ + version: 1, + type: "usageLimitSourcesUpdated", + payload: { sources: snapshots }, + }), + ).not.toThrow(); + expect(snapshots.every((source) => source.error === "No management key configured.")).toBe( + true, + ); + }).pipe( + Effect.provide([ + ServerSettings.layerTest({ + usageLimitSources: { + [UsageLimitSourceId.make("local-hub")]: { + kind: "cliproxy", + url: "localhost:8317", + managementKey: "", + enabled: true, + }, + [UsageLimitSourceId.make("opaque-hub")]: { + kind: "cliproxy", + url: "file:///tmp/hub", + managementKey: "", + enabled: true, + }, + [UsageLimitSourceId.make("named-hub")]: { + kind: "cliproxy", + url: "localhost:8317", + label: "Named hub", + managementKey: "", + enabled: true, + }, + [UsageLimitSourceId.make("valid-hub")]: { + kind: "cliproxy", + url: "https://hub.test:8317", + managementKey: "", + enabled: true, + }, + [UsageLimitSourceId.make(" ")]: { + kind: "cliproxy", + url: "localhost:8317", + managementKey: "", + enabled: true, + }, + }, + }), + Layer.mock(BackgroundPolicy.BackgroundPolicy)({ + shouldRunScopeWork: () => Effect.succeed(false), + }), + Layer.succeed( + HttpClient.HttpClient, + HttpClient.make(() => Effect.die("Unexpected network request")), + ), + ]), + Effect.scoped, + ), +); diff --git a/apps/server/src/usage/UsageLimitSources.ts b/apps/server/src/usage/UsageLimitSources.ts index 957a6ab3321e..8a064e6e1f93 100644 --- a/apps/server/src/usage/UsageLimitSources.ts +++ b/apps/server/src/usage/UsageLimitSources.ts @@ -53,10 +53,11 @@ export class UsageLimitSources extends Context.Service< function sourceLabel(id: string, config: UsageLimitSourceConfig): string { if (config.label) return config.label; + const fallback = id.trim() || "Usage limit source"; try { - return new URL(config.url).host; + return new URL(config.url).host || fallback; } catch { - return id; + return fallback; } }