Completed
Push — master ( 2a724b...f106a8 )
by Alexander
12:30 queued 10:35
created

CsrfTest::validTokenInBodyPutRequestResultIn200()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 4
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 6
rs 10
1
<?php
2
3
4
namespace Yiisoft\Yii\Web\Tests\Middleware;
5
6
use Nyholm\Psr7\Factory\Psr17Factory;
7
use Nyholm\Psr7\Response;
8
use Nyholm\Psr7\ServerRequest;
9
use PHPUnit\Framework\MockObject\MockObject;
10
use PHPUnit\Framework\TestCase;
11
use Psr\Http\Message\ResponseInterface;
12
use Psr\Http\Message\ServerRequestInterface;
13
use Psr\Http\Server\RequestHandlerInterface;
14
use Yiisoft\Router\Method;
15
use Yiisoft\Security\Random;
16
use Yiisoft\Security\TokenMasker;
17
use Yiisoft\Yii\Web\Middleware\Csrf;
18
use Yiisoft\Yii\Web\Session\SessionInterface;
19
20
final class CsrfTest extends TestCase
21
{
22
    private const PARAM_NAME = 'csrf';
23
24
    /**
25
     * @test
26
     */
27
    public function validTokenInBodyPostRequestResultIn200()
28
    {
29
        $token = $this->generateToken();
30
        $middleware = $this->createCsrfMiddlewareWithToken($token);
31
        $response = $middleware->process($this->createPostServerRequestWithBodyToken($token), $this->createRequestHandler());
32
        $this->assertEquals(200, $response->getStatusCode());
33
    }
34
35
    /**
36
     * @test
37
     */
38
    public function validTokenInBodyPutRequestResultIn200()
39
    {
40
        $token = $this->generateToken();
41
        $middleware = $this->createCsrfMiddlewareWithToken($token);
42
        $response = $middleware->process($this->createPutServerRequestWithBodyToken($token), $this->createRequestHandler());
43
        $this->assertEquals(200, $response->getStatusCode());
44
    }
45
46
    /**
47
     * @test
48
     */
49
    public function validTokenInBodyDeleteRequestResultIn200()
50
    {
51
        $token = $this->generateToken();
52
        $middleware = $this->createCsrfMiddlewareWithToken($token);
53
        $response = $middleware->process($this->createDeleteServerRequestWithBodyToken($token), $this->createRequestHandler());
54
        $this->assertEquals(200, $response->getStatusCode());
55
    }
56
57
    /**
58
     * @test
59
     */
60
    public function validTokenInHeaderResultIn200()
61
    {
62
        $token = $this->generateToken();
63
        $middleware = $this->createCsrfMiddlewareWithToken($token);
64
        $response = $middleware->process($this->createPostServerRequestWithHeaderToken($token), $this->createRequestHandler());
65
        $this->assertEquals(200, $response->getStatusCode());
66
    }
67
68
    /**
69
     * @test
70
     */
71
    public function getIsAlwaysAllowed()
72
    {
73
        $middleware = $this->createCsrfMiddlewareWithToken('');
74
        $response = $middleware->process($this->createServerRequest(Method::GET), $this->createRequestHandler());
75
        $this->assertEquals(200, $response->getStatusCode());
76
    }
77
78
    /**
79
     * @test
80
     */
81
    public function invalidTokenResultIn400()
82
    {
83
        $middleware = $this->createCsrfMiddlewareWithToken($this->generateToken());
84
        $response = $middleware->process($this->createPostServerRequestWithBodyToken($this->generateToken()), $this->createRequestHandler());
85
        $this->assertEquals(400, $response->getStatusCode());
86
    }
87
88
    /**
89
     * @test
90
     */
91
    public function emptyTokenInSessionResultIn400()
92
    {
93
        $middleware = $this->createCsrfMiddlewareWithToken('');
94
        $response = $middleware->process($this->createPostServerRequestWithBodyToken($this->generateToken()), $this->createRequestHandler());
95
        $this->assertEquals(400, $response->getStatusCode());
96
    }
97
98
    /**
99
     * @test
100
     */
101
    public function emptyTokenInRequestResultIn400()
102
    {
103
        $middleware = $this->createCsrfMiddlewareWithToken($this->generateToken());
104
        $response = $middleware->process($this->createServerRequest(), $this->createRequestHandler());
105
        $this->assertEquals(400, $response->getStatusCode());
106
    }
107
108
    private function createServerRequest(string $method = Method::POST, array $bodyParams = [], array $headParams = []): ServerRequestInterface
109
    {
110
        $request = new ServerRequest($method, '/', $headParams);
111
        return $request->withParsedBody($bodyParams);
112
    }
113
114
    private function createPostServerRequestWithBodyToken(string $token): ServerRequestInterface
115
    {
116
        return $this->createServerRequest(Method::POST, $this->getBodyRequestParamsByToken($token));
117
    }
118
119
    private function createPutServerRequestWithBodyToken(string $token): ServerRequestInterface
120
    {
121
        return $this->createServerRequest(Method::PUT, $this->getBodyRequestParamsByToken($token));
122
    }
123
124
    private function createDeleteServerRequestWithBodyToken(string $token): ServerRequestInterface
125
    {
126
        return $this->createServerRequest(Method::DELETE, $this->getBodyRequestParamsByToken($token));
127
    }
128
129
    private function createPostServerRequestWithHeaderToken(string $token): ServerRequestInterface
130
    {
131
        return $this->createServerRequest(Method::POST, [], [
132
            Csrf::HEADER_NAME => TokenMasker::mask($token),
133
        ]);
134
    }
135
136
    private function createRequestHandler(): RequestHandlerInterface
137
    {
138
        return new class implements RequestHandlerInterface {
139
            public function handle(ServerRequestInterface $request): ResponseInterface
140
            {
141
                return new Response(200);
142
            }
143
        };
144
    }
145
146
    private function createSessionMock(string $returnToken)
147
    {
148
        /**
149
         * @var SessionInterface|MockObject $sessionMock
150
         */
151
        $sessionMock = $this->createMock(SessionInterface::class);
152
153
        $sessionMock
154
            ->expects($this->once())
155
            ->method('get')
156
            ->willReturn($returnToken);
157
158
        return $sessionMock;
159
    }
160
161
    private function createCsrfMiddlewareWithToken(string $token): Csrf
162
    {
163
        $middleware = new Csrf(new Psr17Factory(), $this->createSessionMock($token));
164
        $middleware->setName(self::PARAM_NAME);
165
166
        return $middleware;
167
    }
168
169
    private function generateToken(): string
170
    {
171
        return Random::string();
172
    }
173
174
    private function getBodyRequestParamsByToken(string $token): array
175
    {
176
        return [
177
            self::PARAM_NAME => TokenMasker::mask($token),
178
        ];
179
    }
180
}
181