Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
49 / 49
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
10pest()->group('unit');
11
12use AppDemo\Shared\Application\Middleware\RbacPermissionMiddleware;
13use AppDemo\Shared\Domain\UserContext;
14use AppDemo\User\Domain\UserGroup;
15use Nyholm\Psr7\Factory\Psr17Factory;
16use Nyholm\Psr7\Response;
17use Nyholm\Psr7\ServerRequest;
18use Tests\AppDemo\Fake\Application\Service\RbacPermissionService as FakeRbacPermissionService;
19use Tests\AppDemo\Fixture\UserMother;
20use Tests\Phexium\Fake\Plugin\Http\RequestHandler as FakeRequestHandler;
21
22const REQUIRED_PERMISSION = 'some-permission';
23
24beforeEach(function (): void {
25    $this->rbacPermissionService = new FakeRbacPermissionService();
26    $this->responseFactory = new Psr17Factory();
27
28    $this->middleware = new RbacPermissionMiddleware(
29        $this->responseFactory,
30        REQUIRED_PERMISSION
31    );
32});
33
34describe('Authorized access', function (): void {
35    it('proceeds to next handler when user has permission', function (): void {
36        $user = UserMother::user();
37        $userContext = new UserContext($user, $this->rbacPermissionService);
38        $expectedResponse = new Response(200);
39
40        $this->rbacPermissionService->addPermission(UserGroup::User, REQUIRED_PERMISSION);
41
42        $request = new ServerRequest('GET', '/');
43        $request = $request->withAttribute('user_context', $userContext);
44        $handler = new FakeRequestHandler($expectedResponse);
45
46        $response = $this->middleware->process($request, $handler);
47
48        expect($response)->toBe($expectedResponse)
49            ->and($handler->getHandleCallCount())->toBe(1)
50        ;
51    });
52});
53
54describe('Unauthorized access', function (): void {
55    it('returns 403 when user does not have permission', function (): void {
56        $user = UserMother::user();
57        $userContext = new UserContext($user, $this->rbacPermissionService);
58
59        $request = new ServerRequest('GET', '/');
60        $request = $request->withAttribute('user_context', $userContext);
61        $handler = new FakeRequestHandler(new Response(200));
62
63        $response = $this->middleware->process($request, $handler);
64
65        expect($response->getStatusCode())->toBe(RbacPermissionMiddleware::STATUS_FORBIDDEN)
66            ->and((string) $response->getBody())->toBe('Permission denied.')
67            ->and($handler->getHandleCallCount())->toBe(0)
68        ;
69    });
70
71    it('returns 403 when user is not authenticated', function (): void {
72        $userContext = new UserContext(null, $this->rbacPermissionService);
73
74        $request = new ServerRequest('GET', '/');
75        $request = $request->withAttribute('user_context', $userContext);
76        $handler = new FakeRequestHandler(new Response(200));
77
78        $response = $this->middleware->process($request, $handler);
79
80        expect($response->getStatusCode())->toBe(RbacPermissionMiddleware::STATUS_FORBIDDEN)
81            ->and((string) $response->getBody())->toBe('Authentication required.')
82            ->and($handler->getHandleCallCount())->toBe(0)
83        ;
84    });
85});