Completed
Push — master ( 14a86b...2eb923 )
by Jonathan
01:40
created

DrupalAuthenticationManager::logout()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 5
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 3
nc 1
nop 0
1
<?php
2
3
namespace Drupal\DrupalExtension\Manager;
4
5
use Behat\Mink\Exception\DriverException;
6
use Behat\Mink\Mink;
7
use Drupal\DrupalExtension\DrupalParametersTrait;
8
use Drupal\DrupalExtension\MinkAwareTrait;
9
10
/**
11
 * Default implementation of the Drupal authentication manager service.
12
 */
13
class DrupalAuthenticationManager implements DrupalAuthenticationManagerInterface, FastLogoutInterface
14
{
15
16
    use DrupalParametersTrait;
17
    use MinkAwareTrait;
18
19
    /**
20
     * The Drupal user manager.
21
     *
22
     * @var \Drupal\DrupalExtension\Manager\DrupalUserManagerInterface
23
     */
24
    protected $userManager;
25
26
    /**
27
     * Constructs a DrupalAuthenticationManager object.
28
     *
29
     * @param \Behat\Mink\Mink $mink
30
     *   The Mink sessions manager.
31
     * @param \Drupal\DrupalExtension\Manager\DrupalUserManagerInterface $drupalUserManager
32
     *   The Drupal user manager.
33
     */
34
    public function __construct(Mink $mink, DrupalUserManagerInterface $drupalUserManager, array $minkParameters, array $drupalParameters)
35
    {
36
        $this->setMink($mink);
37
        $this->userManager = $drupalUserManager;
38
        $this->setMinkParameters($minkParameters);
39
        $this->setDrupalParameters($drupalParameters);
40
    }
41
42
    /**
43
     * {@inheritdoc}
44
     */
45
    public function logIn(\stdClass $user)
46
    {
47
        // Ensure we aren't already logged in.
48
        $this->fastLogout();
49
50
        $this->getSession()->visit($this->locatePath('/user'));
51
        $element = $this->getSession()->getPage();
52
        $element->fillField($this->getDrupalText('username_field'), $user->name);
53
        $element->fillField($this->getDrupalText('password_field'), $user->pass);
54
        $submit = $element->findButton($this->getDrupalText('log_in'));
55
        if (empty($submit)) {
56
            throw new \Exception(sprintf("No submit button at %s", $this->getSession()->getCurrentUrl()));
57
        }
58
59
        // Log in.
60
        $submit->click();
61
62
        if (!$this->loggedIn()) {
63
            if (isset($user->role)) {
64
                throw new \Exception(sprintf("Unable to determine if logged in because 'log_out' link cannot be found for user '%s' with role '%s'", $user->name, $user->role));
65
            } else {
66
                throw new \Exception(sprintf("Unable to determine if logged in because 'log_out' link cannot be found for user '%s'", $user->name));
67
            }
68
        }
69
70
        $this->userManager->setCurrentUser($user);
71
    }
72
73
    /**
74
     * {@inheritdoc}
75
     */
76
    public function logout()
77
    {
78
        $this->getSession()->visit($this->locatePath('/user/logout'));
79
        $this->userManager->setCurrentUser(false);
80
    }
81
82
    /**
83
     * {@inheritdoc}
84
     */
85
    public function loggedIn()
86
    {
87
        $session = $this->getSession();
88
89
        // If the session has not been started yet, or no page has yet been loaded,
90
        // then this is a brand new test session and the user is not logged in.
91
        if (!$session->isStarted() || !$page = $session->getPage()) {
92
            return false;
93
        }
94
95
        // Look for a css selector to determine if a user is logged in.
96
        // Default is the logged-in class on the body tag.
97
        // Which should work with almost any theme.
98
        try {
99
            if ($page->has('css', $this->getDrupalSelector('logged_in_selector'))) {
100
                return true;
101
            }
102
        } catch (DriverException $e) {
103
            // This test may fail if the driver did not load any site yet.
104
        }
105
106
        // Some themes do not add that class to the body, so lets check if the
107
        // login form is displayed on /user/login.
108
        $session->visit($this->locatePath('/user/login'));
109
        if ($page->has('css', $this->getDrupalSelector('login_form_selector'))) {
110
            $this->fastLogout();
111
            return false;
112
        }
113
114
        $session->visit($this->locatePath('/'));
115
116
        // As a last resort, if a logout link is found, we are logged in. While not
117
        // perfect, this is how Drupal SimpleTests currently work as well.
118
        if ($page->findLink($this->getDrupalText('log_out'))) {
119
            return true;
120
        }
121
122
        // The user appears to be anonymous. Calling logout() both ensures this is the
123
        // case and updates the userManager to reflect this.
124
        $this->fastLogout();
125
        return false;
126
    }
127
128
    /**
129
     * {@inheritdoc}
130
     */
131
    public function fastLogout()
132
    {
133
        $this->getSession()->reset();
134
        $this->userManager->setCurrentUser(false);
135
    }
136
}
137