smart_trim-8.x-1.3/tests/src/Functional/SmartTrimFunctionalTest.php

tests/src/Functional/SmartTrimFunctionalTest.php
<?php

declare(strict_types=1);

namespace Drupal\Tests\smart_trim\Functional;

use Drupal\Core\Session\AccountInterface;
use Drupal\field\Entity\FieldConfig;
use Drupal\field\Entity\FieldStorageConfig;
use Drupal\node\Entity\Node;
use Drupal\node\Entity\NodeType;
use Drupal\Tests\BrowserTestBase;

/**
 * This class provides methods specifically for testing something.
 *
 * @group smart_trim
 */
class SmartTrimFunctionalTest extends BrowserTestBase {

  /**
   * {@inheritdoc}
   */
  protected static $modules = [
    'node',
    'test_page_test',
    'field',
    'filter',
    'text',
    'token',
    'token_filter',
    'smart_trim',
    'filter_test',
    'field_ui',
  ];

  /**
   * A user with authenticated permissions.
   *
   * @var \Drupal\Core\Session\AccountInterface
   */
  protected AccountInterface $user;

  /**
   * A user with admin permissions.
   *
   * @var \Drupal\Core\Session\AccountInterface
   */
  protected AccountInterface $adminUser;

  /**
   * {@inheritdoc}
   */
  protected $defaultTheme = 'stark';

  /**
   * {@inheritdoc}
   */
  protected function setUp(): void {
    parent::setUp();

    $this->createContentType(['type' => 'article', 'name' => 'Article']);

    $this->config('system.site')->set('page.front', '/test-page')->save();
    $this->user = $this->drupalCreateUser();
    $this->adminUser = $this->drupalCreateUser();
    $this->adminUser->addRole($this->createAdminRole('admin', 'admin'));
    $this->adminUser->save();
    $this->drupalLogin($this->adminUser);

    $this->drupalCreateNode([
      'title' => $this->randomString(),
      'id' => 1,
      'type' => 'article',
      'body' => [
        'value' => "Test [node:content-type]\r\n  ",
        'format' => 'filter_test',
      ],
    ])->save();

    $this->drupalCreateNode([
      'title' => $this->randomString(),
      'id' => 2,
      'type' => 'article',
      'body' => [
        'value' => '<h3>The situation</h3><p>is dire</p><p>& there is no hope.</p><p>Full stop should not be preceded by <em>space</em>. Really, they should not be.</p>',
        'format' => 'filter_test',
      ],
    ])->save();

    NodeType::create(['type' => 'plain_text_test', 'name' => 'Plain text test'])->save();

    // Create Description field.
    FieldStorageConfig::create([
      'field_name' => 'field_plain_text',
      'type' => 'string_long',
      'entity_type' => 'node',
      'cardinality' => 1,
    ])->save();
    FieldConfig::create([
      'field_name' => 'field_plain_text',
      'entity_type' => 'node',
      'bundle' => 'plain_text_test',
      'label' => 'Plain text test field',
    ])->save();

    $node = Node::create([
      'type' => 'plain_text_test',
      'id' => 3,
      'title' => $this->randomString(),
      'field_plain_text' => 'This is a really long string with Fire & ice right in the middle of it.',
    ]);
    $node->save();
  }

  /**
   * Tests if installing the module, won't break the site.
   */
  public function testInstallation() :void {
    $session = $this->assertSession();
    $this->drupalGet('<front>');
    // Ensure the status code is success:
    $session->statusCodeEquals(200);
    // Ensure the correct test page is loaded as front page:
    $session->pageTextContains('Test page text.');
  }

