class PageContextTest
Tests the PageContext Top Bar item build output.
Attributes
#[CoversClass(PageContext::class)]
#[Group('navigation')]
Hierarchy
- class \Drupal\Tests\UnitTestCase uses \Drupal\Tests\PhpUnitCompatibilityTrait, \Prophecy\PhpUnit\ProphecyTrait, \Drupal\TestTools\Extension\DeprecationBridge\ExpectDeprecationTrait, \Drupal\Tests\RandomGeneratorTrait extends \PHPUnit\Framework\TestCase
- class \Drupal\Tests\navigation\Unit\PageContextTest uses \Drupal\Core\StringTranslation\StringTranslationTrait extends \Drupal\Tests\UnitTestCase
Expanded class hierarchy of PageContextTest
File
-
core/
modules/ navigation/ tests/ src/ Unit/ PageContextTest.php, line 26
Namespace
Drupal\Tests\navigation\UnitView source
class PageContextTest extends UnitTestCase {
use StringTranslationTrait;
/**
* {@inheritdoc}
*/
protected function setUp() : void {
parent::setUp();
$container = new ContainerBuilder();
$container->set('string_translation', $this->getStringTranslationStub());
\Drupal::setContainer($container);
}
/**
* Tests the build method when no entity is present on the route.
*/
public function testBuildWhenNoEntityOnRoute() : void {
$route_helper = $this->prophesize(EntityRouteHelper::class);
$route_helper->getContentEntityFromRoute()
->willReturn(NULL);
$entity_repository = $this->prophesize(EntityRepositoryInterface::class)
->reveal();
$moderation_information = $this->prophesize(ModerationInformationInterface::class)
->reveal();
$plugin = new PageContext([], 'page_context', [], $route_helper->reveal(), $entity_repository, $moderation_information);
$build = $plugin->build();
$this->assertSame([
'#cache' => [
'contexts' => [
'route',
],
],
], $build);
}
/**
* Tests the build of an entity label within the page context plugin.
*
* @param mixed $label_value
* The return value of the entity label method. Can be a string,
* render array, stringable object, or an invalid value.
* @param string|array|null $expected
* The expected parsed label value for the page context. If the label is
* invalid, the value should be NULL.
*/
public function testBuildEntityLabel(mixed $label_value, string|array|null $expected) : void {
// Route returns an entity with different label return types.
$entity = $this->prophesize(ContentEntityInterface::class);
$entity->label()
->willReturn($label_value);
$route_helper = $this->prophesize(EntityRouteHelper::class);
$route_helper->getContentEntityFromRoute()
->willReturn($entity->reveal());
$entity_repository = $this->prophesize(EntityRepositoryInterface::class)
->reveal();
$moderation_information = $this->prophesize(ModerationInformationInterface::class)
->reveal();
$plugin = new PageContext([], 'page_context', [], $route_helper->reveal(), $entity_repository, $moderation_information);
$build = $plugin->build();
$expected_base = [
'#cache' => [
'contexts' => [
'route',
],
],
];
if ($expected === NULL) {
// Invalid label → no components added.
$this->assertSame($expected_base, $build);
return;
}
// Title component should be present as the first item.
$this->assertArrayHasKey(0, $build);
$this->assertSame('component', $build[0]['#type']);
$this->assertSame('navigation:title', $build[0]['#component']);
$this->assertSame('database', $build[0]['#props']['icon']);
$this->assertSame($expected, $build[0]['#slots']['content']);
}
/**
* Data provider for entity label scenarios.
*
* @return array
* [label_return_value, expected]
*/
public static function entityLabelProvider() : array {
$stringable = new class implements \Stringable {
/**
* Dummy string method.
*
* @return string
* The dummy entity label.
*/
public function __toString() : string {
return 'Stringable Label';
}
};
return [
'string' => [
'My Label',
'My Label',
],
'stringable' => [
$stringable,
'Stringable Label',
],
'render_array' => [
[
'#markup' => 'Rendered Label',
],
NULL,
],
'invalid' => [
new \stdClass(),
NULL,
],
];
}
/**
* Tests the status badge for published and unpublished entities.
*/
public function testBuildStatusBadge() : void {
$entity = $this->prophesize(ContentEntityInterface::class);
$entity->willImplement(EntityPublishedInterface::class);
$entity->isPublished()
->willReturn(TRUE);
$entity->label()
->willReturn('Published Title');
$route_helper = $this->prophesize(EntityRouteHelper::class);
$route_helper->getContentEntityFromRoute()
->willReturn($entity->reveal());
$entity_repository = $this->prophesize(EntityRepositoryInterface::class)
->reveal();
$published_plugin = new PageContext([], 'page_context', [], $route_helper->reveal(), $entity_repository, NULL);
$build = $published_plugin->build();
$this->assertSame('Published Title', $build[0]['#slots']['content']);
$this->assertSame('navigation:badge', $build[1]['#component']);
$this->assertSame('Published', $build[1]['#slots']['label']);
$this->assertSame('success', $build[1]['#props']['status']);
// Now assert the Unpublished path.
$entity->isPublished()
->willReturn(FALSE);
$entity->label()
->willReturn('Unpublished Title');
$route_helper->getContentEntityFromRoute()
->willReturn($entity->reveal());
$plugin = new PageContext([], 'page_context', [], $route_helper->reveal(), $entity_repository, NULL);
$build = $plugin->build();
$this->assertSame('Unpublished Title', $build[0]['#slots']['content']);
$this->assertSame('Unpublished', $build[1]['#slots']['label']);
$this->assertSame('info', $build[1]['#props']['status']);
}
/**
* Tests content moderation build output with no pending revisions.
*/
public function testBuildContentModerationNoPending() : void {
// Mock moderated content entity with state 'draft'.
$entity = $this->prophesize(ContentEntityInterface::class);
$entity->get('moderation_state')
->willReturn((object) [
'value' => 'draft',
]);
$entity->isDefaultRevision()
->willReturn(TRUE);
$entity->getEntityTypeId()
->willReturn('node');
$entity->id()
->willReturn('1');
$entity->label()
->willReturn('Example Title');
// Workflow chain: workflow -> type plugin -> state('draft')->label() => 'Draft'.
$state = $this->prophesize(StateInterface::class);
$state->label()
->willReturn('Draft');
$type = $this->prophesize(WorkflowTypeInterface::class);
$type->getState('draft')
->willReturn($state->reveal());
$workflow = $this->prophesize(WorkflowInterface::class);
$workflow->getTypePlugin()
->willReturn($type->reveal());
$moderation = $this->prophesize(ModerationInformationInterface::class);
$moderation->isModeratedEntity($entity->reveal())
->willReturn(TRUE);
$moderation->getWorkflowForEntity($entity->reveal())
->willReturn($workflow->reveal());
$moderation->hasPendingRevision($entity->reveal())
->willReturn(FALSE);
$route_helper = $this->prophesize(EntityRouteHelper::class);
$route_helper->getContentEntityFromRoute()
->willReturn($entity->reveal());
$entity_repository = $this->prophesize(EntityRepositoryInterface::class)
->reveal();
$plugin = new PageContext([], 'page_context', [], $route_helper->reveal(), $entity_repository, $moderation->reveal());
$build = $plugin->build();
// Title component.
$this->assertSame('Example Title', $build[0]['#slots']['content']);
// Badge component with label Draft, default status info (not published interface).
$this->assertSame('navigation:badge', $build[1]['#component']);
$this->assertSame('Draft', $build[1]['#slots']['label']);
$this->assertSame('info', $build[1]['#props']['status']);
}
/**
* Tests the content moderation build when is active with a pending entity.
*/
public function testBuildContentModerationWithPendingActive() : void {
// Entity current state is 'draft', active is 'published'.
$entity = $this->prophesize(ContentEntityInterface::class);
$entity->get('moderation_state')
->willReturn((object) [
'value' => 'draft',
]);
$entity->isDefaultRevision()
->willReturn(TRUE);
$entity->getEntityTypeId()
->willReturn('node');
$entity->id()
->willReturn('1');
$entity->label()
->willReturn('Example Title');
$active = $this->prophesize(ContentEntityInterface::class);
$active->get('moderation_state')
->willReturn((object) [
'value' => 'published',
]);
// State objects and labels.
$draft_state = $this->prophesize(StateInterface::class);
$draft_state->label()
->willReturn('Draft');
$published_state = $this->prophesize(StateInterface::class);
$published_state->label()
->willReturn('Published');
$type = $this->prophesize(WorkflowTypeInterface::class);
$type->getState('draft')
->willReturn($draft_state->reveal());
$type->getState('published')
->willReturn($published_state->reveal());
$workflow = $this->prophesize(WorkflowInterface::class);
$workflow->getTypePlugin()
->willReturn($type->reveal());
$moderation = $this->prophesize(ModerationInformationInterface::class);
$moderation->isModeratedEntity($entity->reveal())
->willReturn(TRUE);
$moderation->getWorkflowForEntity($entity->reveal())
->willReturn($workflow->reveal());
$moderation->getWorkflowForEntity($active->reveal())
->willReturn($workflow->reveal());
$moderation->hasPendingRevision($entity->reveal())
->willReturn(TRUE);
$entity_repository = $this->prophesize(EntityRepositoryInterface::class);
$entity_repository->getActive('node', '1')
->willReturn($active->reveal());
$route_helper = $this->prophesize(EntityRouteHelper::class);
$route_helper->getContentEntityFromRoute()
->willReturn($entity->reveal());
$plugin = new PageContext([], 'page_context', [], $route_helper->reveal(), $entity_repository->reveal(), $moderation->reveal());
$build = $plugin->build();
$this->assertSame('Example Title', $build[0]['#slots']['content']);
$this->assertSame('navigation:badge', $build[1]['#component']);
$this->assertSame('Draft (Published available)', $build[1]['#slots']['label']);
// Status still defaults to info as entity might not be EntityPublishedInterface here.
$this->assertSame('info', $build[1]['#props']['status']);
}
/**
* Tests the behavior of a plugin with no valid badge present.
*/
public function testNoValidBadge() : void {
$entity = $this->prophesize(ContentEntityInterface::class);
$entity->label()
->willReturn('Simple Title');
$route_helper = $this->prophesize(EntityRouteHelper::class);
$route_helper->getContentEntityFromRoute()
->willReturn($entity->reveal());
$entity_repository = $this->prophesize(EntityRepositoryInterface::class)
->reveal();
$plugin = new PageContext([], 'page_context', [], $route_helper->reveal(), $entity_repository, NULL);
$build = $plugin->build();
$this->assertSame('Simple Title', $build[0]['#slots']['content']);
// Only one component (title) should be present.
$this->assertArrayNotHasKey(1, $build);
}
}
Members
| Title Sort descending | Modifiers | Object type | Summary | Overriden Title | Overrides |
|---|---|---|---|---|---|
| ExpectDeprecationTrait::expectDeprecation | public | function | Adds an expected deprecation. | ||
| ExpectDeprecationTrait::setUpErrorHandler | public | function | Sets up the test error handler. | ||
| ExpectDeprecationTrait::tearDownErrorHandler | public | function | Tears down the test error handler. | ||
| PageContextTest::entityLabelProvider | public static | function | Data provider for entity label scenarios. | ||
| PageContextTest::setUp | protected | function | Overrides UnitTestCase::setUp | ||
| PageContextTest::testBuildContentModerationNoPending | public | function | Tests content moderation build output with no pending revisions. | ||
| PageContextTest::testBuildContentModerationWithPendingActive | public | function | Tests the content moderation build when is active with a pending entity. | ||
| PageContextTest::testBuildEntityLabel | public | function | Tests the build of an entity label within the page context plugin. | ||
| PageContextTest::testBuildStatusBadge | public | function | Tests the status badge for published and unpublished entities. | ||
| PageContextTest::testBuildWhenNoEntityOnRoute | public | function | Tests the build method when no entity is present on the route. | ||
| PageContextTest::testNoValidBadge | public | function | Tests the behavior of a plugin with no valid badge present. | ||
| RandomGeneratorTrait::getRandomGenerator | protected | function | Gets the random generator for the utility methods. | ||
| RandomGeneratorTrait::randomMachineName | protected | function | Generates a unique random string containing letters and numbers. | ||
| RandomGeneratorTrait::randomObject | public | function | Generates a random PHP object. | ||
| RandomGeneratorTrait::randomString | public | function | Generates a pseudo-random string of ASCII characters of codes 32 to 126. | ||
| StringTranslationTrait::$stringTranslation | protected | property | The string translation service. | 3 | |
| StringTranslationTrait::formatPlural | protected | function | Formats a string containing a count of items. | ||
| StringTranslationTrait::getNumberOfPlurals | protected | function | Returns the number of plurals supported by a given language. | ||
| StringTranslationTrait::getStringTranslation | protected | function | Gets the string translation service. | ||
| StringTranslationTrait::setStringTranslation | public | function | Sets the string translation service to use. | 2 | |
| StringTranslationTrait::t | protected | function | Translates a string to the current language or to a given language. | 1 | |
| UnitTestCase::$root | protected | property | The app root. | ||
| UnitTestCase::getClassResolverStub | protected | function | Returns a stub class resolver. | ||
| UnitTestCase::getConfigFactoryStub | public | function | Returns a stub config factory that behaves according to the passed array. | ||
| UnitTestCase::getContainerWithCacheTagsInvalidator | protected | function | Sets up a container with a cache tags invalidator. | ||
| UnitTestCase::getStringTranslationStub | public | function | Returns a stub translation manager that just returns the passed string. | ||
| UnitTestCase::setDebugDumpHandler | public static | function | Registers the dumper CLI handler when the DebugDump extension is enabled. | ||
| UnitTestCase::setupMockIterator | protected | function | Set up a traversable class mock to return specific items when iterated. |
Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.