Files
cloudflare-domain-manager/apps/api/test/change-ip.test.ts
T
Denozordec 3f6f402872
quality / commitlint (push) Skipped
CD / update-wiki (push) Failing after 8s
quality / changes (push) Successful in 5s
quality / docker-check (push) Skipped
quality / web (push) Successful in 50s
quality / api (push) Successful in 41s
CD / quality (push) Successful in 1m40s
CD / publish (push) Successful in 1m33s
feat(health-checks): enhance health check functionality and add new routes
- Introduced origin health check routes and integrated them into the application.
- Updated health check configuration to include success recovery thresholds.
- Expanded error handling with new error codes for health check failures.
- Added new service routes for managing health checks, including creation and listing.
- Improved health check service logic to track consecutive successes and failures.

This commit enhances the health check capabilities, providing better monitoring and management of service health.
2026-08-19 12:26:12 +07:00

111 lines
3.6 KiB
TypeScript

import { describe, expect, it } from "vitest";
import { repos } from "@cfdm/db";
import type { CloudflareClient } from "../src/lib/cf-client.js";
import { buildApp } from "../src/app.js";
import { loadConfig } from "../src/config.js";
import { changeBindingIp } from "../src/services/change-ip-service.js";
import { withBindingLock } from "../src/services/routing/index.js";
import { updateConfig } from "../src/services/service-config-service.js";
function mockCf(): CloudflareClient {
return {
listDnsRecords: async () => [],
createDnsRecord: async (_zoneId: string, payload: { type: string; name: string; content: string }) => ({
id: `cf-${payload.name}-${payload.content}`,
type: payload.type,
name: payload.name,
content: payload.content,
ttl: 1,
proxied: false,
}),
updateDnsRecord: async (
_zoneId: string,
id: string,
payload: { type: string; name: string; content: string },
) => ({
id,
type: payload.type,
name: payload.name,
content: payload.content,
ttl: 1,
proxied: false,
}),
patchDnsRecord: async (
_zoneId: string,
id: string,
payload: { content?: string },
) => ({
id,
type: "A",
name: "panel.example.com",
content: payload.content ?? "0.0.0.0",
ttl: 1,
proxied: false,
}),
deleteDnsRecord: async () => undefined,
listZones: async () => [{ id: "zone-1", name: "example.com", status: "active" }],
} as unknown as CloudflareClient;
}
describe("change-ip", () => {
it("dry-run previews from → to without writing", async () => {
const app = await buildApp({
config: { ...loadConfig(), staticDir: null },
memory: true,
});
const cf = mockCf();
repos.createDomain(app.db, null, "example.com", "zone-1");
const service = repos.createService(app.db, "Panel", "panel");
await updateConfig(app.db, cf, service.id, {
ips: ["10.0.0.10"],
domains: [{ fqdn: "panel.example.com", target_ips: ["10.0.0.10"] }],
});
const bindings = repos.listBindingsByService(app.db, service.id);
const preview = await changeBindingIp(app.db, cf, bindings[0]!.id, {
from_ip: "10.0.0.10",
to_ip: "10.0.0.20",
dry_run: true,
});
expect(preview.applied).toBe(false);
expect(preview.message).toBe("10.0.0.10 → 10.0.0.20");
expect(repos.listBindingIps(app.db, bindings[0]!.id)).toEqual(["10.0.0.10"]);
await app.close();
});
it("apply patches binding IP", async () => {
const app = await buildApp({
config: { ...loadConfig(), staticDir: null },
memory: true,
});
const cf = mockCf();
repos.createDomain(app.db, null, "example.com", "zone-1");
const service = repos.createService(app.db, "Panel", "panel");
await updateConfig(app.db, cf, service.id, {
ips: ["10.0.0.10"],
domains: [{ fqdn: "panel.example.com", target_ips: ["10.0.0.10"] }],
});
const binding = repos.listBindingsByService(app.db, service.id)[0]!;
const result = await changeBindingIp(app.db, cf, binding.id, {
from_ip: "10.0.0.10",
to_ip: "10.0.0.20",
});
expect(result.applied).toBe(true);
expect(repos.listBindingIps(app.db, binding.id)).toEqual(["10.0.0.20"]);
await app.close();
});
it("serializes concurrent binding locks", async () => {
const order: number[] = [];
await Promise.all([
withBindingLock(1, async () => {
await new Promise((r) => setTimeout(r, 20));
order.push(1);
}),
withBindingLock(1, async () => {
order.push(2);
}),
]);
expect(order).toEqual([1, 2]);
});
});