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

110 lines
3.3 KiB
TypeScript

import { beforeEach, describe, expect, it, vi } from "vitest";
import { CHAT_PERMISSIONS } from "@hivegrid/chat";
const mocks = vi.hoisted(() => ({ list: vi.fn() }));
vi.mock("@hivegrid/chat/message-discovery.server", () => ({
listChatMessageDiscovery: (...args: unknown[]) => mocks.list(...args),
}));
import { loadChatMessageDiscovery } from "./ChatMessageDiscoveryService.server";
const context = {
tenantId: "tenant_1",
userId: "viewer_1",
tenantUserId: "tenant_user_1",
permissions: [CHAT_PERMISSIONS.readOwnChannels],
hasModule: true,
} as const;
const labels = {
directMessage: "Direct message",
unnamedGroup: "Unnamed group",
unnamedProject: "Project chat",
unknownUser: "Unknown user",
} as const;
describe("ChatMessageDiscoveryService", () => {
beforeEach(() => {
vi.clearAllMocks();
mocks.list.mockResolvedValue({ messages: [], nextCursor: null });
});
it("maps repository records to pure VM rows and resolves a DM counterpart", async () => {
mocks.list.mockResolvedValue({
nextCursor: "cursor_1",
messages: [
{
id: "message_1",
chatId: "chat_dm",
channelKind: "dm",
channelName: null,
projectId: null,
authorUserId: "peer_1",
body: "Heat pump update",
parentMessageId: null,
createdAtIso: "2026-07-16T11:00:00.000Z",
participants: [
{ userId: "viewer_1", displayName: "Raffael Sheikh", avatarUrl: null },
{ userId: "peer_1", displayName: "Ada Lovelace", avatarUrl: "/avatars/ada" },
],
},
],
});
const vm = await loadChatMessageDiscovery({ context, tenantSlug: "demo", mode: "search", query: "heat", labels });
expect(mocks.list).toHaveBeenCalledWith({
tenantId: "tenant_1",
userId: "viewer_1",
permissions: [CHAT_PERMISSIONS.readOwnChannels],
mode: "search",
query: "heat",
});
expect(vm).toMatchObject({
status: "ready",
data: {
nextCursor: "cursor_1",
rows: [
{
channelTitle: "Ada Lovelace",
authorLabel: "Ada Lovelace",
authorAvatar: { imageUrl: "/avatars/ada", fallbackLabel: "AL" },
detailHref: "/demo/chat/chat_dm?message=message_1#message-message_1",
},
],
},
});
});
it("uses localized fallbacks without exposing unresolved identities", async () => {
mocks.list.mockResolvedValue({
nextCursor: null,
messages: [
{
id: "message_2",
chatId: "chat_project",
channelKind: "project",
channelName: null,
projectId: "project_1",
authorUserId: "former_user",
body: "Archived author stays readable",
parentMessageId: "parent_1",
createdAtIso: "2026-07-16T10:00:00.000Z",
participants: [],
},
],
});
const vm = await loadChatMessageDiscovery({ context, tenantSlug: "demo", mode: "mentions", labels });
expect(vm.status === "ready" && vm.data.rows[0]).toMatchObject({
channelTitle: "Project chat",
authorLabel: "Unknown user",
authorAvatar: { fallbackLabel: "UU" },
isThreadReply: true,
detailHref: "/demo/chat/chat_project/thread/parent_1?message=message_2#message-message_2",
});
});
});