From c1592287f513bcb14f776a9843de83e42194cae2 Mon Sep 17 00:00:00 2001 From: Jonathan Hedstrom Date: Thu, 16 Jan 2020 15:13:27 -0800 Subject: [PATCH] Improve PHPSpec coverage. - Changed to use interfaces for type-hinting where necessary. - Closes #565 --- CHANGELOG.md | 1 + .../Context/DrupalContextSpec.php | 7 ++- .../Context/DrushContextSpec.php | 13 ++-- .../DrupalAwareInitializerSpec.php | 3 +- .../Context/RandomContextSpec.php | 36 ++++++++++- .../Context/RawDrupalContextSpec.php | 12 ++-- .../Hook/Scope/BeforeNodeCreateScopeSpec.php | 21 +++++-- .../DrupalAuthenticationManagerSpec.php | 36 +++++++++++ .../Manager/DrupalUserManagerSpec.php | 61 +++++++++++++++++++ .../Selector/RegionSelectorSpec.php | 13 ++-- .../ServiceContainer/DrupalExtensionSpec.php | 4 +- .../Context/DrupalAwareInterface.php | 4 +- .../DrupalExtension/Context/RandomContext.php | 7 +-- .../Context/RawDrupalContext.php | 5 +- .../Manager/DrupalUserManager.php | 2 +- .../Manager/DrupalUserManagerInterface.php | 2 +- 16 files changed, 185 insertions(+), 42 deletions(-) create mode 100644 spec/Drupal/DrupalExtension/Manager/DrupalAuthenticationManagerSpec.php create mode 100644 spec/Drupal/DrupalExtension/Manager/DrupalUserManagerSpec.php diff --git a/CHANGELOG.md b/CHANGELOG.md index eb807bb7..e5f45888 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). * [#488](https://github.com/jhedstrom/drupalextension/issues/488) Authenticate user in the backend bootstrap process on login. ### Changed * [#563](https://github.com/jhedstrom/drupalextension/issues/563) Test on PHP 7.1 through 7.3 (and use Drush 10), remove testing on PHP 7.0. + * [#565](https://github.com/jhedstrom/drupalextension/issues/565) Improved PHPSpec coverage and changed type-hinting to use proper interfaces where necessary. ## [4.0.1] 2019-10-08 ### Fixed * [#552](https://github.com/jhedstrom/drupalextension/issue/552) Remove hard-coded symfony/event-dispatcher requirement. diff --git a/spec/Drupal/DrupalExtension/Context/DrupalContextSpec.php b/spec/Drupal/DrupalExtension/Context/DrupalContextSpec.php index 4cf4878d..247c0218 100644 --- a/spec/Drupal/DrupalExtension/Context/DrupalContextSpec.php +++ b/spec/Drupal/DrupalExtension/Context/DrupalContextSpec.php @@ -2,19 +2,20 @@ namespace spec\Drupal\DrupalExtension\Context; +use Behat\Behat\Context\TranslatableContext; +use Drupal\DrupalExtension\Context\RawDrupalContext; use PhpSpec\ObjectBehavior; -use Prophecy\Argument; class DrupalContextSpec extends ObjectBehavior { function it_is_drupal_aware() { - $this->shouldHaveType('Drupal\DrupalExtension\Context\RawDrupalContext'); + $this->shouldHaveType(RawDrupalContext::class); } function it_is_a_translatable_context() { - $this->shouldHaveType('Behat\Behat\Context\TranslatableContext'); + $this->shouldHaveType(TranslatableContext::class); } } diff --git a/spec/Drupal/DrupalExtension/Context/DrushContextSpec.php b/spec/Drupal/DrupalExtension/Context/DrushContextSpec.php index 88c9b96f..133c5509 100644 --- a/spec/Drupal/DrupalExtension/Context/DrushContextSpec.php +++ b/spec/Drupal/DrupalExtension/Context/DrushContextSpec.php @@ -2,25 +2,26 @@ namespace spec\Drupal\DrupalExtension\Context; -use PhpSpec\ObjectBehavior; -use Prophecy\Argument; - +use Behat\Behat\Context\TranslatableContext; +use Drupal\Driver\DrushDriver; use Drupal\DrupalDriverManager; +use Drupal\DrupalExtension\Context\RawDrupalContext; +use PhpSpec\ObjectBehavior; class DrushContextSpec extends ObjectBehavior { function it_should_be_drupal_aware() { - $this->shouldHaveType('Drupal\DrupalExtension\Context\RawDrupalContext'); + $this->shouldHaveType(RawDrupalContext::class); } function it_will_catch_scenarios_without_any_output() { - $this->shouldThrow('\RuntimeException')->duringReadDrushOutput(); + $this->shouldThrow(\RuntimeException::class)->duringReadDrushOutput(); } function it_is_a_translatable_context() { - $this->shouldHaveType('Behat\Behat\Context\TranslatableContext'); + $this->shouldHaveType(TranslatableContext::class); } } diff --git a/spec/Drupal/DrupalExtension/Context/Initializer/DrupalAwareInitializerSpec.php b/spec/Drupal/DrupalExtension/Context/Initializer/DrupalAwareInitializerSpec.php index 999c905e..40b86a98 100644 --- a/spec/Drupal/DrupalExtension/Context/Initializer/DrupalAwareInitializerSpec.php +++ b/spec/Drupal/DrupalExtension/Context/Initializer/DrupalAwareInitializerSpec.php @@ -4,6 +4,7 @@ use Behat\Behat\Context\Context; +use Behat\Behat\Context\Initializer\ContextInitializer; use Drupal\DrupalDriverManager; use Drupal\DrupalExtension\Context\DrupalAwareInterface; @@ -33,7 +34,7 @@ function let(DrupalDriverManager $drupal, DrupalAuthenticationManagerInterface $ function it_is_a_context_initializer() { - $this->shouldHaveType('Behat\Behat\Context\Initializer\ContextInitializer'); + $this->shouldHaveType(ContextInitializer::class); } function it_does_nothing_for_basic_contexts(Context $context) diff --git a/spec/Drupal/DrupalExtension/Context/RandomContextSpec.php b/spec/Drupal/DrupalExtension/Context/RandomContextSpec.php index 7390b02a..faed5c38 100644 --- a/spec/Drupal/DrupalExtension/Context/RandomContextSpec.php +++ b/spec/Drupal/DrupalExtension/Context/RandomContextSpec.php @@ -2,14 +2,48 @@ namespace spec\Drupal\DrupalExtension\Context; +use Behat\Behat\Hook\Scope\ScenarioScope; +use Behat\Gherkin\Node\FeatureNode; +use Behat\Gherkin\Node\ScenarioInterface; +use Behat\Gherkin\Node\StepNode; +use Drupal\Component\Utility\Random; +use Drupal\Driver\Cores\CoreInterface; +use Drupal\Driver\DrupalDriver; +use Drupal\DrupalDriverManager; use Drupal\DrupalExtension\Context\RandomContext; use PhpSpec\ObjectBehavior; -use Prophecy\Argument; class RandomContextSpec extends ObjectBehavior { + function let(DrupalDriverManager $drupal, DrupalDriver $driver, CoreInterface $core, Random $random) + { + $random->name(10)->willReturn('known_replacement'); + $driver->getRandom()->willReturn($random); + $driver->getCore()->willReturn($core); + $drupal->getDriver(NULL)->willReturn($driver); + $this->setDrupal($drupal); + } + function it_is_initializable() { $this->shouldHaveType(RandomContext::class); } + + function it_converts_placeholders_to_random_strings(ScenarioScope $scope, ScenarioInterface $scenario, FeatureNode $feature, StepNode $step1, StepNode $step2) + { + $step1->getText()->willReturn('Given a string'); + $step2->getText()->willReturn('Then the placeholder will be replaced'); + $step1->getArguments()->shouldBeCalled(); + $step2->getArguments()->shouldBeCalled(); + $steps = [$step1, $step2]; + $scenario->getSteps()->willReturn($steps); + $scope->getScenario()->willReturn($scenario); + $scope->getFeature()->willReturn($feature); + $this->beforeScenarioSetVariables($scope); + + $this->transformVariables('Given a string') + ->shouldBe('Given a known_replacement string'); + $this->transformVariables('Then the placeholder will be replaced') + ->shouldBe('Then the known_replacement placeholder will be replaced'); + } } diff --git a/spec/Drupal/DrupalExtension/Context/RawDrupalContextSpec.php b/spec/Drupal/DrupalExtension/Context/RawDrupalContextSpec.php index 23c94250..42819261 100644 --- a/spec/Drupal/DrupalExtension/Context/RawDrupalContextSpec.php +++ b/spec/Drupal/DrupalExtension/Context/RawDrupalContextSpec.php @@ -2,11 +2,9 @@ namespace spec\Drupal\DrupalExtension\Context; +use Drupal\DrupalDriverManagerInterface; +use Drupal\DrupalExtension\Context\DrupalAwareInterface; use PhpSpec\ObjectBehavior; -use Prophecy\Argument; - -use Behat\Testwork\Hook\HookDispatcher; -use Behat\Testwork\Hook\HookRepository; use Drupal\DrupalDriverManager; @@ -14,13 +12,13 @@ class RawDrupalContextSpec extends ObjectBehavior { function it_should_be_drupal_aware() { - $this->shouldHaveType('Drupal\DrupalExtension\Context\DrupalAwareInterface'); + $this->shouldHaveType(DrupalAwareInterface::class); } - function it_can_set_and_get_drupal_manager(DrupalDriverManager $drupal) + function it_can_set_and_get_drupal_manager(DrupalDriverManagerInterface $drupal) { $this->setDrupal($drupal); - $this->getDrupal()->shouldBeAnInstanceOf('Drupal\DrupalDriverManager'); + $this->getDrupal()->shouldBeAnInstanceOf(DrupalDriverManagerInterface::class); } function it_can_set_and_get_drupal_parameters() diff --git a/spec/Drupal/DrupalExtension/Hook/Scope/BeforeNodeCreateScopeSpec.php b/spec/Drupal/DrupalExtension/Hook/Scope/BeforeNodeCreateScopeSpec.php index ae9330ec..fd690f0e 100644 --- a/spec/Drupal/DrupalExtension/Hook/Scope/BeforeNodeCreateScopeSpec.php +++ b/spec/Drupal/DrupalExtension/Hook/Scope/BeforeNodeCreateScopeSpec.php @@ -5,30 +5,43 @@ use Behat\Behat\Context\Context; use Behat\Testwork\Environment\Environment; +use Behat\Testwork\Suite\Suite; +use Drupal\DrupalExtension\Hook\Scope\BeforeNodeCreateScope; use PhpSpec\ObjectBehavior; use Prophecy\Argument; class BeforeNodeCreateScopeSpec extends ObjectBehavior { - function let(Environment $environment, Context $context) + function let(Environment $environment, Context $context, Suite $suite) { $node = new \stdClass(); + $environment->getSuite()->willReturn($suite); $this->beConstructedWith($environment, $context, $node); } function it_is_initializable() { - $this->shouldHaveType('Drupal\DrupalExtension\Hook\Scope\BeforeNodeCreateScope'); + $this->shouldHaveType(BeforeNodeCreateScope::class); } function it_should_return_context() { $context = $this->getContext(); - $context->shouldBeAnInstanceOf('Behat\Behat\Context\Context'); + $context->shouldBeAnInstanceOf(Context::class); } function it_should_return_a_node() { - $this->getEntity()->shouldBeAnInstanceOf('stdClass'); + $this->getEntity()->shouldBeAnInstanceOf(\stdClass::class); + } + + function it_should_return_environment() + { + $this->getEnvironment()->shouldBeAnInstanceOf(Environment::class); + } + + function it_should_return_suite() + { + $this->getSuite()->shouldBeAnInstanceOf(Suite::class); } } diff --git a/spec/Drupal/DrupalExtension/Manager/DrupalAuthenticationManagerSpec.php b/spec/Drupal/DrupalExtension/Manager/DrupalAuthenticationManagerSpec.php new file mode 100644 index 00000000..b2494f3f --- /dev/null +++ b/spec/Drupal/DrupalExtension/Manager/DrupalAuthenticationManagerSpec.php @@ -0,0 +1,36 @@ +getSession(null)->willReturn($session); + $this->beConstructedWith($mink, $userManager, $driverManager, [], []); + } + + function it_is_initializable() + { + $this->shouldHaveType(DrupalAuthenticationManager::class); + } + + function it_can_check_login_status(Session $session, DocumentElement $page) + { + $this->loggedIn()->shouldBe(false); + + $page->has('css', '.a-class')->willReturn(true); + $session->isStarted()->willReturn(true); + $session->getPage()->willReturn($page); + $this->setDrupalParameters(['selectors' => ['logged_in_selector' => '.a-class']]); + $this->loggedIn()->shouldBe(true); + } +} diff --git a/spec/Drupal/DrupalExtension/Manager/DrupalUserManagerSpec.php b/spec/Drupal/DrupalExtension/Manager/DrupalUserManagerSpec.php new file mode 100644 index 00000000..4d31a097 --- /dev/null +++ b/spec/Drupal/DrupalExtension/Manager/DrupalUserManagerSpec.php @@ -0,0 +1,61 @@ +shouldHaveType(DrupalUserManager::class); + } + + function it_can_set_and_get_the_current_user() + { + $user = new \stdClass(); + $user->name = 'some_name'; + $this->setCurrentUser($user); + $this->getCurrentUser()->shouldBe($user); + } + + function it_can_add_and_remove_users() + { + $user = new \stdClass(); + $user->name = 'some_name'; + $this->addUser($user); + $this->getUser('some_name')->shouldBe($user); + $this->removeUser('some_name'); + $this->shouldThrow(\InvalidArgumentException::class)->duringGetUser('some_name'); + } + + function it_can_get_all_registered_users() + { + $this->hasUsers()->shouldBe(false); + $user = new \stdClass(); + $user->name = 'some_name'; + $this->addUser($user); + $this->hasUsers()->shouldBe(true); + $this->getUsers()->shouldBe(['some_name' => $user]); + } + + function it_can_determine_anonymous_users() + { + $this->currentUserIsAnonymous()->shouldBe(true); + $user = new \stdClass(); + $user->name = 'some_name'; + $this->setCurrentUser($user); + $this->currentUserIsAnonymous()->shouldBe(false); + } + + function it_can_check_roles() + { + $this->currentUserHasRole('some_role')->shouldBe(false); + $user = new \stdClass(); + $user->name = 'some_name'; + $user->role = 'some_role'; + $this->setCurrentUser($user); + $this->currentUserHasRole('some_role')->shouldBe(true); + } +} diff --git a/spec/Drupal/DrupalExtension/Selector/RegionSelectorSpec.php b/spec/Drupal/DrupalExtension/Selector/RegionSelectorSpec.php index 641eb2c6..c47b05db 100644 --- a/spec/Drupal/DrupalExtension/Selector/RegionSelectorSpec.php +++ b/spec/Drupal/DrupalExtension/Selector/RegionSelectorSpec.php @@ -2,11 +2,9 @@ namespace spec\Drupal\DrupalExtension\Selector; -use Behat\Mink\Selector\SelectorInterface; use Behat\Mink\Selector\CssSelector; - +use Drupal\DrupalExtension\Selector\RegionSelector; use PhpSpec\ObjectBehavior; -use Prophecy\Argument; class RegionSelectorSpec extends ObjectBehavior { @@ -15,22 +13,23 @@ function let(CssSelector $selector) $regionMap = array( 'Left sidebar' => '#left-sidebar', ); + $selector->translateToXPath('#left-sidebar')->willReturn('some xpath'); + $this->beConstructedWith($selector, $regionMap); } function it_is_initializable() { - $this->shouldHaveType('Drupal\DrupalExtension\Selector\RegionSelector'); + $this->shouldHaveType(RegionSelector::class); } function it_should_translate_to_xpath() { - // @todo this is not returning properly for some reason. - $xpath = $this->translateToXPath('Left sidebar'); + $this->translateToXPath('Left sidebar')->shouldBe('some xpath'); } function it_should_not_accept_invalid_regions() { - $this->shouldThrow('\InvalidArgumentException')->duringTranslateToXPath('Invalid region'); + $this->shouldThrow(\InvalidArgumentException::class)->duringTranslateToXPath('Invalid region'); } } diff --git a/spec/Drupal/DrupalExtension/ServiceContainer/DrupalExtensionSpec.php b/spec/Drupal/DrupalExtension/ServiceContainer/DrupalExtensionSpec.php index 4934f78a..6bbdcf8d 100644 --- a/spec/Drupal/DrupalExtension/ServiceContainer/DrupalExtensionSpec.php +++ b/spec/Drupal/DrupalExtension/ServiceContainer/DrupalExtensionSpec.php @@ -2,14 +2,14 @@ namespace spec\Drupal\DrupalExtension\ServiceContainer; +use Behat\Testwork\ServiceContainer\Extension; use PhpSpec\ObjectBehavior; -use Prophecy\Argument; class DrupalExtensionSpec extends ObjectBehavior { function it_is_a_testwork_extension() { - $this->shouldHaveType('Behat\Testwork\ServiceContainer\Extension'); + $this->shouldHaveType(Extension::class); } function it_is_named_drupal() diff --git a/src/Drupal/DrupalExtension/Context/DrupalAwareInterface.php b/src/Drupal/DrupalExtension/Context/DrupalAwareInterface.php index 687cce93..1bfce9bd 100644 --- a/src/Drupal/DrupalExtension/Context/DrupalAwareInterface.php +++ b/src/Drupal/DrupalExtension/Context/DrupalAwareInterface.php @@ -5,7 +5,7 @@ use Behat\Behat\Context\Context; use Behat\Testwork\Hook\HookDispatcher; -use Drupal\DrupalDriverManager; +use Drupal\DrupalDriverManagerInterface; use Drupal\DrupalExtension\Manager\DrupalAuthenticationManagerInterface; use Drupal\DrupalExtension\Manager\DrupalUserManagerInterface; @@ -15,7 +15,7 @@ interface DrupalAwareInterface extends Context /** * Sets Drupal instance. */ - public function setDrupal(DrupalDriverManager $drupal); + public function setDrupal(DrupalDriverManagerInterface $drupal); /** * Set event dispatcher. diff --git a/src/Drupal/DrupalExtension/Context/RandomContext.php b/src/Drupal/DrupalExtension/Context/RandomContext.php index dfd9390b..58c8b76a 100644 --- a/src/Drupal/DrupalExtension/Context/RandomContext.php +++ b/src/Drupal/DrupalExtension/Context/RandomContext.php @@ -2,8 +2,7 @@ namespace Drupal\DrupalExtension\Context; -use Behat\Behat\Hook\Scope\AfterScenarioScope; -use Behat\Behat\Hook\Scope\BeforeScenarioScope; +use Behat\Behat\Hook\Scope\ScenarioScope; /** * Class RandomContext @@ -52,7 +51,7 @@ public function transformVariables($message) * * @BeforeScenario */ - public function beforeScenarioSetVariables(BeforeScenarioScope $scope) + public function beforeScenarioSetVariables(ScenarioScope $scope) { $steps = []; if ($scope->getFeature()->hasBackground()) { @@ -83,7 +82,7 @@ public function beforeScenarioSetVariables(BeforeScenarioScope $scope) * * @AfterScenario */ - public function afterScenarioResetVariables(AfterScenarioScope $scope) + public function afterScenarioResetVariables(ScenarioScope $scope) { $this->values = []; } diff --git a/src/Drupal/DrupalExtension/Context/RawDrupalContext.php b/src/Drupal/DrupalExtension/Context/RawDrupalContext.php index b8b9ae18..53328de7 100644 --- a/src/Drupal/DrupalExtension/Context/RawDrupalContext.php +++ b/src/Drupal/DrupalExtension/Context/RawDrupalContext.php @@ -3,11 +3,10 @@ namespace Drupal\DrupalExtension\Context; use Behat\MinkExtension\Context\RawMinkContext; -use Behat\Mink\Exception\DriverException; use Behat\Testwork\Hook\HookDispatcher; use Behat\Behat\Context\Environment\InitializedContextEnvironment; -use Drupal\DrupalDriverManager; +use Drupal\DrupalDriverManagerInterface; use Drupal\DrupalExtension\DrupalParametersTrait; use Drupal\DrupalExtension\Manager\DrupalAuthenticationManagerInterface; use Drupal\DrupalExtension\Manager\DrupalUserManagerInterface; @@ -90,7 +89,7 @@ class RawDrupalContext extends RawMinkContext implements DrupalAwareInterface /** * {@inheritDoc} */ - public function setDrupal(DrupalDriverManager $drupal) + public function setDrupal(DrupalDriverManagerInterface $drupal) { $this->drupal = $drupal; } diff --git a/src/Drupal/DrupalExtension/Manager/DrupalUserManager.php b/src/Drupal/DrupalExtension/Manager/DrupalUserManager.php index 8c03bebf..599dd2ef 100644 --- a/src/Drupal/DrupalExtension/Manager/DrupalUserManager.php +++ b/src/Drupal/DrupalExtension/Manager/DrupalUserManager.php @@ -60,7 +60,7 @@ public function removeUser($userName) public function getUser($userName) { if (!isset($this->users[$userName])) { - throw new \Exception(sprintf('No user with %s name is registered with the driver.', $userName)); + throw new \InvalidArgumentException(sprintf('No user with %s name is registered with the driver.', $userName)); } return $this->users[$userName]; } diff --git a/src/Drupal/DrupalExtension/Manager/DrupalUserManagerInterface.php b/src/Drupal/DrupalExtension/Manager/DrupalUserManagerInterface.php index be39bf4a..46b3e69a 100644 --- a/src/Drupal/DrupalExtension/Manager/DrupalUserManagerInterface.php +++ b/src/Drupal/DrupalExtension/Manager/DrupalUserManagerInterface.php @@ -63,7 +63,7 @@ public function getUsers(); * @return \stdClass * The user object. * - * @throws \Exception + * @throws \InvalidArgumentException * Thrown when the user with the given name does not exist. */ public function getUser($userName);