import { describe, expect, it } from "vitest"; import { BUILTIN_WIDGETS, SERVICE_REGISTRY, getBuiltinBinding, getServiceBinding, resolveWidget, } from "./registry"; import type { ServiceInstance, WidgetInstance } from "../types"; describe("service registry", () => { it("registers the backend service types", () => { expect(Object.keys(SERVICE_REGISTRY).sort()).toEqual([ "alertmanager", "grafana", "jellyfin", "nextcloud", "prometheus", "ssh_tasks", ]); }); it("binds widget kinds per service", () => { expect(SERVICE_REGISTRY.grafana.widgets.map((w) => w.kind)).toEqual([ "link", ]); expect(SERVICE_REGISTRY.prometheus.widgets.map((w) => w.kind)).toEqual([ "metric", "chart", "gauge", "mean", ]); expect(SERVICE_REGISTRY.alertmanager.widgets.map((w) => w.kind)).toEqual([ "active_alerts", ]); expect(SERVICE_REGISTRY.ssh_tasks.widgets.map((w) => w.kind)).toEqual([ "task_output", ]); expect(SERVICE_REGISTRY.nextcloud.widgets).toEqual([]); }); it("registers the two built-in widget kinds", () => { expect(Object.keys(BUILTIN_WIDGETS).sort()).toEqual(["backups", "static"]); }); it("resolves a service-bound widget via the services list", () => { const widget: WidgetInstance = { id: "w1", service_id: "s1", widget_kind: "link", title: "Dashboard", config: {}, enabled: true, sort_order: 0, created_at: 0, updated_at: 0, }; const services: ServiceInstance[] = [ { id: "s1", service_type: "grafana", name: "Grafana", config: { base_url: "https://grafana.example.com" }, secrets_set: { api_key: true }, enabled: true, created_at: 0, updated_at: 0, }, ]; const resolved = resolveWidget(widget, services); expect(resolved).toBeDefined(); expect(resolved?.refreshIntervalMs).toBe(0); }); it("resolves an alertmanager active_alerts widget", () => { const widget: WidgetInstance = { id: "wam", service_id: "sam", widget_kind: "active_alerts", title: "Alerts", config: {}, enabled: true, sort_order: 0, created_at: 0, updated_at: 0, }; const services: ServiceInstance[] = [ { id: "sam", service_type: "alertmanager", name: "Alertmanager", config: { base_url: "http://am:9093" }, secrets_set: {}, enabled: true, created_at: 0, updated_at: 0, }, ]; const resolved = resolveWidget(widget, services); expect(resolved).toBeDefined(); expect(resolved?.refreshIntervalMs).toBe(30_000); }); it("resolves a built-in widget without a service", () => { const widget: WidgetInstance = { id: "w2", service_id: null, widget_kind: "static", title: "Note", config: { text: "hi" }, enabled: true, sort_order: 0, created_at: 0, updated_at: 0, }; const resolved = resolveWidget(widget, []); expect(resolved).toBeDefined(); }); it("returns undefined for an unknown widget kind", () => { const widget: WidgetInstance = { id: "w3", service_id: null, widget_kind: "bogus", title: "x", config: {}, enabled: true, sort_order: 0, created_at: 0, updated_at: 0, }; expect(resolveWidget(widget, [])).toBeUndefined(); }); it("lookups return undefined for unknown types", () => { expect(getServiceBinding("nope")).toBeUndefined(); expect(getBuiltinBinding("nope")).toBeUndefined(); }); });