Skip to content

Commit

Permalink
OPENEUROPA-1561: Refactor behat test classes.
Browse files Browse the repository at this point in the history
  • Loading branch information
imanoleguskiza committed Feb 14, 2019
1 parent d66e81d commit 6229ed8
Show file tree
Hide file tree
Showing 8 changed files with 474 additions and 448 deletions.
5 changes: 2 additions & 3 deletions behat.yml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,8 @@ default:
- Drupal\DrupalExtension\Context\DrupalContext
- Drupal\DrupalExtension\Context\MessageContext
- Drupal\DrupalExtension\Context\ConfigContext
- Drupal\Tests\oe_multilingual\Behat\DrupalContext
- Drupal\Tests\oe_multilingual\Behat\MinkContext
- Drupal\Tests\oe_multilingual\Behat\InterfaceTranslationContext
- Drupal\oe_multilingual\Tests\Behat\DrupalContext
- Drupal\oe_multilingual\Tests\Behat\MultilingualContext
- OpenEuropa\Behat\TransformationContext:
pages:
English administration home: 'en/admin'
Expand Down
71 changes: 71 additions & 0 deletions src/Tests/Behat/DrupalContext.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<?php

declare(strict_types = 1);

namespace Drupal\oe_multilingual\Tests\Behat;

use Behat\Gherkin\Node\TableNode;
use Drupal\DrupalExtension\Context\RawDrupalContext;
use Drupal\oe_multilingual\Tests\Behat\Traits\ContentManagerTrait;

/**
* Class DrupalContext.
*/
class DrupalContext extends RawDrupalContext {
use ContentManagerTrait;

/**
* Create content given its type and fields.
*
* @Given the following :arg1 content item:
*/
public function createContent(string $entity_type_label, TableNode $table): void {
$node = (object) $this->getContentValues($entity_type_label, $table);
$this->nodeCreate($node);
}

/**
* Assert viewing content given its type and title.
*
* @param string $title
* Content title.
*
* @Given I am visiting the :title content
* @Given I visit the :title content
*/
public function iAmViewingTheContent($title): void {
$nid = $this->getEntityByLabel('node', $title)->id();
$this->visitPath("node/$nid");
}

/**
* Redirect user to the node creation page.
*
* @param string $content_type_name
* Content type name.
*
* @Given I visit the :content_type_name creation page
*/
public function iAmVisitingTheCreationPage(string $content_type_name): void {
$node_bundle = $this->getEntityTypeByLabel($content_type_name);
$this->visitPath('node/add/' . $node_bundle);
}

/**
* Check that the field is not present.
*
* @param string $field
* Input id, name or label.
*
* @Then I should not see the field :field
*/
public function iShouldNotSeeTheField(string $field): void {
$element = $this->getSession()
->getPage()
->findField($field);
if ($element) {
throw new \RuntimeException("Field '{$field}' is present.");
}
}

}
147 changes: 147 additions & 0 deletions src/Tests/Behat/MultilingualContext.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
<?php

declare(strict_types = 1);

namespace Drupal\oe_multilingual\Tests\Behat;

use Drupal\locale\SourceString;
use PHPUnit\Framework\Assert;
use Behat\Gherkin\Node\TableNode;

/**
* Provides step to test functionality provided by oe_multilingual.
*/
class MultilingualContext extends RawMultilingualContext {

/**
* Translates an interface string.
*
* @param string $string
* The string to translate.
* @param string $language
* The language to translate into.
* @param string $value
* What to translate to.
*
* @throws \Exception
* Throws an exception if the string to translate is not found.
*
* @Given I translate :string in :language to :value
*/
public function translateString(string $string, string $language, string $value): void {
/** @var \Drupal\locale\StringStorageInterface $locale_storage */
$locale_storage = \Drupal::service('locale.storage');
$language = $this->getLanguageByName($language);

$source = $locale_storage->findString(['source' => $string]);
if (!$source instanceof SourceString) {
throw new \Exception(sprintf('Missing string to translate: %s', $source));
}

// Backup existing translation.
$translation = $locale_storage->findTranslation(['lid' => $source->getId(), 'language' => $language->getId()]);
$this->translations[$source->getId()] = [
'language' => $language,
'translation' => clone $translation,
];

$new_translation = $translation->isTranslation() ? $translation : $locale_storage->createTranslation($source->getValues(['lid']) + ['language' => $language->getId()]);
$new_translation->setString($value);
$new_translation->save();
}

/**
* Create translation for given content.
*
* @Given the following :language translation for the :entity_type_label with title :title:
*/
public function createTranslation(string $language, string $entity_type_label, string $title, TableNode $table): void {
// Build translation entity.
$values = $this->getContentValues($entity_type_label, $table);
$language = $this->getLanguageIdByName($language);
$translation = \Drupal::entityTypeManager()
->getStorage('node')
->create($values);

// Add the translation to the entity.
$entity = $this->getEntityByLabel('node', $title);
$entity->addTranslation($language, $translation->toArray())->save();

// Make sure URL alias is correctly generated for given translation.
$translation = $entity->getTranslation($language);
\Drupal::service('pathauto.generator')->createEntityAlias($translation, 'insert');
}

/**
* Sets the default site language.
*
* @param string $name
* The language name.
*
* @Given (I set) the default site language (is) (to) :name
*/
public function theDefaultSiteLanguageIs(string $name): void {
$language = $this->getLanguageIdByName($name);
$this->configContext->setConfig('system.site', 'default_langcode', $language);
}

/**
* Check that we have the correct language for initial translation.
*
* @param string $title
* Title of node.
*
* @throws \Exception
* Throws an exception if:
* a)the node doesn't exist
* b) the node has more than one translation.
* c) the language of the translation is not the default site language.
*
* @Then The only available translation for :title is in the site's default language
*/
public function assertOnlyDefaultLanguageTranslationExist(string $title): void {
$node = $this->getEntityByLabel('node', $title);
if (!$node) {
throw new \RuntimeException("Node '{$title}' doesn't exist.");
}

$node_translation_languages = $node->getTranslationLanguages();
if (count($node_translation_languages) !== 1) {
throw new \RuntimeException("The node should have only one translation.");
}

$node_language = key($node_translation_languages);
if ($node_language != \Drupal::languageManager()->getDefaultLanguage()->getId()) {
throw new \RuntimeException("Original translation language of the '{$title}' node is not the site's default language.");
}
}

/**
* Assert that visitor is redirected to language selection page.
*
* @Then I should be redirected to the language selection page
*/
public function assertLanguageSelectionPageRedirect() {
$this->assertSession()->addressMatches("/.*\/select-language/");
}

/**
* Assert links in region.
*
* @param \Behat\Gherkin\Node\TableNode $links
* List of links.
*
* @Then I should see the following links in the language switcher:
*/
public function assertLinksInRegion(TableNode $links): void {
$switcher_links = $this->getSession()->getPage()->findAll('css', '#block-oe-multilingual-language-switcher a');
$actual_links = [];
/** @var \Behat\Mink\Element\NodeElement $switcher_link */
foreach ($switcher_links as $switcher_link) {
$actual_links[] = $switcher_link->getText();
}
$expected_links = array_keys($links->getRowsHash());
Assert::assertEquals($expected_links, $actual_links);
}

}
145 changes: 145 additions & 0 deletions src/Tests/Behat/RawMultilingualContext.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
<?php

