Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add integrations: Text field with summary, Taxonomy terms, Image/File field #40

Open
wants to merge 11 commits into
base: drupal8
Choose a base branch
from
204 changes: 184 additions & 20 deletions src/Palantirnet/PalantirBehatExtension/Context/EntityDataContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,11 @@
namespace Palantirnet\PalantirBehatExtension\Context;

use Behat\Behat\Tester\Exception\PendingException;
use Drupal\Component\Utility\UrlHelper;
use Drupal\Core\Url;
use Drupal\DrupalExtension\Context\RawDrupalContext;
use Drupal\DrupalDriverManager;
use Drupal\file\FileInterface;
use Palantirnet\PalantirBehatExtension\NotUpdatedException;

/**
Expand Down Expand Up @@ -89,15 +92,15 @@ public function assertNodeByTitleAndLanguage($contentType, $title, $language)
*
* @When I examine the :termName term in the :vocabulary( vocabulary)
*
* @param string $termName A Drupal taxonomy term name.
* @param string $termName A Drupal taxonomy term name.
* @param string $vocabulary The machine name of a Drupal taxonomy vocabulary.
*
* @throws \Exception
*
* @return void
*/
public function assertTermByName($termName, $vocabulary)
{
throw new NotUpdatedException('Method not yet updated for Drupal 8.');

$term = $this->findTermByName($termName, $vocabulary);

$this->currentEntity = $term;
Expand All @@ -106,6 +109,28 @@ public function assertTermByName($termName, $vocabulary)
}//end assertTermByName()


/**
* Verify field and property values of a taxonomy term entity.
*
* @When I examine the term with machine name :machineName in the :vocabulary( vocabulary)
*
* @param string $machineName A Drupal taxonomy term machine name.
* @param string $vocabulary The machine name of a Drupal taxonomy vocabulary.
*
* @throws \Exception
*
* @return void
*/
public function assertTermByMachineName($machineName, $vocabulary)
{
$term = $this->findTermByMachineName($machineName, $vocabulary);

$this->currentEntity = $term;
$this->currentEntityType = 'taxonomy_term';

}//end assertTermByName()


/**
* Verify field and property values of a block entity.
*
Expand Down Expand Up @@ -506,6 +531,52 @@ public function assertEntityFieldPropertyValue($field_name, $value, $property)

}//end assertEntityFieldPropertyValue()

/**
* Test a link field for a given property value.
*
* @param \Drupal\Core\Field\FieldItemList $field
* A Drupal field object.
* @param mixed $value
* The value to look for.
*
* @throws \Exception when url was not found
*
* @return void
*/
public function assertEntityFieldPropertyValueLink($field, $value, $property)
{
// Check if the provided value matches any of the field values - if no
// property is defined, use the default `value`.
$field_values = array_map(function ($field_value) use ($property) {
return $field_value[$property];
}, $field->getValue());

// Special case for expecting nothing.
if ($value === 'nothing') {
if (!empty($field_values)) {
throw new \Exception(sprintf('Field "%s" has a "%s" of "%s" and does not contain "%s"', $field->getName(), $property, json_encode($field_values), $value));
}

return;
}

// Special case for options.
if ($property == 'options') {
// Options should be passed in as json_encoded string.
$options_array = json_decode($value, TRUE);
if (in_array($options_array, $field_values) === false) {
throw new \Exception(sprintf('Field "%s" has "options" of "%s" and does not contain "%s"', $field->getName(), json_encode($field_values), $value));
}

return;
}

if (in_array($value, $field_values) === false) {
throw new \Exception(sprintf('Field "%s" has a "%s" of "%s" and does not contain "%s"', $field->getName(), $property, json_encode($field_values), $value));
}

}//end assertEntityFieldPropertyValueLink()

