99 lines
3.9 KiB
TypeScript
99 lines
3.9 KiB
TypeScript
import { create } from "@bufbuild/protobuf";
|
|
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
import type { LocalFile } from "@/components/MemoEditor/types/attachment";
|
|
import { MediaMetadataSchema } from "@/types/proto/api/v1/attachment_service_pb";
|
|
|
|
const mocks = vi.hoisted(() => ({
|
|
uploadAttachment: vi.fn(),
|
|
extractMetadata: vi.fn(),
|
|
}));
|
|
|
|
// The ingest helper lives beside useFileUpload, whose module graph reaches
|
|
// AuthContext and the query hooks; stub every client they name-import.
|
|
vi.mock("@/connect", () => ({
|
|
attachmentServiceClient: { uploadAttachment: mocks.uploadAttachment },
|
|
authServiceClient: {},
|
|
userServiceClient: {},
|
|
refreshAccessToken: vi.fn(),
|
|
}));
|
|
|
|
vi.mock("@/components/MemoEditor/services/mediaMetadataService", () => ({
|
|
mediaMetadataService: { extract: mocks.extractMetadata },
|
|
}));
|
|
|
|
import { toLocalFiles } from "@/components/MemoEditor/hooks/useFileUpload";
|
|
import { uploadService } from "@/components/MemoEditor/services/uploadService";
|
|
|
|
const createBlobUrl = (file: File) => `blob:${file.name}`;
|
|
|
|
const localImage = (mediaMetadata?: LocalFile["mediaMetadata"]): LocalFile => ({
|
|
file: new File(["image"], "photo.png", { type: "image/png" }),
|
|
previewUrl: "blob:photo",
|
|
origin: "upload",
|
|
mediaMetadata,
|
|
});
|
|
|
|
describe("media metadata at file ingest", () => {
|
|
it("does not extract metadata when the setting is disabled", () => {
|
|
const file = new File(["image"], "photo.png", { type: "image/png" });
|
|
|
|
const [localFile] = toLocalFiles([file], { createBlobUrl, saveMediaMetadata: false });
|
|
|
|
expect(mocks.extractMetadata).not.toHaveBeenCalled();
|
|
expect(localFile.mediaMetadata).toBeUndefined();
|
|
});
|
|
|
|
it("starts extraction per file when the setting is enabled", async () => {
|
|
const metadata = create(MediaMetadataSchema, { width: 1200, height: 800 });
|
|
mocks.extractMetadata.mockResolvedValue(metadata);
|
|
const file = new File(["image"], "photo.png", { type: "image/png" });
|
|
|
|
const [localFile] = toLocalFiles([file], { createBlobUrl, saveMediaMetadata: true });
|
|
|
|
expect(mocks.extractMetadata).toHaveBeenCalledWith(file);
|
|
await expect(localFile.mediaMetadata).resolves.toEqual(metadata);
|
|
});
|
|
});
|
|
|
|
describe("uploadService media metadata", () => {
|
|
beforeEach(() => {
|
|
mocks.uploadAttachment.mockImplementation(async ({ data }) => ({
|
|
uploadId: "test-id",
|
|
maxChunkSize: 2 * 1024 * 1024,
|
|
committedSize: BigInt(data?.length ?? 0),
|
|
attachment: data ? { name: "attachments/test" } : undefined,
|
|
}));
|
|
});
|
|
|
|
it("submits no metadata for files ingested without any", async () => {
|
|
await uploadService.uploadFiles([localImage()]);
|
|
|
|
expect(mocks.uploadAttachment).toHaveBeenCalledTimes(2);
|
|
expect(mocks.uploadAttachment.mock.calls[0][0].upload.value.attachment.mediaMetadata).toBeUndefined();
|
|
});
|
|
|
|
it("submits the metadata extracted at ingest", async () => {
|
|
const metadata = create(MediaMetadataSchema, { width: 1200, height: 800 });
|
|
|
|
await uploadService.uploadFiles([localImage(Promise.resolve(metadata))]);
|
|
|
|
expect(mocks.uploadAttachment.mock.calls[0][0].upload.value.attachment.mediaMetadata).toEqual(metadata);
|
|
});
|
|
|
|
it("continues without metadata when extraction produced no usable values", async () => {
|
|
await uploadService.uploadFiles([localImage(Promise.resolve(undefined))]);
|
|
|
|
expect(mocks.uploadAttachment).toHaveBeenCalledTimes(2);
|
|
expect(mocks.uploadAttachment.mock.calls[0][0].upload.value.attachment.mediaMetadata).toBeUndefined();
|
|
});
|
|
|
|
it("submits ingest-time metadata end to end", async () => {
|
|
const metadata = create(MediaMetadataSchema, { width: 640, height: 480 });
|
|
mocks.extractMetadata.mockResolvedValue(metadata);
|
|
const file = new File(["image"], "photo.png", { type: "image/png" });
|
|
|
|
await uploadService.uploadFiles(toLocalFiles([file], { createBlobUrl, saveMediaMetadata: true }));
|
|
|
|
expect(mocks.uploadAttachment.mock.calls[0][0].upload.value.attachment.mediaMetadata).toEqual(metadata);
|
|
});
|
|
});
|