declare(strict_types = 1);

namespace Drupal\oe_multilingual\Tests\Behat;

use Behat\Behat\Hook\Scope\AfterScenarioScope;
use Behat\Behat\Hook\Scope\BeforeScenarioScope;
use Drupal\Core\Language\LanguageInterface;
use Drupal\DrupalExtension\Context\RawDrupalContext;
use Drupal\oe_multilingual\Tests\Behat\Traits\ContentManagerTrait;

/**
* Provides the functionality for interacting with multilingual functionality.
*/
class RawMultilingualContext extends RawDrupalContext {
use ContentManagerTrait;

/**
* The backed up translations.
*
* @var array
*/
protected $translations = [];

/**
* The config context.
*
* @var \Drupal\DrupalExtension\Context\ConfigContext
*/
protected $configContext;

/**
* Gathers some other contexts.
*
* @param \Behat\Behat\Hook\Scope\BeforeScenarioScope $scope
* The before scenario scope.
*
* @BeforeScenario
*/
public function gatherContexts(BeforeScenarioScope $scope) {
$environment = $scope->getEnvironment();
$this->configContext = $environment->getContext('Drupal\DrupalExtension\Context\ConfigContext');
}

/**
* Enable OpenEuropa Multilingual Selection Page module.
*
* @param \Behat\Behat\Hook\Scope\BeforeScenarioScope $scope
* The Hook scope.
*
* @BeforeScenario @selection-page
*/
public function setupSelectionPage(BeforeScenarioScope $scope): void {
\Drupal::service('module_installer')->install(['oe_multilingual_selection_page']);
}

/**
* Disable OpenEuropa Multilingual Selection Page module.
*
* @param \Behat\Behat\Hook\Scope\AfterScenarioScope $scope
* The Hook scope.
*
* @AfterScenario @selection-page
*/
public function revertSelectionPage(AfterScenarioScope $scope): void {
\Drupal::service('module_installer')->uninstall([
'oe_multilingual_selection_page',
'language_selection_page',
]);
}

/**
* Get language ID given its name.
*
* @param string $name
* Language name.
*
* @return string
* Language ID.
*/
protected function getLanguageIdByName(string $name): string {
foreach (\Drupal::languageManager()->getLanguages() as $language) {
if ($language->getName() === $name) {
return $language->getId();
}
}

throw new \InvalidArgumentException("Language '{$name}' not found.");
}

/**
* Restores backed up translations.
*
* @param \Behat\Behat\Hook\Scope\AfterScenarioScope $afterScenarioScope
* The scope.
*
* @AfterScenario
*/
public function restoreTranslations(AfterScenarioScope $afterScenarioScope): void {
if (!$this->translations) {
return;
}

/** @var \Drupal\locale\StringStorageInterface $locale_storage */
$locale_storage = \Drupal::service('locale.storage');

foreach ($this->translations as $info) {
/** @var \Drupal\Core\Language\LanguageInterface $language */
$language = $info['language'];
/** @var \Drupal\locale\TranslationString $translation */
$translation = $info['translation'];

// If there is a translation value, we need to restore it by simply
// giving it a save since we had cloned it.
if ($translation->isTranslation()) {
$translation->save();
continue;
}

// Otherwise, we need to delete the translation for that source.
$locale_storage->deleteTranslations(['lid' => $translation->getId(), 'language' => $language->getId()]);
}
}

/**
* Get language given its name.
*
* @param string $name
* Language name.
*
* @return \Drupal\Core\Language\LanguageInterface
* The language.
*/
protected function getLanguageByName(string $name): LanguageInterface {
foreach (\Drupal::languageManager()->getLanguages() as $language) {
if ($language->getName() === $name) {
return $language;
}
}

throw new \InvalidArgumentException(sprintf('Language %s not found.', $name));
}

}
Loading

0 comments on commit 6229ed8

Please sign in to comment.