  /**
   * Tests if uninstalling the module, won't break the site.
   */
  public function testUninstallation(): void {
    // Go to uninstallation page to uninstall smart_trim.
    $session = $this->assertSession();
    $page = $this->getSession()->getPage();
    $this->drupalGet('/admin/modules/uninstall');
    $session->statusCodeEquals(200);
    $page->checkField('edit-uninstall-smart-trim');
    $page->pressButton('edit-submit');
    $session->statusCodeEquals(200);
    // Confirm uninstall.
    $page->pressButton('edit-submit');
    $session->statusCodeEquals(200);
    $session->pageTextContains('The selected modules have been uninstalled.');
    // Retest the frontpage.
    $this->drupalGet('<front>');
    // Ensure the status code is success.
    $session->statusCodeEquals(200);
    // Ensure the correct test page is loaded as front page.
    $session->pageTextContains('Test page text.');
  }

  /**
   * Tests if the token will not get cut off when trimming by characters.
   */
  public function testTokenNotCutOffTrimTypeCharacters(): void {
    $session = $this->assertSession();
    $display_repository = \Drupal::service('entity_display.repository');
    // Editing our "filter_test" format:
    $edit = [
      'edit-filters-token-filter-status' => 1,
      'edit-filters-filter-html-escape-status' => 0,
    ];
    $this->drupalGet('admin/config/content/formats/manage/filter_test');
    $this->submitForm($edit, 'Save configuration');
    // Edit formatter settings:
    $display_repository->getViewDisplay('node', 'article')
      ->setComponent('body', [
        'type' => 'smart_trim',
        'settings' => [
          'trim_length' => 10,
          'trim_type' => 'chars',
          'summary_handler' => 'trim',
          'trim_options' => [
            'replace_tokens' => TRUE,
          ],
        ],
      ])
      ->save();

    $this->drupalGet('/node/1');
    // @todo This might change to "Test Article" in the future, because the
    // "trim_type" is a bit confusing, see
    // https://www.drupal.org/project/smart_trim/issues/3308868.
    $session->elementTextEquals('css', 'article > div > div > div:nth-child(2) > p', 'Test');
  }

  /**
   * Tests if the token will not get cut off when trimming by words.
   */
  public function testTokenNotCutOffTrimTypeWords(): void {
    $session = $this->assertSession();
    $display_repository = \Drupal::service('entity_display.repository');
    // Editing our "filter_test" format:
    $edit = [
      'edit-filters-token-filter-status' => 1,
      'edit-filters-filter-html-escape-status' => 0,
    ];
    $this->drupalGet('admin/config/content/formats/manage/filter_test');
    $this->submitForm($edit, 'Save configuration');
    // Edit formatter settings:
    $display_repository->getViewDisplay('node', 'article')
      ->setComponent('body', [
        'type' => 'smart_trim',
        'settings' => [
          'trim_length' => 10,
          'trim_type' => 'words',
          'summary_handler' => 'trim',
          'trim_options' => [
            'replace_tokens' => TRUE,
          ],
        ],
      ])
      ->save();

    $this->drupalGet('/node/1');
    $session->elementTextEquals('css', 'article > div > div > div:nth-child(2) > p', 'Test Article');
  }

  /**
   * Tests the Strip HTML option.
   */
  public function testStripHtml(): void {
    $session = $this->assertSession();
    $display_repository = \Drupal::service('entity_display.repository');
    // Edit formatter settings:
    $display_repository->getViewDisplay('node', 'article')
      ->setComponent('body', [
        'type' => 'smart_trim',
        'settings' => [
          'trim_length' => 7,
          'trim_type' => 'words',
          'summary_handler' => 'trim',
          'trim_options' => [
            'text' => TRUE,
          ],
        ],
      ])
      ->save();

    $this->drupalGet('/node/2');
    $session->elementTextEquals('css', 'article > div > div > div:nth-child(2) > p', 'The situation is dire & there is');
  }

  /**
   * Test to ensure no extra spaces before punctuation.
   *
   * See https://www.drupal.org/project/smart_trim/issues/3369954.
   */
  public function testNoExtraSpaces(): void {
    $session = $this->assertSession();
    $display_repository = \Drupal::service('entity_display.repository');
    // Edit formatter settings:
    $display_repository->getViewDisplay('node', 'article')
      ->setComponent('body', [
        'type' => 'smart_trim',
        'settings' => [
          'trim_length' => 18,
          'trim_type' => 'words',
          'summary_handler' => 'trim',
          'trim_options' => [
            'text' => TRUE,
          ],
        ],
      ])
      ->save();

    $this->drupalGet('/node/2');
    $session->elementTextEquals('css', 'article > div > div > div:nth-child(2) > p', 'The situation is dire & there is no hope. Full stop should not be preceded by space. Really');
  }

