entity_mesh-1.1.1/tests/src/Unit/EntityRenderTest.php

tests/src/Unit/EntityRenderTest.php
<?php

namespace Drupal\Tests\entity_mesh\Unit;

use Drupal\Core\Access\AccessManager;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Language\LanguageManagerInterface;
use Drupal\Core\Render\RendererInterface;
use Drupal\Core\Session\AccountSwitcherInterface;
use Drupal\entity_mesh\EntityRender;
use Drupal\entity_mesh\Language\LanguageNegotiatorSwitcher;
use Drupal\entity_mesh\RepositoryInterface;
use Drupal\entity_mesh\Target;
use Drupal\entity_mesh\ThemeSwitcher;
use Drupal\entity_mesh\TrackerManagerInterface;
use Drupal\Tests\UnitTestCase;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;

/**
 * Tests the EntityRender class.
 *
 * @group entity_mesh
 * @coversDefaultClass \Drupal\entity_mesh\EntityRender
 */
class EntityRenderTest extends UnitTestCase {

  /**
   * The entity render service under test.
   *
   * @var \Drupal\entity_mesh\EntityRender
   */
  protected $entityRender;

  /**
   * The mocked request stack.
   *
   * @var \Symfony\Component\HttpFoundation\RequestStack|\PHPUnit\Framework\MockObject\MockObject
   */
  protected $requestStack;

  /**
   * The mocked repository.
   *
   * @var \Drupal\entity_mesh\RepositoryInterface|\PHPUnit\Framework\MockObject\MockObject
   */
  protected $repository;

  /**
   * The mocked entity type manager.
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface|\PHPUnit\Framework\MockObject\MockObject
   */
  protected $entityTypeManager;

  /**
   * The mocked language manager.
   *
   * @var \Drupal\Core\Language\LanguageManagerInterface|\PHPUnit\Framework\MockObject\MockObject
   */
  protected $languageManager;

  /**
   * The mocked config factory.
   *
   * @var \Drupal\Core\Config\ConfigFactoryInterface|\PHPUnit\Framework\MockObject\MockObject
   */
  protected $configFactory;

  /**
   * The mocked renderer.
   *
   * @var \Drupal\Core\Render\RendererInterface|\PHPUnit\Framework\MockObject\MockObject
   */
  protected $renderer;

  /**
   * The mocked account switcher.
   *
   * @var \Drupal\Core\Session\AccountSwitcherInterface|\PHPUnit\Framework\MockObject\MockObject
   */
  protected $accountSwitcher;

  /**
   * The mocked language negotiator switcher.
   *
   * @var \Drupal\entity_mesh\Language\LanguageNegotiatorSwitcher|\PHPUnit\Framework\MockObject\MockObject
   */
  protected $languageNegotiatorSwitcher;

  /**
   * The mocked module handler.
   *
   * @var \Drupal\Core\Extension\ModuleHandlerInterface|\PHPUnit\Framework\MockObject\MockObject
   */
  protected $moduleHandler;

  /**
   * The mocked access manager.
   *
   * @var \Drupal\Core\Access\AccessManager|\PHPUnit\Framework\MockObject\MockObject
   */
  protected $accessManager;

  /**
   * The mocked theme switcher.
   *
   * @var \Drupal\entity_mesh\ThemeSwitcher|\PHPUnit\Framework\MockObject\MockObject
   */
  protected $themeSwitcher;

  /**
   * The mocked tracker manager.
   *
   * @var \Drupal\entity_mesh\TrackerManagerInterface|\PHPUnit\Framework\MockObject\MockObject
   */
  protected $trackerManager;

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

    $this->repository = $this->createMock(RepositoryInterface::class);
    $this->entityTypeManager = $this->createMock(EntityTypeManagerInterface::class);
    $this->languageManager = $this->createMock(LanguageManagerInterface::class);
    $this->configFactory = $this->createMock(ConfigFactoryInterface::class);
    $this->renderer = $this->createMock(RendererInterface::class);
    $this->accountSwitcher = $this->createMock(AccountSwitcherInterface::class);
    $this->languageNegotiatorSwitcher = $this->createMock(LanguageNegotiatorSwitcher::class);
    $this->moduleHandler = $this->createMock(ModuleHandlerInterface::class);
    $this->accessManager = $this->createMock(AccessManager::class);
    $this->themeSwitcher = $this->createMock(ThemeSwitcher::class);
    $this->trackerManager = $this->createMock(TrackerManagerInterface::class);
    $this->requestStack = $this->createMock(RequestStack::class);

