feat(integration): improve integration test connection (#3005)
This commit is contained in:
@@ -1,9 +1,20 @@
|
||||
import type { StartedTestContainer } from "testcontainers";
|
||||
import { GenericContainer, getContainerRuntimeClient, ImageName, Wait } from "testcontainers";
|
||||
import { beforeAll, describe, expect, test } from "vitest";
|
||||
import { beforeAll, describe, expect, test, vi } from "vitest";
|
||||
|
||||
import { createDb } from "@homarr/db/test";
|
||||
|
||||
import { Aria2Integration } from "../src";
|
||||
|
||||
vi.mock("@homarr/db", async (importActual) => {
|
||||
// eslint-disable-next-line @typescript-eslint/consistent-type-imports
|
||||
const actual = await importActual<typeof import("@homarr/db")>();
|
||||
return {
|
||||
...actual,
|
||||
db: createDb(),
|
||||
};
|
||||
});
|
||||
|
||||
const API_KEY = "ARIA2_API_KEY";
|
||||
const IMAGE_NAME = "hurlenko/aria2-ariang:latest";
|
||||
|
||||
@@ -19,10 +30,10 @@ describe("Aria2 integration", () => {
|
||||
const aria2Integration = createAria2Intergration(startedContainer, API_KEY);
|
||||
|
||||
// Act
|
||||
const actAsync = async () => await aria2Integration.testConnectionAsync();
|
||||
const result = await aria2Integration.testConnectionAsync();
|
||||
|
||||
// Assert
|
||||
await expect(actAsync()).resolves.not.toThrow();
|
||||
expect(result.success).toBe(true);
|
||||
|
||||
// Cleanup
|
||||
await startedContainer.stop();
|
||||
|
||||
@@ -1,250 +1,57 @@
|
||||
import { Response } from "undici";
|
||||
import { describe, expect, test } from "vitest";
|
||||
import { describe, expect, test, vi } from "vitest";
|
||||
|
||||
import { IntegrationTestConnectionError } from "../src";
|
||||
import { ResponseError } from "@homarr/common/server";
|
||||
import { createDb } from "@homarr/db/test";
|
||||
|
||||
import type { IntegrationTestingInput } from "../src/base/integration";
|
||||
import { Integration } from "../src/base/integration";
|
||||
import type { TestingResult } from "../src/base/test-connection/test-connection-service";
|
||||
|
||||
type HandleResponseProps = Parameters<Integration["handleTestConnectionResponseAsync"]>[0];
|
||||
|
||||
class BaseIntegrationMock extends Integration {
|
||||
public async fakeTestConnectionAsync(props: HandleResponseProps): Promise<void> {
|
||||
await super.handleTestConnectionResponseAsync(props);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
||||
public async testConnectionAsync(): Promise<void> {}
|
||||
}
|
||||
vi.mock("@homarr/db", async (importActual) => {
|
||||
// eslint-disable-next-line @typescript-eslint/consistent-type-imports
|
||||
const actual = await importActual<typeof import("@homarr/db")>();
|
||||
return {
|
||||
...actual,
|
||||
db: createDb(),
|
||||
};
|
||||
});
|
||||
|
||||
describe("Base integration", () => {
|
||||
describe("handleTestConnectionResponseAsync", () => {
|
||||
test("With no cause error should throw IntegrationTestConnectionError with key commonError", async () => {
|
||||
// Arrange
|
||||
const integration = new BaseIntegrationMock({ id: "id", name: "name", url: "url", decryptedSecrets: [] });
|
||||
test("testConnectionAsync should handle errors", async () => {
|
||||
const responseError = new ResponseError({ status: 500, url: "https://example.com" });
|
||||
const integration = new FakeIntegration(undefined, responseError);
|
||||
|
||||
const errorMessage = "The error message";
|
||||
const props: HandleResponseProps = {
|
||||
async queryFunctionAsync() {
|
||||
return await Promise.reject(new Error(errorMessage));
|
||||
},
|
||||
};
|
||||
const result = await integration.testConnectionAsync();
|
||||
|
||||
// Act
|
||||
const actPromise = integration.fakeTestConnectionAsync(props);
|
||||
|
||||
// Assert
|
||||
await expect(actPromise).rejects.toHaveProperty("key", "commonError");
|
||||
await expect(actPromise).rejects.toHaveProperty("detailMessage", errorMessage);
|
||||
});
|
||||
|
||||
test("With cause ENOTFOUND should throw IntegrationTestConnectionError with key domainNotFound", async () => {
|
||||
// Arrange
|
||||
const integration = new BaseIntegrationMock({ id: "id", name: "name", url: "url", decryptedSecrets: [] });
|
||||
|
||||
const props: HandleResponseProps = {
|
||||
async queryFunctionAsync() {
|
||||
return await Promise.reject(new Error("Error", { cause: { code: "ENOTFOUND" } }));
|
||||
},
|
||||
};
|
||||
|
||||
// Act
|
||||
const actAsync = async () => await integration.fakeTestConnectionAsync(props);
|
||||
|
||||
// Assert
|
||||
await expect(actAsync()).rejects.toHaveProperty("key", "domainNotFound");
|
||||
});
|
||||
|
||||
test("With cause ENOTFOUND should throw IntegrationTestConnectionError with key connectionRefused", async () => {
|
||||
// Arrange
|
||||
const integration = new BaseIntegrationMock({ id: "id", name: "name", url: "url", decryptedSecrets: [] });
|
||||
|
||||
const props: HandleResponseProps = {
|
||||
async queryFunctionAsync() {
|
||||
return await Promise.reject(new Error("Error", { cause: { code: "ECONNREFUSED" } }));
|
||||
},
|
||||
};
|
||||
|
||||
// Act
|
||||
const actAsync = async () => await integration.fakeTestConnectionAsync(props);
|
||||
|
||||
// Assert
|
||||
await expect(actAsync()).rejects.toHaveProperty("key", "connectionRefused");
|
||||
});
|
||||
|
||||
test("With cause ENOTFOUND should throw IntegrationTestConnectionError with key connectionAborted", async () => {
|
||||
// Arrange
|
||||
const integration = new BaseIntegrationMock({ id: "id", name: "name", url: "url", decryptedSecrets: [] });
|
||||
|
||||
const props: HandleResponseProps = {
|
||||
async queryFunctionAsync() {
|
||||
return await Promise.reject(new Error("Error", { cause: { code: "ECONNABORTED" } }));
|
||||
},
|
||||
};
|
||||
|
||||
// Act
|
||||
const actAsync = async () => await integration.fakeTestConnectionAsync(props);
|
||||
|
||||
// Assert
|
||||
await expect(actAsync()).rejects.toHaveProperty("key", "connectionAborted");
|
||||
});
|
||||
|
||||
test("With not handled cause error should throw IntegrationTestConnectionError with key commonError", async () => {
|
||||
// Arrange
|
||||
const integration = new BaseIntegrationMock({ id: "id", name: "name", url: "url", decryptedSecrets: [] });
|
||||
|
||||
const errorMessage = "The error message";
|
||||
const props: HandleResponseProps = {
|
||||
async queryFunctionAsync() {
|
||||
return await Promise.reject(new Error(errorMessage));
|
||||
},
|
||||
};
|
||||
|
||||
// Act
|
||||
const actPromise = integration.fakeTestConnectionAsync(props);
|
||||
|
||||
// Assert
|
||||
await expect(actPromise).rejects.toHaveProperty("key", "commonError");
|
||||
await expect(actPromise).rejects.toHaveProperty("detailMessage", errorMessage);
|
||||
});
|
||||
|
||||
test("With response status code 400 should throw IntegrationTestConnectionError with key badRequest", async () => {
|
||||
// Arrange
|
||||
const integration = new BaseIntegrationMock({ id: "id", name: "name", url: "url", decryptedSecrets: [] });
|
||||
|
||||
const props: HandleResponseProps = {
|
||||
async queryFunctionAsync() {
|
||||
return await Promise.resolve(new Response(null, { status: 400 }));
|
||||
},
|
||||
};
|
||||
|
||||
// Act
|
||||
const actAsync = async () => await integration.fakeTestConnectionAsync(props);
|
||||
|
||||
// Assert
|
||||
await expect(actAsync()).rejects.toHaveProperty("key", "badRequest");
|
||||
});
|
||||
|
||||
test("With response status code 401 should throw IntegrationTestConnectionError with key unauthorized", async () => {
|
||||
// Arrange
|
||||
const integration = new BaseIntegrationMock({ id: "id", name: "name", url: "url", decryptedSecrets: [] });
|
||||
|
||||
const props: HandleResponseProps = {
|
||||
async queryFunctionAsync() {
|
||||
return await Promise.resolve(new Response(null, { status: 401 }));
|
||||
},
|
||||
};
|
||||
|
||||
// Act
|
||||
const actAsync = async () => await integration.fakeTestConnectionAsync(props);
|
||||
|
||||
// Assert
|
||||
await expect(actAsync()).rejects.toHaveProperty("key", "unauthorized");
|
||||
});
|
||||
|
||||
test("With response status code 403 should throw IntegrationTestConnectionError with key forbidden", async () => {
|
||||
// Arrange
|
||||
const integration = new BaseIntegrationMock({ id: "id", name: "name", url: "url", decryptedSecrets: [] });
|
||||
|
||||
const props: HandleResponseProps = {
|
||||
async queryFunctionAsync() {
|
||||
return await Promise.resolve(new Response(null, { status: 403 }));
|
||||
},
|
||||
};
|
||||
|
||||
// Act
|
||||
const actAsync = async () => await integration.fakeTestConnectionAsync(props);
|
||||
|
||||
// Assert
|
||||
await expect(actAsync()).rejects.toHaveProperty("key", "forbidden");
|
||||
});
|
||||
|
||||
test("With response status code 404 should throw IntegrationTestConnectionError with key notFound", async () => {
|
||||
// Arrange
|
||||
const integration = new BaseIntegrationMock({ id: "id", name: "name", url: "url", decryptedSecrets: [] });
|
||||
|
||||
const props: HandleResponseProps = {
|
||||
async queryFunctionAsync() {
|
||||
return await Promise.resolve(new Response(null, { status: 404 }));
|
||||
},
|
||||
};
|
||||
|
||||
// Act
|
||||
const actAsync = async () => await integration.fakeTestConnectionAsync(props);
|
||||
|
||||
// Assert
|
||||
await expect(actAsync()).rejects.toHaveProperty("key", "notFound");
|
||||
});
|
||||
|
||||
test("With response status code 500 should throw IntegrationTestConnectionError with key internalServerError", async () => {
|
||||
// Arrange
|
||||
const integration = new BaseIntegrationMock({ id: "id", name: "name", url: "url", decryptedSecrets: [] });
|
||||
|
||||
const props: HandleResponseProps = {
|
||||
async queryFunctionAsync() {
|
||||
return await Promise.resolve(new Response(null, { status: 500 }));
|
||||
},
|
||||
};
|
||||
|
||||
// Act
|
||||
const actAsync = async () => await integration.fakeTestConnectionAsync(props);
|
||||
|
||||
// Assert
|
||||
await expect(actAsync()).rejects.toHaveProperty("key", "internalServerError");
|
||||
});
|
||||
|
||||
test("With response status code 503 should throw IntegrationTestConnectionError with key serviceUnavailable", async () => {
|
||||
// Arrange
|
||||
const integration = new BaseIntegrationMock({ id: "id", name: "name", url: "url", decryptedSecrets: [] });
|
||||
|
||||
const props: HandleResponseProps = {
|
||||
async queryFunctionAsync() {
|
||||
return await Promise.resolve(new Response(null, { status: 503 }));
|
||||
},
|
||||
};
|
||||
|
||||
// Act
|
||||
const actAsync = async () => await integration.fakeTestConnectionAsync(props);
|
||||
|
||||
// Assert
|
||||
await expect(actAsync()).rejects.toHaveProperty("key", "serviceUnavailable");
|
||||
});
|
||||
|
||||
test("With response status code 418 (or any other unhandled code) should throw IntegrationTestConnectionError with key commonError", async () => {
|
||||
// Arrange
|
||||
const integration = new BaseIntegrationMock({ id: "id", name: "name", url: "url", decryptedSecrets: [] });
|
||||
|
||||
const props: HandleResponseProps = {
|
||||
async queryFunctionAsync() {
|
||||
return await Promise.resolve(new Response(null, { status: 418 }));
|
||||
},
|
||||
};
|
||||
|
||||
// Act
|
||||
const actAsync = async () => await integration.fakeTestConnectionAsync(props);
|
||||
|
||||
// Assert
|
||||
await expect(actAsync()).rejects.toHaveProperty("key", "commonError");
|
||||
});
|
||||
|
||||
test("Errors from handleResponseAsync should be thrown", async () => {
|
||||
// Arrange
|
||||
const integration = new BaseIntegrationMock({ id: "id", name: "name", url: "url", decryptedSecrets: [] });
|
||||
|
||||
const errorMessage = "The error message";
|
||||
const props: HandleResponseProps = {
|
||||
async queryFunctionAsync() {
|
||||
return await Promise.resolve(new Response(null, { status: 200 }));
|
||||
},
|
||||
async handleResponseAsync() {
|
||||
return await Promise.reject(new IntegrationTestConnectionError("commonError", errorMessage));
|
||||
},
|
||||
};
|
||||
|
||||
// Act
|
||||
const actPromise = integration.fakeTestConnectionAsync(props);
|
||||
|
||||
// Assert
|
||||
await expect(actPromise).rejects.toHaveProperty("key", "commonError");
|
||||
await expect(actPromise).rejects.toHaveProperty("detailMessage", errorMessage);
|
||||
});
|
||||
expect(result.success).toBe(false);
|
||||
if (result.success) return;
|
||||
expect(result.error.type === "statusCode").toBe(true);
|
||||
if (result.error.type !== "statusCode") return;
|
||||
expect(result.error.data.statusCode).toBe(500);
|
||||
expect(result.error.data.url).toContain("https://example.com");
|
||||
expect(result.error.data.reason).toBe("internalServerError");
|
||||
});
|
||||
});
|
||||
|
||||
class FakeIntegration extends Integration {
|
||||
constructor(
|
||||
private testingResult?: TestingResult,
|
||||
private error?: Error,
|
||||
) {
|
||||
super({
|
||||
id: "test",
|
||||
name: "Test",
|
||||
url: "https://example.com",
|
||||
decryptedSecrets: [],
|
||||
});
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
protected testingAsync(_: IntegrationTestingInput): Promise<TestingResult> {
|
||||
if (this.error) {
|
||||
return Promise.reject(this.error);
|
||||
}
|
||||
|
||||
return Promise.resolve(this.testingResult ?? { success: true });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,21 @@
|
||||
import { join } from "path";
|
||||
import type { StartedTestContainer } from "testcontainers";
|
||||
import { GenericContainer, getContainerRuntimeClient, ImageName, Wait } from "testcontainers";
|
||||
import { beforeAll, describe, expect, test } from "vitest";
|
||||
import { beforeAll, describe, expect, test, vi } from "vitest";
|
||||
|
||||
import { HomeAssistantIntegration, IntegrationTestConnectionError } from "../src";
|
||||
import { createDb } from "@homarr/db/test";
|
||||
|
||||
import { HomeAssistantIntegration } from "../src";
|
||||
import { TestConnectionError } from "../src/base/test-connection/test-connection-error";
|
||||
|
||||
vi.mock("@homarr/db", async (importActual) => {
|
||||
// eslint-disable-next-line @typescript-eslint/consistent-type-imports
|
||||
const actual = await importActual<typeof import("@homarr/db")>();
|
||||
return {
|
||||
...actual,
|
||||
db: createDb(),
|
||||
};
|
||||
});
|
||||
|
||||
const DEFAULT_API_KEY =
|
||||
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJkNjQwY2VjNDFjOGU0NGM5YmRlNWQ4ZmFjMjUzYWViZiIsImlhdCI6MTcxODQ3MTE1MSwiZXhwIjoyMDMzODMxMTUxfQ.uQCZ5FZTokipa6N27DtFhLHkwYEXU1LZr0fsVTryL2Q";
|
||||
@@ -21,10 +33,10 @@ describe("Home Assistant integration", () => {
|
||||
const homeAssistantIntegration = createHomeAssistantIntegration(startedContainer);
|
||||
|
||||
// Act
|
||||
const actAsync = async () => await homeAssistantIntegration.testConnectionAsync();
|
||||
const result = await homeAssistantIntegration.testConnectionAsync();
|
||||
|
||||
// Assert
|
||||
await expect(actAsync()).resolves.not.toThrow();
|
||||
expect(result.success).toBe(true);
|
||||
|
||||
// Cleanup
|
||||
await startedContainer.stop();
|
||||
@@ -35,10 +47,14 @@ describe("Home Assistant integration", () => {
|
||||
const homeAssistantIntegration = createHomeAssistantIntegration(startedContainer, "wrong-api-key");
|
||||
|
||||
// Act
|
||||
const actAsync = async () => await homeAssistantIntegration.testConnectionAsync();
|
||||
const result = await homeAssistantIntegration.testConnectionAsync();
|
||||
|
||||
// Assert
|
||||
await expect(actAsync()).rejects.toThrow(IntegrationTestConnectionError);
|
||||
expect(result.success).toBe(false);
|
||||
if (result.success) return;
|
||||
|
||||
expect(result.error).toBeInstanceOf(TestConnectionError);
|
||||
expect(result.error.type).toBe("authorization");
|
||||
|
||||
// Cleanup
|
||||
await startedContainer.stop();
|
||||
|
||||
@@ -2,9 +2,21 @@ import { readFile } from "fs/promises";
|
||||
import { join } from "path";
|
||||
import type { StartedTestContainer } from "testcontainers";
|
||||
import { GenericContainer, getContainerRuntimeClient, ImageName, Wait } from "testcontainers";
|
||||
import { beforeAll, describe, expect, test } from "vitest";
|
||||
import { beforeAll, describe, expect, test, vi } from "vitest";
|
||||
|
||||
import { createDb } from "@homarr/db/test";
|
||||
|
||||
import { NzbGetIntegration } from "../src";
|
||||
import { TestConnectionError } from "../src/base/test-connection/test-connection-error";
|
||||
|
||||
vi.mock("@homarr/db", async (importActual) => {
|
||||
// eslint-disable-next-line @typescript-eslint/consistent-type-imports
|
||||
const actual = await importActual<typeof import("@homarr/db")>();
|
||||
return {
|
||||
...actual,
|
||||
db: createDb(),
|
||||
};
|
||||
});
|
||||
|
||||
const username = "nzbget";
|
||||
const password = "tegbzn6789";
|
||||
@@ -22,10 +34,10 @@ describe("Nzbget integration", () => {
|
||||
const nzbGetIntegration = createNzbGetIntegration(startedContainer, username, password);
|
||||
|
||||
// Act
|
||||
const actAsync = async () => await nzbGetIntegration.testConnectionAsync();
|
||||
const result = await nzbGetIntegration.testConnectionAsync();
|
||||
|
||||
// Assert
|
||||
await expect(actAsync()).resolves.not.toThrow();
|
||||
expect(result.success).toBe(true);
|
||||
|
||||
// Cleanup
|
||||
await startedContainer.stop();
|
||||
@@ -37,10 +49,14 @@ describe("Nzbget integration", () => {
|
||||
const nzbGetIntegration = createNzbGetIntegration(startedContainer, "wrong-user", "wrong-password");
|
||||
|
||||
// Act
|
||||
const actAsync = async () => await nzbGetIntegration.testConnectionAsync();
|
||||
const result = await nzbGetIntegration.testConnectionAsync();
|
||||
|
||||
// Assert
|
||||
await expect(actAsync()).rejects.toThrow();
|
||||
expect(result.success).toBe(false);
|
||||
if (result.success) return;
|
||||
|
||||
expect(result.error).toBeInstanceOf(TestConnectionError);
|
||||
expect(result.error.type).toBe("authorization");
|
||||
|
||||
// Cleanup
|
||||
await startedContainer.stop();
|
||||
|
||||
@@ -2,8 +2,20 @@ import type { StartedTestContainer } from "testcontainers";
|
||||
import { GenericContainer, Wait } from "testcontainers";
|
||||
import { describe, expect, test, vi } from "vitest";
|
||||
|
||||
import { createDb } from "@homarr/db/test";
|
||||
|
||||
import { PiHoleIntegrationV5, PiHoleIntegrationV6 } from "../src";
|
||||
import type { SessionStore } from "../src/base/session-store";
|
||||
import { TestConnectionError } from "../src/base/test-connection/test-connection-error";
|
||||
|
||||
vi.mock("@homarr/db", async (importActual) => {
|
||||
// eslint-disable-next-line @typescript-eslint/consistent-type-imports
|
||||
const actual = await importActual<typeof import("@homarr/db")>();
|
||||
return {
|
||||
...actual,
|
||||
db: createDb(),
|
||||
};
|
||||
});
|
||||
|
||||
const DEFAULT_PASSWORD = "12341234";
|
||||
const DEFAULT_API_KEY = "3b1434980677dcf53fa8c4a611db3b1f0f88478790097515c0abb539102778b9"; // Some hash generated from password
|
||||
@@ -27,31 +39,34 @@ describe("Pi-hole v5 integration", () => {
|
||||
await piholeContainer.stop();
|
||||
}, 20_000); // Timeout of 20 seconds
|
||||
|
||||
test("testConnectionAsync should not throw", async () => {
|
||||
test("testConnectionAsync should be successful", async () => {
|
||||
// Arrange
|
||||
const piholeContainer = await createPiHoleV5Container(DEFAULT_PASSWORD).start();
|
||||
const piHoleIntegration = createPiHoleIntegrationV5(piholeContainer, DEFAULT_API_KEY);
|
||||
|
||||
// Act
|
||||
const actAsync = async () => await piHoleIntegration.testConnectionAsync();
|
||||
const result = await piHoleIntegration.testConnectionAsync();
|
||||
|
||||
// Assert
|
||||
await expect(actAsync()).resolves.not.toThrow();
|
||||
expect(result.success).toBe(true);
|
||||
|
||||
// Cleanup
|
||||
await piholeContainer.stop();
|
||||
}, 20_000); // Timeout of 20 seconds
|
||||
|
||||
test("testConnectionAsync should throw with wrong credentials", async () => {
|
||||
test("testConnectionAsync should fail with unauthorized for wrong credentials", async () => {
|
||||
// Arrange
|
||||
const piholeContainer = await createPiHoleV5Container(DEFAULT_PASSWORD).start();
|
||||
const piHoleIntegration = createPiHoleIntegrationV5(piholeContainer, "wrong-api-key");
|
||||
|
||||
// Act
|
||||
const actAsync = async () => await piHoleIntegration.testConnectionAsync();
|
||||
const result = await piHoleIntegration.testConnectionAsync();
|
||||
|
||||
// Assert
|
||||
await expect(actAsync()).rejects.toThrow();
|
||||
expect(result.success).toBe(false);
|
||||
if (result.success) return;
|
||||
expect(result.error).toBeInstanceOf(TestConnectionError);
|
||||
expect(result.error.type).toBe("authorization");
|
||||
|
||||
// Cleanup
|
||||
await piholeContainer.stop();
|
||||
@@ -138,31 +153,34 @@ describe("Pi-hole v6 integration", () => {
|
||||
expect(status.timer).toBeGreaterThan(timer - 10);
|
||||
}, 20_000); // Timeout of 20 seconds
|
||||
|
||||
test("testConnectionAsync should not throw", async () => {
|
||||
test("testConnectionAsync should be successful", async () => {
|
||||
// Arrange
|
||||
const piholeContainer = await createPiHoleV6Container(DEFAULT_PASSWORD).start();
|
||||
const piHoleIntegration = createPiHoleIntegrationV6(piholeContainer, DEFAULT_PASSWORD);
|
||||
|
||||
// Act
|
||||
const actAsync = async () => await piHoleIntegration.testConnectionAsync();
|
||||
const result = await piHoleIntegration.testConnectionAsync();
|
||||
|
||||
// Assert
|
||||
await expect(actAsync()).resolves.not.toThrow();
|
||||
expect(result.success).toBe(true);
|
||||
|
||||
// Cleanup
|
||||
await piholeContainer.stop();
|
||||
}, 20_000); // Timeout of 20 seconds
|
||||
|
||||
test("testConnectionAsync should throw with wrong credentials", async () => {
|
||||
test("testConnectionAsync should fail with unauthorized for wrong credentials", async () => {
|
||||
// Arrange
|
||||
const piholeContainer = await createPiHoleV6Container(DEFAULT_PASSWORD).start();
|
||||
const piHoleIntegration = createPiHoleIntegrationV6(piholeContainer, "wrong-api-key");
|
||||
|
||||
// Act
|
||||
const actAsync = async () => await piHoleIntegration.testConnectionAsync();
|
||||
const result = await piHoleIntegration.testConnectionAsync();
|
||||
|
||||
// Assert
|
||||
await expect(actAsync()).rejects.toThrow();
|
||||
expect(result.success).toBe(false);
|
||||
if (result.success) return;
|
||||
expect(result.error).toBeInstanceOf(TestConnectionError);
|
||||
expect(result.error.type).toBe("authorization");
|
||||
|
||||
// Cleanup
|
||||
await piholeContainer.stop();
|
||||
|
||||
@@ -1,11 +1,23 @@
|
||||
import { join } from "path";
|
||||
import { GenericContainer, getContainerRuntimeClient, ImageName, Wait } from "testcontainers";
|
||||
import type { StartedTestContainer } from "testcontainers";
|
||||
import { beforeAll, describe, expect, test } from "vitest";
|
||||
import { beforeAll, describe, expect, test, vi } from "vitest";
|
||||
|
||||
import { createDb } from "@homarr/db/test";
|
||||
|
||||
import { SabnzbdIntegration } from "../src";
|
||||
import { TestConnectionError } from "../src/base/test-connection/test-connection-error";
|
||||
import type { DownloadClientItem } from "../src/interfaces/downloads/download-client-items";
|
||||
|
||||
vi.mock("@homarr/db", async (importActual) => {
|
||||
// eslint-disable-next-line @typescript-eslint/consistent-type-imports
|
||||
const actual = await importActual<typeof import("@homarr/db")>();
|
||||
return {
|
||||
...actual,
|
||||
db: createDb(),
|
||||
};
|
||||
});
|
||||
|
||||
const DEFAULT_API_KEY = "8r45mfes43s3iw7x3oecto6dl9ilxnf9";
|
||||
const IMAGE_NAME = "linuxserver/sabnzbd:latest";
|
||||
|
||||
@@ -21,10 +33,10 @@ describe("Sabnzbd integration", () => {
|
||||
const sabnzbdIntegration = createSabnzbdIntegration(startedContainer, DEFAULT_API_KEY);
|
||||
|
||||
// Act
|
||||
const actAsync = async () => await sabnzbdIntegration.testConnectionAsync();
|
||||
const result = await sabnzbdIntegration.testConnectionAsync();
|
||||
|
||||
// Assert
|
||||
await expect(actAsync()).resolves.not.toThrow();
|
||||
expect(result.success).toBe(true);
|
||||
|
||||
// Cleanup
|
||||
await startedContainer.stop();
|
||||
@@ -36,10 +48,13 @@ describe("Sabnzbd integration", () => {
|
||||
const sabnzbdIntegration = createSabnzbdIntegration(startedContainer, "wrong-api-key");
|
||||
|
||||
// Act
|
||||
const actAsync = async () => await sabnzbdIntegration.testConnectionAsync();
|
||||
const result = await sabnzbdIntegration.testConnectionAsync();
|
||||
|
||||
// Assert
|
||||
await expect(actAsync()).rejects.toThrow();
|
||||
expect(result.success).toBe(false);
|
||||
if (result.success) return;
|
||||
expect(result.error).toBeInstanceOf(TestConnectionError);
|
||||
expect(result.error.type).toBe("authorization");
|
||||
|
||||
// Cleanup
|
||||
await startedContainer.stop();
|
||||
|
||||
Reference in New Issue
Block a user