mirror of
https://github.com/tale/headplane.git
synced 2026-09-02 02:08:44 +00:00
feat: replace openapi hashing system with /version
Apparently I didn't use my brain cells and rely on the /version endpoint that Headscale has exposed since 0.26 (our lowest supported version). Switching to that significantly simplifies the API surface.
This commit is contained in:
@@ -0,0 +1,110 @@
|
||||
import { describe, expect, test } from "vitest";
|
||||
|
||||
import { capabilitiesFor } from "~/server/headscale/api/capabilities";
|
||||
import {
|
||||
formatServerVersion,
|
||||
gte,
|
||||
parseServerVersion,
|
||||
} from "~/server/headscale/api/server-version";
|
||||
|
||||
describe("parseServerVersion", () => {
|
||||
test("parses release versions with and without a leading v", () => {
|
||||
expect(parseServerVersion("0.28.0")).toMatchObject({
|
||||
major: 0,
|
||||
minor: 28,
|
||||
patch: 0,
|
||||
prerelease: undefined,
|
||||
unknown: false,
|
||||
});
|
||||
expect(parseServerVersion("v0.27.1")).toMatchObject({
|
||||
major: 0,
|
||||
minor: 27,
|
||||
patch: 1,
|
||||
unknown: false,
|
||||
});
|
||||
});
|
||||
|
||||
test("captures prerelease and build metadata", () => {
|
||||
const v = parseServerVersion("v0.28.0-beta.1+abcdef");
|
||||
expect(v.major).toBe(0);
|
||||
expect(v.minor).toBe(28);
|
||||
expect(v.patch).toBe(0);
|
||||
expect(v.prerelease).toBe("beta.1");
|
||||
expect(v.build).toBe("abcdef");
|
||||
expect(v.unknown).toBe(false);
|
||||
});
|
||||
|
||||
test("flags unparseable versions (e.g. dev builds)", () => {
|
||||
const v = parseServerVersion("dev");
|
||||
expect(v.unknown).toBe(true);
|
||||
expect(v.raw).toBe("dev");
|
||||
});
|
||||
});
|
||||
|
||||
describe("gte", () => {
|
||||
test("compares plain versions correctly", () => {
|
||||
const v = parseServerVersion("0.28.0");
|
||||
expect(gte(v, "0.27.0")).toBe(true);
|
||||
expect(gte(v, "0.28.0")).toBe(true);
|
||||
expect(gte(v, "0.29.0")).toBe(false);
|
||||
});
|
||||
|
||||
test("ignores prerelease tags so betas get modern capabilities", () => {
|
||||
// 0.28.0-beta.1 ships every wire format change that 0.28.0 does, so
|
||||
// strict semver (where 0.28.0-beta.1 < 0.28.0) would lock beta users
|
||||
// out of features their server actually supports.
|
||||
const beta = parseServerVersion("0.28.0-beta.1");
|
||||
expect(gte(beta, "0.28.0")).toBe(true);
|
||||
expect(gte(beta, "0.27.0")).toBe(true);
|
||||
});
|
||||
|
||||
test("unknown versions are treated as the newest known release", () => {
|
||||
const dev = parseServerVersion("dev");
|
||||
expect(gte(dev, "9.9.9")).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe("formatServerVersion", () => {
|
||||
test("renders release and prerelease versions without a leading v", () => {
|
||||
expect(formatServerVersion(parseServerVersion("v0.28.0"))).toBe("0.28.0");
|
||||
expect(formatServerVersion(parseServerVersion("0.28.0-beta.1"))).toBe("0.28.0-beta.1");
|
||||
});
|
||||
|
||||
test("falls back to the raw string for unknown versions", () => {
|
||||
expect(formatServerVersion(parseServerVersion("dev"))).toBe("dev");
|
||||
});
|
||||
});
|
||||
|
||||
describe("capabilitiesFor", () => {
|
||||
test("0.28.0 enables every modern flag", () => {
|
||||
const caps = capabilitiesFor(parseServerVersion("0.28.0"));
|
||||
expect(caps).toEqual({
|
||||
preAuthKeysHaveStableIds: true,
|
||||
nodeTagsAreFlat: true,
|
||||
nodeOwnerIsImmutable: true,
|
||||
policyErrorsUseModernFormat: true,
|
||||
});
|
||||
});
|
||||
|
||||
test("0.28.0-beta.1 matches 0.28.0 capabilities (prerelease gating)", () => {
|
||||
expect(capabilitiesFor(parseServerVersion("0.28.0-beta.1"))).toEqual(
|
||||
capabilitiesFor(parseServerVersion("0.28.0")),
|
||||
);
|
||||
});
|
||||
|
||||
test("0.27.1 only has the policy-error format flag", () => {
|
||||
const caps = capabilitiesFor(parseServerVersion("0.27.1"));
|
||||
expect(caps.preAuthKeysHaveStableIds).toBe(false);
|
||||
expect(caps.nodeTagsAreFlat).toBe(false);
|
||||
expect(caps.nodeOwnerIsImmutable).toBe(false);
|
||||
expect(caps.policyErrorsUseModernFormat).toBe(true);
|
||||
});
|
||||
|
||||
test("0.26.1 has none of the modern capabilities", () => {
|
||||
const caps = capabilitiesFor(parseServerVersion("0.26.1"));
|
||||
expect(caps.preAuthKeysHaveStableIds).toBe(false);
|
||||
expect(caps.nodeTagsAreFlat).toBe(false);
|
||||
expect(caps.nodeOwnerIsImmutable).toBe(false);
|
||||
expect(caps.policyErrorsUseModernFormat).toBe(false);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user