Completed
Pull Request — master (#10)
by
unknown
02:33
created

RawUserContext::getUserByColumn()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 13
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 13
rs 9.4285
cc 2
eloc 9
nc 2
nop 2
1
<?php
2
/**
3
 * @author Sergii Bondarenko, <[email protected]>
4
 */
5
namespace Drupal\TqExtension\Context\User;
6
7
// Contexts.
8
use Drupal\TqExtension\Context\RawTqContext;
9
use Drupal\TqExtension\Utils\EntityDrupalWrapper;
10
11
class RawUserContext extends RawTqContext
12
{
13
    /**
14
     * @param string $roles
15
     *   Necessary user roles separated by comma.
16
     *
17
     * @return \stdClass
18
     */
19
    public function createUserWithRoles($roles, array $fields = [])
20
    {
21
        $user = $this->createTestUser($fields);
22
        $driver = $this->getDriver();
23
24
        foreach (array_map('trim', explode(',', $roles)) as $role) {
25
            $driver->userAddRole($user, $role);
26
        }
27
28
        return $user;
29
    }
30
31
    /**
32
     * @throws \Exception
33
     */
34
    public function loginUser()
35
    {
36
        $this->logoutUser();
37
38
        if (empty($this->user)) {
39
            throw new \Exception('Tried to login without a user.');
40
        }
41
42
        $this->fillLoginForm([
43
            'username' => $this->user->name,
44
            'password' => $this->user->pass,
45
        ]);
46
    }
47
48
    /**
49
     * @param array $props
50
     *   An array with two keys: "username" and "password". Both of them are required.
51
     * @param string $message
52
     *   An error message, that will be thrown when user cannot be authenticated.
53
     *
54
     * @throws \Behat\Mink\Exception\ElementNotFoundException
55
     *   When one of a fields cannot be not found.
56
     * @throws \Exception
57
     *   When login process failed.
58
     * @throws \WebDriver\Exception\NoSuchElement
59
     *   When log in button cannot be found.
60
     */
61
    public function fillLoginForm(array $props, $message = '')
0 ignored issues
show
Coding Style introduced by
fillLoginForm uses the super-global variable $GLOBALS which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
62
    {
63
        $this->visitPath('/user/login');
64
        $formContext = $this->getFormContext();
65
66
        foreach (['username', 'password'] as $prop) {
67
            $formContext->fillField($this->getDrupalText($prop . '_field'), $props[$prop]);
68
        }
69
70
        $this->getWorkingElement()->pressButton($this->getDrupalText('log_in'));
71
72
        if (!$this->isLoggedIn()) {
73
            if (empty($message)) {
74
                $message = sprintf(
75
                    'Failed to login as a user "%s" with password "%s".',
76
                    $props['username'],
77
                    $props['password']
78
                );
79
            }
80
81
            throw new \Exception($message);
82
        }
83
84
        $GLOBALS['user'] = $this->user;
85
    }
86
87
    /**
88
     * Cookies are set when at least one page of the site has been visited. This
89
     * action done in "beforeScenario" hook of TqContext.
90
     *
91
     * @see TqContext::beforeScenario()
92
     *
93
     * @return bool
94
     */
95
    public function isLoggedIn()
96
    {
97
        $cookieName = session_name();
98
        $cookie = $this->getSession()->getCookie($cookieName);
99
100
        if (null !== $cookie) {
101
            $this->getSession('goutte')->setCookie($cookieName, $cookie);
102
103
            return true;
104
        }
105
106
        return false;
107
    }
108
109
    public function logoutUser()
110
    {
111
        if ($this->isLoggedIn()) {
112
            $this->logout();
113
            $this->user = false;
114
        }
115
    }
116
117
    /**
118
     * @param array $fields
119
     *   Additional data for user account.
120
     *
121
     * @throws \Exception
122
     *
123
     * @return \stdClass
124
     */
125
    public function createTestUser(array $fields = [])
126
    {
127
        $random = $this->getRandom();
128
        $username = $random->name(8);
129
        $user = [
130
            'uid' => 0,
131
            'name' => $username,
132
            'pass' => $random->name(16),
133
            'mail' => "[email protected]",
134
            'roles' => [
135
                DRUPAL_AUTHENTICATED_RID => 'authenticated user',
136
            ],
137
        ];
138
139
        $user = (object) $user;
140
141
        if (!empty($fields)) {
142
            $entity = new EntityDrupalWrapper('user');
143
            $required = $entity->getRequiredFields();
144
145
            // Fill fields. Field can be found by name or label.
146
            foreach ($fields as $field_name => $value) {
147
                $field_info = $entity->getFieldInfo($field_name);
148
149
                if (!empty($field_info)) {
150
                    $field_name = $field_info['field_name'];
151
                }
152
153
                $user->$field_name = $value;
154
155
                // Remove field from $required if it was there and filled.
156
                unset($required[$field_name]);
157
            }
158
159
            // Throw an exception when one of required fields was not filled.
160
            if (!empty($required)) {
161
                throw new \Exception(sprintf(
162
                    'The following fields "%s" are required and has not filled.',
163
                    implode('", "', $required)
164
                ));
165
            }
166
        }
167
168
        if (isset($user->name)) {
169
            $existing_user = user_load_by_name($user->name);
170
171
            if (!empty($existing_user)) {
172
                user_delete($existing_user->uid);
173
            }
174
        }
175
176
        // $this->user always exist but when no user created it has "false" as a value.
177
        // Variable stored to another because RawDrupalContext::userCreate() will modify
178
        // it and this will affect for future actions.
179
        if (!empty($this->user)) {
180
            $tmp = $this->user;
181
        }
182
183
        $this->userCreate($user);
184
185
        if (isset($tmp)) {
186
            $this->user = $tmp;
187
        }
188
189
        return $user;
190
    }
191
192
    /**
193
     * Retrieves user by given property.
194
     *
195
     * @param $column
196
     *   User property, name or mail, to look for.
197
     * @param $value
198
     *   The value to search for in the given column.
199
     *
200
     * @return int|null
201
     *   Returns user uid if found.
202
     *
203
     * @throws \Exception
204
     */
205
    public function getUserByColumn($column, $value)
206
    {
207
        $uid = db_select('users', 'u')
208
          ->fields('u', array('uid'))
209
          ->condition('u.' . $column, '%' . db_like($value) . '%', 'LIKE')
210
          ->range(0, 1)
211
          ->execute()->fetchField();
212
213
        if (empty($uid)) {
214
            throw new \Exception(sprintf("User with the %s: %s not found.", $column, $value));
215
        }
216
        return $uid;
217
    }
218
}
219