fix(downloads): compact finalization statuses

Normalize German and English finalization producer labels before they reach package and item status cells. Derive percentages from valid fractions, clamp them to the visible 0-100 range, and reduce malformed fractions or zero totals to the phase name.

Preserve legacy percentage labels while preventing finalization lines ending in archive names from being classified as bare extraction archives. Cover current and legacy forms, both languages, package and item rendering, localization, and invalid numeric input.
This commit is contained in:
Sucukdeluxe
2026-08-12 00:09:18 +02:00
parent 15f53f9c92
commit 1664478770
4 changed files with 75 additions and 2 deletions
+45
View File
@@ -923,6 +923,51 @@ describe("download table row contracts", () => {
expect(html).not.toContain(">release.part1.rar</span>");
});
it.each([
["package", "Finalisieren (1/2) · release.part1.rar", "Finalisieren - 50%"],
["package", "Finalizing - 50% * release.part1.rar", "Finalizing - 50%"],
["item", "Finalizing (3/4) · release.part1.rar", "Finalizing - 75%"],
["item", "Finalisieren - 50% * release.part1.rar", "Finalisieren - 50%"]
])("shows %s finalization status without archive details", (target, rawStatus, expectedStatus) => {
const html = target === "package"
? renderToStaticMarkup(PackageCardContent({
actions: createActions(),
columnOrder: ["status"],
editing: false,
editingName: "",
gridTemplate: "220px",
packageSpeedBps: 0,
row: {
package: { ...pkg("finalization-package", "Finalization", ["finalization-item"]), postProcessLabel: rawStatus, status: "extracting" } as PackageEntry,
items: [item("finalization-item", "finalization-package", "completed")],
allItems: [item("finalization-item", "finalization-package", "completed")],
collapsed: true
},
selectedIds: new Set<string>(),
selectedVersion: 0
}))
: renderToStaticMarkup(ItemRowContent({
actions: createActions(),
columnOrder: ["status"],
gridTemplate: "220px",
item: item("finalization-item", "finalization-package", "completed", { fullStatus: rawStatus }),
selected: false
}));
expect(html).toContain(`aria-label="${expectedStatus}"`);
expect(html.match(new RegExp(`>${expectedStatus}</span>`, "g"))).toHaveLength(2);
expect(html).not.toContain(">release.part1.rar</span>");
});
it.each([
["Finalisieren (3/2) · release.part1.rar", "Finalisieren - 100%"],
["Finalizing (-1/2) · release.part1.rar", "Finalizing - 0%"],
["Finalisieren (1/0) · release.part1.rar", "Finalisieren"],
["Finalizing (invalid/2) · release.part1.rar", "Finalizing"]
])("derives only finite finalization percentages", (rawStatus, expectedStatus) => {
expect(compactDownloadStatus(rawStatus)).toBe(expectedStatus);
});
it("renders meter text in clipped track and fill layers", () => {
const html = renderToStaticMarkup(ItemRowContent({
actions: createActions(),
+9
View File
@@ -22,6 +22,15 @@ describe("renderer localization", () => {
expect(translateUiText("100.001100.005 of 100.005", "de")).toBe("100.001100.005 von 100.005");
});
it.each([
["Finalisieren - 0%", "Finalizing - 0%"],
["Finalisieren - 50%", "Finalizing - 50%"],
["Finalisieren - 100%", "Finalizing - 100%"]
])("translates compact finalization progress %s in both directions", (german, english) => {
expect(translateUiText(german, "en")).toBe(english);
expect(translateUiText(english, "de")).toBe(german);
});
it("translates the complete history surface including status values", () => {
const translations = new Map([
["Alle Einträge", "All entries"],