You are here

public function NodeLanguageTest::testLanguages in Drupal 9

Same name and namespace in other branches
  1. 8 core/modules/node/tests/src/Functional/Views/NodeLanguageTest.php \Drupal\Tests\node\Functional\Views\NodeLanguageTest::testLanguages()

Tests translation language filter, field, and sort.

File

core/modules/node/tests/src/Functional/Views/NodeLanguageTest.php, line 114

Class

NodeLanguageTest
Tests node language fields, filters, and sorting.

Namespace

Drupal\Tests\node\Functional\Views

Code

public function testLanguages() {

  // Test the page with no arguments. It is filtered to Spanish and French.
  // The page shows node titles and languages.
  $this
    ->drupalGet('test-language');
  $message = 'French/Spanish page';

  // Test that the correct nodes are shown.
  foreach ($this->nodeTitles as $langcode => $list) {
    foreach ($list as $title) {
      if ($langcode == 'en') {
        $this
          ->assertSession()
          ->pageTextNotContains($title);
      }
      else {
        $this
          ->assertSession()
          ->pageTextContains($title);
      }
    }
  }

  // Test that the language field value is shown.
  $this
    ->assertSession()
    ->pageTextNotContains('English');
  $this
    ->assertSession()
    ->pageTextContains('French');
  $this
    ->assertSession()
    ->pageTextContains('Spanish');

  // Test page sorting, which is by language code, ascending. So the
  // Spanish nodes should appear before the French nodes.
  $page = $this
    ->getTextContent();
  $pos_es_max = 0;
  $pos_fr_min = 10000;
  foreach ($this->nodeTitles['es'] as $title) {
    $pos_es_max = max($pos_es_max, strpos($page, $title));
  }
  foreach ($this->nodeTitles['fr'] as $title) {
    $pos_fr_min = min($pos_fr_min, strpos($page, $title));
  }
  $this
    ->assertLessThan($pos_fr_min, $pos_es_max, "The Spanish translation should appear before the French one on {$message}.");

  // Test the argument -- filter to just Spanish.
  $this
    ->drupalGet('test-language/es');

  // This time, test just the language field.
  $message = 'Spanish argument page';
  $this
    ->assertSession()
    ->pageTextNotContains('English');
  $this
    ->assertSession()
    ->pageTextNotContains('French');
  $this
    ->assertSession()
    ->pageTextContains('Spanish');

  // Test the front page view filter. Only node titles in the current language
  // should be displayed on the front page by default.
  foreach ($this->nodeTitles as $langcode => $titles) {

    // The frontpage view does not display content without a language.
    if ($langcode == LanguageInterface::LANGCODE_NOT_SPECIFIED) {
      continue;
    }
    $this
      ->drupalGet(($langcode == 'en' ? '' : "{$langcode}/") . 'node');
    foreach ($titles as $title) {
      $this
        ->assertSession()
        ->pageTextContains($title);
    }
    foreach ($this->nodeTitles as $control_langcode => $control_titles) {
      if ($langcode != $control_langcode) {
        foreach ($control_titles as $title) {
          $this
            ->assertSession()
            ->pageTextNotContains($title);
        }
      }
    }
  }

  // Test the node admin view filter. By default all translations should show.
  $this
    ->drupalGet('admin/content');
  foreach ($this->nodeTitles as $titles) {
    foreach ($titles as $title) {
      $this
        ->assertSession()
        ->pageTextContains($title);
    }
  }

  // When filtered, only the specific languages should show.
  foreach ($this->nodeTitles as $langcode => $titles) {
    $this
      ->drupalGet('admin/content', [
      'query' => [
        'langcode' => $langcode,
      ],
    ]);
    foreach ($titles as $title) {
      $this
        ->assertSession()
        ->pageTextContains($title);
    }
    foreach ($this->nodeTitles as $control_langcode => $control_titles) {
      if ($langcode != $control_langcode) {
        foreach ($control_titles as $title) {
          $this
            ->assertSession()
            ->pageTextNotContains($title);
        }
      }
    }
  }

  // Override the config for the front page view, so that the language
  // filter is set to the site default language instead. This should just
  // show the English nodes, no matter what the content language is.
  $config = $this
    ->config('views.view.frontpage');
  $config
    ->set('display.default.display_options.filters.langcode.value', [
    PluginBase::VIEWS_QUERY_LANGUAGE_SITE_DEFAULT => PluginBase::VIEWS_QUERY_LANGUAGE_SITE_DEFAULT,
  ]);
  $config
    ->save();
  foreach ($this->nodeTitles as $langcode => $titles) {
    if ($langcode == LanguageInterface::LANGCODE_NOT_SPECIFIED) {
      continue;
    }
    $this
      ->drupalGet(($langcode == 'en' ? '' : "{$langcode}/") . 'node');
    foreach ($this->nodeTitles as $control_langcode => $control_titles) {
      foreach ($control_titles as $title) {
        if ($control_langcode == 'en') {
          $this
            ->assertSession()
            ->pageTextContains($title);
        }
        else {
          $this
            ->assertSession()
            ->pageTextNotContains($title);
        }
      }
    }
  }

  // Override the config so that the language filter is set to the UI
  // language, and make that have a fixed value of 'es'.
  //
  // IMPORTANT: Make sure this part of the test is last -- it is changing
  // language configuration!
  $config
    ->set('display.default.display_options.filters.langcode.value', [
    '***LANGUAGE_language_interface***' => '***LANGUAGE_language_interface***',
  ]);
  $config
    ->save();
  $language_config = $this
    ->config('language.types');
  $language_config
    ->set('negotiation.language_interface.enabled', [
    'language-selected' => 1,
  ]);
  $language_config
    ->save();
  $language_config = $this
    ->config('language.negotiation');
  $language_config
    ->set('selected_langcode', 'es');
  $language_config
    ->save();

  // With a fixed language selected, there is no language-based URL.
  $this
    ->drupalGet('node');
  foreach ($this->nodeTitles as $control_langcode => $control_titles) {
    foreach ($control_titles as $title) {
      if ($control_langcode == 'es') {
        $this
          ->assertSession()
          ->pageTextContains($title);
      }
      else {
        $this
          ->assertSession()
          ->pageTextNotContains($title);
      }
    }
  }
}