You are here

public function IndexFacetsTest::testWithFacets in JSON:API Search API 8

Test facet data.

@dataProvider dataForFacets

File

modules/jsonapi_search_api_facets/tests/src/Functional/IndexFacetsTest.php, line 150

Class

IndexFacetsTest
Tests searching with facets.

Namespace

Drupal\Tests\jsonapi_search_api_facets\Functional

Code

public function testWithFacets(array $faceted_fields, bool $show_numbers, array $facet_query, int $expected_filtered_count) {
  foreach ($faceted_fields as $field_name => $faceted_field) {
    $query_operator = $faceted_field['query_operator'] ?? 'or';
    $facet_filter_path = $faceted_field['alias'] ?? $field_name;
    $this
      ->createFacet($field_name, $faceted_field['name'], $facet_filter_path, $query_operator, $show_numbers);
  }
  $url = Url::fromRoute('jsonapi_search_api.index_database_search_index');
  $data = $this
    ->doRequest($url);
  $this
    ->assertArrayHasKey('facets', $data['meta']);
  foreach ($data['meta']['facets'] as $facet) {
    $this
      ->assertArrayHasKey($facet['id'], $faceted_fields);
    $faceted_field_info = $faceted_fields[$facet['id']];
    $this
      ->assertEquals($faceted_field_info['name'], $facet['label'], var_export($facet, TRUE));
    $first_term = $facet['terms'][0];
    $this
      ->assertUrlFilterParams($first_term, [
      $facet['path'] => $first_term['values']['value'],
    ]);
    $this
      ->assertEquals($show_numbers, isset($first_term['values']['count']), var_export($facet, TRUE));
  }
  $url
    ->setOption('query', [
    'filter' => $facet_query,
  ]);
  $data = $this
    ->doRequest($url);
  $this
    ->assertCount($expected_filtered_count, $data['data'], var_export($data, TRUE));

  // Check that applied facets are marked as active.
  $filter_condition_paths = [];
  foreach ($facet_query as $filter_name => $filter_condition) {
    $filter_condition_paths[] = is_array($filter_condition) ? $filter_condition['condition']['path'] : $filter_name;
  }
  $applied_facets = array_filter($data['meta']['facets'], static function (array $facet) use ($filter_condition_paths) {
    return in_array($facet['path'], $filter_condition_paths, TRUE);
  });
  $this
    ->assertCount(count($filter_condition_paths), $applied_facets);
  foreach ($applied_facets as $facet) {
    $active_terms = array_filter($facet['terms'], static function (array $term) {
      return $term['values']['active'] === TRUE;
    });
    $this
      ->assertNotCount(0, $active_terms, var_export($facet['terms'], TRUE));
    $first_term = $facet['terms'][0];
    $expected_filter_query = $facet_query;

    // Remove the current facet condition from the existing filters, so that
    // we may assert it has been updated.
    foreach ($expected_filter_query as $filter_name => $filter_condition) {
      $filter_condition_path = is_array($filter_condition) ? $filter_condition['condition']['path'] : $filter_name;
      if ($filter_condition_path === $facet['path']) {
        unset($expected_filter_query[$filter_name]);
      }
    }

    // The facet URL should contain the active terms, and the first time.
    // The first term may be an active term, so we filter it out when
    // determing the values.
    $expected_filter_query_facets = $active_terms;
    $expected_filter_query_facets[] = $first_term;
    $expected_filter_query_values = array_unique(array_values(array_map(static function (array $item) {
      return $item['values']['value'];
    }, $expected_filter_query_facets)));
    if (count($expected_filter_query_values) > 1) {
      $expected_filter_query[strtr('!field-facet', [
        '!field' => $facet['path'],
      ])] = [
        'condition' => [
          'path' => $facet['path'],
          'operator' => 'IN',
          'value' => $expected_filter_query_values,
        ],
      ];
    }
    else {
      $expected_filter_query[$facet['path']] = $first_term['values']['value'];
    }
    $this
      ->assertUrlFilterParams($first_term, $expected_filter_query);
  }
}