Tests several valid and invalid partial update requests on test entities.
public function testPatchUpdate() {
$serializer = drupal_container()
->get('serializer');
// @todo once EntityNG is implemented for other entity types test all other
// entity types here as well.
$entity_type = 'entity_test';
$this
->enableService('entity:' . $entity_type, 'PATCH');
// Create a user account that has the required permissions to create
// resources via the REST API.
$permissions = $this
->entityPermissions($entity_type, 'update');
$permissions[] = 'restful patch entity:' . $entity_type;
$account = $this
->drupalCreateUser($permissions);
$this
->drupalLogin($account);
// Create an entity and save it to the database.
$entity = $this
->entityCreate($entity_type);
$entity
->save();
// Create a second stub entity for overwriting a field.
$patch_values['field_test_text'] = array(
0 => array(
'value' => $this
->randomString(),
),
);
$patch_entity = entity_create($entity_type, $patch_values);
// We don't want to overwrite the UUID.
unset($patch_entity->uuid);
$serialized = $serializer
->serialize($patch_entity, $this->defaultFormat);
// Update the entity over the REST API.
$this
->httpRequest('entity/' . $entity_type . '/' . $entity
->id(), 'PATCH', $serialized, $this->defaultMimeType);
$this
->assertResponse(204);
// Re-load updated entity from the database.
$entity = entity_load($entity_type, $entity
->id(), TRUE);
$this
->assertEqual($entity->field_test_text->value, $patch_entity->field_test_text->value, 'Field was successfully updated.');
// Try to empty a field.
$normalized = $serializer
->normalize($patch_entity, $this->defaultFormat);
$normalized['field_test_text'] = array();
$serialized = $serializer
->encode($normalized, $this->defaultFormat);
// Update the entity over the REST API.
$this
->httpRequest('entity/' . $entity_type . '/' . $entity
->id(), 'PATCH', $serialized, $this->defaultMimeType);
$this
->assertResponse(204);
// Re-load updated entity from the database.
$entity = entity_load($entity_type, $entity
->id(), TRUE);
$this
->assertNull($entity->field_test_text->value, 'Test field has been cleared.');
// Enable access protection for the text field.
// @see entity_test_entity_field_access()
$entity->field_test_text->value = 'no access value';
$entity
->save();
// Try to empty a field that is access protected.
$this
->httpRequest('entity/' . $entity_type . '/' . $entity
->id(), 'PATCH', $serialized, $this->defaultMimeType);
$this
->assertResponse(403);
// Re-load the entity from the database.
$entity = entity_load($entity_type, $entity
->id(), TRUE);
$this
->assertEqual($entity->field_test_text->value, 'no access value', 'Text field was not updated.');
// Try to update an access protected field.
$serialized = $serializer
->serialize($patch_entity, $this->defaultFormat);
$this
->httpRequest('entity/' . $entity_type . '/' . $entity
->id(), 'PATCH', $serialized, $this->defaultMimeType);
$this
->assertResponse(403);
// Re-load the entity from the database.
$entity = entity_load($entity_type, $entity
->id(), TRUE);
$this
->assertEqual($entity->field_test_text->value, 'no access value', 'Text field was not updated.');
// Restore the valid test value.
$entity->field_test_text->value = $this
->randomString();
$entity
->save();
// Try to update a non-existing entity with ID 9999.
$this
->httpRequest('entity/' . $entity_type . '/9999', 'PATCH', $serialized, $this->defaultMimeType);
$this
->assertResponse(404);
$loaded_entity = entity_load($entity_type, 9999, TRUE);
$this
->assertFalse($loaded_entity, 'Entity 9999 was not created.');
// Try to update an entity without proper permissions.
$this
->drupalLogout();
$this
->httpRequest('entity/' . $entity_type . '/' . $entity
->id(), 'PATCH', $serialized, $this->defaultMimeType);
$this
->assertResponse(403);
// Try to update a resource which is not REST API enabled.
$this
->enableService(FALSE);
$this
->drupalLogin($account);
$this
->httpRequest('entity/' . $entity_type . '/' . $entity
->id(), 'PATCH', $serialized, $this->defaultMimeType);
$this
->assertResponse(404);
}