You are here

RestfulSubResourcesCreateEntityTestCase.test in RESTful 7.2

Same filename and directory in other branches
  1. 7 tests/RestfulSubResourcesCreateEntityTestCase.test

Contains RestfulSubResourcesCreateEntityTestCase.

File

tests/RestfulSubResourcesCreateEntityTestCase.test
View source
<?php

/**
 * @file
 * Contains RestfulSubResourcesCreateEntityTestCase.
 */
use Drupal\restful\Exception\BadRequestException;
use Drupal\restful\Http\Request;
use Drupal\restful\Http\RequestInterface;
class RestfulSubResourcesCreateEntityTestCase extends DrupalWebTestCase {

  /**
   * Hold the RESTful handler.
   *
   * @var \Drupal\restful\Plugin\resource\ResourceInterface
   */
  protected $handler = NULL;

  /**
   * {@inheritdoc}
   */
  public static function getInfo() {
    return array(
      'name' => 'Sub requests',
      'description' => 'Test the creation of sub-resources (referenced entities) via sub requests.',
      'group' => 'RESTful',
    );
  }

  /**
   * {@inheritdoc}
   */
  public function setUp() {
    parent::setUp('restful_test', 'entity_validator_example');

    // Entity reference - single.
    $field = array(
      'entity_types' => array(
        'node',
      ),
      'settings' => array(
        'handler' => 'base',
        'target_type' => 'node',
        'handler_settings' => array(),
      ),
      'field_name' => 'entity_reference_single',
      'type' => 'entityreference',
      'cardinality' => 1,
    );
    field_create_field($field);
    $instance = array(
      'entity_type' => 'node',
      'field_name' => 'entity_reference_single',
      'bundle' => 'article',
      'label' => t('Entity reference single'),
    );
    field_create_instance($instance);

    // Entity reference - multiple.
    $field = array(
      'entity_types' => array(
        'node',
      ),
      'settings' => array(
        'handler' => 'base',
        'target_type' => 'node',
        'handler_settings' => array(),
      ),
      'field_name' => 'entity_reference_multiple',
      'type' => 'entityreference',
      'cardinality' => FIELD_CARDINALITY_UNLIMITED,
    );
    field_create_field($field);
    $instance = array(
      'entity_type' => 'node',
      'field_name' => 'entity_reference_multiple',
      'bundle' => 'article',
      'label' => t('Entity reference multiple'),
    );
    field_create_instance($instance);
    $resource_manager = restful()
      ->getResourceManager();
    $resource_manager
      ->clearPluginCache('test_articles:1.2');
    $this->handler = $resource_manager
      ->getPlugin('test_articles:1.2');
    user_role_change_permissions(DRUPAL_ANONYMOUS_RID, array(
      'create article content' => TRUE,
    ));
  }

  /**
   * Test creating and updating an entity with sub-resources.
   */
  public function testCreateAndUpdateEntity() {
    $base_request = $request = array(
      'label' => 'parent',
      'body' => 'Drupal',
      'entity_reference_single' => array(
        'body' => array(
          'label' => 'child1',
          'body' => 'Drupal1',
        ),
        'request' => array(
          'method' => 'POST',
        ),
      ),
      'entity_reference_multiple' => array(
        array(
          'body' => array(
            'label' => 'child2',
            'body' => 'Drupal2',
          ),
          'request' => array(
            'method' => 'POST',
          ),
        ),
        array(
          'body' => array(
            'label' => 'child3',
            'body' => 'Drupal3',
          ),
          'request' => array(
            'method' => 'POST',
          ),
        ),
      ),
    );

    // POST parent.
    $this
      ->processRequests('post', '', $request);

    // PUT/ PATCH parent.
    $settings = array(
      'type' => 'article',
      'title' => 'title1',
    );
    $node1 = $this
      ->drupalCreateNode($settings);
    $request = $base_request;
    foreach (array(
      'put',
      'patch',
    ) as $method) {
      $this
        ->processRequests($method, $node1->nid, $request);
    }

    // POST parent, reference existing on single reference, multiple reference
    // empty.
    $node2 = $this
      ->drupalCreateNode($settings);
    $node3 = $this
      ->drupalCreateNode($settings);
    $node4 = $this
      ->drupalCreateNode($settings);
    $node5 = $this
      ->drupalCreateNode($settings);
    $request = $base_request;
    $request['entity_reference_single'] = $node1->nid;
    $request['entity_reference_multiple'] = array(
      $node2->nid,
      $node3->nid,
    );
    $this
      ->processRequests('post', '', $request);

    // POST parent, reference existing on multiple reference, POST a new one,
    // PATCH existing one, and PUT existing one.
    $request = $base_request;
    $request['entity_reference_single'] = $node2->nid;
    $request['entity_reference_multiple']['request'] = array(
      'method' => RequestInterface::METHOD_PATCH,
    );
    $request['entity_reference_multiple'] = array(
      array(
        // Set the $node3.
        'id' => $node3->nid,
      ),
      array(
        'body' => array(
          // Create a new node.
          'label' => 'POST new one',
          'body' => 'Drupal',
        ),
        'request' => array(
          'method' => 'POST',
        ),
      ),
      array(
        // Set $node4 and update some of the fields.
        'id' => $node4->nid,
        'body' => array(
          'label' => 'PATCH existing one',
          'body' => 'Drupal',
        ),
        'request' => array(
          'method' => 'PATCH',
        ),
      ),
      array(
        // Set $node5 and update some of the fields.
        'id' => $node5->nid,
        'body' => array(
          'label' => 'PATCH existing one',
          'body' => 'Drupal',
        ),
        'request' => array(
          'method' => 'POST',
        ),
      ),
    );
    $this
      ->processRequests('post', '', $request);

    // Test the version of the sub-resource.
    $public_fields = $this->handler
      ->getFieldDefinitions();
    $erm_resource = $public_fields
      ->get('entity_reference_multiple')
      ->getResource();
    $this
      ->assertEqual($erm_resource['majorVersion'], 1, 'Sub resource major version is correct.');
    $this
      ->assertEqual($erm_resource['minorVersion'], 2, 'Sub resource minor version is correct.');
  }