  /**
   * Tests the formatter settings summary.
   *
   * @covers \Drupal\smart_trim\Plugin\Field\FieldFormatter\SmartTrimFormatter::settingsSummary
   *
   * @test
   */
  public function testFormatterSettingsSummary(): void {
    /** @var \Drupal\Core\Entity\EntityDisplayRepositoryInterface $display_repository */
    $display_repository = \Drupal::service('entity_display.repository');

    // Check summary with minimal settings and not more link.
    $display_repository->getViewDisplay('node', 'article', 'default')
      ->setComponent('body', [
        'type' => 'smart_trim',
        'settings' => [
          'trim_length' => 100,
          'trim_type' => 'chars',
          'more' => [
            'display_link' => FALSE,
          ],
          'trim_options' => [],
        ],
      ])
      ->save();
    $this->drupalGet('admin/structure/types/manage/article/display');
    $this->assertSession()->responseContains('100 characters');
    $this->assertSession()->responseNotContains('Suffix:');
    $this->assertSession()->responseNotContains('<em>More</em> link enabled');
    $this->assertSession()->responseNotContains('Only display <em>More</em> link when trimmed');
    $this->assertSession()->responseNotContains('Open <em>More</em> link in new window');
    $this->assertSession()->responseNotContains('<em>More</em> link aria-label:');
    $this->assertSession()->responseNotContains('<em>More</em> link class:');
    $this->assertSession()->responseNotContains('Strip HTML');
    $this->assertSession()->responseNotContains('Honor a zero trim length');
    $this->assertSession()->responseNotContains('Replace tokens before trimming');

    // Check summary with 15 words, a suffix, default more link settings, and
    // strip HTML checked.
    $display_repository->getViewDisplay('node', 'article', 'default')
      ->setComponent('body', [
        'type' => 'smart_trim',
        'settings' => [
          'trim_length' => 15,
          'trim_type' => 'words',
          'trim_suffix' => '- - -',
          'more' => [
            'display_link' => TRUE,
            'class' => 'more-link',
            'link_trim_only' => FALSE,
            'target_blank' => FALSE,
            'text' => 'More',
            'aria_label' => 'Read more about [node:title]',
          ],
          'trim_options' => ['text' => 1],
        ],
      ])
      ->save();
    $this->drupalGet('admin/structure/types/manage/article/display');
    $this->assertSession()->responseContains('15 words');
    $this->assertSession()->responseContains('Suffix: <em class="placeholder">- - -</em>');
    $this->assertSession()->responseContains('<em>More</em> link enabled, text: <em class="placeholder">More</em>');
    $this->assertSession()->responseNotContains('Only display <em>More</em> link when trimmed');
    $this->assertSession()->responseNotContains('Open <em>More</em> link in new window');
    $this->assertSession()->responseContains('<em>More</em> link aria-label: <em class="placeholder">Read more about [node:title]</em>');
    $this->assertSession()->responseContains('<em>More</em> link class: <em class="placeholder">more-link</em>');
    $this->assertSession()->responseContains('Strip HTML');
    $this->assertSession()->responseNotContains('Honor a zero trim length');
    $this->assertSession()->responseNotContains('Replace tokens before trimming');

    // Check summary with 99 chars, no suffix, customized more settings, and
    // honor zero length and apply tokens before checked.
    $display_repository->getViewDisplay('node', 'article', 'default')
      ->setComponent('body', [
        'type' => 'smart_trim',
        'settings' => [
          'trim_length' => 99,
          'trim_type' => 'chars',
          'more' => [
            'display_link' => TRUE,
            'class' => 'blah-link',
            'link_trim_only' => TRUE,
            'target_blank' => TRUE,
            'text' => 'Blah',
            'aria_label' => 'Blah blah blah [node:title]',
          ],
          'trim_options' => [
            'trim_zero' => 1,
            'replace_tokens' => 1,
          ],
        ],
      ])
      ->save();
    $this->drupalGet('admin/structure/types/manage/article/display');
    $this->assertSession()->responseContains('99 characters');
    $this->assertSession()->responseNotContains('Suffix:');
    $this->assertSession()->responseContains('<em>More</em> link enabled, text: <em class="placeholder">Blah</em>');
    $this->assertSession()->responseContains('Only display <em>More</em> link when trimmed');
    $this->assertSession()->responseContains('Open <em>More</em> link in new window');
    $this->assertSession()->responseContains('<em>More</em> link aria-label: <em class="placeholder">Blah blah blah [node:title]</em>');
    $this->assertSession()->responseContains('<em>More</em> link class: <em class="placeholder">blah-link</em>');
    $this->assertSession()->responseNotContains('Strip HTML');
    $this->assertSession()->responseContains('Honor a zero trim length');
    $this->assertSession()->responseContains('Replace tokens before trimming');
  }

