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;
}
}
