diff --git a/core/lib/Drupal/Core/Routing/AcceptHeaderMatcher.php b/core/lib/Drupal/Core/Routing/AcceptHeaderMatcher.php index 29b111f..eee3056 100644 --- a/core/lib/Drupal/Core/Routing/AcceptHeaderMatcher.php +++ b/core/lib/Drupal/Core/Routing/AcceptHeaderMatcher.php @@ -7,6 +7,7 @@ namespace Drupal\Core\Routing; +use Drupal\Component\Utility\String; use Drupal\Core\ContentNegotiation; use Symfony\Cmf\Component\Routing\NestedMatcher\RouteFilterInterface; use Symfony\Component\HttpFoundation\Request; @@ -81,7 +82,7 @@ public function filter(RouteCollection $collection, Request $request) { // We do not throw a // \Symfony\Component\Routing\Exception\ResourceNotFoundException here // because we don't want to return a 404 status code, but rather a 406. - throw new NotAcceptableHttpException(format_string('No route found for the specified formats @formats.', array('@formats' => implode(' ', $acceptable_mime_types)))); + throw new NotAcceptableHttpException(String::format('No route found for the specified formats @formats.', array('@formats' => implode(' ', $acceptable_mime_types)))); } } diff --git a/core/modules/system/lib/Drupal/system/Tests/Routing/RoutingFixtures.php b/core/modules/system/lib/Drupal/system/Tests/Routing/RoutingFixtures.php index 06f0953..353a987 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Routing/RoutingFixtures.php +++ b/core/modules/system/lib/Drupal/system/Tests/Routing/RoutingFixtures.php @@ -106,6 +106,26 @@ public function complexRouteCollection() { } /** + * Returns a Content-type restricted set of routes for testing. + * + * @return \Symfony\Component\Routing\RouteCollection + */ + public function contentRouteCollection() { + $collection = new RouteCollection(); + + $route = new Route('path/three'); + $route->setRequirement('_method', 'POST'); + $route->setRequirement('_content_type_format', 'json'); + $collection->add('route_f', $route); + + $route = new Route('path/three'); + $route->setRequirement('_method', 'PATCH'); + $route->setRequirement('_content_type_format', 'xml'); + $collection->add('route_g', $route); + return $collection; + } + + /** * Returns the table definition for the routing fixtures. * * @return array diff --git a/core/modules/system/lib/Drupal/system/Tests/Routing/AcceptHeaderMatcherTest.php b/core/tests/Drupal/Tests/Core/Routing/AcceptHeaderMatcherTest.php similarity index 73% rename from core/modules/system/lib/Drupal/system/Tests/Routing/AcceptHeaderMatcherTest.php rename to core/tests/Drupal/Tests/Core/Routing/AcceptHeaderMatcherTest.php index 34b38a1..2ad2dde 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Routing/AcceptHeaderMatcherTest.php +++ b/core/tests/Drupal/Tests/Core/Routing/AcceptHeaderMatcherTest.php @@ -2,21 +2,22 @@ /** * @file - * Contains Drupal\system\Tests\Routing\AcceptHeaderMatcherTest. + * Contains Drupal\Tests\Core\Routing\AcceptHeaderMatcherTest. */ -namespace Drupal\system\Tests\Routing; +namespace Drupal\Tests\Core\Routing; use Drupal\Core\ContentNegotiation; use Drupal\Core\Routing\AcceptHeaderMatcher; -use Drupal\simpletest\UnitTestBase; +use Drupal\system\Tests\Routing\RoutingFixtures; +use Drupal\Tests\UnitTestCase; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\Exception\NotAcceptableHttpException; /** * Basic tests for the AcceptHeaderMatcher class. */ -class AcceptHeaderMatcherTest extends UnitTestBase { +class AcceptHeaderMatcherTest extends UnitTestCase { /** * A collection of shared fixture data for tests. @@ -33,8 +34,8 @@ public static function getInfo() { ); } - function __construct($test_id = NULL) { - parent::__construct($test_id); + public function setUp() { + parent::setUp(); $this->fixtures = new RoutingFixtures(); } @@ -51,11 +52,11 @@ public function testFilterRoutes() { $request = Request::create('path/two', 'GET'); $request->headers->set('Accept', 'application/json, text/xml;q=0.9'); $routes = $matcher->filter($collection, $request); - $this->assertEqual(count($routes), 4, 'The correct number of routes was found.'); + $this->assertEquals(count($routes), 4, 'The correct number of routes was found.'); $this->assertNotNull($routes->get('route_c'), 'The json route was found.'); $this->assertNull($routes->get('route_e'), 'The html route was not found.'); foreach ($routes as $name => $route) { - $this->assertEqual($name, 'route_c', 'The json route is the first one in the collection.'); + $this->assertEquals($name, 'route_c', 'The json route is the first one in the collection.'); break; } @@ -63,11 +64,11 @@ public function testFilterRoutes() { $request = Request::create('path/two', 'GET'); $request->headers->set('Accept', 'application/x-json, text/xml;q=0.9'); $routes = $matcher->filter($collection, $request); - $this->assertEqual(count($routes), 4, 'The correct number of routes was found.'); + $this->assertEquals(count($routes), 4, 'The correct number of routes was found.'); $this->assertNotNull($routes->get('route_c'), 'The json route was found.'); $this->assertNull($routes->get('route_e'), 'The html route was not found.'); foreach ($routes as $name => $route) { - $this->assertEqual($name, 'route_c', 'The json route is the first one in the collection.'); + $this->assertEquals($name, 'route_c', 'The json route is the first one in the collection.'); break; } @@ -75,11 +76,11 @@ public function testFilterRoutes() { $request = Request::create('path/two', 'GET'); $request->headers->set('Accept', 'text/html, text/xml;q=0.9'); $routes = $matcher->filter($collection, $request); - $this->assertEqual(count($routes), 4, 'The correct number of routes was found.'); + $this->assertEquals(count($routes), 4, 'The correct number of routes was found.'); $this->assertNull($routes->get('route_c'), 'The json route was not found.'); $this->assertNotNull($routes->get('route_e'), 'The html route was found.'); foreach ($routes as $name => $route) { - $this->assertEqual($name, 'route_e', 'The html route is the first one in the collection.'); + $this->assertEquals($name, 'route_e', 'The html route is the first one in the collection.'); break; } } @@ -100,11 +101,11 @@ public function testNoRouteFound() { try { $request = Request::create('path/two', 'GET'); $request->headers->set('Accept', 'application/json, text/xml;q=0.9'); - $routes = $matcher->filter($routes, $request); - $this->fail(t('No exception was thrown.')); + $matcher->filter($routes, $request); + $this->fail('No exception was thrown.'); } catch (NotAcceptableHttpException $e) { - $this->pass('The correct exception was thrown.'); + $this->assertEquals($e->getMessage(), 'No route found for the specified formats application/json text/xml.'); } } diff --git a/core/tests/Drupal/Tests/Core/Routing/ContentTypeHeaderMatcherTest.php b/core/tests/Drupal/Tests/Core/Routing/ContentTypeHeaderMatcherTest.php new file mode 100644 index 0000000..1ecd142 --- /dev/null +++ b/core/tests/Drupal/Tests/Core/Routing/ContentTypeHeaderMatcherTest.php @@ -0,0 +1,96 @@ + 'Content Type header matcher test', + 'description' => 'Confirm that the content types partial matcher is functioning properly.', + 'group' => 'Routing', + ); + } + + public function setUp() { + parent::setUp(); + + $this->fixtures = new RoutingFixtures(); + } + + /** + * Confirms that the Content type matcher matches properly. + */ + public function testFilterRoutes() { + + $matcher = new ContentTypeHeaderMatcher(); + $collection = $this->fixtures->sampleRouteCollection(); + $collection->addCollection($this->fixtures->contentRouteCollection()); + + // Tests that routes are not filtered on GET requests. + $request = Request::create('path/two', 'GET'); + $routes = $matcher->filter($collection, $request); + $this->assertEquals(count($routes), 7, 'The correct number of routes was found.'); + + // Test that XML-restricted routes get filtered out on JSON requests. + $request = Request::create('path/two', 'POST'); + $request->headers->set('Content-type', 'application/json'); + $routes = $matcher->filter($collection, $request); + $this->assertEquals(count($routes), 6, 'The correct number of routes was found.'); + $this->assertNotNull($routes->get('route_f'), 'The json route was found.'); + $this->assertNull($routes->get('route_g'), 'The xml route was not found.'); + foreach ($routes as $name => $route) { + $this->assertEquals($name, 'route_f', 'The json route is the first one in the collection.'); + break; + } + + // Test all XML and JSON restricted routes get filtered out on a POST form + // submission. + $request = Request::create('path/two', 'POST'); + $request->headers->set('Content-type', 'application/www-form-urlencoded'); + $routes = $matcher->filter($collection, $request); + $this->assertEquals(count($routes), 5, 'The correct number of routes was found.'); + $this->assertNull($routes->get('route_f'), 'The json route was found.'); + $this->assertNull($routes->get('route_g'), 'The xml route was not found.'); + } + + /** + * Confirms that the matcher throws an exception for no-route. + */ + public function testNoRouteFound() { + $matcher = new ContentTypeHeaderMatcher(); + + $routes = $this->fixtures->contentRouteCollection(); + try { + $request = Request::create('path/two', 'POST'); + $request->headers->set('Content-type', 'application/hal+json'); + $matcher->filter($routes, $request); + $this->fail('No exception was thrown.'); + } + catch (BadRequestHttpException $e) { + $this->assertEquals($e->getMessage(), 'No route found that matches the Content-Type header.'); + } + } + +}