Completed
Push — 62-logout-performance ( 836b21 )
by Jonathan
01:27
created

DrupalAuthenticationManager::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 7
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 5
nc 1
nop 4
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
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
        $this->getSession()->visit($this->locatePath('/user/logout'));
78
      $this->userManager->setCurrentUser(FALSE);
79
    }
80
81
    /**
82
     * {@inheritdoc}
83
     */
84
    public function loggedIn() {
85
        $session = $this->getSession();
86
87
        // If the session has not been started yet, or no page has yet been loaded,
88
        // then this is a brand new test session and the user is not logged in.
89
        if (!$session->isStarted() || !$page = $session->getPage()) {
90
            return FALSE;
91
        }
92
93
        // Look for a css selector to determine if a user is logged in.
94
        // Default is the logged-in class on the body tag.
95
        // Which should work with almost any theme.
96
        try {
97
            if ($page->has('css', $this->getDrupalSelector('logged_in_selector'))) {
98
                return TRUE;
99
            }
100
        } catch (DriverException $e) {
101
            // This test may fail if the driver did not load any site yet.
102
        }
103
104
        // Some themes do not add that class to the body, so lets check if the
105
        // login form is displayed on /user/login.
106
        $session->visit($this->locatePath('/user/login'));
107
        if ($page->has('css', $this->getDrupalSelector('login_form_selector'))) {
108
            $this->fastLogout();
109
            return FALSE;
110
        }
111
112
        $session->visit($this->locatePath('/'));
113
114
        // As a last resort, if a logout link is found, we are logged in. While not
115
        // perfect, this is how Drupal SimpleTests currently work as well.
116
        if ($page->findLink($this->getDrupalText('log_out'))) {
117
            return TRUE;
118
        }
119
120
        // The user appears to be anonymous. Calling logout() both ensures this is the 
121
        // case and updates the userManager to reflect this.
122
        $this->fastLogout();
123
        return FALSE;
124
    }
125
126
    /**
127
     * Logs out by directly resetting the session.
128
     *
129
     * A fast logout method that resets the session and doesn't need to
130
     * bootstrap Drupal. This should not be used if logout hooks need to fire.
131
     */
132
    protected function fastLogout()
133
    {
134
        $this->getSession()->reset();
135
        $this->userManager->setCurrentUser(FALSE);
136
    }
137
}
138