create(); $this->actingAs($user); return $user; } public function test_confirm_with_a_valid_token_audits_from_the_payload_and_dispatches_the_event(): void { $this->login(); $server = Server::create(['name' => 'box', 'ip' => '10.0.0.9', 'ssh_port' => 22, 'status' => 'online']); $token = ConfirmToken::issue('keyRemoved', ['fingerprint' => 'ab:cd'], 'ssh_key.remove', 'box · key', $server->id); Livewire::test(ConfirmAction::class, ['token' => $token]) ->call('confirm') ->assertDispatched('keyRemoved', confirmToken: $token); $this->assertSame(1, AuditEvent::where('action', 'ssh_key.remove')->count()); $this->assertDatabaseHas('audit_events', [ 'action' => 'ssh_key.remove', 'target' => 'box · key', 'server_id' => $server->id, ]); } public function test_confirm_on_a_deferred_flow_dispatches_without_writing_audit(): void { $this->login(); // No auditAction → the handler audits after the remote op; confirm() must not. $token = ConfirmToken::issue('firewallRuleDelete', ['spec' => '22/tcp', 'label' => 'SSH']); Livewire::test(ConfirmAction::class, ['token' => $token]) ->call('confirm') ->assertDispatched('firewallRuleDelete', confirmToken: $token); $this->assertSame(0, AuditEvent::count()); } public function test_confirm_with_a_forged_token_is_rejected_no_audit_no_dispatch(): void { $this->login(); Livewire::test(ConfirmAction::class, ['token' => 'forged-token']) ->call('confirm') ->assertDispatched('notify', message: __('modals.confirm_action.rejected')) ->assertNotDispatched('keyRemoved'); $this->assertSame(0, AuditEvent::count()); } public function test_confirm_cannot_be_replayed_after_the_handler_burned_the_token(): void { $this->login(); $token = ConfirmToken::issue('twoFactorDisabled', [], 'two_factor.disable', 'a@b.c'); // Simulate the full lifecycle: modal confirmed it, handler burned it. ConfirmToken::confirm($token); ConfirmToken::consume($token, 'twoFactorDisabled'); Livewire::test(ConfirmAction::class, ['token' => $token]) ->call('confirm') ->assertDispatched('notify', message: __('modals.confirm_action.rejected')) ->assertNotDispatched('twoFactorDisabled'); $this->assertSame(0, AuditEvent::count()); } public function test_the_routing_token_is_locked_against_client_tampering(): void { $this->login(); $token = ConfirmToken::issue('twoFactorDisabled'); $this->expectException(CannotUpdateLockedPropertyException::class); Livewire::test(ConfirmAction::class, ['token' => $token]) ->set('token', ConfirmToken::issue('userRemoved', ['userId' => 1])); } public function test_the_display_target_comes_from_the_signed_token(): void { $this->login(); $token = ConfirmToken::issue('keyRemoved', [], 'ssh_key.remove', 'webserver · deploy@host', 7); Livewire::test(ConfirmAction::class, ['token' => $token]) ->assertSee('webserver · deploy@host'); } }