Completed
Pull Request — master (#339)
by Pieter
02:07
created

DrupalAuthenticationManager::loggedIn()   B

Complexity

Conditions 5
Paths 7

Size

Total Lines 36
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 36
rs 8.439
c 0
b 0
f 0
cc 5
eloc 15
nc 7
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
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
        // Check if we are already logged in.
48
        if ($this->loggedIn()) {
49
            $this->logout();
50
        }
51
52
        $this->getSession()->visit($this->locatePath('/user'));
53
        $element = $this->getSession()->getPage();
54
        $element->fillField($this->getDrupalText('username_field'), $user->name);
55
        $element->fillField($this->getDrupalText('password_field'), $user->pass);
56
        $submit = $element->findButton($this->getDrupalText('log_in'));
57
        if (empty($submit)) {
58
            throw new \Exception(sprintf("No submit button at %s", $this->getSession()->getCurrentUrl()));
59
        }
60
61
        // Log in.
62
        $submit->click();
63
64
        if (!$this->loggedIn()) {
65
            if (isset($user->role)) {
66
                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));
67
            } else {
68
                throw new \Exception(sprintf("Unable to determine if logged in because 'log_out' link cannot be found for user '%s'", $user->name));
69
            }
70
        }
71
72
        $this->userManager->setCurrentUser($user);
73
    }
74
75
    /**
76
     * {@inheritdoc}
77
     */
78
    public function logout() {
79
        $this->getSession()->visit($this->locatePath('/user/logout'));
80
        $this->userManager->setCurrentUser(FALSE);
81
    }
82
83
    /**
84
     * {@inheritdoc}
85
     */
86
    public function loggedIn() {
87
        $session = $this->getSession();
88
        $page = $session->getPage();
89
90
        // Look for a css selector to determine if a user is logged in.
91
        // Default is the logged-in class on the body tag.
92
        // Which should work with almost any theme.
93
        try {
94
            if ($page->has('css', $this->getDrupalSelector('logged_in_selector'))) {
95
                return TRUE;
96
            }
97
        } catch (DriverException $e) {
98
            // This test may fail if the driver did not load any site yet.
99
        }
100
101
        // Some themes do not add that class to the body, so lets check if the
102
        // login form is displayed on /user/login.
103
        $session->visit($this->locatePath('/user/login'));
104
        if (!$page->has('css', $this->getDrupalSelector('login_form_selector'))) {
105
            return TRUE;
106
        }
107
108
        $session->visit($this->locatePath('/'));
109
110
        // As a last resort, if a logout link is found, we are logged in. While not
111
        // perfect, this is how Drupal SimpleTests currently work as well.
112
        if ($page->findLink($this->getDrupalText('log_out'))) {
113
            return TRUE;
114
        }
115
116
        // The user appears to be anonymous. Clear the current user from the user
117
        // manager so this reflects the actual situation.
118
        $this->userManager->setCurrentUser(FALSE);
119
120
        return FALSE;
121
    }
122
}
123