AcceptHeaderMatcherTest.php 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. <?php
  2. namespace Drupal\Tests\Core\Routing;
  3. use Drupal\accept_header_routing_test\Routing\AcceptHeaderMatcher;
  4. use Drupal\Tests\UnitTestCase;
  5. use Symfony\Component\HttpFoundation\Request;
  6. use Symfony\Component\HttpKernel\Exception\NotAcceptableHttpException;
  7. /**
  8. * Confirm that the mime types partial matcher is functioning properly.
  9. *
  10. * @group Routing
  11. */
  12. class AcceptHeaderMatcherTest extends UnitTestCase {
  13. /**
  14. * A collection of shared fixture data for tests.
  15. *
  16. * @var \Drupal\Tests\Core\Routing\RoutingFixtures
  17. */
  18. protected $fixtures;
  19. /**
  20. * The matcher object that is going to be tested.
  21. *
  22. * @var \Drupal\accept_header_routing_test\Routing\AcceptHeaderMatcher
  23. */
  24. protected $matcher;
  25. /**
  26. * {@inheritdoc}
  27. */
  28. protected function setUp() {
  29. parent::setUp();
  30. $this->fixtures = new RoutingFixtures();
  31. $this->matcher = new AcceptHeaderMatcher();
  32. }
  33. /**
  34. * Provides data for the Accept header filtering test.
  35. *
  36. * @see Drupal\Tests\Core\Routing\AcceptHeaderMatcherTest::testAcceptFiltering()
  37. */
  38. public function acceptFilterProvider() {
  39. return [
  40. // Check that JSON routes get filtered and prioritized correctly.
  41. ['application/json, text/xml;q=0.9', 'json', 'route_c', 'route_e'],
  42. // Tests a JSON request with alternative JSON MIME type Accept header.
  43. ['application/x-json, text/xml;q=0.9', 'json', 'route_c', 'route_e'],
  44. // Tests a standard HTML request.
  45. ['text/html, text/xml;q=0.9', 'html', 'route_e', 'route_c'],
  46. ];
  47. }
  48. /**
  49. * Tests that requests using Accept headers get filtered correctly.
  50. *
  51. * @param string $accept_header
  52. * The HTTP Accept header value of the request.
  53. * @param string $format
  54. * The request format.
  55. * @param string $included_route
  56. * The route name that should survive the filter and be ranked first.
  57. * @param string $excluded_route
  58. * The route name that should be filtered out during matching.
  59. *
  60. * @dataProvider acceptFilterProvider
  61. */
  62. public function testAcceptFiltering($accept_header, $format, $included_route, $excluded_route) {
  63. $collection = $this->fixtures->sampleRouteCollection();
  64. $request = Request::create('path/two', 'GET');
  65. $request->headers->set('Accept', $accept_header);
  66. $request->setRequestFormat($format);
  67. $routes = $this->matcher->filter($collection, $request);
  68. $this->assertCount(4, $routes, 'The correct number of routes was found.');
  69. $this->assertNotNull($routes->get($included_route), "Route $included_route was found when matching $accept_header.");
  70. $this->assertNull($routes->get($excluded_route), "Route $excluded_route was not found when matching $accept_header.");
  71. foreach ($routes as $name => $route) {
  72. $this->assertEquals($name, $included_route, "Route $included_route is the first one in the collection when matching $accept_header.");
  73. break;
  74. }
  75. }
  76. /**
  77. * Confirms that the AcceptHeaderMatcher throws an exception for no-route.
  78. */
  79. public function testNoRouteFound() {
  80. // Remove the sample routes that would match any method.
  81. $routes = $this->fixtures->sampleRouteCollection();
  82. $routes->remove('route_a');
  83. $routes->remove('route_b');
  84. $routes->remove('route_c');
  85. $routes->remove('route_d');
  86. $request = Request::create('path/two', 'GET');
  87. $request->headers->set('Accept', 'application/json, text/xml;q=0.9');
  88. $request->setRequestFormat('json');
  89. $this->expectException(NotAcceptableHttpException::class);
  90. $this->expectExceptionMessage('No route found for the specified formats application/json text/xml');
  91. $this->matcher->filter($routes, $request);
  92. }
  93. }