linkchecker-8.x-1.x-dev/tests/src/Kernel/LinkcheckerCleanUpTest.php

tests/src/Kernel/LinkcheckerCleanUpTest.php
<?php

namespace Drupal\Tests\linkchecker\Kernel;

use Drupal\Core\Queue\DatabaseQueue;
use Drupal\KernelTests\KernelTestBase;
use Drupal\linkchecker\Entity\LinkCheckerLink;
use Drupal\node\Entity\NodeType;
use Drupal\node\NodeInterface;
use Drupal\Tests\node\Traits\NodeCreationTrait;

/**
 * Test for linkchecker.clean_up service.
 *
 * @coversDefaultClass \Drupal\linkchecker\LinkCleanUp
 *
 * @group linkchecker
 */
class LinkcheckerCleanUpTest extends KernelTestBase {

  use NodeCreationTrait;

  /**
   * {@inheritdoc}
   */
  protected static $modules = [
    'system',
    'linkchecker',
    'node',
    'user',
    'field',
    'filter',
    'text',
  ];

  /**
   * The link checker service.
   *
   * @var \Drupal\linkchecker\LinkCheckerService
   */
  protected $linkChecker;

  /**
   * The link clean up service.
   *
   * @var \Drupal\linkchecker\LinkCleanUp
   */
  protected $linkCleanUp;

  /**
   * The link checker link storage.
   *
   * @var \Drupal\Core\Entity\EntityStorageInterface
   */
  protected $linkCheckerLinkStorage;

  /**
   * {@inheritdoc}
   */
  public function setUp(): void {
    parent::setUp();
    // Installing sequences table is deprecated since 10.2 release so call it
    // conditionally.
    // @see https://www.drupal.org/node/3349345
    if (version_compare(\Drupal::VERSION, '10.2', '<')) {
      $this->installSchema('system', 'sequences');
    }
    $this->installEntitySchema('node');
    $this->installSchema('node', 'node_access');
    $this->installEntitySchema('user');
    $this->installEntitySchema('linkcheckerlink');
    $this->installConfig(['field', 'node', 'filter', 'linkchecker']);
    $this->installSchema('linkchecker', 'linkchecker_index');

    $this->linkCleanUp = $this->container->get('linkchecker.clean_up');
    $this->linkCheckerLinkStorage = $this->container->get('entity_type.manager')
      ->getStorage('linkcheckerlink');
    $this->linkChecker = $this->container->get('linkchecker.checker');

    // Prepare queue table cuz it's being used in hook_entity_delete().
    $database_connection = $this->container->get('database');
    $database_schema = $database_connection->schema();
    $database_queue = new DatabaseQueue($this->randomString(), $database_connection);
    $schema_definition = $database_queue->schemaDefinition();
    $database_schema->createTable(DatabaseQueue::TABLE_NAME, $schema_definition);
  }

  /**
   * @covers ::cleanUpForEntity
   */
  public function testEntityCleanup() {
    $urls = [
      'http://httpstat.us/304',
      'http://httpstat.us/503',
    ];

    $node_type = NodeType::create([
      'type' => 'page',
    ]);
    $node_type->save();
    node_add_body_field($node_type);
    $node = $this->createNode([
      'type' => 'page',
      'body' => [
        [
          'value' => '
          <a href="http://httpstat.us/304">The nightmare continues</a>',
        ],
      ],
    ]);
    $fieldDefinition = $node->get('body')->getFieldDefinition();
    /** @var \Drupal\field\Entity\FieldConfig $config */
    $config = $fieldDefinition->getConfig($node->bundle());
    $config->setThirdPartySetting('linkchecker', 'scan', TRUE);
    $config->setThirdPartySetting('linkchecker', 'extractor', 'html_link_extractor');
    $config->save();

    foreach ($urls as $url) {
      $link = $this->createDummyLink($url);
      $link->setParentEntity($node);
      $link->setParentEntityFieldName($config->getName());
      $link->save();
    }

    // So, given we have 2 link entities that seemingly belong to this new
    // entity, and then we run the cleanup function to see which links should
    // really be there, we now expect it to be 1 link, since only one of them
    // are found in the node body.
    $this->assertCount(2, $this->linkCheckerLinkStorage->loadMultiple(NULL));
    $this->linkCleanUp->cleanUpForEntity($node);
    $this->assertCount(1, $this->linkCheckerLinkStorage->loadMultiple(NULL));
  }

