diff --git a/core/modules/rest/src/Plugin/views/display/RestExport.php b/core/modules/rest/src/Plugin/views/display/RestExport.php index 582a9c4719..d2f66fff95 100644 --- a/core/modules/rest/src/Plugin/views/display/RestExport.php +++ b/core/modules/rest/src/Plugin/views/display/RestExport.php @@ -139,14 +139,22 @@ public static function create(ContainerInterface $container, array $configuratio public function initDisplay(ViewExecutable $view, array &$display, array &$options = NULL) { parent::initDisplay($view, $display, $options); + // If the default 'json' format is not selected as a format option in the + // view display, fallback to the first format available for the default. + if (!empty($options['style']['options']['formats']) && !isset($options['style']['options']['formats'][$this->getContentType()])) { + $default_format = reset($options['style']['options']['formats']); + $this->setContentType($default_format); + } + + // Only use the requested content type if it's not 'html'. This allows + // still falling back to the default for things like views preview. $request_content_type = $this->view->getRequest()->getRequestFormat(); - // This allows still falling back to the default for things like views - // preview. if ($request_content_type !== 'html') { $this->setContentType($request_content_type); - $this->setMimeType($this->view->getRequest()->getMimeType($request_content_type)); } + + $this->setMimeType($this->view->getRequest()->getMimeType($this->getContentType())); } /** diff --git a/core/modules/rest/src/Tests/Views/StyleSerializerTest.php b/core/modules/rest/src/Tests/Views/StyleSerializerTest.php index 6e04d6b96e..5711b7b865 100644 --- a/core/modules/rest/src/Tests/Views/StyleSerializerTest.php +++ b/core/modules/rest/src/Tests/Views/StyleSerializerTest.php @@ -176,6 +176,11 @@ public function testSerializerResponses() { $this->assertCacheTags($expected_cache_tags); $this->assertCacheContexts(['languages:language_interface', 'theme', 'entity_test_view_grants', 'request_format']); + // This should fall back to JSON. + $actual_json = $this->drupalGet('test/serialize/entity'); + $this->assertResponse(200); + $this->assertIdentical($actual_json, $expected, 'The expected JSON output was found.'); + $expected = $serializer->serialize($entities, 'hal_json'); $actual_json = $this->drupalGetWithFormat('test/serialize/entity', 'hal_json'); $this->assertIdentical($actual_json, $expected, 'The expected HAL output was found.'); @@ -195,9 +200,15 @@ public function testSerializerResponses() { $view->save(); $expected = $serializer->serialize($entities, 'xml'); $actual_xml = $this->drupalGetWithFormat('test/serialize/entity', 'xml'); + $this->assertResponse(200); $this->assertIdentical($actual_xml, $expected, 'The expected XML output was found.'); $this->assertCacheContexts(['languages:language_interface', 'theme', 'entity_test_view_grants', 'request_format']); + // This should fall back to XML. + $actual_xml = $this->drupalGetWithFormat('test/serialize/entity'); + $this->assertResponse(200); + $this->assertIdentical($actual_xml, $expected, 'The expected XML output was found.'); + // Allow multiple formats. $view->setDisplay('rest_export_1'); $view->getDisplay()->setOption('style', [ @@ -348,6 +359,11 @@ public function testResponseFormatConfiguration() { $style_options = 'admin/structure/views/nojs/display/test_serializer_display_field/rest_export_1/style_options'; + // Test with no format. + $this->drupalGet('test/serialize/field'); + $this->assertHeader('content-type', 'application/json'); + $this->assertResponse(406, 'A 406 response was returned when no format was requested.'); + // Select only 'xml' as an accepted format. $this->drupalPostForm($style_options, ['style_options[formats][xml]' => 'xml'], t('Apply')); $this->drupalPostForm(NULL, [], t('Save')); @@ -365,12 +381,6 @@ public function testResponseFormatConfiguration() { $this->drupalPostForm($style_options, ['style_options[formats][json]' => 'json'], t('Apply')); $this->drupalPostForm(NULL, [], t('Save')); - // Should return a 200. - // @todo This should be fixed when we have better content negotiation. - $this->drupalGetWithFormat('test/serialize/field', 'json'); - $this->assertHeader('content-type', 'application/json'); - $this->assertResponse(200, 'A 200 response was returned when any format was requested.'); - // Should return a 406. Emulates a sample Firefox header. $this->drupalGet('test/serialize/field', [], ['Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8']); $this->assertHeader('content-type', 'text/html; charset=UTF-8');