Completed
Push — master ( 4b008c...2009c1 )
by Sam
22s
created

testDenyOriginIfDoesNotMatchPattern()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 17
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 9
nc 1
nop 0
dl 0
loc 17
rs 9.9666
c 0
b 0
f 0
1
<?php
2
3
namespace Nord\Lumen\Cors\Tests;
4
5
use Closure;
6
use Nord\Lumen\Cors\CorsService;
7
use Symfony\Component\HttpFoundation\Request;
8
use Symfony\Component\HttpFoundation\Response;
9
10
class CorsServiceTest extends \Codeception\Test\Unit
11
{
12
    use \Codeception\Specify;
13
14
    /**
15
     * @var \UnitTester
16
     */
17
    protected $tester;
18
19
    /**
20
     * @var CorsService
21
     */
22
    protected $service;
23
24
    /**
25
     * @var Request
26
     */
27
    protected $request;
28
29
    /**
30
     * @var Response
31
     */
32
    protected $response;
33
34
    /**
35
     * @var Closure
36
     */
37
    protected $closure;
38
39
    public function testServiceConfig()
40
    {
41
        $this->specify('service config max_age is less than zero', function () {
42
            new CorsService(['max_age' => -1]);
43
        }, ['throws' => 'InvalidArgumentException']);
44
    }
45
46
    public function testHandlePreflightRequest()
47
    {
48
        $this->service = new CorsService([
49
            'allow_origins' => ['http://foo.com'],
50
            'allow_methods' => ['post'],
51
            'allow_headers' => ['accept', 'authorization', 'content-type'],
52
        ]);
53
54
        $this->request = new Request;
55
56
        $this->specify('200 response when origin, method and headers are allowed', function () {
57
            $this->request->headers->set('Origin', 'http://foo.com');
58
            $this->request->headers->set('Access-Control-Request-Method', 'POST');
59
            $this->request->headers->set('Access-Control-Request-Headers', 'accept, authorization, content-type');
60
61
            $response = $this->service->handlePreflightRequest($this->request);
62
63
            verify($response->getStatusCode())->equals(200);
64
        });
65
66
        $this->service = new CorsService([
67
            'allow_origins' => ['http://foo.com'],
68
            'allow_methods' => ['post'],
69
            'allow_headers' => ['accept', 'authorization', 'content-type'],
70
        ]);
71
72
        $this->request = new Request;
73
74
        $this->specify('response headers are set', function () {
75
            $this->request->headers->set('Origin', 'http://foo.com');
76
            $this->request->headers->set('Access-Control-Request-Method', 'POST');
77
            $this->request->headers->set('Access-Control-Request-Headers', 'accept, authorization, content-type');
78
79
            $response = $this->service->handlePreflightRequest($this->request);
80
81
            verify($response->headers->get('Access-Control-Allow-Origin'))->equals('http://foo.com');
82
            verify($response->headers->get('Access-Control-Allow-Methods'))->equals('POST');
83
            verify($response->headers->get('Access-Control-Allow-Headers'))->equals('accept, authorization, content-type');
84
            verify($response->headers->has('Access-Control-Allow-Credentials'))->false();
85
            verify($response->headers->has('Access-Control-Max-Age'))->false();
86
        });
87
88
        $this->service = new CorsService([
89
            'allow_origins' => ['http://foo.com'],
90
            'allow_methods' => ['post'],
91
            'allow_headers' => ['accept', 'authorization', 'content-type'],
92
        ]);
93
94
        $this->request = new Request;
95
96
        $this->specify('regression test for issue #31', function () {
97
            $this->request->headers->set('Origin', 'http://foo.com');
98
            $this->request->headers->set('Access-Control-Request-Method', 'POST');
99
            $this->request->headers->set('Access-Control-Request-Headers', 'accept,authorization, content-type');
100
101
            $response = $this->service->handlePreflightRequest($this->request);
102
103
            verify($response->headers->get('Access-Control-Allow-Origin'))->equals('http://foo.com');
104
            verify($response->headers->get('Access-Control-Allow-Methods'))->equals('POST');
105
            verify($response->headers->get('Access-Control-Allow-Headers'))->equals('accept, authorization, content-type');
106
            verify($response->headers->has('Access-Control-Allow-Credentials'))->false();
107
            verify($response->headers->has('Access-Control-Max-Age'))->false();
108
        });
109
110
        $this->service = new CorsService([
111
            'allow_origins'     => ['*'],
112
            'allow_methods'     => ['*'],
113
            'allow_headers'     => ['*'],
114
            'allow_credentials' => true,
115
        ]);
116
117
        $this->request = new Request;
118
119
        $this->specify('response credentials header is set', function () {
120
            $this->request->headers->set('Origin', 'http://foo.com');
121
            $this->request->headers->set('Access-Control-Request-Method', 'POST');
122
            $this->request->headers->set('Access-Control-Request-Headers', 'accept, authorization, content-type');
123
124
            $response = $this->service->handlePreflightRequest($this->request);
125
126
            verify($response->headers->get('Access-Control-Allow-Credentials'))->equals('true');
127
        });
128
129
        $this->service = new CorsService([
130
            'allow_origins' => ['*'],
131
            'allow_methods' => ['*'],
132
            'allow_headers' => ['*'],
133
            'max_age'       => 3600,
134
        ]);
135
136
        $this->request = new Request;
137
138
        $this->specify('response max-age header is set', function () {
139
            $this->request->headers->set('Origin', 'http://foo.com');
140
            $this->request->headers->set('Access-Control-Request-Method', 'POST');
141
            $this->request->headers->set('Access-Control-Request-Headers', 'accept, authorization, content-type');
142
143
            $response = $this->service->handlePreflightRequest($this->request);
144
145
            verify($response->headers->get('Access-Control-Max-Age'))->equals(3600);
146
        });
147
    }
148
149
    public function testHandleRequest()
150
    {
151
        $this->request = new Request;
152
153
        $this->response = new Response;
154
155
        $this->service = new CorsService([
156
            'allow_origins' => ['*'],
157
        ]);
158
159
        $this->specify('response origin header is set', function () {
160
            $this->request->headers->set('Origin', 'http://foo.com');
161
162
            $response = $this->service->handleRequest($this->request, new Response());
163
164
            verify($response->headers->get('Access-Control-Allow-Origin'))->equals('*');
165
        });
166
167
        $this->service = new CorsService([
168
            'allow_origins' => ['*'],
169
        ]);
170
171
        $this->specify('response vary header is not set when all origins are allowed', function () {
172
            $this->request->headers->set('Origin', 'http://foo.com');
173
174
            $response = new Response();
175
            $response->headers->set('Vary', 'Accept-Encoding');
176
            $response = $this->service->handleRequest($this->request, $response);
177
178
            verify($response->headers->get('Vary'))->equals('Accept-Encoding');
179
        });
180
181
        $this->service = new CorsService([
182
            'allow_origins' => ['http://foo.com'],
183
        ]);
184
185
        $this->specify('response vary header is set', function () {
186
            $this->request->headers->set('Origin', 'http://foo.com');
187
            $this->request->headers->set('Vary', 'Accept-Encoding');
188
189
            $response = $this->service->handleRequest($this->request, new Response());
190
191
            verify($response->headers->get('Vary'))->equals('Accept-Encoding, Origin');
192
        });
193
194
        $this->service = new CorsService([
195
            'allow_origins'     => ['*'],
196
            'allow_methods'     => ['*'],
197
            'allow_headers'     => ['*'],
198
            'allow_credentials' => true,
199
        ]);
200
201
        $this->specify('response credentials header is set', function () {
202
            $this->request->headers->set('Origin', 'http://foo.com');
203
204
            $response = $this->service->handleRequest($this->request, new Response());
205
206
            verify($response->headers->get('Access-Control-Allow-Credentials'))->equals('true');
207
        });
208
209
        $this->service = new CorsService([
210
            'allow_origins'  => ['*'],
211
            'allow_methods'  => ['*'],
212
            'allow_headers'  => ['*'],
213
            'expose_headers' => ['Accept', 'Authorization', 'Content-Type'],
214
        ]);
215
216
        $this->specify('response expose headers header is set', function () {
217
            $this->request->headers->set('Origin', 'http://foo.com');
218
219
            $response = $this->service->handleRequest($this->request, new Response());
220
221
            verify($response->headers->get('Access-Control-Expose-Headers'))->equals('accept, authorization, content-type');
222
        });
223
224
        $this->service = new CorsService([
225
            'allow_origins' => ['http://foo.com', 'http://notbar.com'],
226
        ]);
227
228
        $this->specify('response origin header is not set when origin is not allowed', function () {
229
            $this->request->headers->set('Origin', 'http://bar.com');
230
231
            $response = $this->service->handleRequest($this->request, new Response());
232
233
            verify($response->getStatusCode())->equals(200);
234
            verify($response->headers->get('Access-Control-Allow-Origin'))->equals(null);
235
        });
236
    }
237
238
    public function testIsCorsRequest()
239
    {
240
        $this->service = new CorsService;
241
242
        $this->request = new Request;
243
244
        $this->specify('cors request is recognized', function () {
245
            verify($this->service->isCorsRequest($this->request))->false();
246
247
            $this->request->headers->set('Origin', 'http://foo.com');
248
249
            verify($this->service->isCorsRequest($this->request))->true();
250
        });
251
    }
252
253
    public function testIsPreflightRequest()
254
    {
255
        $this->service = new CorsService;
256
257
        $this->request = new Request;
258
259
        $this->specify('preflight request is recognized', function () {
260
            verify($this->service->isPreflightRequest($this->request))->false();
261
262
            $this->request->setMethod('OPTIONS');
263
264
            verify($this->service->isPreflightRequest($this->request))->false();
265
266
            $this->request->headers->set('Access-Control-Request-Method', 'POST');
267
268
            verify($this->service->isPreflightRequest($this->request))->false();
269
270
            $this->request->headers->set('Origin', 'http://foo.com');
271
272
            verify($this->service->isPreflightRequest($this->request))->true();
273
        });
274
    }
275
276
    public function testAllowOriginIfMatchPattern()
277
    {
278
        $this->request = new Request;
279
280
        $this->response = new Response;
281
282
        $this->service = new CorsService([
283
            'allow_origins' => ['http://*.foo.com', 'http://notbar.com'],
284
        ]);
285
286
        $this->specify('response origin header is set when origin is match to a pattern', function () {
287
            $this->request->headers->set('Origin', 'http://bar.foo.com');
288
289
            $response = $this->service->handleRequest($this->request, new Response());
290
291
            verify($response->getStatusCode())->equals(200);
292
            verify($response->headers->get('Access-Control-Allow-Origin'))->equals('http://bar.foo.com');
293
        });
294
    }
295
296
    public function testDenyOriginIfDoesNotMatchPattern()
297
    {
298
        $this->request = new Request;
299
300
        $this->response = new Response;
301
302
        $this->service = new CorsService([
303
            'allow_origins' => ['http://*.foo.com', 'http://notbar.com'],
304
        ]);
305
306
        $this->specify('response origin header is not set when origin is not a match to a pattern', function () {
307
            $this->request->headers->set('Origin', 'http://bar.com');
308
309
            $response = $this->service->handleRequest($this->request, new Response());
310
311
            verify($response->getStatusCode())->equals(200);
312
            verify($response->headers->get('Access-Control-Allow-Origin'))->equals(null);
313
        });
314
    }
315
}
316