  /**
   * Tests the more link displays when option selected.
   *
   * @test
   */
  public function testMoreLink(): void {
    $display_repository = \Drupal::service('entity_display.repository');
    // Edit formatter settings:
    $display_repository->getViewDisplay('node', 'article')
      ->setComponent('body', [
        'type' => 'smart_trim',
        'settings' => [
          'trim_length' => 6,
          'trim_type' => 'words',
          'summary_handler' => 'trim',
          'more' => [
            'display_link' => FALSE,
          ],
        ],
      ])
      ->save();

    $this->drupalGet('/node/1');
    $query = $this->xpath('//a[text() = "More"]');
    $this->assertEmpty($query, 'Expected zero "More" links.');

    // Edit formatter settings:
    $display_repository->getViewDisplay('node', 'article')
      ->setComponent('body', [
        'type' => 'smart_trim',
        'settings' => [
          'trim_length' => 6,
          'trim_type' => 'words',
          'summary_handler' => 'trim',
          'more' => [
            'display_link' => TRUE,
            'class' => 'more-link',
            'link_trim_only' => FALSE,
            'target_blank' => FALSE,
            'text' => 'More',
            'aria_label' => 'Read more about [node:title]',
          ],
        ],
      ])
      ->save();
    $this->drupalGet('/node/1');
    $query = $this->xpath('//a[text() = "More"]');
    $this->assertCount(1, $query, 'Expected 1 "More" link.');
  }

  /**
   * Tests that when "wrap output" is selected, wrapper class is output.
   */
  public function testWrapperClass() {
    $display_repository = \Drupal::service('entity_display.repository');
    // Edit formatter settings, specify no wrapper:
    $display_repository->getViewDisplay('node', 'article')
      ->setComponent('body', [
        'type' => 'smart_trim',
        'settings' => [
          'trim_length' => 10,
          'trim_type' => 'words',
          'wrap_output' => FALSE,
          'summary_handler' => 'trim',
          'more' => [
            'display_link' => FALSE,
          ],
        ],
      ])
      ->save();

    // Confirm no wrapper class present.
    $this->drupalGet('/node/1');
    $query = $this->xpath('//div[contains(@class, "trimmed")]');
    $this->assertEquals(0, count($query));

    // Find div following "Body" label.
    $query = $this->xpath('//div[text() = "Body"]/following-sibling::div');
    $this->assertEquals('Test [node:content-type]', $query[0]->getText());

    // Edit formatter settings to use wrapper div and class.
    $display_repository->getViewDisplay('node', 'article')
      ->setComponent('body', [
        'type' => 'smart_trim',
        'settings' => [
          'trim_length' => 10,
          'trim_type' => 'words',
          'wrap_output' => TRUE,
          'wrap_class' => 'trimmed',
          'summary_handler' => 'trim',
          'more' => [
            'display_link' => TRUE,
            'class' => 'more-link',
            'link_trim_only' => FALSE,
            'target_blank' => FALSE,
            'text' => 'More',
            'aria_label' => 'Read more about [node:title]',
          ],
        ],
      ])
      ->save();

    // Check that wrapper class present in output.
    $this->drupalGet('/node/1');
    $query = $this->xpath('//div[contains(@class, "trimmed")]');
    $this->assertEquals(1, count($query));
  }

