diff --git a/system/HTTP/Negotiate.php b/system/HTTP/Negotiate.php index 7af05b35b701..1a0aa7be7e6b 100644 --- a/system/HTTP/Negotiate.php +++ b/system/HTTP/Negotiate.php @@ -1,4 +1,6 @@ -parseHeader($header); - // If no acceptable values exist, return the - // first that we support. - if (count($acceptable) === 0) - { - return $supported[0]; - } - foreach ($acceptable as $accept) { // if acceptable quality is zero, skip it. @@ -290,8 +284,8 @@ public function parseHeader(string $header) } $results[] = [ - 'value' => trim($value), - 'q' => (float) $quality, + 'value' => trim($value), + 'q' => (float) $quality, 'params' => $parameters ]; } diff --git a/system/HTTP/RedirectResponse.php b/system/HTTP/RedirectResponse.php index e4136ed89ec9..02a3ef8f9caa 100644 --- a/system/HTTP/RedirectResponse.php +++ b/system/HTTP/RedirectResponse.php @@ -190,10 +190,13 @@ protected function ensureSession() $session = Services::session(); // Ensure we have the session started up. + // true for travis-ci, so not coverable + // @codeCoverageIgnoreStart if ( ! isset($_SESSION)) { $session->start(); } + // @codeCoverageIgnoreEnd return $session; } diff --git a/tests/system/HTTP/NegotiateTest.php b/tests/system/HTTP/NegotiateTest.php index 4dbeefc39c14..dffc6b32e0cc 100644 --- a/tests/system/HTTP/NegotiateTest.php +++ b/tests/system/HTTP/NegotiateTest.php @@ -146,28 +146,44 @@ public function testBestMatchEmpty() public function testBestMatchNoHeader() { - $this->request->setHeader('Accept',''); + $this->request->setHeader('Accept', ''); $this->assertEquals('', $this->negotiate->media(['apple', 'banana'], true)); $this->assertEquals('apple/mac', $this->negotiate->media(['apple/mac', 'banana/yellow'], false)); } public function testBestMatchNotAcceptable() { - $this->request->setHeader('Accept','popcorn/cheddar'); - $this->assertEquals('apple/mac', $this->negotiate->media(['apple/mac', 'banana/yellow'],false)); + $this->request->setHeader('Accept', 'popcorn/cheddar'); + $this->assertEquals('apple/mac', $this->negotiate->media(['apple/mac', 'banana/yellow'], false)); + $this->assertEquals('banana/yellow', $this->negotiate->media(['banana/yellow', 'apple/mac'], false)); } public function testBestMatchFirstSupported() { - $this->request->setHeader('Accept','popcorn/cheddar, */*'); - $this->assertEquals('apple/mac', $this->negotiate->media(['apple/mac', 'banana/yellow'],false)); + $this->request->setHeader('Accept', 'popcorn/cheddar, */*'); + $this->assertEquals('apple/mac', $this->negotiate->media(['apple/mac', 'banana/yellow'], false)); } public function testBestMatchLowQuality() { - $this->request->setHeader('Accept','popcorn/cheddar;q=0, apple/mac, */*'); - $this->assertEquals('apple/mac', $this->negotiate->media(['apple/mac', 'popcorn/cheddar'],false)); - $this->assertEquals('apple/mac', $this->negotiate->media(['popcorn/cheddar','apple/mac'],false)); + $this->request->setHeader('Accept', 'popcorn/cheddar;q=0, apple/mac, */*'); + $this->assertEquals('apple/mac', $this->negotiate->media(['apple/mac', 'popcorn/cheddar'], false)); + $this->assertEquals('apple/mac', $this->negotiate->media(['popcorn/cheddar', 'apple/mac'], false)); + } + + public function testBestMatchOnlyLowQuality() + { + $this->request->setHeader('Accept', 'popcorn/cheddar;q=0'); + // the first supported should be returned, since nothing will make us happy + $this->assertEquals('apple/mac', $this->negotiate->media(['apple/mac', 'popcorn/cheddar'], false)); + $this->assertEquals('popcorn/cheddar', $this->negotiate->media(['popcorn/cheddar', 'apple/mac'], false)); + } + + public function testParameterMatching() + { + $this->request->setHeader('Accept', 'popcorn/cheddar;a=0;b=1'); + $this->assertEquals('popcorn/cheddar;a=2', $this->negotiate->media(['popcorn/cheddar;a=2'], false)); + $this->assertEquals('popcorn/cheddar;a=0', $this->negotiate->media(['popcorn/cheddar;a=0', 'popcorn/cheddar;a=2;b=1'], false)); } } diff --git a/tests/system/HTTP/RedirectResponseTest.php b/tests/system/HTTP/RedirectResponseTest.php index d292aad6057e..fece957954a1 100644 --- a/tests/system/HTTP/RedirectResponseTest.php +++ b/tests/system/HTTP/RedirectResponseTest.php @@ -1,4 +1,6 @@ -routes->add( 'exampleRoute', 'Home::index' ); + $this->routes->add('exampleRoute', 'Home::index'); - $response->route( 'exampleRoute' ); + $response->route('exampleRoute'); $this->assertTrue($response->hasHeader('Location')); $this->assertEquals('http://example.com/exampleRoute', $response->getHeaderLine('Location')); } + public function testRedirectRouteBad() + { + $this->expectException(Exceptions\HTTPException::class); + + $response = new RedirectResponse(new App()); + + $this->routes->add('exampleRoute', 'Home::index'); + + $response->route('differentRoute'); + } + public function testRedirectRelativeConvertsToFullURI() { $response = new RedirectResponse($this->config); @@ -97,7 +109,7 @@ public function testWithValidationErrors() $validation = $this->createMock(Validation::class); $validation->method('getErrors') - ->willReturn(['foo' =>'bar']); + ->willReturn(['foo' => 'bar']); Services::injectMock('validation', $validation); @@ -154,4 +166,36 @@ public function testRedirectWithQueryOnly() $this->assertTrue($response->hasHeader('Location')); $this->assertEquals('http://example.com/foo?foo=bar', $response->getHeaderLine('Location')); } + + /** + * @runInSeparateProcess + * @preserveGlobalState disabled + */ + public function testRedirectBack() + { + $_SERVER['HTTP_REFERER'] = 'http://somewhere.com'; + $this->request = new MockIncomingRequest($this->config, new URI('http://somewhere.com'), null, new UserAgent()); + Services::injectMock('request', $this->request); + + $response = new RedirectResponse(new App()); + + $returned = $response->back(); + $this->assertEquals('http://somewhere.com', $returned->getHeader('location')->getValue()); + } + + /** + * @runInSeparateProcess + * @preserveGlobalState disabled + */ + public function testRedirectBackMissing() + { + $_SESSION = []; + + $response = new RedirectResponse(new App()); + + $returned = $response->back(); + + $this->assertSame($response, $returned); + } + }