  /**
   * @covers ::removeAllBatch
   */
  public function testRemoveAllBatch() {
    $urls = [
      'https://existing.com',
      'https://not-existing.com',
      'https://example.com/existing',
    ];

    foreach ($urls as $url) {
      $this->createDummyLink($url);
    }

    $this->assertCount(3, $this->linkCheckerLinkStorage->loadMultiple(NULL));

    $this->linkCleanUp->removeAllBatch();
    $this->runBatch();

    $this->assertEmpty($this->linkCheckerLinkStorage->loadMultiple($this->linkCheckerLinkStorage->loadMultiple(NULL)));
  }

  /**
   * Checks if removed links are being cleared from queues.
   */
  public function testQueueCleanUp(): void {
    $type = NodeType::create(['name' => 'Links', 'type' => 'links']);
    $type->save();
    node_add_body_field($type);

    $node = $this->createNode([
      'type' => 'links',
      'body' => [
        [
          'value' => '<a href="https://existing.com"></a>',
        ],
      ],
      'status' => NodeInterface::PUBLISHED,
    ]);

    $fieldDefinition = $node->get('body')->getFieldDefinition();
    $config = $fieldDefinition->getConfig($node->bundle());
    $config->setThirdPartySetting('linkchecker', 'scan', TRUE);
    $config->setThirdPartySetting('linkchecker', 'extractor', 'html_link_extractor');
    $config->save();

    // Re-save the node, so we can find it in the linkchecker entities.
    $node->save();

    // We expect it to be queued 1 item if we run the service now.
    $number = $this->linkChecker->queueLinks(TRUE);
    self::assertEquals(1, $number);

    // Now delete the link entity and see if it was cleared from queue.
    $this->linkCheckerLinkStorage->delete($this->linkCheckerLinkStorage->loadMultiple());
    $number_after_deletion = $this->linkChecker->queueLinks();
    self::assertEquals(0, $number_after_deletion);

    // Try a case when 1 queue item contains multiple linkchecker entities ids.
    // Only the id of the entity that was deleted should be cleaned but the
    // queue item should stay.
    $node2 = $this->createNode([
      'type' => 'links',
      'body' => [
        [
          'value' => '<a href="https://existing.com"></a> and another link - <a href="https://google.com/non-existing"></a>',
        ],
      ],
      'status' => NodeInterface::PUBLISHED,
    ]);
    $node2->save();

    $number = $this->linkChecker->queueLinks(TRUE);
    // Verify that only 1 item is in queue.
    self::assertEquals(1, $number);
    $links_ids = $this->linkCheckerLinkStorage->getQuery()->accessCheck(FALSE)->execute();
    // Verify that both links are created.
    self::assertCount(2, $links_ids);
    [$to_delete_id, $remaining_id] = array_values($links_ids);
    // Delete 1 entity and verify that queue item is not deleted but containing
    // only 1 id.
    $this->linkCheckerLinkStorage->delete([$this->linkCheckerLinkStorage->load($to_delete_id)]);
    $queue_item = $this->container->get('database')
      ->select('queue', 'q')
      ->fields('q', ['data'])
      ->condition('name', 'linkchecker_check')
      ->execute()
      ->fetchCol();
    self::assertNotEmpty($queue_item);
    $queue_item_unserialized = unserialize(reset($queue_item), ['allowed_classes' => FALSE]);
    self::assertTrue(in_array($remaining_id, $queue_item_unserialized, TRUE) && !in_array($to_delete_id, $queue_item_unserialized, TRUE));
  }

  /**
   * Helper function for link creation.
   */
  protected function createDummyLink($url) {
    /** @var \Drupal\linkchecker\Entity\LinkCheckerLink $link */
    $link = LinkCheckerLink::create([
      'url' => $url,
      'parent_entity_type_id' => 'dummy_type',
      'parent_entity_id' => 1,
      'entity_field' => 'dummy_field',
      'entity_langcode' => 'en',
    ]);
    $link->save();
    return $link;
  }

  /**
   * Runs the currently set batch, if any exists.
   */
  protected function runBatch() {
    $batch = &batch_get();
    if ($batch) {
      $batch['progressive'] = FALSE;
      batch_process();
    }
  }

}

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

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