235 lines
6.5 KiB
TypeScript
235 lines
6.5 KiB
TypeScript
import { describe, expect, it, vi, beforeEach, afterEach } from "vitest";
|
|
import { prepareFileConsentActivity, requiresFileConsent } from "./file-consent-helpers.js";
|
|
import * as pendingUploads from "./pending-uploads.js";
|
|
|
|
describe("requiresFileConsent", () => {
|
|
const thresholdBytes = 4 * 1024 * 1024; // 4MB
|
|
|
|
it("returns true for personal chat with non-image", () => {
|
|
expect(
|
|
requiresFileConsent({
|
|
conversationType: "personal",
|
|
contentType: "application/pdf",
|
|
bufferSize: 1000,
|
|
thresholdBytes,
|
|
}),
|
|
).toBe(true);
|
|
});
|
|
|
|
it("returns true for personal chat with large image", () => {
|
|
expect(
|
|
requiresFileConsent({
|
|
conversationType: "personal",
|
|
contentType: "image/png",
|
|
bufferSize: 5 * 1024 * 1024, // 5MB
|
|
thresholdBytes,
|
|
}),
|
|
).toBe(true);
|
|
});
|
|
|
|
it("returns false for personal chat with small image", () => {
|
|
expect(
|
|
requiresFileConsent({
|
|
conversationType: "personal",
|
|
contentType: "image/png",
|
|
bufferSize: 1000,
|
|
thresholdBytes,
|
|
}),
|
|
).toBe(false);
|
|
});
|
|
|
|
it("returns false for group chat with large non-image", () => {
|
|
expect(
|
|
requiresFileConsent({
|
|
conversationType: "groupChat",
|
|
contentType: "application/pdf",
|
|
bufferSize: 5 * 1024 * 1024,
|
|
thresholdBytes,
|
|
}),
|
|
).toBe(false);
|
|
});
|
|
|
|
it("returns false for channel with large non-image", () => {
|
|
expect(
|
|
requiresFileConsent({
|
|
conversationType: "channel",
|
|
contentType: "application/pdf",
|
|
bufferSize: 5 * 1024 * 1024,
|
|
thresholdBytes,
|
|
}),
|
|
).toBe(false);
|
|
});
|
|
|
|
it("handles case-insensitive conversation type", () => {
|
|
expect(
|
|
requiresFileConsent({
|
|
conversationType: "Personal",
|
|
contentType: "application/pdf",
|
|
bufferSize: 1000,
|
|
thresholdBytes,
|
|
}),
|
|
).toBe(true);
|
|
|
|
expect(
|
|
requiresFileConsent({
|
|
conversationType: "PERSONAL",
|
|
contentType: "application/pdf",
|
|
bufferSize: 1000,
|
|
thresholdBytes,
|
|
}),
|
|
).toBe(true);
|
|
});
|
|
|
|
it("returns false when conversationType is undefined", () => {
|
|
expect(
|
|
requiresFileConsent({
|
|
conversationType: undefined,
|
|
contentType: "application/pdf",
|
|
bufferSize: 1000,
|
|
thresholdBytes,
|
|
}),
|
|
).toBe(false);
|
|
});
|
|
|
|
it("returns true for personal chat when contentType is undefined (non-image)", () => {
|
|
expect(
|
|
requiresFileConsent({
|
|
conversationType: "personal",
|
|
contentType: undefined,
|
|
bufferSize: 1000,
|
|
thresholdBytes,
|
|
}),
|
|
).toBe(true);
|
|
});
|
|
|
|
it("returns true for personal chat with file exactly at threshold", () => {
|
|
expect(
|
|
requiresFileConsent({
|
|
conversationType: "personal",
|
|
contentType: "image/jpeg",
|
|
bufferSize: thresholdBytes, // exactly 4MB
|
|
thresholdBytes,
|
|
}),
|
|
).toBe(true);
|
|
});
|
|
|
|
it("returns false for personal chat with file just below threshold", () => {
|
|
expect(
|
|
requiresFileConsent({
|
|
conversationType: "personal",
|
|
contentType: "image/jpeg",
|
|
bufferSize: thresholdBytes - 1, // 4MB - 1 byte
|
|
thresholdBytes,
|
|
}),
|
|
).toBe(false);
|
|
});
|
|
});
|
|
|
|
describe("prepareFileConsentActivity", () => {
|
|
const mockUploadId = "test-upload-id-123";
|
|
|
|
beforeEach(() => {
|
|
vi.spyOn(pendingUploads, "storePendingUpload").mockReturnValue(mockUploadId);
|
|
});
|
|
|
|
afterEach(() => {
|
|
vi.restoreAllMocks();
|
|
});
|
|
|
|
it("creates activity with consent card attachment", () => {
|
|
const result = prepareFileConsentActivity({
|
|
media: {
|
|
buffer: Buffer.from("test content"),
|
|
filename: "test.pdf",
|
|
contentType: "application/pdf",
|
|
},
|
|
conversationId: "conv123",
|
|
description: "My file",
|
|
});
|
|
|
|
expect(result.uploadId).toBe(mockUploadId);
|
|
expect(result.activity.type).toBe("message");
|
|
expect(result.activity.attachments).toHaveLength(1);
|
|
|
|
const attachment = (result.activity.attachments as unknown[])[0] as Record<string, unknown>;
|
|
expect(attachment.contentType).toBe("application/vnd.microsoft.teams.card.file.consent");
|
|
expect(attachment.name).toBe("test.pdf");
|
|
});
|
|
|
|
it("stores pending upload with correct data", () => {
|
|
const buffer = Buffer.from("test content");
|
|
prepareFileConsentActivity({
|
|
media: {
|
|
buffer,
|
|
filename: "test.pdf",
|
|
contentType: "application/pdf",
|
|
},
|
|
conversationId: "conv123",
|
|
description: "My file",
|
|
});
|
|
|
|
expect(pendingUploads.storePendingUpload).toHaveBeenCalledWith({
|
|
buffer,
|
|
filename: "test.pdf",
|
|
contentType: "application/pdf",
|
|
conversationId: "conv123",
|
|
});
|
|
});
|
|
|
|
it("uses default description when not provided", () => {
|
|
const result = prepareFileConsentActivity({
|
|
media: {
|
|
buffer: Buffer.from("test"),
|
|
filename: "document.docx",
|
|
contentType: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
|
},
|
|
conversationId: "conv456",
|
|
});
|
|
|
|
const attachment = (result.activity.attachments as unknown[])[0] as Record<string, { description: string }>;
|
|
expect(attachment.content.description).toBe("File: document.docx");
|
|
});
|
|
|
|
it("uses provided description", () => {
|
|
const result = prepareFileConsentActivity({
|
|
media: {
|
|
buffer: Buffer.from("test"),
|
|
filename: "report.pdf",
|
|
contentType: "application/pdf",
|
|
},
|
|
conversationId: "conv789",
|
|
description: "Q4 Financial Report",
|
|
});
|
|
|
|
const attachment = (result.activity.attachments as unknown[])[0] as Record<string, { description: string }>;
|
|
expect(attachment.content.description).toBe("Q4 Financial Report");
|
|
});
|
|
|
|
it("includes uploadId in consent card context", () => {
|
|
const result = prepareFileConsentActivity({
|
|
media: {
|
|
buffer: Buffer.from("test"),
|
|
filename: "file.txt",
|
|
contentType: "text/plain",
|
|
},
|
|
conversationId: "conv000",
|
|
});
|
|
|
|
const attachment = (result.activity.attachments as unknown[])[0] as Record<string, { acceptContext: { uploadId: string } }>;
|
|
expect(attachment.content.acceptContext.uploadId).toBe(mockUploadId);
|
|
});
|
|
|
|
it("handles media without contentType", () => {
|
|
const result = prepareFileConsentActivity({
|
|
media: {
|
|
buffer: Buffer.from("binary data"),
|
|
filename: "unknown.bin",
|
|
},
|
|
conversationId: "conv111",
|
|
});
|
|
|
|
expect(result.uploadId).toBe(mockUploadId);
|
|
expect(result.activity.type).toBe("message");
|
|
});
|
|
});
|