Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
92 / 92
n/a
0 / 0
CRAP
n/a
0 / 0
1<?php
2
3// ╔════════════════════════════════════════════════════════════╗
4// ║ MIT Licence (#Expat) - https://opensource.org/licenses/MIT ║
5// ║ Copyright 2026 Frederic Poeydomenge <dyno@phexium.com>     ║
6// ╚════════════════════════════════════════════════════════════╝
7
8declare(strict_types=1);
9
10use Phexium\Plugin\Authorization\Adapter\RbacAuthorizationService;
11use Phexium\Plugin\Authorization\Adapter\StringSubject;
12
13beforeEach(function (): void {
14    $permissionsConfig = [
15        'admin' => [
16            'can.sing',
17            'can.dance',
18            'can.dance', // Duplicated permission to test that get(All)Permissions returns unique values
19            'can.fly',
20        ],
21        'user' => [
22            'can.sing',
23            '', // Empty permission to test that can() returns false for empty strings
24        ],
25        'guest' => [],
26    ];
27
28    $this->service = new RbacAuthorizationService($permissionsConfig);
29
30    $this->adminSubject = StringSubject::fromString('admin');
31    $this->userSubject = StringSubject::fromString('user');
32    $this->guestSubject = StringSubject::fromString('guest');
33    $this->unknownSubject = StringSubject::fromString('unknown');
34});
35
36test('Returns true when subject has the required permission', function (): void {
37    $can = $this->service->can($this->adminSubject, 'can.dance');
38
39    expect($can)->toBeTrue();
40});
41
42test('Returns false when subject does not have the required permission', function (): void {
43    $can = $this->service->can($this->userSubject, 'can.dance');
44
45    expect($can)->toBeFalse();
46});
47
48test('Returns false when checking empty permission string', function (): void {
49    $can = $this->service->can($this->adminSubject, '');
50
51    expect($can)->toBeFalse();
52});
53
54test('Returns false for empty permission even if empty string exists in subject permissions', function (): void {
55    $can = $this->service->can($this->userSubject, '');
56
57    expect($can)->toBeFalse();
58});
59
60test('Returns false when subject identifier is not in configuration', function (): void {
61    $can = $this->service->can($this->unknownSubject, 'can.fly');
62
63    expect($can)->toBeFalse();
64});
65
66test('Permission check is case sensitive', function (): void {
67    $can = $this->service->can($this->adminSubject, 'CAN.FLY');
68
69    expect($can)->toBeFalse();
70});
71
72test('Returns true when subject has at least one of the required permissions', function (): void {
73    $result = $this->service->canAny($this->userSubject, ['can.dance', 'can.sing']);
74
75    expect($result)->toBeTrue();
76});
77
78test('Returns false when subject has none of the required permissions', function (): void {
79    $result = $this->service->canAny($this->userSubject, ['can.dance', 'can.fly']);
80
81    expect($result)->toBeFalse();
82});
83
84test('Returns false when checking empty permissions array with canAny', function (): void {
85    $result = $this->service->canAny($this->adminSubject, []);
86
87    expect($result)->toBeFalse();
88});
89
90test('Returns true when subject has all required permissions', function (): void {
91    $result = $this->service->canAll($this->adminSubject, ['can.dance', 'can.sing', 'can.fly']);
92
93    expect($result)->toBeTrue();
94});
95
96test('Returns false when subject is missing at least one required permission', function (): void {
97    $result = $this->service->canAll($this->userSubject, ['can.dance', 'can.sing']);
98
99    expect($result)->toBeFalse();
100});
101
102test('Returns true when checking empty permissions array with canAll', function (): void {
103    $result = $this->service->canAll($this->adminSubject, []);
104
105    expect($result)->toBeTrue();
106});
107
108test('Returns all permissions for a given subject', function (): void {
109    $permissions = $this->service->getPermissions($this->adminSubject);
110
111    expect($permissions)->toBe(['can.sing', 'can.dance', 'can.fly']);
112});
113
114test('Returns empty array for subject with no permissions', function (): void {
115    $permissions = $this->service->getPermissions($this->guestSubject);
116
117    expect($permissions)->toBeEmpty();
118});
119
120test('Returns empty array for unknown subject', function (): void {
121    $unknownSubject = StringSubject::fromString('unknown');
122
123    $permissions = $this->service->getPermissions($unknownSubject);
124
125    expect($permissions)->toBeEmpty();
126});
127
128test('Returns all unique permissions across all subjects', function (): void {
129    $allPermissions = $this->service->getAllPermissions();
130
131    expect($allPermissions)->toBe(['can.sing', 'can.dance', 'can.fly', '']);
132});
133
134test('Returns all subject identifiers from configuration', function (): void {
135    $subjects = $this->service->getAllSubjects();
136
137    expect($subjects)->toHaveCount(3);
138    expect($subjects)->toContain('admin');
139    expect($subjects)->toContain('user');
140    expect($subjects)->toContain('guest');
141});