Completed
Push — master ( 13ea80...f68543 )
by Matthew Weier
02:13
created

testCanHandleConfiguredRouteMatch()   B

Complexity

Conditions 2
Paths 2

Size

Total Lines 38
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 38
rs 8.8571
cc 2
eloc 27
nc 2
nop 0
1
<?php
2
/*
3
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
4
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
5
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
6
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
7
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
8
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
9
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
10
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
11
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
13
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14
 *
15
 * This software consists of voluntary contributions made by many individuals
16
 * and is licensed under the MIT license.
17
 */
18
19
namespace ZfrCorsTest\Service;
20
21
use PHPUnit_Framework_TestCase as TestCase;
22
use Zend\Http\Response as HttpResponse;
23
use Zend\Http\Request as HttpRequest;
24
use Zend\Mvc\MvcEvent;
25
use Zend\Mvc\Router\Http\RouteMatch as DeprecatedRouteMatch;
26
use Zend\Router\Http\RouteMatch;
27
use ZfrCors\Options\CorsOptions;
28
use ZfrCors\Service\CorsService;
29
30
/**
31
 * Integration tests for {@see \ZfrCors\Service\CorsService}
32
 *
33
 * @author Florent Blaison <[email protected]>
34
 *
35
 * @covers \ZfrCors\Service\CorsService
36
 * @group Coverage
37
 */
