You are here

public function RestfulListTestCase::testFilter in RESTful 7.2

Same name and namespace in other branches
  1. 7 tests/RestfulListTestCase.test \RestfulListTestCase::testFilter()

Test filtering.

File

tests/RestfulListTestCase.test, line 369
Contains RestfulListTestCase.

Class

RestfulListTestCase
Class RestfulListTestCase.

Code

public function testFilter() {
  $resource_manager = restful()
    ->getResourceManager();
  $user1 = $this
    ->drupalCreateUser();
  $user2 = $this
    ->drupalCreateUser();
  $this
    ->addIntegerFields();
  $info = array(
    array(
      'title' => 'abc',
      'integer_single' => 1,
      'integer_multiple' => array(
        1,
        2,
        3,
      ),
      'uid' => $user1->uid,
    ),
    array(
      'title' => 'another abc',
      'integer_single' => 5,
      'integer_multiple' => array(
        3,
        4,
        5,
      ),
      'uid' => $user1->uid,
    ),
    array(
      'title' => 'last',
      'integer_single' => NULL,
      'integer_multiple' => array(),
      'uid' => $user2->uid,
    ),
  );
  $nodes = array();
  foreach ($info as $row) {
    $title = $row['title'];
    $settings = array(
      'type' => 'article',
      'title' => $title,
    );
    $settings['integer_single'][LANGUAGE_NONE][0]['value'] = $row['integer_single'];
    foreach ($row['integer_multiple'] as $key => $value) {
      $settings['integer_multiple'][LANGUAGE_NONE][$key]['value'] = $value;
    }
    $settings['uid'] = $row['uid'];
    $node = $this
      ->drupalCreateNode($settings);
    $nodes[$title] = $node->nid;
  }
  $handler = $resource_manager
    ->getPlugin('test_articles:1.2');
  $fields = array(
    'id',
    'label',
    'integer_single',
    'intger_multiple',
  );
  $query['fields'] = implode(',', $fields);

  // Single value property.
  $query['filter'] = array(
    'label' => 'abc',
  );
  $handler
    ->setRequest(Request::create('', $query, RequestInterface::METHOD_GET));
  $handler
    ->setPath('');
  $result = drupal_json_decode(restful()
    ->getFormatterManager()
    ->format($handler
    ->process(), 'json'));
  $result = $result['data'];
  $this
    ->assertEqual($result[0]['id'], $nodes['abc'], 'Filter list by single value property.');

  // Assert count is correct.
  $formatter_handler = restful()
    ->getFormatterManager()
    ->getPlugin('hal_json');
  $instance_configuration = $formatter_handler
    ->getConfiguration();
  $formatter_handler
    ->setConfiguration(array_merge($instance_configuration ?: array(), array(
    'resource' => $handler,
  )));
  $output = $formatter_handler
    ->prepare($result);
  $this
    ->assertEqual($output['count'], 1, '"count" property is correct.');

  // Single value field.
  $resource_manager
    ->clearPluginCache($handler
    ->getPluginId());
  $handler = $resource_manager
    ->getPlugin('test_articles:1.2');
  $query['filter'] = array(
    'integer_single' => '1',
  );
  $handler
    ->setRequest(Request::create('', $query, RequestInterface::METHOD_GET));
  $handler
    ->setPath('');
  $result = drupal_json_decode(restful()
    ->getFormatterManager()
    ->format($handler
    ->process(), 'json'));
  $result = $result['data'];
  $this
    ->assertEqual($result[0]['id'], $nodes['abc'], 'Filter list by Single value field.');

  // LIKE operator.
  $input['filter'] = array(
    'label' => array(
      'value' => '%nothe%',
      'operator' => 'LIKE',
    ),
  );
  $result = drupal_json_decode(restful()
    ->getFormatterManager()
    ->format($handler
    ->doGet('', $input), 'json'));
  $result = $result['data'];
  $this
    ->assertEqual($result[0]['id'], $nodes['another abc'], 'Filter list using LIKE operator.');

  // STARTS_WITH operator.
  $input['filter'] = array(
    'label' => array(
      'value' => 'las',
      'operator' => 'STARTS_WITH',
    ),
  );
  $result = drupal_json_decode(restful()
    ->getFormatterManager()
    ->format($handler
    ->doGet('', $input), 'json'));
  $result = $result['data'];
  $this
    ->assertEqual($result[0]['id'], $nodes['last'], 'Filter list using STARTS_WITH operator.');

  // CONTAINS operator.
  $input['filter'] = array(
    'label' => array(
      'value' => 'bc',
      'operator' => 'CONTAINS',
    ),
  );
  $result = drupal_json_decode(restful()
    ->getFormatterManager()
    ->format($handler
    ->doGet('', $input), 'json'));
  $result = $result['data'];

  // Sort the results before checking it.
  usort($result, function ($a, $b) {
    return strcmp($a['label'], $b['label']);
  });
  $this
    ->assertEqual($result[0]['id'], $nodes['abc'], 'Filter list using CONTAINS operator.');
  $this
    ->assertEqual($result[1]['id'], $nodes['another abc'], 'Filter list using CONTAINS operator.');

  // Multiple value field.
  $query['filter'] = array(
    'integer_multiple' => array(
      'value' => array(
        4,
        5,
      ),
      'operator' => 'BETWEEN',
    ),
  );
  $handler
    ->setRequest(Request::create('', $query, RequestInterface::METHOD_GET));
  $handler
    ->setPath('');
  $result = drupal_json_decode(restful()
    ->getFormatterManager()
    ->format($handler
    ->process(), 'json'));
  $result = $result['data'];
  $this
    ->assertEqual($result[0]['id'], $nodes['another abc'], 'Filter list by multiple value field.');

  // Invalid key.
  $query['filter'] = array(
    'invalid_key' => '3',
  );
  $handler
    ->setRequest(Request::create('', $query, RequestInterface::METHOD_GET));
  $handler
    ->setPath('');
  try {
    restful()
      ->getFormatterManager()
      ->format($handler
      ->process(), 'json');
    $this
      ->fail('No exception was thrown on invalid key for filter.');
  } catch (BadRequestException $e) {
    $this
      ->pass('Correct exception was thrown on invalid key for filter.');
  } catch (\Exception $e) {
    $this
      ->fail('Incorrect exception was thrown on invalid key for filter.');
  }

  // Assert filtering doesn't apply for non-list request
  // (e.g. /api/v1.0/articles/1?filter[label]=foo), as this might be called
  // from a formatter plugin, after RESTful's error handling has finished.
  $query_string = array(
    'filter' => array(
      'invalid-key' => 'foo',
    ),
  );
  $result = $this
    ->httpRequest('api/v1.0/articles/1', RequestInterface::METHOD_GET, $query_string);
  $this
    ->assertEqual($result['code'], '200', 'Invalid filter key was ignored on non-list query.');

  // Test multiple filters on the same field.
  $query = array(
    'filter' => array(
      'integer_single' => array(
        'value' => array(
          1,
          4,
        ),
        'operator' => array(
          '>',
          '<>',
        ),
      ),
    ),
  );
  $handler
    ->setRequest(Request::create('', $query, RequestInterface::METHOD_GET));
  $handler
    ->setPath('');
  $result = drupal_json_decode(restful()
    ->getFormatterManager()
    ->format($handler
    ->process(), 'json'));
  $result = $result['data'];
  $this
    ->assertEqual($nodes['another abc'], $result[0]['id']);
  $query = array(
    'filter' => array(
      'integer_single' => array(
        'value' => array(
          1,
          5,
        ),
        'operator' => array(
          '>',
          '<>',
        ),
      ),
    ),
  );
  $handler
    ->setRequest(Request::create('', $query, RequestInterface::METHOD_GET));
  $handler
    ->setPath('');
  $result = drupal_json_decode(restful()
    ->getFormatterManager()
    ->format($handler
    ->process(), 'json'));
  $result = $result['data'];
  $this
    ->assertEqual($result, array());
  $query = array(
    'filter' => array(
      'integer_multiple' => array(
        'value' => array(
          3,
          4,
        ),
      ),
    ),
  );
  $handler
    ->setRequest(Request::create('', $query, RequestInterface::METHOD_GET));
  $handler
    ->setPath('');
  $result = drupal_json_decode(restful()
    ->getFormatterManager()
    ->format($handler
    ->process(), 'json'));
  $result = $result['data'];
  $this
    ->assertEqual($nodes['another abc'], $result[0]['id']);

  // Test valid filter with filter params disabled.
  $resource_manager
    ->clearPluginCache($handler
    ->getPluginId());
  $plugin_definition = $handler
    ->getPluginDefinition();
  $plugin_definition['dataProvider']['urlParams'] = array(
    'filter' => FALSE,
    'sort' => TRUE,
    'range' => TRUE,
  );
  $handler
    ->setPluginDefinition($plugin_definition);
  $handler
    ->setDataProvider(NULL);
  $query['filter'] = array(
    'label' => 'abc',
  );
  $handler
    ->setRequest(Request::create('', $query, RequestInterface::METHOD_GET));
  $handler
    ->setPath('');
  try {
    restful()
      ->getFormatterManager()
      ->format($handler
      ->process(), 'json');
    $this
      ->fail('Exception not raised for disabled filter parameter.');
  } catch (UnprocessableEntityException $e) {
    $this
      ->pass('Exception raised for disabled filter parameter.');
  }

  // Filter by an entity metadata wrapper property that is different from the
  // DB column name.
  $handler = $resource_manager
    ->getPlugin('articles:1.5');
  $query = array(
    'filter' => array(
      'user' => array(
        'value' => $user1->uid,
      ),
    ),
  );
  $handler
    ->setRequest(Request::create('', $query, RequestInterface::METHOD_GET));
  $handler
    ->setPath('');
  $result = drupal_json_decode(restful()
    ->getFormatterManager()
    ->format($handler
    ->process(), 'json'));
  $result = $result['data'];
  $this
    ->assertEqual(count($result), 2, 'List filtered by the "author" entity metadata wrapper property, which maps to the "uid" DB column name.');
  $query = array(
    'filter' => array(
      'static' => array(
        'value' => 0,
      ),
    ),
  );
  $handler
    ->setRequest(Request::create('', $query, RequestInterface::METHOD_GET));
  $handler
    ->setPath('');
  try {
    restful()
      ->getFormatterManager()
      ->format($handler
      ->process(), 'json');
    $this
      ->fail('Illegal filter property used.');
  } catch (BadRequestException $e) {
    $this
      ->pass('Exception thrown on illegal filter property.');
  }
}