  /**
   * Tests wrapper class applied to more link when present.
   */
  public function testMoreLinkWrapperClass() {
    $display_repository = \Drupal::service('entity_display.repository');
    // Edit formatter settings, specify no wrapper:
    $display_repository->getViewDisplay('node', 'article')
      ->setComponent('body', [
        'type' => 'smart_trim',
        'settings' => [
          'trim_length' => 10,
          'trim_type' => 'words',
          'wrap_output' => FALSE,
          'summary_handler' => 'trim',
          'more' => [
            'display_link' => FALSE,
          ],
        ],
      ])
      ->save();

    // Confirm that when more link not shown, more wrapper not in content.
    $this->drupalGet('/node/1');
    $query = $this->xpath('//div[contains(@class, "more-link")]');
    $this->assertEquals(0, count($query));

    // Edit formatter settings to display more link wrapper class.
    $display_repository->getViewDisplay('node', 'article')
      ->setComponent('body', [
        'type' => 'smart_trim',
        'settings' => [
          'trim_length' => 10,
          'trim_type' => 'words',
          'wrap_output' => FALSE,
          'summary_handler' => 'trim',
          'more' => [
            'display_link' => TRUE,
            'class' => 'more-link',
            'link_trim_only' => FALSE,
            'target_blank' => FALSE,
            'text' => 'More',
            'aria_label' => 'Read more about [node:title]',
          ],
        ],
      ])
      ->save();

    // Check that default more link wrapper class present in output.
    $this->drupalGet('/node/1');
    $query = $this->xpath('//div[contains(@class, "more-link")]');
    $this->assertEquals(1, count($query));

    // Edit formatter settings with custom more link wrapper class.
    $display_repository->getViewDisplay('node', 'article')
      ->setComponent('body', [
        'type' => 'smart_trim',
        'settings' => [
          'trim_length' => 10,
          'trim_type' => 'words',
          'wrap_output' => FALSE,
          'summary_handler' => 'trim',
          'more' => [
            'display_link' => TRUE,
            'class' => 'more-wrapper',
            'link_trim_only' => FALSE,
            'target_blank' => FALSE,
            'text' => 'More',
            'aria_label' => 'Read more about [node:title]',
          ],
        ],
      ])
      ->save();

    // Check that default more link wrapper class not present.
    $this->drupalGet('/node/1');
    $query = $this->xpath('//div[contains(@class, "more-link")]');
    $this->assertEquals(0, count($query));
    // Check that modified more link wrapper class present in output.
    $query = $this->xpath('//div[contains(@class, "more-wrapper")]');
    $this->assertEquals(1, count($query));
  }

  /**
   * Tests the more link's "open in a new window" configuration.
   */
  public function testOpenInNewWindow() {
    $display_repository = \Drupal::service('entity_display.repository');
    // Edit formatter settings:
    $display_repository->getViewDisplay('node', 'article')
      ->setComponent('body', [
        'type' => 'smart_trim',
        'settings' => [
          'trim_length' => 6,
          'trim_type' => 'words',
          'summary_handler' => 'trim',
          'more' => [
            'display_link' => TRUE,
            'class' => 'more-link',
            'link_trim_only' => FALSE,
            'target_blank' => TRUE,
            'text' => 'More',
            'aria_label' => 'Read more about [node:title]',
          ],
        ],
      ])
      ->save();

    // Verify more link specifies target: _blank.
    $this->drupalGet('/node/1');
    $query = $this->xpath('//a[text() = "More"]');
    $this->assertEquals('_blank', $query[0]->getAttribute('target'));

    // Edit formatter settings:
    $display_repository->getViewDisplay('node', 'article')
      ->setComponent('body', [
        'type' => 'smart_trim',
        'settings' => [
          'trim_length' => 10,
          'trim_type' => 'words',
          'summary_handler' => 'trim',
          'more' => [
            'display_link' => TRUE,
            'class' => 'more-link',
            'link_trim_only' => FALSE,
            'target_blank' => FALSE,
            'text' => 'More',
            'aria_label' => 'Read more about [node:title]',
          ],
        ],
      ])
      ->save();
    // Verify target not present.
    $this->drupalGet('/node/1');
    $query = $this->xpath('//a[text() = "More"]');
    $this->assertNull($query[0]->getAttribute('target'));
  }

