Restore and persist the package-based link collector with progressive metadata, bounded high-volume updates, safe hydration, visible selection, and complete localization. Harden download controls, snapshot ordering, history pagination, statistics recovery, settings saves, backup imports, notification persistence, and Windows storage races with regression coverage.
92 lines
3.8 KiB
TypeScript
92 lines
3.8 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import * as collector from "../src/shared/collector";
|
|
import * as collectorModel from "../src/renderer/views/collector/collector-model";
|
|
import type { CollectorLink, CollectorPackage } from "../src/shared/collector";
|
|
|
|
function link(index: number): CollectorLink {
|
|
return {
|
|
id: `link-${index}`,
|
|
url: `https://example.test/${index}`,
|
|
fileName: `file-${index}.bin`,
|
|
fileSizeBytes: null,
|
|
hoster: "example",
|
|
availability: "unknown",
|
|
status: "unknown",
|
|
addedAt: 1
|
|
};
|
|
}
|
|
|
|
function packageEntry(index: number, links: CollectorLink[] = [link(index)]): CollectorPackage {
|
|
return {
|
|
id: `package-${index}`,
|
|
name: `Package ${index}`,
|
|
nameSource: "explicit",
|
|
links,
|
|
addedAt: 1
|
|
};
|
|
}
|
|
|
|
describe("collector capacity", () => {
|
|
it("reports package and link overflow without cloning the state", () => {
|
|
const inspect = (collector as unknown as {
|
|
inspectCollectorCapacity?: (packages: CollectorPackage[]) => unknown;
|
|
}).inspectCollectorCapacity;
|
|
|
|
expect(inspect).toBeTypeOf("function");
|
|
expect(inspect?.(Array.from({ length: 2_001 }, (_, index) => packageEntry(index)))).toEqual({
|
|
ok: false,
|
|
packageCount: 2_001,
|
|
linkCount: 2_001,
|
|
message: "Der Linksammler kann höchstens 2.000 Pakete enthalten."
|
|
});
|
|
expect(inspect?.([packageEntry(0, Array.from({ length: 20_001 }, (_, index) => link(index)))])).toEqual({
|
|
ok: false,
|
|
packageCount: 1,
|
|
linkCount: 20_001,
|
|
message: "Der Linksammler kann höchstens 20.000 Links enthalten."
|
|
});
|
|
});
|
|
|
|
it("reports the exact serialized persistence overflow independently of count limits", () => {
|
|
const inspectPersistence = (collector as unknown as {
|
|
inspectCollectorPersistenceSize?: (state: { packages: CollectorPackage[]; collapsedPackageIds: string[] }, maximumBytes?: number) => { ok: boolean; byteCount: number; message?: string };
|
|
}).inspectCollectorPersistenceSize;
|
|
const state = { packages: [packageEntry(1)], collapsedPackageIds: ["package-1"] };
|
|
|
|
expect(inspectPersistence).toBeTypeOf("function");
|
|
const result = inspectPersistence?.(state, 128);
|
|
expect(result?.ok).toBe(false);
|
|
expect(result?.byteCount).toBeGreaterThan(128);
|
|
expect(result?.message).toBe("Der Linksammler ist zu groß, um gespeichert zu werden.");
|
|
});
|
|
|
|
it("rejects only the cumulative post-merge result and leaves the current state untouched", () => {
|
|
const mergeWithinCapacity = (collectorModel as unknown as {
|
|
mergeCollectorPackagesWithinCapacity?: (current: CollectorPackage[], incoming: CollectorPackage[], enrichment?: boolean) => unknown;
|
|
}).mergeCollectorPackagesWithinCapacity;
|
|
const current = Array.from({ length: 1_999 }, (_, index) => packageEntry(index));
|
|
const incoming = [packageEntry(1_999), packageEntry(2_000)];
|
|
|
|
expect(mergeWithinCapacity).toBeTypeOf("function");
|
|
expect(mergeWithinCapacity?.(current, incoming)).toEqual({
|
|
ok: false,
|
|
packageCount: 2_001,
|
|
linkCount: 2_001,
|
|
message: "Der Linksammler kann höchstens 2.000 Pakete enthalten."
|
|
});
|
|
expect(current).toHaveLength(1_999);
|
|
});
|
|
|
|
it("accepts an at-limit merge when the incoming link is only a duplicate", () => {
|
|
const mergeWithinCapacity = (collectorModel as unknown as {
|
|
mergeCollectorPackagesWithinCapacity?: (current: CollectorPackage[], incoming: CollectorPackage[], enrichment?: boolean) => { ok: boolean; value?: { packages: CollectorPackage[] } };
|
|
}).mergeCollectorPackagesWithinCapacity;
|
|
const current = Array.from({ length: 2_000 }, (_, index) => packageEntry(index));
|
|
|
|
expect(mergeWithinCapacity).toBeTypeOf("function");
|
|
const result = mergeWithinCapacity?.(current, [{ ...current[0], links: [{ ...current[0].links[0] }] }]);
|
|
expect(result?.ok).toBe(true);
|
|
expect(result?.value?.packages).toHaveLength(2_000);
|
|
});
|
|
});
|