38
class CorsServiceTest extends TestCase
39
{
40
    /**
41
     * @var CorsService
42
     */
43
    protected $corsService;
44
45
    /**
46
     * @var HttpResponse
47
     */
48
    protected $response;
49
50
    /**
51
     * @var HttpRequest
52
     */
53
    protected $request;
54
55
    /**
56
     * @var MvcEvent
57
     */
58
    protected $event;
59
60
    /**
61
     * @var CorsOptions
62
     */
63
    protected $corsOptions;
64
65
    /**
66
     * Set up
67
     */
68
    public function setUp()
69
    {
70
        parent::setUp();
71
72
        $this->corsOptions = new CorsOptions(
73
            [
74
                'allowed_origins'     => ['http://example.com'],
75
                'allowed_methods'     => ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
76
                'allowed_headers'     => ['Content-Type', 'Accept'],
77
                'exposed_headers'     => ['Location'],
78
                'max_age'             => 10,
79
                'allowed_credentials' => true,
80
            ]
81
        );
82
83
        $this->corsService = new CorsService($this->corsOptions);
84
    }
85
86
    public function testCanDetectCorsRequest()
87
    {
88
        $request = new HttpRequest();
89
90
        $this->assertFalse($this->corsService->isCorsRequest($request));
91
92
        $request->getHeaders()->addHeaderLine('Origin', 'http://example.com');
93
        $this->assertEquals(true, $this->corsService->isCorsRequest($request));
94
    }
95
96
    public function testIsNotCorsRequestIfNotACrossRequest()
97
    {
98
        $request = new HttpRequest();
99
        $request->setUri('http://example.com');
100
101
        $request->getHeaders()->addHeaderLine('Origin', 'http://example.com');
102
        $this->assertEquals(false, $this->corsService->isCorsRequest($request));
103
    }
104
105
    public function testCanDetectPreflightRequest()
106
    {
107
        $request = new HttpRequest();
108
109
        $this->assertFalse($this->corsService->isPreflightRequest($request));
110
111
        $request->setMethod('OPTIONS');
112
        $this->assertFalse($this->corsService->isPreflightRequest($request));
113
114
        $request->getHeaders()->addHeaderLine('Origin', 'http://example.com');
115
        $this->assertFalse($this->corsService->isPreflightRequest($request));
116
117
        $request->getHeaders()->addHeaderLine('Access-Control-Request-Method', 'POST');
118
        $this->assertTrue($this->corsService->isPreflightRequest($request));
119
    }
120
121
    public function testProperlyCreatePreflightResponse()
122
    {
123
        $request  = new HttpRequest();
124
        $request->getHeaders()->addHeaderLine('Origin', 'http://example.com');
125
126
        $response = $this->corsService->createPreflightCorsResponse($request);
127
128
        $headers = $response->getHeaders();
129
130
        $this->assertEquals(200, $response->getStatusCode());
131
        $this->assertEquals('', $response->getContent());
132
        $this->assertEquals('http://example.com', $headers->get('Access-Control-Allow-Origin')->getFieldValue());
0 ignored issues
show
Bug introduced by
The method getFieldValue does only exist in Zend\Http\Header\HeaderInterface, but not in ArrayIterator.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
133
        $this->assertEquals(
134
            'GET, POST, PUT, DELETE, OPTIONS',
135
            $headers->get('Access-Control-Allow-Methods')->getFieldValue()
136
        );
137
        $this->assertEquals('Content-Type, Accept', $headers->get('Access-Control-Allow-Headers')->getFieldValue());
138
        $this->assertEquals(10, $headers->get('Access-Control-Max-Age')->getFieldValue());
139
        $this->assertEquals(0, $headers->get('Content-Length')->getFieldValue());
140
141
        $this->assertEquals('true', $headers->get('Access-Control-Allow-Credentials')->getFieldValue());
142
    }
143
144
    public function testDoesNotAddAllowCredentialsHeadersIfAsked()
145
    {
146
        $request  = new HttpRequest();
147
        $request->getHeaders()->addHeaderLine('Origin', 'http://example.com');
148
        $this->corsOptions->setAllowedCredentials(false);
149
150
        $response = $this->corsService->createPreflightCorsResponse($request);
151
152
        $headers = $response->getHeaders();
153
        $this->assertFalse($headers->has('Access-Control-Allow-Credentials'));
154
    }
155
156
    public function testCanReturnWildCardAllowOrigin()
157
    {
158
        $request  = new HttpRequest();
159
        $request->getHeaders()->addHeaderLine('Origin', 'http://funny-origin.com');
160
        $this->corsOptions->setAllowedOrigins(['*']);
161
162
        $response = $this->corsService->createPreflightCorsResponse($request);
163
164
        $headers = $response->getHeaders();
165
        $this->assertEquals('http://funny-origin.com', $headers->get('Access-Control-Allow-Origin')->getFieldValue());
0 ignored issues
show
Bug introduced by
The method getFieldValue does only exist in Zend\Http\Header\HeaderInterface, but not in ArrayIterator.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
166
    }
167
168
    public function testCanReturnWildCardSubDomainAllowOrigin()
169
    {
170
        $request  = new HttpRequest();
171
        $request->getHeaders()->addHeaderLine('Origin', 'http://subdomain.example.com');
172
        $this->corsOptions->setAllowedOrigins(['*.example.com']);
173
174
        $response = $this->corsService->createPreflightCorsResponse($request);
175
176
        $headers = $response->getHeaders();
177
        $headerValue = $headers->get('Access-Control-Allow-Origin')->getFieldValue();
0 ignored issues
show
Bug introduced by
The method getFieldValue does only exist in Zend\Http\Header\HeaderInterface, but not in ArrayIterator.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
178
        $this->assertEquals('http://subdomain.example.com', $headerValue);
179
    }
180
181
    public function testCanReturnWildCardSubDomainWithSchemeAllowOrigin()
182
    {
183
        $request  = new HttpRequest();
184
        $request->getHeaders()->addHeaderLine('Origin', 'https://subdomain.example.com');
185
        $this->corsOptions->setAllowedOrigins(['https://*.example.com']);
186
187
        $response = $this->corsService->createPreflightCorsResponse($request);
188
189
        $headers = $response->getHeaders();
190
        $headerValue = $headers->get('Access-Control-Allow-Origin')->getFieldValue();
0 ignored issues
show
Bug introduced by
The method getFieldValue does only exist in Zend\Http\Header\HeaderInterface, but not in ArrayIterator.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
191
        $this->assertEquals('https://subdomain.example.com', $headerValue);
192
    }
193
194
    public function testReturnNullForMissMatchedWildcardSubDomainOrigin()
195
    {
196
        $request  = new HttpRequest();
197
        $request->getHeaders()->addHeaderLine('Origin', 'http://subdomain.example.org');
198
        $this->corsOptions->setAllowedOrigins(['*.example.com']);
199
200
        $response = $this->corsService->createPreflightCorsResponse($request);
201
202
        $headers = $response->getHeaders();
203
        $this->assertEquals('null', $headers->get('Access-Control-Allow-Origin')->getFieldValue());
0 ignored issues
show
Bug introduced by
The method getFieldValue does only exist in Zend\Http\Header\HeaderInterface, but not in ArrayIterator.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
204
    }
205
206
    public function testReturnNullForRootDomainOnWildcardSubDomainOrigin()
207
    {
208
        $request  = new HttpRequest();
209
        $request->getHeaders()->addHeaderLine('Origin', 'http://example.com');
210
        $this->corsOptions->setAllowedOrigins(['*.example.com']);
211
212
        $response = $this->corsService->createPreflightCorsResponse($request);
213
214
        $headers = $response->getHeaders();
215
        $this->assertEquals('null', $headers->get('Access-Control-Allow-Origin')->getFieldValue());
0 ignored issues
show
Bug introduced by
The method getFieldValue does only exist in Zend\Http\Header\HeaderInterface, but not in ArrayIterator.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
216
    }
217
218
    public function testReturnNullForDifferentSchemeOnWildcardSubDomainOrigin()
219
    {
220
        $request  = new HttpRequest();
221
        $request->getHeaders()->addHeaderLine('Origin', 'https://example.com');
222
        $this->corsOptions->setAllowedOrigins(['http://*.example.com']);
223
224
        $response = $this->corsService->createPreflightCorsResponse($request);
225
226
        $headers = $response->getHeaders();
227
        $this->assertEquals('null', $headers->get('Access-Control-Allow-Origin')->getFieldValue());
0 ignored issues
show
Bug introduced by
The method getFieldValue does only exist in Zend\Http\Header\HeaderInterface, but not in ArrayIterator.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
228
    }
229
230
    public function testReturnNullForUnknownOrigin()
231
    {
232
        $request  = new HttpRequest();
233
        $request->getHeaders()->addHeaderLine('Origin', 'http://unauthorized-origin.com');
234
235
        $response = $this->corsService->createPreflightCorsResponse($request);
236
237
        $headers = $response->getHeaders();
238
        $this->assertEquals('null', $headers->get('Access-Control-Allow-Origin')->getFieldValue());
0 ignored issues
show
Bug introduced by
The method getFieldValue does only exist in Zend\Http\Header\HeaderInterface, but not in ArrayIterator.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
239
    }
240
241
    public function testEnsureVaryHeaderForNoOrigin()
242
    {
243
        $response = new HttpResponse();
244
245
        $this->corsService->ensureVaryHeader($response);
246
247
        $headers = $response->getHeaders();
248
249
        $this->assertEquals(false, $headers->get('Origin'));
250
        $this->assertNotEquals(false, $headers->get('Vary'));
251
    }
252
253
    public function testCanPopulateNormalCorsRequest()
254
    {
255
        $request  = new HttpRequest();
256
        $response = new HttpResponse();
257
258
        $request->getHeaders()->addHeaderLine('Origin', 'http://example.com');
259
260
        $this->corsService->populateCorsResponse($request, $response);
261
262
        $headers = $response->getHeaders();
263
264
        $this->assertEquals('http://example.com', $headers->get('Access-Control-Allow-Origin')->getFieldValue());
0 ignored issues
show
Bug introduced by
The method getFieldValue does only exist in Zend\Http\Header\HeaderInterface, but not in ArrayIterator.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
265
        $this->assertEquals('Location', $headers->get('Access-Control-Expose-Headers')->getFieldValue());
266
    }
267
268
    public function testRefuseNormalCorsRequestIfUnauthorized()
269
    {
270
        $request  = new HttpRequest();
271
        $response = new HttpResponse();
272
273
        $request->getHeaders()->addHeaderLine('Origin', 'http://unauthorized.com');
274
275
        $this->setExpectedException(
0 ignored issues
show
Deprecated Code introduced by
The method PHPUnit_Framework_TestCase::setExpectedException() has been deprecated with message: Method deprecated since Release 5.2.0; use expectException() instead

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
276
            'ZfrCors\Exception\DisallowedOriginException',
277
            'The origin "http://unauthorized.com" is not authorized'
278
        );
279
280
        $this->corsService->populateCorsResponse($request, $response);
281
    }
282
283
    public function testAddVaryHeaderInNormalRequest()
284
    {
285
        $request  = new HttpRequest();
286
        $response = new HttpResponse();
287
288
        $request->getHeaders()->addHeaderLine('Origin', 'http://example.com');
289
290
        $this->corsService->populateCorsResponse($request, $response);
291
292
        $headers = $response->getHeaders();
293
        $this->assertTrue($headers->has('Vary'));
294
    }
295
296
    public function testAppendVaryHeaderInNormalRequest()
297
    {
298
        $request  = new HttpRequest();
299
        $response = new HttpResponse();
300
301
        $request->getHeaders()->addHeaderLine('Origin', 'http://example.com');
302
        $response->getHeaders()->addHeaderLine('Vary', 'Foo');
303
304
        $this->corsService->populateCorsResponse($request, $response);
305
306
        $headers = $response->getHeaders();
307
        $this->assertTrue($headers->has('Vary'));
308
        $this->assertEquals('Foo, Origin', $headers->get('Vary')->getFieldValue());
0 ignored issues
show
Bug introduced by
The method getFieldValue does only exist in Zend\Http\Header\HeaderInterface, but not in ArrayIterator.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
309
    }
310
311
    public function testPopulatesAllowCredentialsNormalCorsRequest()
312
    {
313
        $request  = new HttpRequest();
314
        $response = new HttpResponse();
315
316
        $request->getHeaders()->addHeaderLine('Origin', 'http://example.com');
317
318
        $this->corsService->populateCorsResponse($request, $response);
319
320
        $headers = $response->getHeaders();
321
322
        $this->assertEquals('true', $headers->get('Access-Control-Allow-Credentials')->getFieldValue());
0 ignored issues
show
Bug introduced by
The method getFieldValue does only exist in Zend\Http\Header\HeaderInterface, but not in ArrayIterator.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
323
    }
324
325
    public function testCanDetectCorsRequestFromSameHostButDifferentPort()
326
    {
327
        $request = new HttpRequest();
328
        $request->setUri('http://example.com');
329
        $request->getHeaders()->addHeaderLine('Origin', 'http://example.com:9000');
330
        $this->assertTrue($this->corsService->isCorsRequest($request));
331
    }
332
333
    public function testCanDetectCorsRequestFromSameHostButDifferentScheme()
334
    {
335
        $request = new HttpRequest();
336
        $request->setUri('https://example.com');
337
        $request->getHeaders()->addHeaderLine('Origin', 'http://example.com');
338
        $this->assertTrue($this->corsService->isCorsRequest($request));
339
    }
340
341
    public function testCanHandleUnconfiguredRouteMatch()
342
    {
343
        $routeMatch = class_exists(DeprecatedRouteMatch::class) ? new DeprecatedRouteMatch([]) : new RouteMatch([]);
344
345
        $request = new HttpRequest();
346
        $request->getHeaders()->addHeaderLine('Origin', 'http://example.com');
347
        $response = $this->corsService->createPreflightCorsResponseWithRouteOptions($request, $routeMatch);
348
349
        $headers = $response->getHeaders();
350
351
        $this->assertEquals(200, $response->getStatusCode());
352
        $this->assertEquals('', $response->getContent());
353
        $this->assertEquals('http://example.com', $headers->get('Access-Control-Allow-Origin')->getFieldValue());
0 ignored issues
show
Bug introduced by
The method getFieldValue does only exist in Zend\Http\Header\HeaderInterface, but not in ArrayIterator.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
354
        $this->assertEquals(
355
            'GET, POST, PUT, DELETE, OPTIONS',
356
            $headers->get('Access-Control-Allow-Methods')->getFieldValue()
357
        );
358
        $this->assertEquals('Content-Type, Accept', $headers->get('Access-Control-Allow-Headers')->getFieldValue());
359
        $this->assertEquals(10, $headers->get('Access-Control-Max-Age')->getFieldValue());
360
        $this->assertEquals(0, $headers->get('Content-Length')->getFieldValue());
361
362
        $this->assertEquals('true', $headers->get('Access-Control-Allow-Credentials')->getFieldValue());
363
    }
364
365
    public function testCanHandleConfiguredRouteMatch()
366
    {
367
368
        $routeMatchParameters = [
369
            CorsOptions::ROUTE_PARAM => [
370
                'allowed_origins'     => ['http://example.org'],
371
                'allowed_methods'     => ['POST', 'DELETE', 'OPTIONS'],
372
                'allowed_headers'     => ['Content-Type', 'Accept', 'Cookie'],
373
                'exposed_headers'     => ['Location'],
374
                'max_age'             => 5,
375
                'allowed_credentials' => false,
376
            ],
377
        ];
378
379
        $routeMatch = class_exists(DeprecatedRouteMatch::class) ? new DeprecatedRouteMatch($routeMatchParameters) :
380
            new RouteMatch($routeMatchParameters);
381
382
        $request = new HttpRequest();
383
        $request->getHeaders()->addHeaderLine('Origin', 'http://example.org');
384
        $response = $this->corsService->createPreflightCorsResponseWithRouteOptions($request, $routeMatch);
385
386
        $headers = $response->getHeaders();
387
        $this->assertEquals(200, $response->getStatusCode());
388
        $this->assertEquals('', $response->getContent());
389
        $this->assertEquals('http://example.org', $headers->get('Access-Control-Allow-Origin')->getFieldValue());
0 ignored issues
show
Bug introduced by
The method getFieldValue does only exist in Zend\Http\Header\HeaderInterface, but not in ArrayIterator.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
390
        $this->assertEquals(
391
            'POST, DELETE, OPTIONS',
392
            $headers->get('Access-Control-Allow-Methods')->getFieldValue()
393
        );
394
        $this->assertEquals(
395
            'Content-Type, Accept, Cookie',
396
            $headers->get('Access-Control-Allow-Headers')->getFieldValue()
397
        );
398
        $this->assertEquals(5, $headers->get('Access-Control-Max-Age')->getFieldValue());
399
        $this->assertEquals(0, $headers->get('Content-Length')->getFieldValue());
400
401
        $this->assertFalse($headers->has('Access-Control-Allow-Credentials'));
402
    }
403
404
    /**
405
     * @see https://github.com/zf-fr/zfr-cors/issues/44
406
     * @expectedException \ZfrCors\Exception\InvalidOriginException
407
     */
408
    public function testDoesNotCrashApplicationOnInvalidOriginValue()
409
    {
410
        $request = new HttpRequest();
411
        $request->setUri('https://example.com');
412
        $request->getHeaders()->addHeaderLine('Origin', 'file:');
413
        $this->corsService->isCorsRequest($request);
414
    }
415
}
416