class EntityContext in Lightning Core 8.2
Same name and namespace in other branches
- 8.5 tests/contexts/EntityContext.behat.inc \Acquia\LightningExtension\Context\EntityContext
- 8 tests/contexts/EntityContext.behat.inc \Acquia\LightningExtension\Context\EntityContext
- 8.3 tests/contexts/EntityContext.behat.inc \Acquia\LightningExtension\Context\EntityContext
- 8.4 tests/contexts/EntityContext.behat.inc \Acquia\LightningExtension\Context\EntityContext
Contains miscellaneous step definitions for working with Drupal entities.
@internal This class is part of Lightning's internal testing code. It is not an API and should not be extended. This class will be marked final, and all protected members will be made private, in Lightning Core 3.x.
Hierarchy
- class \Acquia\LightningExtension\Context\EntityContext extends \Drupal\DrupalExtension\Context\DrupalSubContextBase
Expanded class hierarchy of EntityContext
File
- tests/
contexts/ EntityContext.behat.inc, line 21
Namespace
Acquia\LightningExtension\ContextView source
class EntityContext extends DrupalSubContextBase {
/**
* IDs of entities created during the scenario, divided into sets keyed by
* entity type ID.
*
* @var array
*/
protected $trash = [];
/**
* Saves an entity, ensuring automatic clean-up.
*
* @param \Drupal\Core\Entity\EntityInterface $entity
* The entity to save.
*/
public function save(EntityInterface $entity) {
$uid = $this
->getUser();
if ($uid && $entity instanceof EntityOwnerInterface && $entity
->getOwnerId() == 0) {
$entity
->setOwnerId($uid)
->save();
}
else {
$entity
->save();
$entity_type = $entity
->getEntityTypeId();
$this->trash[$entity_type][] = $entity
->id();
}
}
/**
* Creates a set of entities from tabular data.
*
* @param string $entity_type
* The entity type ID.
* @param \Behat\Gherkin\Node\TableNode $table
* The table of entity data.
*
* @Given :entity_type entities:
*/
public function createMultiple($entity_type, TableNode $table) {
$storage = \Drupal::entityTypeManager()
->getStorage($entity_type);
foreach ($table as $values) {
$this
->save($storage
->create($values));
}
}
/**
* Deletes entities created during the scenario.
*
* @afterScenario
*/
public function tearDown() {
foreach ($this->trash as $entity_type => $IDs) {
/** @var \Drupal\Core\Entity\EntityInterface[] $entities */
$entities = \Drupal::entityTypeManager()
->getStorage($entity_type)
->loadMultiple($IDs);
foreach ($entities as $entity) {
$entity
->delete();
}
}
}
/**
* Visits a randomly chosen entity of a specific type and (optional) bundle.
*
* @param string $entity_type
* The entity type ID.
* @param string $bundle
* (optional) The bundle.
*
* @throws \Exception if there are no entities to visit.
*
* @When I visit (?:a|an) :entity_type
* @When I visit (?:a|an) :bundle :entity_type
*/
public function visitEntity($entity_type, $bundle = NULL) {
$storage = \Drupal::entityTypeManager()
->getStorage($entity_type);
$query = $storage
->getQuery();
if ($bundle) {
$key = $storage
->getEntityType()
->getKey('bundle');
if ($key) {
$query
->condition($key, $bundle);
}
}
$items = $query
->execute();
if ($items) {
$id = reset($items);
$url = $storage
->load($id)
->toUrl()
->getInternalPath();
$this
->visitPath($url);
}
else {
$label = $storage
->getEntityType()
->getPluralLabel();
throw new \Exception("There are no {$bundle} {$label} available.");
}
}
/**
* Marks recently created entities to be deleted after the test scenario.
*
* @param string $entity_type
* The entity type ID.
* @param int $n
* (optional) How many entities to delete.
*
* @When I delete the latest :entity_type
* @When I delete the latest :entity_type entity
* @When I delete the latest :n :entity_type entities
*/
public function trashNewest($entity_type, $n = 1) {
$items = \Drupal::entityTypeManager()
->getStorage($entity_type)
->getQuery()
->sort('created', 'DESC')
->range(0, $n)
->execute();
foreach ($items as $id) {
$this->trash[$entity_type][] = $id;
}
}
/**
* Counts the number of entities of a specific type and optional bundle.
*
* @param string $entity_type
* The entity type ID.
* @param string $bundle
* (optional) The bundle.
*
* @return int
* How many entities exist of the given type and bundle.
*/
protected function count($entity_type, $bundle = NULL) {
$storage = \Drupal::entityTypeManager()
->getStorage($entity_type);
$query = $storage
->getQuery()
->count();
if ($bundle) {
$query
->condition($storage
->getEntityType()
->getKey('bundle'), $bundle);
}
return (int) $query
->execute();
}
/**
* Asserts that entities of a specific type and optional bundle exist.
*
* @param string $entity_type
* The entity type ID.
* @param int $n
* (optional) How many entities are expected to exist.
* @param string $bundle
* (optional) The bundle.
*
* @throws \Behat\Mink\Exception\ExpectationException if the number of
* existing entities does not match the expected number.
*
* @Then 1 :entity_type entity should exist
* @Then 1 :bundle :entity_type entity should exist
* @Then :n :entity_type entities should exist
* @Then :n :bundle :entity_type entities should exist
*/
public function assertCount($entity_type, $n = 1, $bundle = NULL) {
$count = $this
->count($entity_type, $bundle);
if ($count !== (int) $n) {
$message = sprintf('Expected %s to exist, but there are only %s.', $this
->formatCount($entity_type, $n), $this
->formatCount($entity_type, $count));
throw new ExpectationException($message, $this
->getSession()
->getDriver());
}
}
/**
* Generates a formatted entity count string.
*
* @param string $entity_type
* The entity type ID.
* @param int $n
* The number of entities.
*
* @see ::assertCount()
*
* @return string
* A formatted entity count string, e.g. '33 content items'.
*/
protected function formatCount($entity_type, $n) {
$entity_type = \Drupal::entityTypeManager()
->getDefinition($entity_type);
return (string) new Plural((int) $n, '@count ' . $entity_type
->getSingularLabel(), '@count' . $entity_type
->getPluralLabel());
}
/**
* Visits the edit form for an entity.
*
* @see lightning_dev_local_tasks_alter()
*
* @When I visit the edit form
*/
public function edit() {
$this
->assertSession()
->elementExists('named', [
'link',
'edit-form',
])
->click();
}
/**
* Reacts when a node is created by Drupal Extension's step definition.
*
* @BeforeNodeCreate
*/
public function onNodeCreate(BeforeNodeCreateScope $scope) {
$node = $scope
->getEntity();
if (!isset($node->uid)) {
$node->uid = $this
->getUser();
}
}
/**
* {@inheritdoc}
*/
protected function getUser() {
$user = $this
->getUserManager()
->getCurrentUser();
return $user ? $user->uid : 0;
}
/**
* Visits a specific revision of a node.
*
* @param int $n
* The one-based index of the revision.
*
* @When /^I visit the (\d+)(?:st|nd|rd|th) revision$/
*/
public function visitRevision($n) {
$this
->assertSession()
->elementExists('named', [
'link',
'Revisions',
])
->click();
$this
->getContext(ElementContext::class)
->click("main table tr:nth-child({$n}) td:first-child a");
}
/**
* Visits the current revision of a node.
*
* @When I visit the current revision
*/
public function visitCurrentRevision() {
$this
->assertSession()
->elementExists('named', [
'link',
'Revisions',
])
->click();
$session = $this
->getSession();
// The revision table's selector may vary depending on whether or not Diff
// is installed, so we need to use a pretty general selector.
$rows = $session
->getPage()
->findAll('css', 'main table > tbody tr');
/** @var \Behat\Mink\Element\NodeElement $row */
foreach ($rows as $row) {
if ($row
->find('css', 'td:last-child')
->getText() == 'Current revision') {
return $row
->find('css', 'td:first-child a')
->click();
}
}
// WTF? None of the rows were the current revision.
throw new ExpectationException('Current revision not found.', $session
->getDriver());
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
EntityContext:: |
protected | property | IDs of entities created during the scenario, divided into sets keyed by entity type ID. | |
EntityContext:: |
public | function | Asserts that entities of a specific type and optional bundle exist. | |
EntityContext:: |
protected | function | Counts the number of entities of a specific type and optional bundle. | |
EntityContext:: |
public | function | Creates a set of entities from tabular data. | |
EntityContext:: |
public | function | Visits the edit form for an entity. | |
EntityContext:: |
protected | function | Generates a formatted entity count string. | |
EntityContext:: |
protected | function | ||
EntityContext:: |
public | function | Reacts when a node is created by Drupal Extension's step definition. | |
EntityContext:: |
public | function | Saves an entity, ensuring automatic clean-up. | |
EntityContext:: |
public | function | Deletes entities created during the scenario. | |
EntityContext:: |
public | function | Marks recently created entities to be deleted after the test scenario. | |
EntityContext:: |
public | function | Visits the current revision of a node. | |
EntityContext:: |
public | function | Visits a randomly chosen entity of a specific type and (optional) bundle. | |
EntityContext:: |
public | function | Visits a specific revision of a node. |