$ability, 'context' => $context]); } }; $service = new AuthorizationService([$policy]); $decision = $service->authorize('users.test', ['actor_user_id' => 12]); $this->assertTrue($decision->isAllowed()); $this->assertSame('users.test', $decision->attribute('ability')); $this->assertSame(['actor_user_id' => 12], $decision->attribute('context')); } public function testReturnsMissingPolicyDecisionWhenAbilityIsUnknown(): void { $policy = new class () implements AuthorizationPolicyInterface { public function supports(string $ability): bool { return false; } public function authorize(string $ability, array $context = []): AuthorizationDecision { return AuthorizationDecision::allow(); } }; $service = new AuthorizationService([$policy]); $decision = $service->authorize('unknown.ability'); $this->assertFalse($decision->isAllowed()); $this->assertSame(500, $decision->status()); $this->assertSame('authorization_policy_missing', $decision->error()); } public function testAllowReturnsBoolDecisionShortcut(): void { $policy = new class () implements AuthorizationPolicyInterface { public function supports(string $ability): bool { return $ability === 'users.test'; } public function authorize(string $ability, array $context = []): AuthorizationDecision { return AuthorizationDecision::allow(); } }; $service = new AuthorizationService([$policy]); $this->assertTrue($service->allow('users.test', ['actor_user_id' => 7])); $this->assertFalse($service->allow('users.unknown', ['actor_user_id' => 7])); } }