113 lines
4.3 KiB
JavaScript
113 lines
4.3 KiB
JavaScript
// @vitest-environment jsdom
|
|
|
|
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
|
|
const { axiosMock } = vi.hoisted(() => ({
|
|
axiosMock: vi.fn(),
|
|
}));
|
|
|
|
vi.mock("axios", () => ({
|
|
default: axiosMock,
|
|
}));
|
|
|
|
import {
|
|
clearReleaseManagerControlApiUrl,
|
|
getReleaseManagerControlApiUrl,
|
|
getReleaseSummary,
|
|
RELEASE_MANAGER_CONTROL_API_STORAGE_KEY,
|
|
releaseManagerControlApiCandidates,
|
|
setReleaseManagerControlApiUrl,
|
|
} from "@/services/superuserReleases.js";
|
|
import { configureReleaseRuntime } from "@/services/releaseTimeline.js";
|
|
import { deployCoolifyGatewayRoutes } from "@/services/superuserCoolify.js";
|
|
import { __configureRequestQueueForTests, __resetRequestQueueForTests } from "@/services/requestQueue.js";
|
|
|
|
describe("superuser release manager service", () => {
|
|
beforeEach(() => {
|
|
axiosMock.mockReset();
|
|
localStorage.clear();
|
|
sessionStorage.clear();
|
|
localStorage.setItem("token", "release-token");
|
|
configureReleaseRuntime({ source: "deployment", api_base_url: "https://api.truckwash.io" });
|
|
__resetRequestQueueForTests();
|
|
__configureRequestQueueForTests({
|
|
maxConcurrentGet: 1,
|
|
maxConcurrentOther: 1,
|
|
spacingMs: 0,
|
|
retryByStatusCode: {},
|
|
});
|
|
});
|
|
|
|
it("uses the runtime release API before legacy control API overrides", async () => {
|
|
configureReleaseRuntime({ api_base_url: "https://api-v2.truckwash.io/master/api" });
|
|
setReleaseManagerControlApiUrl("https://control.example.test/");
|
|
axiosMock.mockResolvedValueOnce({ status: 200, data: { data: { channels: [] } } });
|
|
|
|
await getReleaseSummary();
|
|
|
|
expect(getReleaseManagerControlApiUrl()).toBe("https://api-v2.truckwash.io/master/api");
|
|
expect(axiosMock).toHaveBeenCalledWith(
|
|
expect.objectContaining({
|
|
url: "https://api-v2.truckwash.io/master/api/superuser/releases",
|
|
method: "GET",
|
|
headers: expect.objectContaining({ Authorization: "Bearer release-token" }),
|
|
})
|
|
);
|
|
});
|
|
|
|
it("falls back when the selected API does not have release manager endpoints", async () => {
|
|
localStorage.setItem(RELEASE_MANAGER_CONTROL_API_STORAGE_KEY, "https://api.truckwash.io");
|
|
axiosMock
|
|
.mockRejectedValueOnce({ response: { status: 404 } })
|
|
.mockResolvedValueOnce({ status: 200, data: { data: { channels: [] } } });
|
|
|
|
await getReleaseSummary();
|
|
|
|
expect(axiosMock.mock.calls[0][0].url).toBe("https://api.truckwash.io/superuser/releases");
|
|
expect(axiosMock.mock.calls[1][0].url).toBe("https://api-v2.truckwash.io/master/api/superuser/releases");
|
|
expect(releaseManagerControlApiCandidates()).toContain("https://api-v2.truckwash.io/master/api");
|
|
});
|
|
|
|
it("uses local runtime API only when the release source is local", async () => {
|
|
configureReleaseRuntime({ source: "local", api_base_url: "/api" });
|
|
localStorage.setItem(RELEASE_MANAGER_CONTROL_API_STORAGE_KEY, "https://api.truckwash.io");
|
|
axiosMock.mockResolvedValueOnce({ status: 200, data: { data: { channels: [] } } });
|
|
|
|
await getReleaseSummary();
|
|
|
|
expect(releaseManagerControlApiCandidates()).toEqual(["/api"]);
|
|
expect(getReleaseManagerControlApiUrl()).toBe("/api");
|
|
expect(axiosMock).toHaveBeenCalledWith(
|
|
expect.objectContaining({
|
|
url: "/api/superuser/releases",
|
|
method: "GET",
|
|
})
|
|
);
|
|
});
|
|
|
|
it("can clear the explicit control API override", () => {
|
|
setReleaseManagerControlApiUrl("https://control.example.test");
|
|
clearReleaseManagerControlApiUrl();
|
|
|
|
expect(localStorage.getItem(RELEASE_MANAGER_CONTROL_API_STORAGE_KEY)).toBeNull();
|
|
expect(releaseManagerControlApiCandidates()).toContain("https://api-v2.truckwash.io/master/api");
|
|
});
|
|
|
|
it("keeps Coolify route deployment on the runtime release API", async () => {
|
|
configureReleaseRuntime({ api_base_url: "https://api-v2.truckwash.io/master/api" });
|
|
setReleaseManagerControlApiUrl("https://control.example.test");
|
|
axiosMock.mockResolvedValueOnce({ status: 200, data: { success: true } });
|
|
|
|
await deployCoolifyGatewayRoutes({ dry_run: true });
|
|
|
|
expect(axiosMock).toHaveBeenCalledWith(
|
|
expect.objectContaining({
|
|
url: "https://api-v2.truckwash.io/master/api/superuser/coolify/load-balancer/routes/deploy",
|
|
method: "POST",
|
|
data: { dry_run: true },
|
|
__skipReleaseApiRewrite: true,
|
|
})
|
|
);
|
|
});
|
|
});
|