This commit is contained in:
Mateusz Gruszczyński committed 2026-10-21 08:08:59 +02:00
1 parent 05185a94f7
commit bb5caa769f
28 files changed
+592 -130

No files matched your search

+52
View File
@@ -0,0 +1,52 @@
// Run with: node scripts/test_flow_disable_ui.js
// Regression checks for Flow OFF hiding generated rules even with stale plan data.
const assert = require('node:assert/strict');
const fs = require('node:fs');
const vm = require('node:vm');
const path = require('node:path');
const root = path.resolve(__dirname, '..');
const host = { innerHTML: '' };
const section = { hidden: false };
const app = {
flows: [{ id: 'flow1', enabled: false, draft: false, name: 'Disabled heating' }],
automations: [], devices: [], groups: [], zones: [],
controlPlan: { zones: [], next_events: [], rules: [], emergency_stop_active: false },
};
const context = vm.createContext({
app,
$: selector => selector === '#controlPlan' ? host : selector === '#controlPlanSection' ? section : null,
tr: key => key,
esc: x => String(x),
fmtTemp: n => String(n),
houseModeLabel: x => x,
zoneRuntimeStatusLabel: () => '',
zonePresetLabel: x => x,
groupState: () => ({}),
modeLabel: x => x,
locale: () => 'pl-PL',
});
vm.runInContext(fs.readFileSync(path.join(root, 'web/js-dynamic/dashboard.js'), 'utf8'), context);
function rule(flowId, enabled = true, id = 'FLOW_RULE_MARKER') {
return { id, name: id, enabled, flow_id: flowId, trigger_kind: 'flow', action: {} };
}
const generated = rule('flow1');
const orphan = rule('missing-flow', true, 'ORPHAN_RULE_MARKER');
const local = rule(null, true, 'LOCAL_RULE_MARKER');
app.controlPlan.rules = [generated, orphan, local];
function visible(r) { return context.planRuleEffectivelyEnabled(r); }
assert.equal(visible(generated), false, 'disabled parent must block generated rule');
assert.equal(visible(orphan), false, 'missing parent must block generated rule');
assert.equal(visible(local), true, 'unrelated local automation remains available');
context.renderControlPlan();
assert.doesNotMatch(host.innerHTML, /FLOW_RULE_MARKER|ORPHAN_RULE_MARKER/);
assert.match(host.innerHTML, /LOCAL_RULE_MARKER/);
app.flows[0].enabled = true;
assert.equal(visible(generated), true);
context.renderControlPlan();
assert.match(host.innerHTML, /FLOW_RULE_MARKER/);
app.flows[0].draft = true;
assert.equal(visible(generated), false, 'draft Flow must never execute');
app.flows[0].draft = false;
app.flows[0].enabled = false;
assert.equal(visible(rule('flow1', false)), false, 'disabled compiled rule must remain disabled');
console.log('OK: 9 disabled Flow UI/regression checks');
+1 -1
View File
@@ -78,7 +78,7 @@ def main() -> None:
for value in ("zone_heat_cycle", "boost_after_minutes", "day_off_after_minutes"):
assert value in rust and value in ui, value
assert "simple_heat_step(" in engine and "action_zone_simple_heat" in auto
assert "zone.simple_heat" in engine and "enabled_heat_actions" in engine
assert "zone.simple_heat" in engine and "active_flow_zone_action_ids" in engine
assert "automation.flow" in status and "zones.flowDayOff" in status
assert 'data-flow-add="zone_heat_cycle"' in html
assert "day_target_20_starts_at_21_then_boosts_to_22" in (ROOT / "src" / "engine" / "simple_heat.rs").read_text()