From d25747646e6173d7bc42ce4198fd21e39435e967 Mon Sep 17 00:00:00 2001 From: VAIO73 <50487331+Vaso73@users.noreply.github.com> Date: Fri, 16 Oct 2026 16:38:32 +0000 Subject: [PATCH] fix: distinguish current and historical stopped schedule state --- .../tests/test_command_descriptions.py | 4 +++ AppImage/components/virtual-machines.tsx | 4 ++- AppImage/messages/en/common.json | 3 +- AppImage/messages/sk/common.json | 3 +- .../test_scheduled_reason_i18n.cjs | 28 +++++++++++++------ 5 files changed, 31 insertions(+), 11 deletions(-) diff --git a/.github/scripts/tests/test_command_descriptions.py b/.github/scripts/tests/test_command_descriptions.py index 8e48a44d..93186be9 100644 --- a/.github/scripts/tests/test_command_descriptions.py +++ b/.github/scripts/tests/test_command_descriptions.py @@ -217,6 +217,10 @@ class CommandDescriptionsTests(unittest.TestCase): "reasonStoppedContainer", english["vmLxc"]["scheduled"]["reasonStoppedContainer"], ) + messages["vmLxc"]["scheduled"].setdefault( + "reasonStoppedContainerHistorical", + english["vmLxc"]["scheduled"]["reasonStoppedContainerHistorical"], + ) messages["vmLxc"]["scheduled"].setdefault( "runSkippedStatus", english["vmLxc"]["scheduled"]["runSkippedStatus"], diff --git a/AppImage/components/virtual-machines.tsx b/AppImage/components/virtual-machines.tsx index a571c426..901655d4 100644 --- a/AppImage/components/virtual-machines.tsx +++ b/AppImage/components/virtual-machines.tsx @@ -2450,7 +2450,9 @@ const handleDownloadLogs = async (vmid: number, vmName: string) => { if (!scheduleLastRunAt || !selectedVM) return null const spacing = indented ? "pl-4" : "" const scheduleLastRunReasonText = scheduleLastRunReasonCode === "stopped_container" - ? t("vmLxc.scheduled.reasonStoppedContainer") + ? selectedVM.status === "stopped" + ? t("vmLxc.scheduled.reasonStoppedContainer") + : t("vmLxc.scheduled.reasonStoppedContainerHistorical") : scheduleLastRunReason return (
diff --git a/AppImage/messages/en/common.json b/AppImage/messages/en/common.json index 55b5b4b9..832f5c77 100644 --- a/AppImage/messages/en/common.json +++ b/AppImage/messages/en/common.json @@ -1289,7 +1289,8 @@ "runDeferred": "held for safety", "runSkipped": "nothing pending", "runSkippedStatus": "run skipped", - "reasonStoppedContainer": "Container was stopped; scheduled update was skipped.", + "reasonStoppedContainer": "Container is stopped; scheduled update was skipped.", + "reasonStoppedContainerHistorical": "Container was stopped when the scheduled update was due to run.", "releaseDelaySummary": "{days}-day release hold", "releaseDelayLabel": "Wait after a new app release", "releaseDelayNone": "No waiting period", diff --git a/AppImage/messages/sk/common.json b/AppImage/messages/sk/common.json index 2297cb21..cd290e08 100644 --- a/AppImage/messages/sk/common.json +++ b/AppImage/messages/sk/common.json @@ -1289,7 +1289,8 @@ "runDeferred": "odložené z bezpečnostných dôvodov", "runSkipped": "nič nečaká", "runSkippedStatus": "spustenie bolo preskočené", - "reasonStoppedContainer": "Kontajner bol vypnutý; plánovaná aktualizácia sa preskočila.", + "reasonStoppedContainer": "Kontajner je vypnutý; plánovaná aktualizácia sa preskočila.", + "reasonStoppedContainerHistorical": "Kontajner bol vypnutý, keď sa mala spustiť plánovaná aktualizácia.", "releaseDelaySummary": "odklad {days} deň/dní", "releaseDelayLabel": "Počkať po novej verzii aplikácie", "releaseDelayNone": "Bez čakacej doby", diff --git a/tests/lxc_updates/test_scheduled_reason_i18n.cjs b/tests/lxc_updates/test_scheduled_reason_i18n.cjs index a87e7354..c03f4c8c 100644 --- a/tests/lxc_updates/test_scheduled_reason_i18n.cjs +++ b/tests/lxc_updates/test_scheduled_reason_i18n.cjs @@ -63,7 +63,7 @@ for (const locale of ['en', 'sk']) { return String(message ?? key).replace(/\{([^}]+)\}/g, (_, name) => String(variables[name] ?? `{${name}}`)) } const context = { - exports: {}, t, selectedVM: { vmid: 100 }, scheduleLastRunAt: '2026-10-16T05:10:02Z', + exports: {}, t, selectedVM: { vmid: 100, status: 'stopped' }, scheduleLastRunAt: '2026-10-16T05:10:02Z', scheduleLastRunStatus: 'skipped', scheduleLastRunReasonCode: 'stopped_container', scheduleLastRunReason: 'container is stopped; scheduled update was skipped', scheduleLastRunRebootRequired: false, scheduleLastRunRebootPackages: [], scheduleLastRunLog: null, @@ -72,17 +72,29 @@ for (const locale of ['en', 'sk']) { } const render = compile(context) const translated = flattenText(render(true)) - const expected = t('vmLxc.scheduled.reasonStoppedContainer') + const expectedCurrentReason = t('vmLxc.scheduled.reasonStoppedContainer') + const expectedHistoricalReason = t('vmLxc.scheduled.reasonStoppedContainerHistorical') const skippedLabel = t('vmLxc.scheduled.runSkippedStatus') - const expectedHistoricalReason = locale === 'sk' - ? 'Kontajner bol vypnutý; plánovaná aktualizácia sa preskočila.' - : 'Container was stopped; scheduled update was skipped.' - assert.equal(expected, expectedHistoricalReason, - `${locale}: stopped reason must describe the historical scheduled run, not current container state`) - assert(translated.includes(expected), `${locale}: known reason code must use the locale catalog`) + const expectedCurrentText = locale === 'sk' + ? 'Kontajner je vypnutý; plánovaná aktualizácia sa preskočila.' + : 'Container is stopped; scheduled update was skipped.' + const expectedHistoricalText = locale === 'sk' + ? 'Kontajner bol vypnutý, keď sa mala spustiť plánovaná aktualizácia.' + : 'Container was stopped when the scheduled update was due to run.' + assert.equal(expectedCurrentReason, expectedCurrentText, + `${locale}: stopped CT must describe its current stopped state`) + assert.equal(expectedHistoricalReason, expectedHistoricalText, + `${locale}: running CT must describe the stopped state at the prior scheduled run`) + assert(translated.includes(expectedCurrentReason), `${locale}: currently stopped CT must use the present-state catalog`) + assert(!translated.includes(expectedHistoricalReason), `${locale}: currently stopped CT must not use historical wording`) assert(translated.includes(skippedLabel), `${locale}: skipped run must not claim that no updates are pending`) assert(!translated.includes(context.scheduleLastRunReason), `${locale}: raw stopped reason must not leak into UI`) + context.selectedVM.status = 'running' + const historical = flattenText(render(true)) + assert(historical.includes(expectedHistoricalReason), `${locale}: running CT must use historical wording for a past skipped run`) + assert(!historical.includes(expectedCurrentReason), `${locale}: running CT must not claim it is currently stopped`) + context.scheduleLastRunReasonCode = 'unknown_reason' const fallback = flattenText(render(true)) assert(fallback.includes(context.scheduleLastRunReason), `${locale}: unknown code must retain the raw diagnostic`)