ContentNegotiationRoutingTest.php 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. <?php
  2. namespace Drupal\KernelTests\Core\Routing;
  3. use Drupal\Core\DependencyInjection\ContainerBuilder;
  4. use Drupal\KernelTests\KernelTestBase;
  5. use Symfony\Component\HttpFoundation\Request;
  6. use Symfony\Component\HttpFoundation\Response;
  7. /**
  8. * Tests content negotiation routing variations.
  9. *
  10. * @group ContentNegotiation
  11. */
  12. class ContentNegotiationRoutingTest extends KernelTestBase {
  13. /**
  14. * {@inheritdoc}
  15. */
  16. public static $modules = ['conneg_test'];
  17. /**
  18. * {@inheritdoc}
  19. */
  20. public function register(ContainerBuilder $container) {
  21. parent::register($container);
  22. // \Drupal\KernelTests\KernelTestBase::register() removes the alias path
  23. // processor.
  24. if ($container->hasDefinition('path_processor_alias')) {
  25. $definition = $container->getDefinition('path_processor_alias');
  26. $definition->addTag('path_processor_inbound', ['priority' => 100])->addTag('path_processor_outbound', ['priority' => 300]);
  27. }
  28. }
  29. /**
  30. * Tests the content negotiation aspect of routing.
  31. */
  32. public function testContentRouting() {
  33. /** @var \Drupal\Core\Path\AliasStorageInterface $path_alias_storage */
  34. $path_alias_storage = $this->container->get('path.alias_storage');
  35. // Alias with extension pointing to no extension/constant content-type.
  36. $path_alias_storage->save('/conneg/html', '/alias.html');
  37. // Alias with extension pointing to dynamic extension/linked content-type.
  38. $path_alias_storage->save('/conneg/html?_format=json', '/alias.json');
  39. $tests = [
  40. // ['path', 'accept', 'content-type'],
  41. // Extension is part of the route path. Constant Content-type.
  42. ['conneg/simple.json', '', 'application/json'],
  43. ['conneg/simple.json', 'application/xml', 'application/json'],
  44. ['conneg/simple.json', 'application/json', 'application/json'],
  45. // No extension. Constant Content-type.
  46. ['conneg/html', '', 'text/html'],
  47. ['conneg/html', '*/*', 'text/html'],
  48. ['conneg/html', 'application/xml', 'text/html'],
  49. ['conneg/html', 'text/xml', 'text/html'],
  50. ['conneg/html', 'text/html', 'text/html'],
  51. // Dynamic extension. Linked Content-type.
  52. ['conneg/html?_format=json', '', 'application/json'],
  53. ['conneg/html?_format=json', '*/*', 'application/json'],
  54. ['conneg/html?_format=json', 'application/xml', 'application/json'],
  55. ['conneg/html?_format=json', 'application/json', 'application/json'],
  56. ['conneg/html?_format=xml', '', 'application/xml'],
  57. ['conneg/html?_format=xml', '*/*', 'application/xml'],
  58. ['conneg/html?_format=xml', 'application/json', 'application/xml'],
  59. ['conneg/html?_format=xml', 'application/xml', 'application/xml'],
  60. // Path with a variable. Variable contains a period.
  61. ['conneg/plugin/plugin.id', '', 'text/html'],
  62. ['conneg/plugin/plugin.id', '*/*', 'text/html'],
  63. ['conneg/plugin/plugin.id', 'text/xml', 'text/html'],
  64. ['conneg/plugin/plugin.id', 'text/html', 'text/html'],
  65. // Alias with extension pointing to no extension/constant content-type.
  66. ['alias.html', '', 'text/html'],
  67. ['alias.html', '*/*', 'text/html'],
  68. ['alias.html', 'text/xml', 'text/html'],
  69. ['alias.html', 'text/html', 'text/html'],
  70. ];
  71. foreach ($tests as $test) {
  72. $path = $test[0];
  73. $accept_header = $test[1];
  74. $content_type = $test[2];
  75. $message = "Testing path:$path Accept:$accept_header Content-type:$content_type";
  76. $request = Request::create('/' . $path);
  77. if ($accept_header) {
  78. $request->headers->set('Accept', $accept_header);
  79. }
  80. /** @var \Symfony\Component\HttpKernel\HttpKernelInterface $kernel */
  81. $kernel = \Drupal::getContainer()->get('http_kernel');
  82. $response = $kernel->handle($request);
  83. // Verbose message since simpletest doesn't let us provide a message and
  84. // see the error.
  85. $this->assertTrue(TRUE, $message);
  86. $this->assertEqual($response->getStatusCode(), Response::HTTP_OK);
  87. $this->assertTrue(strpos($response->headers->get('Content-type'), $content_type) !== FALSE);
  88. }
  89. }
  90. /**
  91. * Full negotiation by header only.
  92. */
  93. public function testFullNegotiation() {
  94. $this->enableModules(['accept_header_routing_test']);
  95. \Drupal::service('router.builder')->rebuild();
  96. $tests = [
  97. // ['path', 'accept', 'content-type'],
  98. // 406?
  99. ['conneg/negotiate', '', 'text/html'],
  100. // 406?
  101. ['conneg/negotiate', '', 'text/html'],
  102. // ['conneg/negotiate', '*/*', '??'],
  103. ['conneg/negotiate', 'application/json', 'application/json'],
  104. ['conneg/negotiate', 'application/xml', 'application/xml'],
  105. ['conneg/negotiate', 'application/json', 'application/json'],
  106. ['conneg/negotiate', 'application/xml', 'application/xml'],
  107. ];
  108. foreach ($tests as $test) {
  109. $path = $test[0];
  110. $accept_header = $test[1];
  111. $content_type = $test[2];
  112. $message = "Testing path:$path Accept:$accept_header Content-type:$content_type";
  113. $request = Request::create('/' . $path);
  114. $request->headers->set('Accept', $accept_header);
  115. /** @var \Symfony\Component\HttpKernel\HttpKernelInterface $kernel */
  116. $kernel = \Drupal::getContainer()->get('http_kernel');
  117. $response = $kernel->handle($request);
  118. // Verbose message since simpletest doesn't let us provide a message and
  119. // see the error.
  120. $this->pass($message);
  121. $this->assertEqual($response->getStatusCode(), Response::HTTP_OK);
  122. }
  123. }
  124. }