  /**
   * Assert valid and invalid requests.
   *
   * @param string $method
   *   The method name.
   * @param string $path
   *   The path.
   * @param array $request
   *   The request array.
   */
  protected function processRequests($method = 'post', $path = '', array $request = array()) {
    $method = strtoupper($method);
    $query = $parsed_body = array();
    if (Request::isWriteMethod($method)) {
      $parsed_body = $request;
    }
    else {
      $query = $request;
    }
    $this->handler
      ->setRequest(Request::create($path, $query, $method, NULL, FALSE, NULL, array(), array(), array(), $parsed_body));
    $this->handler
      ->setPath($path);
    $result = drupal_json_decode(restful()
      ->getFormatterManager()
      ->format($this->handler
      ->process(), 'json'));
    $result = $result['data'][0];
    $this
      ->assertTrue($result['id'], 'Parent entity created.');
    $this
      ->assertTrue($result['entity_reference_single']['id'], 'Single sub-resource created or updated.');
    $this
      ->assertTrue($result['entity_reference_multiple'][0]['id'] && $result['entity_reference_multiple'][1]['id'], 'Multiple sub-resource created or updated.');

    // Validation fail on the parent.
    $request['label'] = 'no';
    $this
      ->assertInvalidRequest($method, $path, $request);

    // Validation fail on the single resource.
    $request['label'] = 'parent';
    if (is_array($request['entity_reference_single'])) {
      $request['entity_reference_single']['label'] = 'no';
      $this
        ->assertInvalidRequest($method, $path, $request);
      $request['entity_reference_single']['label'] = 'child1';
    }

    // Validation fail on the multiple resource.
    if (!empty($request['entity_reference_multiple'][0]['label']) && is_array($request['entity_reference_multiple'][0]['label'])) {
      $request['entity_reference_multiple'][0]['label'] = 'no';
      $this
        ->assertInvalidRequest($method, $path, $request);
    }
  }

  /**
   * Assert an invalid request fails.
   *
   * @param string $method
   *   The method name.
   * @param string $path
   *   The path.
   * @param array $request
   *   The request array.
   */
  protected function assertInvalidRequest($method = 'post', $path = '', array $request = array()) {
    $method = strtoupper($method);
    $query = $parsed_body = array();
    if (Request::isWriteMethod($method)) {
      $query = $request;
    }
    else {
      $parsed_body = $request;
    }
    try {
      $this->handler
        ->setRequest(Request::create($path, $query, $method, NULL, FALSE, NULL, array(), array(), array(), $parsed_body));
      $this->handler
        ->setPath($path);
      $this->handler
        ->process();
      $this
        ->fail('No exception thrown on validation fail on the parent.');
    } catch (BadRequestException $e) {
      $this
        ->pass('Correct exception thrown on validation fail on the parent.');
    } catch (\Exception $e) {
      $this
        ->fail('Wrong exception thrown on validation fail on the parent.');
    }
  }

}