Completed
Push — 1.0.x ( b718a3...04e9a6 )
by Fabian
02:26
created

MenuContext::deleteMenuLinks()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 9
c 0
b 0
f 0
rs 9.6666
cc 3
eloc 5
nc 3
nop 1
1
<?php
2
3
namespace NuvoleWeb\Drupal\DrupalExtension\Context;
4
5
use Drupal\menu_link_content\Entity\MenuLinkContent;
6
use Drupal\system\Entity\Menu;
7
use Behat\Gherkin\Node\TableNode;
8
use Behat\Behat\Hook\Scope\AfterScenarioScope;
9
use Behat\Mink\Exception\ExpectationException;
10
11
/**
12
 * Class MenuContext.
13
 *
14
 * @package NuvoleWeb\Drupal\DrupalExtension\Context
15
 */
16
class MenuContext extends RawDrupalContext {
17
18
19
  /**
20
   * Menu links created during test execution.
21
   *
22
   * @var \Drupal\menu_link_content\Entity\MenuLinkContent[]
23
   */
24
  private $menuLinks = [];
25
26
  /**
27
   * Create menu structure for nodes.
28
   *
29
   * @param string $menu_name
30
   *    Menu machine name.
31
   * @param \Behat\Gherkin\Node\TableNode $table
32
   *    Table representing the menu structure to be specified as follows:
33
   *      | title  | parent |
34
   *      | Page 1 |        |
35
   *      | Page 2 | Page 1 |
36
   *      | Page 3 | Page 2 |.
37
   *
38
   * @throws \Behat\Mink\Exception\ExpectationException
39
   *    Throws exception if menu not found.
40
   *
41
   * @Given the following :menu_name menu structure for content:
42
   */
43
  public function assertMenuStructureForContent($menu_name, TableNode $table) {
44
    $menu_items = $table->getColumnsHash();
45
    foreach ($menu_items as $key => $menu_item) {
46
      $node = $this->getCore()->loadNodeByName($menu_item['title']);
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Drupal\Driver\Cores\CoreInterface as the method loadNodeByName() does only exist in the following implementations of said interface: NuvoleWeb\Drupal\Driver\Cores\Drupal8.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
47
      $menu_items[$key]['uri'] = "entity:node/{$this->getCore()->getNodeId($node)}";
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Drupal\Driver\Cores\CoreInterface as the method getNodeId() does only exist in the following implementations of said interface: NuvoleWeb\Drupal\Driver\Cores\Drupal8.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
48
    }
49
50
    try {
51
      $this->menuLinks = array_merge($this->menuLinks, $this->getCore()->createMenuStructure($menu_name, $menu_items));
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Drupal\Driver\Cores\CoreInterface as the method createMenuStructure() does only exist in the following implementations of said interface: NuvoleWeb\Drupal\Driver\Cores\Drupal8.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
52
    }
53
    catch (\InvalidArgumentException $e) {
54
      throw new ExpectationException($e->getMessage(), $this->getSession());
55
    }
56
  }
57
58
  /**
59
   * Create menu structure my adding menu links.
60
   *
61
   * @param string $menu_name
62
   *    Menu machine name.
63
   * @param \Behat\Gherkin\Node\TableNode $table
64
   *    Table representing the menu structure to be specified as follows:
65
   *       | title   | uri        | parent |
66
   *       | Link 1  | internal:/ |        |
67
   *       | Link 2  | internal:/ | Link 1 |
68
   *       | Link 3  | internal:/ | Link 1 |.
69
   *
70
   * @throws \Behat\Mink\Exception\ExpectationException
71
   *    Throws exception if menu not found.
72
   *
73
   * @Given the following :menu_name menu structure:
74
   */
75
  public function assertMenuStructure($menu_name, TableNode $table) {
76
    try {
77
      $this->menuLinks = array_merge($this->menuLinks, $this->getCore()->createMenuStructure($menu_name, $table->getColumnsHash()));
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Drupal\Driver\Cores\CoreInterface as the method createMenuStructure() does only exist in the following implementations of said interface: NuvoleWeb\Drupal\Driver\Cores\Drupal8.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
78
    }
79
    catch (\InvalidArgumentException $e) {
80
      throw new ExpectationException($e->getMessage(), $this->getSession());
81
    }
82
83
  }
84
85
  /**
86
   * Assert clean Watchdog after every step.
87
   *
88
   * @param \Behat\Behat\Hook\Scope\AfterScenarioScope $event
89
   *    Event object.
90
   *
91
   * @AfterScenario
92
   */
93
  public function deleteMenuLinks(AfterScenarioScope $event) {
0 ignored issues
show
Unused Code introduced by
The parameter $event is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
94
    if ($this->menuLinks) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->menuLinks of type Drupal\menu_link_content\Entity\MenuLinkContent[] is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
95
      foreach ($this->menuLinks as $menu_link) {
96
        $this->getCore()->entityDelete($menu_link);
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Drupal\Driver\Cores\CoreInterface as the method entityDelete() does only exist in the following implementations of said interface: NuvoleWeb\Drupal\Driver\Cores\Drupal8.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
97
      }
98
99
      $this->getCore()->clearMenuCache();
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Drupal\Driver\Cores\CoreInterface as the method clearMenuCache() does only exist in the following implementations of said interface: NuvoleWeb\Drupal\Driver\Cores\Drupal8.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
100
    }
101
  }
102
103
}