Files
edgeever/apps/mobile/src/lib/mobile-note-image-export.test.ts
T

46 lines
2.3 KiB
TypeScript

import { describe, expect, test } from "bun:test";
import { PathUtilities } from "../../node_modules/expo-file-system/src/pathUtilities";
import { buildImageExportBasename } from "@edgeever/shared/note-image-card";
import { encodeMobileNoteImageFileUri, planMobileNoteImageRender } from "./mobile-note-image-export";
describe("mobile note image file URI", () => {
test.each(["png", "jpg"])("preserves bracketed titles for %s exports through Expo path joining", (extension) => {
const filename = `${buildImageExportBasename("[Serv00.com] Account activation tuuki", "Untitled")}.${extension}`;
const uri = encodeMobileNoteImageFileUri(PathUtilities.join("file:///cache/exports/request-1/", filename));
expect(uri).toBe(`file:///cache/exports/request-1/%5BServ00.com%5D%20Account%20activation%20tuuki.${extension}`);
// File's constructor joins the URI once more before handing it to Android.
expect(PathUtilities.join(uri)).toBe(uri);
expect(decodeURIComponent(new URL(uri).pathname.split("/").at(-1)!)).toBe(filename);
});
test.each(["中文 [标题] 100% #1.png", "literal %5Bname%5D.png", "普通笔记.jpg"])("preserves the filename %s without double encoding", (filename) => {
const uri = encodeMobileNoteImageFileUri(PathUtilities.join("file:///cache/exports/", filename));
expect(uri).not.toMatch(/[\[\]]/);
expect(decodeURIComponent(new URL(uri).pathname.split("/").at(-1)!)).toBe(filename);
expect(encodeMobileNoteImageFileUri(uri)).toBe(uri);
});
});
describe("planMobileNoteImageRender", () => {
test("keeps a short card at full quality", () => {
expect(planMobileNoteImageRender(680, 1_000)).toEqual({
pixelRatio: 2,
sourceHeight: 1_000,
sourceScale: 1,
sourceWidth: 680,
});
});
test("fits a long digest within the mobile image budget", () => {
const plan = planMobileNoteImageRender(680, 20_000);
expect(plan.sourceScale).toBe(0.75);
expect(plan.sourceHeight).toBeLessThanOrEqual(15_000);
expect(plan.sourceHeight * plan.pixelRatio).toBeLessThanOrEqual(15_000);
expect(plan.sourceWidth * plan.sourceHeight * plan.pixelRatio ** 2).toBeLessThanOrEqual(12_000_000);
});
test("rejects a card that would be unreadable as one image", () => {
expect(() => planMobileNoteImageRender(680, 40_000)).toThrow("NOTE_IMAGE_TOO_LONG");
});
});