    $this->entityRender = new TestableEntityRender(
      $this->repository,
      $this->entityTypeManager,
      $this->languageManager,
      $this->configFactory,
      $this->renderer,
      $this->accountSwitcher,
      $this->languageNegotiatorSwitcher,
      $this->moduleHandler,
      $this->accessManager,
      $this->themeSwitcher,
      $this->trackerManager
    );
  }

  /**
   * Tests setDataTargetFromRoute with root installation.
   *
   * @covers ::setDataTargetFromRoute
   */
  public function testSetDataTargetFromRouteRootInstallation() {
    $request = new Request();
    $this->requestStack->expects($this->once())
      ->method('getCurrentRequest')
      ->willReturn($request);

    $target = Target::create($this->requestStack);
    $target->setPath('/node/1');

    $routeMatch = [
      '_route' => 'entity.node.canonical',
      '_entity' => $this->createMockEntity('node', '1'),
    ];

    $this->entityRender->setMockRouteMatch($routeMatch);
    $this->entityRender->callSetDataTargetFromRoute($target);

    $this->assertEquals('node', $target->getEntityType());
    $this->assertEquals('1', $target->getEntityId());
  }

  /**
   * Tests setDataTargetFromRoute with subdirectory installation.
   *
   * @covers ::setDataTargetFromRoute
   */
  public function testSetDataTargetFromRouteSubdirectoryInstallation() {
    $request = new Request();
    $request->server->set('SCRIPT_NAME', '/drupal_site/index.php');
    $request->server->set('SCRIPT_FILENAME', '/var/www/html/drupal_site/index.php');
    $this->requestStack->expects($this->once())
      ->method('getCurrentRequest')
      ->willReturn($request);

    $target = Target::create($this->requestStack);
    $target->setPath('/drupal_site/node/1');

    $routeMatch = [
      '_route' => 'entity.node.canonical',
      '_entity' => $this->createMockEntity('node', '1'),
    ];

    $this->entityRender->setMockRouteMatch($routeMatch);
    $this->entityRender->callSetDataTargetFromRoute($target);

    $this->assertEquals('node', $target->getEntityType());
    $this->assertEquals('1', $target->getEntityId());
  }

  /**
   * Tests setDataTargetFromRoute with nested subdirectory installation.
   *
   * @covers ::setDataTargetFromRoute
   */
  public function testSetDataTargetFromRouteNestedSubdirectoryInstallation() {
    $request = new Request();
    $request->server->set('SCRIPT_NAME', '/sites/drupal_site/index.php');
    $request->server->set('SCRIPT_FILENAME', '/var/www/html/sites/drupal_site/index.php');
    $this->requestStack->expects($this->once())
      ->method('getCurrentRequest')
      ->willReturn($request);

    $target = Target::create($this->requestStack);
    $target->setPath('/sites/drupal_site/node/1');

    $routeMatch = [
      '_route' => 'entity.node.canonical',
      '_entity' => $this->createMockEntity('node', '1'),
    ];

    $this->entityRender->setMockRouteMatch($routeMatch);
    $this->entityRender->callSetDataTargetFromRoute($target);

    $this->assertEquals('node', $target->getEntityType());
    $this->assertEquals('1', $target->getEntityId());
  }

  /**
   * Tests setDataTargetFromRoute with trailing slash in base path.
   *
   * @covers ::setDataTargetFromRoute
   */
  public function testSetDataTargetFromRouteTrailingSlash() {
    $request = new Request();
    $request->server->set('SCRIPT_NAME', '/drupal_site/index.php');
    $request->server->set('SCRIPT_FILENAME', '/var/www/html/drupal_site/index.php');
    $this->requestStack->expects($this->once())
      ->method('getCurrentRequest')
      ->willReturn($request);

    $target = Target::create($this->requestStack);
    $target->setPath('/drupal_site/node/1');

    $routeMatch = [
      '_route' => 'entity.node.canonical',
      '_entity' => $this->createMockEntity('node', '1'),
    ];

    $this->entityRender->setMockRouteMatch($routeMatch);
    $this->entityRender->callSetDataTargetFromRoute($target);

    $this->assertEquals('node', $target->getEntityType());
    $this->assertEquals('1', $target->getEntityId());
  }

  /**
   * Tests setDataTargetFromRoute when route matching fails.
   *
   * @covers ::setDataTargetFromRoute
   */
  public function testSetDataTargetFromRouteBrokenLink() {
    $request = new Request();
    $request->server->set('SCRIPT_NAME', '/drupal_site/index.php');
    $this->requestStack->expects($this->once())
      ->method('getCurrentRequest')
      ->willReturn($request);

    $target = Target::create($this->requestStack);
    $target->setPath('/drupal_site/non-existent');

    $this->entityRender->setRouteMatchException(new \Exception('Route not found'));
    $this->entityRender->callSetDataTargetFromRoute($target);

    $this->assertEquals('broken-link', $target->getSubcategory());
  }

  /**
   * Tests setDataTargetFromRoute with no request.
   *
   * @covers ::setDataTargetFromRoute
   */
  public function testSetDataTargetFromRouteNoRequest() {
    $this->requestStack->expects($this->once())
      ->method('getCurrentRequest')
      ->willReturn(NULL);

    $target = Target::create($this->requestStack);
    $target->setPath('/node/1');

    $routeMatch = [
      '_route' => 'entity.node.canonical',
      '_entity' => $this->createMockEntity('node', '1'),
    ];

    $this->entityRender->setMockRouteMatch($routeMatch);
    $this->entityRender->callSetDataTargetFromRoute($target);

    $this->assertEquals('node', $target->getEntityType());
    $this->assertEquals('1', $target->getEntityId());
  }

  /**
   * Tests setDataTargetFromRoute with view route.
   *
   * @covers ::setDataTargetFromRoute
   */
  public function testSetDataTargetFromRouteViewRoute() {
    $request = new Request();
    $request->server->set('SCRIPT_NAME', '/drupal_site/index.php');
    $this->requestStack->expects($this->once())
      ->method('getCurrentRequest')
      ->willReturn($request);

    $target = Target::create($this->requestStack);
    $target->setPath('/drupal_site/admin/content');

    $routeMatch = [
      '_route' => 'view.content.page_1',
      'view_id' => 'content',
      'display_id' => 'page_1',
    ];

    $this->entityRender->setMockRouteMatch($routeMatch);
    $this->entityRender->callSetDataTargetFromRoute($target);

    $this->assertEquals('view', $target->getEntityType());
    $this->assertEquals('content.page_1', $target->getEntityId());
  }

  /**
   * Creates a mock entity.
   *
   * @param string $entity_type
   *   The entity type.
   * @param string $id
   *   The entity ID.
   *
   * @return \Drupal\Core\Entity\EntityInterface|\PHPUnit\Framework\MockObject\MockObject
   *   The mock entity.
   */
  protected function createMockEntity($entity_type, $id) {
    $entity = $this->createMock(EntityInterface::class);
    $entity->expects($this->any())
      ->method('getEntityTypeId')
      ->willReturn($entity_type);
    $entity->expects($this->any())
      ->method('id')
      ->willReturn($id);
    return $entity;
  }

}