  /**
   * Tests the "More link only when content is trimmed" formatter config option.
   */
  public function testMoreLinkOnlyWhenContentIsTrimmed(): void {
    $session = $this->assertSession();
    $display_repository = \Drupal::service('entity_display.repository');
    $display_repository->getViewDisplay('node', 'article')
      ->setComponent('body', [
        'type' => 'smart_trim',
        'settings' => [
          'trim_length' => 100,
          'trim_type' => 'chars',
          'summary_handler' => 'trim',
          'more' => [
            'display_link' => TRUE,
            'class' => 'more-link',
            'link_trim_only' => TRUE,
            'target_blank' => 0,
            'text' => 'More',
            'aria_label' => 'Read more about [node:title]',
          ],
        ],
      ])
      ->save();
    $this->drupalGet('/node/1');
    $session->linkNotExists('More');

    $display_repository->getViewDisplay('node', 'article')
      ->setComponent('body', [
        'type' => 'smart_trim',
        'settings' => [
          'trim_length' => 5,
          'trim_type' => 'chars',
          'summary_handler' => 'trim',
          'more' => [
            'display_link' => TRUE,
            'class' => 'more-link',
            'link_trim_only' => TRUE,
            'target_blank' => 0,
            'text' => 'More',
            'aria_label' => 'Read more about [node:title]',
          ],
        ],
      ])
      ->save();
    $this->drupalGet('/node/1');
    $session->linkExists('More');

    $display_repository->getViewDisplay('node', 'article')
      ->setComponent('body', [
        'type' => 'smart_trim',
        'settings' => [
          'trim_length' => 100,
          'trim_type' => 'chars',
          'summary_handler' => 'trim',
          'more' => [
            'display_link' => TRUE,
            'class' => 'more-link',
            'link_trim_only' => FALSE,
            'target_blank' => 0,
            'text' => 'More',
            'aria_label' => 'Read more about [node:title]',
          ],
        ],
      ])
      ->save();
    $this->drupalGet('/node/1');
    $session->linkExists('More');
  }

  /**
   * Tests that HTML entities are handled correctly.
   *
   * @test
   */
  public function testHtmlEntities(): void {
    $session = $this->assertSession();
    $display_repository = \Drupal::service('entity_display.repository');
    // Edit formatter settings:
    $display_repository->getViewDisplay('node', 'plain_text_test')
      ->setComponent('field_plain_text', [
        'type' => 'smart_trim',
        'settings' => [
          'trim_length' => 10,
          'trim_type' => 'words',
          'summary_handler' => 'ignore',
          'more' => [
            'display_link' => FALSE,
          ],
        ],
      ])
      ->save();

    $this->drupalGet('/node/3');
    $session->pageTextContains('Fire & ice');

    $display_repository->getViewDisplay('node', 'article')
      ->setComponent('body', [
        'type' => 'smart_trim',
        'settings' => [
          'trim_length' => 30,
          'trim_type' => 'chars',
          'summary_handler' => 'trim',
          'more' => [
            'display_link' => FALSE,
          ],
        ],
      ])
      ->save();
    $this->drupalGet('/node/2');
    $session->pageTextContains('& there');
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc