Update to drupal 8.0.0-rc1. For more information, see https://www.drupal.org/node/2582663

This commit is contained in:
Greg Anderson 2015-10-08 11:40:12 -07:00
parent eb34d130a8
commit f32e58e4b1
8476 changed files with 211648 additions and 170042 deletions

View file

@ -62,6 +62,18 @@ class RelationLinkManager extends LinkManagerBase implements RelationLinkManager
* {@inheritdoc}
*/
public function getRelationUri($entity_type, $bundle, $field_name, $context = array()) {
// Per the interface documention of this method, the returned URI may
// optionally also serve as the URL of a documentation page about this
// field. However, the REST module does not currently implement such
// a documentation page. Therefore, we return a URI assembled relative to
// the site's base URL, which is sufficient to uniquely identify the site's
// entity type + bundle + field for use in hypermedia formats, but we do
// not take into account unclean URLs, language prefixing, or anything else
// that would be required for Drupal to be able to respond with content
// at this URL. If a module is installed that adds such content, but
// requires this URL to be different (e.g., include a language prefix),
// then the module must also override the RelationLinkManager class/service
// to return the desired URL.
$uri = $this->getLinkDomain() . "/rest/relation/$entity_type/$bundle/$field_name";
$this->moduleHandler->alter('rest_relation_uri', $uri, $context);
return $uri;

View file

@ -12,6 +12,10 @@ interface RelationLinkManagerInterface extends ConfigurableLinkManagerInterface
/**
* Gets the URI that corresponds to a field.
*
* When using hypermedia formats, this URI can be used to indicate which
* field the data represents. Documentation about this field can also be
* provided at this URI.
*
* @param string $entity_type
* The bundle's entity type.
* @param string $bundle

View file

@ -49,19 +49,21 @@ class TypeLinkManager extends LinkManagerBase implements TypeLinkManagerInterfac
}
/**
* Get a type link for a bundle.
*
* @param string $entity_type
* The bundle's entity type.
* @param string $bundle
* The name of the bundle.
* @param array $context
* Context of normalizer/serializer.
*
* @return string
* The URI that identifies this bundle.
* {@inheritdoc}
*/
public function getTypeUri($entity_type, $bundle, $context = array()) {
// Per the interface documention of this method, the returned URI may
// optionally also serve as the URL of a documentation page about this
// bundle. However, the REST module does not currently implement such
// a documentation page. Therefore, we return a URI assembled relative to
// the site's base URL, which is sufficient to uniquely identify the site's
// entity type and bundle for use in hypermedia formats, but we do not
// take into account unclean URLs, language prefixing, or anything else
// that would be required for Drupal to be able to respond with content
// at this URL. If a module is installed that adds such content, but
// requires this URL to be different (e.g., include a language prefix),
// then the module must also override the TypeLinkManager class/service to
// return the desired URL.
$uri = $this->getLinkDomain() . "/rest/type/$entity_type/$bundle";
$this->moduleHandler->alter('rest_type_uri', $uri, $context);
return $uri;

View file

@ -14,7 +14,7 @@ use Drupal\Core\Render\RendererInterface;
use Drupal\Core\Routing\RouteProviderInterface;
use Drupal\Core\State\StateInterface;
use Drupal\views\Plugin\views\display\ResponseDisplayPluginInterface;
use Drupal\views\Render\ViewsRenderPipelineSafeString;
use Drupal\views\Render\ViewsRenderPipelineMarkup;
use Drupal\views\ViewExecutable;
use Drupal\views\Plugin\views\display\PathPluginBase;
use Symfony\Component\DependencyInjection\ContainerInterface;
@ -143,7 +143,7 @@ class RestExport extends PathPluginBase implements ResponseDisplayPluginInterfac
/**
* {@inheritdoc}
*/
protected function getType() {
public function getType() {
return 'data';
}
@ -335,7 +335,7 @@ class RestExport extends PathPluginBase implements ResponseDisplayPluginInterfac
// executed by an HTML agent.
// @todo Decide how to support non-HTML in the render API in
// https://www.drupal.org/node/2501313.
$build['#markup'] = ViewsRenderPipelineSafeString::create($build['#markup']);
$build['#markup'] = ViewsRenderPipelineMarkup::create($build['#markup']);
}
parent::applyDisplayCachablityMetadata($build);

View file

@ -7,8 +7,9 @@
namespace Drupal\rest\Plugin\views\style;
use Drupal\Core\Cache\Cache;
use Drupal\Core\Cache\CacheableDependencyInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\views\Plugin\CacheablePluginInterface;
use Drupal\views\ViewExecutable;
use Drupal\views\Plugin\views\display\DisplayPluginBase;
use Drupal\views\Plugin\views\style\StylePluginBase;
@ -27,7 +28,7 @@ use Symfony\Component\Serializer\SerializerInterface;
* display_types = {"data"}
* )
*/
class Serializer extends StylePluginBase implements CacheablePluginInterface {
class Serializer extends StylePluginBase implements CacheableDependencyInterface {
/**
* Overrides \Drupal\views\Plugin\views\style\StylePluginBase::$usesRowPlugin.
@ -155,8 +156,8 @@ class Serializer extends StylePluginBase implements CacheablePluginInterface {
/**
* {@inheritdoc}
*/
public function isCacheable() {
return TRUE;
public function getCacheMaxAge() {
return Cache::PERMANENT;
}
/**
@ -166,4 +167,11 @@ class Serializer extends StylePluginBase implements CacheablePluginInterface {
return ['request_format'];
}
/**
* {@inheritdoc}
*/
public function getCacheTags() {
return [];
}
}

View file

@ -8,7 +8,7 @@
namespace Drupal\rest\Tests;
use Drupal\Core\Url;
use Drupal\rest\Tests\RESTTestBase;
use Drupal\node\Entity\Node;
/**
* Tests special cases for node entities.
@ -42,6 +42,40 @@ class NodeTest extends RESTTestBase {
$this->drupalLogin($account);
}
/**
* Serializes and attempts to create a node via a REST "post" http request.
*
* @param array $data
*/
protected function postNode($data) {
// Enable node creation via POST.
$this->enableNodeConfiguration('POST', 'create');
$this->enableService('entity:node', 'POST', 'json');
// Create a JSON version of a simple node with the title.
$serialized = $this->container->get('serializer')->serialize($data, 'json');
// Post to the REST service to create the node.
$this->httpRequest('/entity/node', 'POST', $serialized, 'application/json');
}
/**
* Tests the title on a newly created node.
*
* @param array $data
* @return \Drupal\node\Entity\Node
*/
protected function assertNodeTitleMatch($data) {
/** @var \Drupal\node\Entity\Node $node */
// Load the newly created node.
$node = Node::load(1);
// Test that the title is the same as what we posted.
$this->assertEqual($node->title->value, $data['title'][0]['value']);
return $node;
}
/**
* Performs various tests on nodes and their REST API.
*/
@ -90,4 +124,79 @@ class NodeTest extends RESTTestBase {
// Make sure that the UUID of the node has not changed.
$this->assertEqual($node->get('uuid')->getValue(), $updated_node->get('uuid')->getValue(), 'UUID was not changed.');
}
/**
* Test creating a node using json serialization.
*/
public function testCreate() {
// Data to be used for serialization.
$data = [
'type' => [['target_id' => 'resttest']],
'title' => [['value' => $this->randomString() ]],
];
$this->postNode($data);
// Make sure the response is "CREATED".
$this->assertResponse(201);
// Make sure the node was created and the title matches.
$node = $this->assertNodeTitleMatch($data);
// Make sure the request returned a redirect header to view the node.
$this->assertHeader('Location', $node->url('canonical', ['absolute' => TRUE]));
}
/**
* Test bundle normalization when posting bundle as a simple string.
*/
public function testBundleNormalization() {
// Data to be used for serialization.
$data = [
'type' => 'resttest',
'title' => [['value' => $this->randomString() ]],
];
$this->postNode($data);
// Make sure the response is "CREATED".
$this->assertResponse(201);
// Make sure the node was created and the title matches.
$this->assertNodeTitleMatch($data);
}
/**
* Test bundle normalization when posting using a simple string.
*/
public function testInvalidBundle() {
// Data to be used for serialization.
$data = [
'type' => 'bad_bundle_name',
'title' => [['value' => $this->randomString() ]],
];
$this->postNode($data);
// Make sure the response is "Bad Request".
$this->assertResponse(400);
$this->assertResponseBody('{"error":"\"bad_bundle_name\" is not a valid bundle type for denormalization."}');
}
/**
* Test when the bundle is missing.
*/
public function testMissingBundle() {
// Data to be used for serialization.
$data = [
'title' => [['value' => $this->randomString() ]],
];
// testing
$this->postNode($data);
// Make sure the response is "Bad Request".
$this->assertResponse(400);
$this->assertResponseBody('{"error":"A string must be provided as a bundle value."}');
}
}

View file

@ -7,11 +7,9 @@
namespace Drupal\rest\Tests;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Url;
use Drupal\Component\Utility\SafeMarkup;
use Drupal\node\NodeInterface;
use Drupal\simpletest\WebTestBase;
use Drupal\user\UserInterface;
/**
* Test helper class that provides a REST client method to send HTTP requests.
@ -46,6 +44,14 @@ abstract class RESTTestBase extends WebTestBase {
*/
protected $defaultAuth;
/**
* The raw response body from http request operations.
*
* @var array
*/
protected $responseBody;
/**
* Modules to install.
*
@ -153,7 +159,7 @@ abstract class RESTTestBase extends WebTestBase {
break;
}
$response = $this->curlExec($curl_options);
$this->responseBody = $this->curlExec($curl_options);
// Ensure that any changes to variables in the other thread are picked up.
$this->refreshVariables();
@ -163,9 +169,9 @@ abstract class RESTTestBase extends WebTestBase {
$this->verbose($method . ' request to: ' . $url .
'<hr />Code: ' . curl_getinfo($this->curlHandle, CURLINFO_HTTP_CODE) .
'<hr />Response headers: ' . nl2br(print_r($headers, TRUE)) .
'<hr />Response body: ' . $response);
'<hr />Response body: ' . $this->responseBody);
return $response;
return $this->responseBody;
}
/**
@ -383,9 +389,33 @@ abstract class RESTTestBase extends WebTestBase {
$node->set('promote', NULL);
$node->set('sticky', NULL);
$node->set('revision_timestamp', NULL);
$node->set('revision_log', NULL);
$node->set('uid', NULL);
return $node;
}
/**
* Check to see if the HTTP request response body is identical to the expected
* value.
*
* @param $expected
* The first value to check.
* @param $message
* (optional) A message to display with the assertion. Do not translate
* messages: use \Drupal\Component\Utility\SafeMarkup::format() to embed
* variables in the message text, not t(). If left blank, a default message
* will be displayed.
* @param $group
* (optional) The group this message is in, which is displayed in a column
* in test output. Use 'Debug' to indicate this is debugging output. Do not
* translate this string. Defaults to 'Other'; most tests do not override
* this default.
*
* @return bool
* TRUE if the assertion succeeded, FALSE otherwise.
*/
protected function assertResponseBody($expected, $message = '', $group = 'REST Response') {
return $this->assertIdentical($expected, $this->responseBody, $message ? $message : strtr('Response body @expected (expected) is equal to @response (actual).', array('@expected' => var_export($expected, TRUE), '@response' => var_export($this->responseBody, TRUE))), $group);
}
}

View file

@ -395,7 +395,7 @@ class StyleSerializerTest extends PluginTestBase {
$expected[] = $expected_row;
}
$this->assertIdentical($this->drupalGetJSON('test/serialize/field'), $expected);
$this->assertIdentical($this->drupalGetJSON('test/serialize/field'), $this->castSafeStrings($expected));
// Test a random aliases for fields, they should be replaced.
$alias_map = array(
@ -430,7 +430,7 @@ class StyleSerializerTest extends PluginTestBase {
$expected[] = $expected_row;
}
$this->assertIdentical($this->drupalGetJSON('test/serialize/field'), $expected);
$this->assertIdentical($this->drupalGetJSON('test/serialize/field'), $this->castSafeStrings($expected));
}
/**