/**
 * Testable version of EntityRender that allows mocking router service.
 */
class TestableEntityRender extends EntityRender {

  /**
   * Mock route match to return.
   *
   * @var array
   */
  protected $mockRouteMatch;

  /**
   * Exception to throw when matching routes.
   *
   * @var \Exception|null
   */
  protected $routeMatchException;

  /**
   * Sets the mock route match.
   *
   * @param array $routeMatch
   *   The route match to return.
   */
  public function setMockRouteMatch(array $routeMatch) {
    $this->mockRouteMatch = $routeMatch;
  }

  /**
   * Sets an exception to throw when matching routes.
   *
   * @param \Exception $exception
   *   The exception to throw.
   */
  public function setRouteMatchException(\Exception $exception) {
    $this->routeMatchException = $exception;
  }

  /**
   * Public wrapper for protected setDataTargetFromRoute method.
   *
   * @param \Drupal\entity_mesh\Target $target
   *   The target.
   */
  public function callSetDataTargetFromRoute($target) {
    $this->setDataTargetFromRoute($target);
  }

  /**
   * {@inheritdoc}
   */
  protected function setDataTargetFromRoute($target) {
    if (empty($target->getPath())) {
      return;
    }

    if ($this->routeMatchException) {
      $target->setSubcategory('broken-link');
      return;
    }

    $route_match = $this->mockRouteMatch;

    if (empty($route_match['_route'])) {
      $target->setSubcategory('broken-link');
      return;
    }

    $entity = $this->checkAndGetEntityFromEntityRoute($route_match);
    if ($entity instanceof EntityInterface) {
      $target->setEntityType($entity->getEntityTypeId());
      $target->setEntityId((string) $entity->id());
      return;
    }

    if (isset($route_match['view_id']) && isset($route_match['display_id'])) {
      $target->setEntityType('view');
      $target->setEntityId($route_match['view_id'] . '.' . $route_match['display_id']);
      return;
    }

    $route_parts = explode('.', $route_match['_route']);
    if (count($route_parts) > 1) {
      $entity = $route_parts[1];
      $target->setEntityType($entity);
      $target->setEntityId("");
    }
  }

  /**
   * {@inheritdoc}
   */
  protected function checkAndGetEntityFromEntityRoute(array $route_match): ?EntityInterface {
    return $route_match['_entity'] ?? NULL;
  }

}

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

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