/**
* For a given field - and optional field property - check if a value is
* present.
Expand Down Expand Up @@ -668,7 +739,11 @@ public function assertEntityFieldValueParagraph($field_name, $type)


/**
* Test a link field for its URL value.
* Test a link field for its uri value.
*
* We first check for an external url test value to test against the the
* field value uri. If the test value is not an external url, we assume
* it is the label of an entity referenced by an internal uri.
*
* @param \Drupal\Core\Field\FieldItemList $field
* A Drupal field object.
Expand All @@ -681,11 +756,79 @@ public function assertEntityFieldValueParagraph($field_name, $type)
*/
public function assertEntityFieldValueLink($field, $value)
{
// Check if the provided value matches any of the field values.
$this->assertEntityFieldHasPropertyValue($field, $value, 'uri');
// Special case for expecting nothing.
if ($value === 'nothing') {
if (!empty($titles_from_field_values)) {
throw new \Exception(sprintf('Field "%s" has value of "%s" and does not contain "%s"', $field->getName(), json_encode($field->getValue()), $value));
}

return;
}

// Determine if the value being tested is external or internal.
$is_value_external = UrlHelper::isExternal($value);

if ($is_value_external) {
// Check if the provided uri matches any of the field values.
$this->assertEntityFieldHasPropertyValue($field, $value, 'uri');
}
else {
// We assume that the value is a label from a referenced entity.
// Check if the provided test value matches any of the field value
// referenced entity labels.
$this->assertEntityLinkFieldInternalReferenceByTitle($field, $value);
}

}//end assertEntityFieldValueLink()

/**
* Test a link field for its internal referenced entity label.
*
* @param \Drupal\Core\Field\FieldItemList $field
* A Drupal field object.
* @param mixed $value
* The value to look for.
*
* @throws \Exception when url was not found
*
* @return void
*/
public function assertEntityLinkFieldInternalReferenceByTitle($field, $value) {
// Determine if we have an internal link uri present as a field value.
$internal_uri_field_values = array_filter($field->getValue(), function ($field_value) {
return !UrlHelper::isExternal($field_value['uri']);
});

// Get titles of the referenced entities from internal uri field values.
$titles_from_field_values = array_map(function ($field_value) {
$params = Url::fromUri($field_value['uri'])->getRouteParameters();
$entity_type = key($params);
$entity = \Drupal::entityTypeManager()->getStorage($entity_type)->load($params[$entity_type]);
return $entity->label();
}, $internal_uri_field_values);

if (in_array($value, $titles_from_field_values) === false) {
throw new \Exception(sprintf('Field "%s" has a uri referencing entity(ies) with title(s) "%s" and does not contain "%s"', $field->getName(), json_encode($titles_from_field_values), $value));
}
} // end assertEntityLinkFieldInternalReferenceByTitle()

/**
* Test a text field for a partial string.
*
* @param \Drupal\Core\Field\FieldItemList $field
* A Drupal field object.
* @param mixed $value
* The value to look for.
*
* @throws \Exception when value was not found.
*
* @return void
*/
public function assertEntityFieldValueTextWithSummary($field, $value)
{
// Re-use the assertEntityFieldVallueTextLong for now.
return $this->assertEntityFieldValueTextLong($field, $value);
}

