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

100 lines
3.0 KiB
TypeScript

import { buildChatChannelDetailVM, type ChatResolvedAuthorVM } from "@hivegrid/view-models";
import { describe, expect, it } from "vitest";
import { overlayChatAttachmentSendAttempt, type ChatAttachmentSendAttempt } from "./chatAttachmentOptimistic";
const currentUser: ChatResolvedAuthorVM = {
userId: "user_1",
displayName: "Raffael",
avatar: { imageUrl: null, fallbackLabel: "RS" },
isCurrentUser: true,
};
function vm() {
return buildChatChannelDetailVM({
header: {
id: "chat_1",
kind: "group",
title: "Team",
subtitle: null,
avatar: { imageUrl: null, fallbackLabel: "T" },
project: null,
memberCount: 3,
isPrivate: true,
isArchived: false,
isAuditMode: false,
canManage: false,
settingsHref: null,
pinnedHref: null,
searchHref: "/demo/chat/search",
},
messages: [],
pinnedMessages: [],
typingLabels: [],
history: { hasOlder: false, olderCursor: null },
composer: {
disabledReasonKey: null,
canSend: true,
canAttachFiles: true,
canRecordVoice: true,
canMention: true,
canMarkAsTask: true,
draftStorageKey: "chat:draft:chat_1",
maxBodyLength: 4_000,
},
connection: { state: "online", reconnectAttempt: 0, retryAtIso: null },
});
}
function attempt(deliveryState: "sending" | "failed", errorKey: string | null): ChatAttachmentSendAttempt {
return {
payloadKey: "payload",
requestId: "request_stable",
clientMessageId: "client_stable",
fileIds: ["file_1"],
body: "Montagefoto",
attachments: [
{
clientId: "upload_1",
fileId: "file_1",
fileName: "camera.jpg",
mimeType: "image/jpeg",
sizeBytes: 1024,
kind: "image",
status: "ready",
progress: 100,
errorKey: null,
durationSeconds: null,
},
],
createdAtIso: "2026-07-16T08:00:00.000Z",
deliveryState,
errorKey,
};
}
describe("attachment optimistic message overlay", () => {
it("shows a local sending echo with the stable client id and attachment metadata", () => {
const result = overlayChatAttachmentSendAttempt(vm(), attempt("sending", null), currentUser);
expect(result.status).toBe("ready");
if (result.status !== "ready") return;
expect(result.data.messages[0]).toMatchObject({
id: "local:client_stable",
clientMessageId: "client_stable",
source: "local_echo",
deliveryState: "sending",
attachments: [{ fileId: "file_1", fileName: "camera.jpg" }],
});
});
it("keeps a failed send element-local and retryable without changing its identity", () => {
const result = overlayChatAttachmentSendAttempt(vm(), attempt("failed", "chat.errors.invalidInput"), currentUser);
expect(result.status === "ready" ? result.data.messages[0] : null).toMatchObject({
clientMessageId: "client_stable",
deliveryState: "failed",
retryable: true,
failureReasonKey: "chat.errors.invalidInput",
});
});
});