adds tests for hub-client

This commit is contained in:
pandeymangg
2026-02-26 14:34:16 +05:30
parent de79b58648
commit e867caa373
3 changed files with 90 additions and 10 deletions

View File

@@ -0,0 +1,80 @@
import { beforeEach, describe, expect, test, vi } from "vitest";
import FormbricksHub from "@formbricks/hub";
vi.mock("@formbricks/hub", () => {
const MockFormbricksHub = vi.fn();
return { default: MockFormbricksHub };
});
vi.mock("@/lib/env", () => ({
env: {
HUB_API_KEY: "",
HUB_API_URL: "https://hub.test",
},
}));
const { env } = await import("@/lib/env");
const mutableEnv = env as unknown as Record<string, string>;
const globalForHub = globalThis as unknown as {
formbricksHubClient: FormbricksHub | undefined;
};
describe("getHubClient", () => {
beforeEach(() => {
vi.clearAllMocks();
globalForHub.formbricksHubClient = undefined;
});
test("returns null when HUB_API_KEY is not set", async () => {
mutableEnv.HUB_API_KEY = "";
const { getHubClient } = await import("./hub-client");
const client = getHubClient();
expect(client).toBeNull();
expect(FormbricksHub).not.toHaveBeenCalled();
});
test("creates and caches a new client when HUB_API_KEY is set", async () => {
mutableEnv.HUB_API_KEY = "test-key";
const mockInstance = { feedbackRecords: {} } as unknown as FormbricksHub;
vi.mocked(FormbricksHub).mockReturnValue(mockInstance);
const { getHubClient } = await import("./hub-client");
const client = getHubClient();
expect(FormbricksHub).toHaveBeenCalledWith({ apiKey: "test-key", baseURL: "https://hub.test" });
expect(client).toBe(mockInstance);
expect(globalForHub.formbricksHubClient).toBe(mockInstance);
});
test("returns cached client on subsequent calls", async () => {
const cachedInstance = { feedbackRecords: {} } as unknown as FormbricksHub;
globalForHub.formbricksHubClient = cachedInstance;
const { getHubClient } = await import("./hub-client");
const client = getHubClient();
expect(client).toBe(cachedInstance);
expect(FormbricksHub).not.toHaveBeenCalled();
});
test("does not cache null result so a later call with the key set can create the client", async () => {
mutableEnv.HUB_API_KEY = "";
const { getHubClient } = await import("./hub-client");
const first = getHubClient();
expect(first).toBeNull();
expect(globalForHub.formbricksHubClient).toBeUndefined();
mutableEnv.HUB_API_KEY = "now-set";
const mockInstance = { feedbackRecords: {} } as unknown as FormbricksHub;
vi.mocked(FormbricksHub).mockReturnValue(mockInstance);
const second = getHubClient();
expect(second).toBe(mockInstance);
expect(globalForHub.formbricksHubClient).toBe(mockInstance);
});
});

View File

@@ -13,7 +13,7 @@ const globalForHub = globalThis as unknown as {
* null and does not cache that result so a later call with the key set
* can create the client.
*/
export function getHubClient(): FormbricksHub | null {
export const getHubClient = (): FormbricksHub | null => {
if (globalForHub.formbricksHubClient) {
return globalForHub.formbricksHubClient;
}
@@ -22,4 +22,4 @@ export function getHubClient(): FormbricksHub | null {
const client = new FormbricksHub({ apiKey, baseURL: env.HUB_API_URL });
globalForHub.formbricksHubClient = client;
return client;
}
};

View File

@@ -15,19 +15,19 @@ const NO_CONFIG_ERROR = {
detail: "HUB_API_KEY is not set; Hub integration is disabled.",
} as const;
function createResultFromError(err: unknown): CreateFeedbackRecordResult {
const createResultFromError = (err: unknown): CreateFeedbackRecordResult => {
const status = err instanceof FormbricksHub.APIError ? err.status : 0;
const message = err instanceof Error ? err.message : String(err);
return { data: null, error: { status, message, detail: message } };
}
};
/**
* Create a single feedback record in the Hub.
* Returns a result shape with data or error; logs failures.
*/
export async function createFeedbackRecord(
export const createFeedbackRecord = async (
input: FeedbackRecordCreateParams
): Promise<CreateFeedbackRecordResult> {
): Promise<CreateFeedbackRecordResult> => {
const client = getHubClient();
if (!client) {
return { data: null, error: { ...NO_CONFIG_ERROR } };
@@ -39,15 +39,15 @@ export async function createFeedbackRecord(
logger.warn({ err, fieldId: input.field_id }, "Hub: createFeedbackRecord failed");
return createResultFromError(err);
}
}
};
/**
* Create multiple feedback records in the Hub in parallel.
* Returns an array of results (data or error) per input; logs failures.
*/
export async function createFeedbackRecordsBatch(
export const createFeedbackRecordsBatch = async (
inputs: FeedbackRecordCreateParams[]
): Promise<{ results: CreateFeedbackRecordResult[] }> {
): Promise<{ results: CreateFeedbackRecordResult[] }> => {
const client = getHubClient();
if (!client) {
return {
@@ -67,4 +67,4 @@ export async function createFeedbackRecordsBatch(
})
);
return { results };
}
};