/**
* Test a text field for a partial string.
Expand Down Expand Up @@ -722,13 +865,15 @@ public function assertEntityFieldValueTextLong($field, $value)
return;
}
}

throw new \Exception(sprintf('Field value of "%s" does not contain expected value "%s"', $field_value, $value));
}//end assertEntityFieldValueTextLong()


/**
* Test a file field for a Drupal stream wrapper URI.
* Test a file field for a given filename.
*
* @param \Drupal\Core\Field\FieldItemList $field A Drupal field name.
* @param \Drupal\Core\Field\FieldItemList $field A Drupal field item list.
* @param mixed $value The value to look for.
*
* @throws \Exception
Expand All @@ -737,25 +882,45 @@ public function assertEntityFieldValueTextLong($field, $value)
*/
public function assertEntityFieldValueFile($field, $value)
{
throw new NotUpdatedException('Method not yet updated for Drupal 8.');
// Initialize array to collect field referenced filename(s).
$filenames = [];

$wrapper = entity_metadata_wrapper($this->currentEntityType, $this->currentEntity);
// Get the referenced file id(s) so we can load file(s).
$property = 'target_id';
$field_values = array_map(function ($field_value) use ($property) {
return $field_value[$property];
}, $field->getValue());

$field_value = $wrapper->$field->value();
if (!empty($field_values)) {
foreach ($field_values as $field_value) {
/**
* @var $file \Drupal\file\FileInterface|NULL
*/
$file = file_load($field_value);
if ($file instanceof FileInterface) {
$filename = $file->getFilename();

// Note that file field values are array('fid' => '...', ... ),
// which makes it somewhat hard to tell single values from multiple values.
if (isset($field_value['fid']) === true) {
$field_value = array($field_value);
}
if (strpos($filename, $value) !== false) {
return;
}

$filenames[] = $filename;
}
}

// Special case for expecting nothing.
if ($value === 'nothing') {
if (!empty($field_values)) {
throw new \Exception(sprintf('Field "%s" has file(s) "%s" and is not empty.', $field->getName(), json_encode($filenames)));
}

foreach ($field_value as $f) {
if (strpos($f['uri'], $value) !== false) {
return;
}

throw new \Exception(sprintf('Field "%s" does not contain file with name "%s", has "%s" instead.', $field->getName(), $value, json_encode($filenames)));
}

throw new \Exception(sprintf('Field "%s" does not contain file with URI "%s"', $field, $value));
throw new \Exception('Field is empty.');

}//end assertEntityFieldValueFile()

Expand All @@ -772,7 +937,6 @@ public function assertEntityFieldValueFile($field, $value)
*/
public function assertEntityFieldValueImage($field, $value)
{
throw new NotUpdatedException('Method not yet updated for Drupal 8.');

$this->assertEntityFieldValueFile($field, $value);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,31 +124,70 @@ protected function getNodeByTitle($contentType, $title)
* @param string $termName A Drupal taxonomy term name.
* @param string $vocabulary The machine name of a Drupal taxonomy vocabulary.
*
* @return stdclass
* @return Drupal\taxonomy\TermInterface
* The Drupal term object, if it exists.
*/
public function findTermByName($termName, $vocabulary)
{
throw new NotUpdatedException('Method not yet updated for Drupal 8.');

$query = new \EntityFieldQuery();
/**
* @var $query \Drupal\Core\Entity\Query\QueryInterface
*/
$query = \Drupal::entityQuery('taxonomy_term');

$entities = $query->entityCondition('entity_type', 'taxonomy_term')
->entityCondition('bundle', $vocabulary)
->propertyCondition('name', $termName)
$entities = $query
->condition('name', $termName)
->condition('vid', $vocabulary)
->execute();

if (empty($entities['taxonomy_term']) === false && count($entities['taxonomy_term']) === 1) {
$id = key($entities['taxonomy_term']);
return taxonomy_term_load($id);
} else if (empty($entities['taxonomy_term']) === false && count($entities['taxonomy_term']) > 1) {
throw new \Exception(sprintf('Found more than one "%s" term entitled "%s"', $vocabulary, $termName));
if (count($entities) === 1) {
$term_storage = \Drupal::entityTypeManager()->getStorage('taxonomy_term');
$tid = array_shift($entities);

$term = $term_storage->load($tid);

return $term;
} else if (count($entities) > 1) {
throw new \Exception(sprintf('Found more than one term with name "%s"', $termName));
} else {
throw new \Exception(sprintf('No "%s" term entitled "%s" exists', $vocabulary, $termName));
throw new \Exception(sprintf('No term with name "%s" exists', $termName));
}

}//end findTermByName()

/**
* Get a term object by machine name and vocabulary.
*
* @param string $machineName A Drupal taxonomy term machine name.
* @param string $vocabulary The machine name of a Drupal taxonomy vocabulary.
*
* @return Drupal\taxonomy\TermInterface
* The Drupal term object, if it exists.
*/
public function findTermByMachineName($machineName, $vocabulary)
{
/**
* @var $query \Drupal\Core\Entity\Query\QueryInterface
*/
$query = \Drupal::entityQuery('taxonomy_term');

$entities = $query
->condition('machine_name', $machineName)
->condition('vid', $vocabulary)
->execute();

if (count($entities) === 1) {
$term_storage = \Drupal::entityTypeManager()->getStorage('taxonomy_term');
$tid = array_shift($entities);

$term = $term_storage->load($tid);

return $term;
} else if (count($entities) > 1) {
throw new \Exception(sprintf('Found more than one term with machine name "%s"', $machineName));
} else {
throw new \Exception(sprintf('No term with machine name "%s" exists', $machineName));
}
}//end findTermByMachineName()


/**
* Get block object by its description.
Expand Down