mirror of
https://github.com/Vateron-Media/XC_VM.git
synced 2026-10-03 12:02:29 +02:00
fix(modules): stop a reinstall from switching a disabled module back on
installModule() ended with an unconditional setState(Enabled). Store updates, zip uploads and plain reinstalls all pass through it, so switching a module off in the panel survived only until its next update — which is how a disabled plex came back and then blocked `watch` from being disabled at all. The admin's choice is now captured before the Installing transition overwrites it and restored at the end; a first install still enables, since there is no choice to preserve. stateAfterInstall() reads the raw override rather than listModules() so the transient Installing / Failed states cannot be mistaken for a deliberate "disabled". Restoring that state uses the new writeState() instead of setState(): putting a module back into the state it already had is a lifecycle transition, not an admin "disable", and must not be vetoed by the dependents guard — otherwise updating a disabled `watch` would fail at the last step because `plex` exists. setState() keeps the guard for the deliberate case. Three tests cover it; two of them fail against the previous behaviour. Verified: 860 tests, make gates, CRAP gate.
This commit is contained in:
@@ -348,6 +348,45 @@ final class ModuleManagerMigrationsTest extends TestCase {
|
||||
$this->assertSame([], $byName['ok-consumer']['dependency_warnings']);
|
||||
}
|
||||
|
||||
// ── install keeps the admin's on/off decision ─────────────────────────
|
||||
|
||||
public function testReinstallKeepsAModuleTheAdminDisabled(): void {
|
||||
// A store update lands in installModule(), which used to finish with an
|
||||
// unconditional Enabled — silently switching a disabled module back on.
|
||||
$this->createModule('keep-off', '1.0.0');
|
||||
$this->writeOverrides(['keep-off' => ['state' => 'disabled', 'installed_version' => '1.0.0']]);
|
||||
|
||||
$this->manager()->installModule('keep-off');
|
||||
|
||||
$overrides = $this->readOverrides();
|
||||
$this->assertSame('disabled', $overrides['keep-off']['state'] ?? null);
|
||||
$this->assertSame('1.0.0', $overrides['keep-off']['installed_version'] ?? null);
|
||||
}
|
||||
|
||||
public function testFirstInstallEnablesTheModule(): void {
|
||||
$this->createModule('turn-on', '1.0.0');
|
||||
|
||||
$this->manager()->installModule('turn-on');
|
||||
|
||||
// Enabled is the clean default, recorded by the ABSENCE of a state key.
|
||||
$this->assertArrayNotHasKey('state', $this->readOverrides()['turn-on']);
|
||||
}
|
||||
|
||||
public function testReinstallRestoresDisabledEvenWithADependent(): void {
|
||||
// Restoring Disabled is a lifecycle transition, not an admin "disable",
|
||||
// so the dependents guard must not veto it and fail the install.
|
||||
$this->createModuleWithDeps('dep-off', '1.0.0', []);
|
||||
$this->createModuleWithDeps('dep-user', '1.0.0', ['dep-off']);
|
||||
$this->writeOverrides([
|
||||
'dep-off' => ['state' => 'disabled', 'installed_version' => '1.0.0'],
|
||||
'dep-user' => ['installed_version' => '1.0.0'],
|
||||
]);
|
||||
|
||||
$this->manager()->installModule('dep-off');
|
||||
|
||||
$this->assertSame('disabled', $this->readOverrides()['dep-off']['state'] ?? null);
|
||||
}
|
||||
|
||||
// ── update/uninstall failure containment ──────────────────────────────
|
||||
|
||||
public function testUpdateKeepsWatermarkAtLastCompletedVersionOnFailure(): void {
|
||||
|
||||
Reference in New Issue
Block a user