import { describe, expect, it } from "vitest" ;
import { validateConfigObject } from "./validation.js" ;
describe("gateway tailscale bind validation" , () => {
it("accepts loopback bind when tailscale serve/funnel is enabled" , () => {
const serveRes = validateConfigObject({
gateway: {
bind: "loopback" ,
tailscale: { mode: "serve" },
},
});
expect(serveRes.ok).toBe(true );
const funnelRes = validateConfigObject({
gateway: {
bind: "loopback" ,
tailscale: { mode: "funnel" },
},
});
expect(funnelRes.ok).toBe(true );
});
it("accepts custom loopback bind host with tailscale serve/funnel" , () => {
const res = validateConfigObject({
gateway: {
bind: "custom" ,
customBindHost: "127.0.0.1" ,
tailscale: { mode: "serve" },
},
});
expect(res.ok).toBe(true );
});
it("rejects IPv6 custom bind host for tailscale serve/funnel" , () => {
const res = validateConfigObject({
gateway: {
bind: "custom" ,
customBindHost: "::1" ,
tailscale: { mode: "serve" },
},
});
expect(res.ok).toBe(false );
if (!res.ok) {
expect(res.issues.some((issue) => issue.path === "gateway.bind" )).toBe(true );
}
});
it("rejects non-loopback bind when tailscale serve/funnel is enabled" , () => {
const lanRes = validateConfigObject({
gateway: {
bind: "lan" ,
tailscale: { mode: "serve" },
},
});
expect(lanRes.ok).toBe(false );
if (!lanRes.ok) {
expect(lanRes.issues).toEqual(
expect.arrayContaining([
expect.objectContaining({
path: "gateway.bind" ,
message: expect.stringContaining("gateway.bind must resolve to loopback" ),
}),
]),
);
}
const customRes = validateConfigObject({
gateway: {
bind: "custom" ,
customBindHost: "10.0.0.5" ,
tailscale: { mode: "funnel" },
},
});
expect(customRes.ok).toBe(false );
if (!customRes.ok) {
expect(customRes.issues.some((issue) => issue.path === "gateway.bind" )).toBe(true );
}
});
});
Messung V0.5 in Prozent C=93 H=95 G=93
¤ Dauer der Verarbeitung: 0.10 Sekunden
(vorverarbeitet am 2026-06-05)
¤
*© Formatika GbR, Deutschland