Files
HiveGrid-Wireframes/03 Quellen und Referenzen/hivegrid-cloud/apps/web/app/modules/chat/services/projectChatLink.server.test.ts
T

64 lines
2.3 KiB
TypeScript

import { CatalogError, foundationErrors } from "@hivegrid/foundation";
import { beforeEach, describe, expect, it, vi } from "vitest";
const mocks = vi.hoisted(() => ({
loadChatContext: vi.fn(),
findMemberProjectChatLink: vi.fn(),
}));
vi.mock("../routes/chatAccess.server", () => ({
loadChatContext: mocks.loadChatContext,
}));
vi.mock("@hivegrid/chat/project-link.server", () => ({
findMemberProjectChatLink: mocks.findMemberProjectChatLink,
}));
import { loadOptionalProjectChatLink } from "./projectChatLink.server";
const request = new Request("https://app.example.test/demo/projects/project_1");
const params = { tenant: "demo", id: "project_1" };
const context = {
tenantId: "tenant_1",
userId: "user_1",
tenantUserId: "tenant_user_1",
permissions: ["chat.read_own_channels"],
hasModule: true as const,
};
describe("optional project chat link", () => {
beforeEach(() => {
vi.clearAllMocks();
mocks.loadChatContext.mockResolvedValue(context);
mocks.findMemberProjectChatLink.mockResolvedValue({ chatId: "chat_1", archivedAtIso: null, canWrite: true });
});
it("gates the repository lookup through the tenant chat context", async () => {
await expect(loadOptionalProjectChatLink({ request, params, projectId: "project_1" })).resolves.toEqual({
chatId: "chat_1",
archivedAtIso: null,
canWrite: true,
});
expect(mocks.loadChatContext).toHaveBeenCalledWith({ request, params });
expect(mocks.findMemberProjectChatLink).toHaveBeenCalledWith({
tenantId: "tenant_1",
userId: "user_1",
permissions: ["chat.read_own_channels"],
projectId: "project_1",
});
});
it("hides the affordance when the module, permission or membership is unavailable", async () => {
mocks.loadChatContext.mockRejectedValue(new CatalogError(foundationErrors.notFound));
await expect(loadOptionalProjectChatLink({ request, params, projectId: "project_1" })).resolves.toBeNull();
expect(mocks.findMemberProjectChatLink).not.toHaveBeenCalled();
});
it("does not swallow operational failures", async () => {
mocks.findMemberProjectChatLink.mockRejectedValue(new Error("database unavailable"));
await expect(loadOptionalProjectChatLink({ request, params, projectId: "project_1" })).rejects.toThrow("database unavailable");
});
});