Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a0a3ef02f0 | ||
|
|
aa7d4e69b5 |
No files matched your search
@@ -55,7 +55,7 @@ export abstract class Integration {
|
||||
return this.integration.decryptedSecrets.some((secret) => secret.kind === kind);
|
||||
}
|
||||
|
||||
private createUrl(
|
||||
protected createUrl(
|
||||
inputUrl: string,
|
||||
path: `/${string}`,
|
||||
queryParams?: Record<string, string | Date | number | boolean | null | undefined>,
|
||||
|
||||
@@ -16,6 +16,19 @@ import type { ISystemHealthMonitoringIntegration } from "../interfaces/health-mo
|
||||
import type { SystemHealthMonitoring } from "../interfaces/health-monitoring/health-monitoring-types";
|
||||
|
||||
export class DashDotIntegration extends Integration implements ISystemHealthMonitoringIntegration {
|
||||
/**
|
||||
* Dashdot v5 had endpoints at /api/info, /api/load/* etc.
|
||||
* Dashdot v6 removed the /api prefix. Users who previously configured
|
||||
* their integration URL as http://host:port/api need it normalized.
|
||||
*/
|
||||
protected override url(
|
||||
path: `/${string}`,
|
||||
queryParams?: Record<string, string | Date | number | boolean | null | undefined>,
|
||||
) {
|
||||
const normalizedUrl = this.integration.url.replace(/\/api\/?$/, "");
|
||||
return this.createUrl(normalizedUrl, path, queryParams);
|
||||
}
|
||||
|
||||
protected async testingAsync(input: IntegrationTestingInput): Promise<TestingResult> {
|
||||
const response = await input.fetchAsync(this.url("/info"));
|
||||
if (!response.ok) return TestConnectionError.StatusResult(response);
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
import { describe, expect, test, vi } from "vitest";
|
||||
|
||||
import { createDb } from "@homarr/db/test";
|
||||
|
||||
import type { IntegrationTestingInput } from "../src/base/integration";
|
||||
import { DashDotIntegration } from "../src/dashdot/dashdot-integration";
|
||||
|
||||
vi.mock("@homarr/db", async (importActual) => {
|
||||
const actual = await importActual<typeof import("@homarr/db")>();
|
||||
return {
|
||||
...actual,
|
||||
db: createDb(),
|
||||
};
|
||||
});
|
||||
|
||||
vi.mock("@homarr/core/infrastructure/certificates", async (importActual) => {
|
||||
const actual = await importActual<typeof import("@homarr/core/infrastructure/certificates")>();
|
||||
return {
|
||||
...actual,
|
||||
getTrustedCertificateHostnamesAsync: vi.fn().mockResolvedValue([]),
|
||||
};
|
||||
});
|
||||
|
||||
vi.mock("@homarr/redis", () => ({}));
|
||||
|
||||
const createIntegration = (url: string) =>
|
||||
new DashDotIntegration({
|
||||
id: "test",
|
||||
name: "Dashdot",
|
||||
url,
|
||||
decryptedSecrets: [],
|
||||
externalUrl: null,
|
||||
});
|
||||
|
||||
describe("DashDot URL normalization", () => {
|
||||
test("url with /api suffix is stripped", async () => {
|
||||
const integration = createIntegration("http://dashdot:3001/api");
|
||||
// Access protected url() via testingAsync which calls this.url("/info")
|
||||
const url = (integration as unknown as { url: (path: string) => URL }).url("/info");
|
||||
expect(url.toString()).toBe("http://dashdot:3001/info");
|
||||
});
|
||||
|
||||
test("url with /api/ trailing slash is stripped", async () => {
|
||||
const integration = createIntegration("http://dashdot:3001/api/");
|
||||
const url = (integration as unknown as { url: (path: string) => URL }).url("/info");
|
||||
expect(url.toString()).toBe("http://dashdot:3001/info");
|
||||
});
|
||||
|
||||
test("url without /api suffix is unchanged", async () => {
|
||||
const integration = createIntegration("http://dashdot:3001");
|
||||
const url = (integration as unknown as { url: (path: string) => URL }).url("/info");
|
||||
expect(url.toString()).toBe("http://dashdot:3001/info");
|
||||
});
|
||||
|
||||
test("url with /api only at end is stripped (not mid-path)", async () => {
|
||||
const integration = createIntegration("http://dashdot:3001/somepath/api");
|
||||
const url = (integration as unknown as { url: (path: string) => URL }).url("/info");
|
||||
expect(url.toString()).toBe("http://dashdot:3001/somepath/info");
|
||||
});
|
||||
|
||||
test("url with path prefix other than /api is preserved", async () => {
|
||||
const integration = createIntegration("http://dashdot:3001/dashdot");
|
||||
const url = (integration as unknown as { url: (path: string) => URL }).url("/load/cpu");
|
||||
expect(url.toString()).toBe("http://dashdot:3001/dashdot/load/cpu");
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user