Apply account and key changes to active queues without a restart and isolate provider attempt cancellation so fallback accounts remain usable. Preserve pause ownership, bound persisted HTTP 416 recovery, reconcile resets with authoritative state, and stabilize package ordering and live update cadence. Correlate rotation, conversion, resume, disk, queue-control, clipboard, and support-export events while redacting sensitive data at every persistent boundary and again in generated bundles. Release as v2.0.31 with updated English documentation and regression coverage.
124 lines
3.7 KiB
TypeScript
124 lines
3.7 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import type { PackageEntry } from "../src/shared/types";
|
|
import {
|
|
preservePackageOrderForDisplay,
|
|
reconcileCollapsedPackageState,
|
|
reconcileOptimisticPackageOrder
|
|
} from "../src/renderer/package-order";
|
|
|
|
function createPackage(id: string, itemIds: string[], downloadStartedAt = 0): PackageEntry {
|
|
const now = Date.now();
|
|
return {
|
|
id,
|
|
name: id,
|
|
outputDir: "",
|
|
extractDir: "",
|
|
status: "queued",
|
|
itemIds,
|
|
cancelled: false,
|
|
enabled: true,
|
|
priority: "normal",
|
|
createdAt: now,
|
|
updatedAt: now,
|
|
downloadStartedAt
|
|
};
|
|
}
|
|
|
|
describe("preservePackageOrderForDisplay", () => {
|
|
it("keeps the exact queue order", () => {
|
|
const packages = [
|
|
createPackage("pkg-a", ["a1", "a2"]),
|
|
createPackage("pkg-c", ["c1"]),
|
|
createPackage("pkg-b", ["b1", "b2"])
|
|
];
|
|
expect(preservePackageOrderForDisplay(packages).map((pkg) => pkg.id)).toEqual(["pkg-a", "pkg-c", "pkg-b"]);
|
|
});
|
|
|
|
it("keeps the visible queue order stable across start and completion metadata", () => {
|
|
const packages = [
|
|
createPackage("pkg-first", ["first-item"], 100),
|
|
createPackage("pkg-second", ["second-item"], 200),
|
|
createPackage("pkg-third", ["third-item"], 300)
|
|
];
|
|
expect(preservePackageOrderForDisplay(packages).map((pkg) => pkg.id)).toEqual(["pkg-first", "pkg-second", "pkg-third"]);
|
|
});
|
|
});
|
|
|
|
describe("reconcileCollapsedPackageState", () => {
|
|
it("keeps user collapse choices stable while package metadata and order change", () => {
|
|
const previous = { "pkg-first": true, "pkg-second": false };
|
|
const packages = {
|
|
"pkg-first": { ...createPackage("pkg-first", ["first-item"], 300), status: "downloading" as const },
|
|
"pkg-second": { ...createPackage("pkg-second", ["second-item"], 100), status: "completed" as const }
|
|
};
|
|
|
|
const next = reconcileCollapsedPackageState(previous, ["pkg-second", "pkg-first"], packages, true);
|
|
|
|
expect(next).toBe(previous);
|
|
expect(next).toEqual({ "pkg-first": true, "pkg-second": false });
|
|
});
|
|
|
|
it("defaults only new packages and removes packages that disappeared", () => {
|
|
const previous = { "pkg-old": false, "pkg-stale": true };
|
|
const packages = {
|
|
"pkg-old": createPackage("pkg-old", ["old-item"]),
|
|
"pkg-new": createPackage("pkg-new", ["new-item"])
|
|
};
|
|
|
|
expect(reconcileCollapsedPackageState(previous, ["pkg-old", "pkg-new"], packages, true)).toEqual({
|
|
"pkg-old": false,
|
|
"pkg-new": true
|
|
});
|
|
});
|
|
});
|
|
|
|
describe("reconcileOptimisticPackageOrder", () => {
|
|
it("keeps the optimistic order visible while an older state event arrives", () => {
|
|
const pending = ["pkg-a", "pkg-c", "pkg-b"];
|
|
|
|
expect(reconcileOptimisticPackageOrder(
|
|
["pkg-a", "pkg-b", "pkg-c"],
|
|
pending,
|
|
1_000,
|
|
1_500
|
|
)).toEqual({
|
|
displayOrder: pending,
|
|
pendingOrder: pending,
|
|
pendingAt: 1_000,
|
|
status: "pending"
|
|
});
|
|
});
|
|
|
|
it("accepts the authoritative order once it acknowledges the optimistic change", () => {
|
|
const pending = ["pkg-a", "pkg-c", "pkg-b"];
|
|
|
|
expect(reconcileOptimisticPackageOrder(
|
|
pending,
|
|
pending,
|
|
1_000,
|
|
1_500
|
|
)).toEqual({
|
|
displayOrder: pending,
|
|
pendingOrder: null,
|
|
pendingAt: 0,
|
|
status: "acknowledged"
|
|
});
|
|
});
|
|
|
|
it("returns to the authoritative order after the optimistic hold times out", () => {
|
|
const authoritative = ["pkg-a", "pkg-b", "pkg-c"];
|
|
|
|
expect(reconcileOptimisticPackageOrder(
|
|
authoritative,
|
|
["pkg-a", "pkg-c", "pkg-b"],
|
|
1_000,
|
|
2_500
|
|
)).toEqual({
|
|
displayOrder: authoritative,
|
|
pendingOrder: null,
|
|
pendingAt: 0,
|
|
status: "timed-out"
|
|
});
|
|
});
|
|
});
|