create(['must_change_password' => false]); $server = Server::create(['name' => 'box', 'ip' => '10.0.0.9', 'ssh_port' => 22, 'status' => 'online']); // The destructive SSH action must never be reached once the gate re-runs. $fleet = Mockery::mock(FleetService::class)->shouldIgnoreMissing(); $fleet->shouldReceive('removeAuthorizedKey')->never(); app()->instance(FleetService::class, $fleet); // 1. Mount the panel page while fully onboarded — the rendered snapshot carries // memo.path = servers/{uuid}, the route that bears EnsureSecurityOnboarded. $html = $this->actingAs($user) ->get(route('servers.show', $server)) ->assertOk() ->getContent(); $snapshot = $this->extractSnapshot($html, 'servers.show'); // 2. The account is reverted to must_change_password AFTER the component mounted. $user->forceFill(['must_change_password' => true])->save(); // 3. Replay a destructive call against the still-valid snapshot, exactly as the // browser would on the next interaction. $response = $this->actingAs($user)->postJson('/livewire/update', [ 'components' => [[ 'snapshot' => $snapshot, 'updates' => [], 'calls' => [[ 'path' => '', 'method' => 'removeKey', 'params' => ['SHA256:'.str_repeat('a', 43)], ]], ]], ], ['X-Livewire' => 'true']); // The persistent gate redirects to the password change before removeKey runs; // the ->never() expectation above proves the destructive call was blocked. $response->assertRedirect(route('password.change')); } /** Pull the wire:snapshot JSON for a specific component out of rendered page HTML. */ private function extractSnapshot(string $html, string $name): string { preg_match_all('/wire:snapshot="([^"]*)"/', $html, $matches); foreach ($matches[1] as $encoded) { $json = htmlspecialchars_decode($encoded, ENT_QUOTES | ENT_SUBSTITUTE); if ((json_decode($json, true)['memo']['name'] ?? null) === $name) { return $json; } } $this->fail("No wire:snapshot found for component [{$name}] in the rendered page."); } }