Completed
Push — master ( a36a2e...782846 )
by Sergii
05:45
created

RawUserContext::entityType()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 1
Metric Value
c 1
b 1
f 1
dl 0
loc 4
rs 10
cc 1
eloc 2
nc 1
nop 0
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
// Utils.
12
use Drupal\TqExtension\Utils\Database\FetchField;
13
use Drupal\TqExtension\Utils\BaseEntity;
14
15
class RawUserContext extends RawTqContext
16
{
17
    use BaseEntity;
18
19
    /**
20
     * {@inheritdoc}
21
     */
22
    protected function entityType()
23
    {
24
        return 'user';
25
    }
26
27
    /**
28
     * {@inheritdoc}
29
     */
30
    protected function getCurrentId()
31
    {
32
        return empty($this->user->uid) ? 0 : $this->user->uid;
33
    }
34
35
    /**
36
     * @param string $column
37
     *   Column of a "users" table.
38
     * @param string $value
39
     *   Expected value in column.
40
     *
41
     * @return int
42
     */
43
    protected function getIdByArguments($column, $value)
44
    {
45
        return (new FetchField('users', 'uid'))
46
            ->condition($column, $value)
47
            ->execute();
48
    }
49
50
    /**
51
     * @param string $roles
52
     *   Necessary user roles separated by comma.
53
     * @param array $fields
54
     *
55
     * @return \stdClass
56
     */
57
    public function createUserWithRoles($roles, array $fields = [])
58
    {
59
        $user = $this->createTestUser($fields);
60
        $driver = $this->getDriver();
61
62
        foreach (array_map('trim', explode(',', $roles)) as $role) {
63
            $driver->userAddRole($user, $role);
64
        }
65
66
        return $user;
67
    }
68
69
    /**
70
     * @throws \Exception
71
     */
72
    public function loginUser()
73
    {
74
        $this->logoutUser();
75
76
        if (empty($this->user)) {
77
            throw new \Exception('Tried to login without a user.');
78
        }
79
80
        $this->fillLoginForm([
81
            'username' => $this->user->name,
82
            'password' => $this->user->pass,
83
        ]);
84
    }
85
86
    /**
87
     * @param array $props
88
     *   An array with two keys: "username" and "password". Both of them are required.
89
     * @param string $message
90
     *   An error message, that will be thrown when user cannot be authenticated.
91
     *
92
     * @throws \Behat\Mink\Exception\ElementNotFoundException
93
     *   When one of a fields cannot be not found.
94
     * @throws \Exception
95
     *   When login process failed.
96
     * @throws \WebDriver\Exception\NoSuchElement
97
     *   When log in button cannot be found.
98
     */
99
    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...
100
    {
101
        $this->visitPath('/user/login');
102
        $formContext = $this->getFormContext();
103
104
        foreach (['username', 'password'] as $prop) {
105
            $formContext->fillField($this->getDrupalText($prop . '_field'), $props[$prop]);
106
        }
107
108
        $this->getWorkingElement()->pressButton($this->getDrupalText('log_in'));
109
110
        if (!$this->isLoggedIn()) {
111
            if (empty($message)) {
112
                $message = sprintf(
113
                    'Failed to login as a user "%s" with password "%s".',
114
                    $props['username'],
115
                    $props['password']
116
                );
117
            }
118
119
            throw new \Exception($message);
120
        }
121
122
        $GLOBALS['user'] = $this->user = user_load_by_name($props['username']);
123
    }
124
125
    /**
126
     * Cookies are set when at least one page of the site has been visited. This
127
     * action done in "beforeScenario" hook of TqContext.
128
     *
129
     * @see TqContext::beforeScenario()
130
     *
131
     * @return bool
132
     */
133
    public function isLoggedIn()
134
    {
135
        $cookieName = session_name();
136
        $cookie = $this->getSession()->getCookie($cookieName);
137
138
        if (null !== $cookie) {
139
            $this->getSession('goutte')->setCookie($cookieName, $cookie);
140
141
            return true;
142
        }
143
144
        return false;
145
    }
146
147
    public function logoutUser()
148
    {
149
        if ($this->isLoggedIn()) {
150
            $this->logout();
151
            $this->user = false;
152
        }
153
    }
154
155
    /**
156
     * @param array $fields
157
     *   Additional data for user account.
158
     *
159
     * @throws \Exception
160
     *
161
     * @return \stdClass
162
     */
163
    public function createTestUser(array $fields = [])
164
    {
165
        $random = $this->getRandom();
166
        $username = $random->name(8);
167
        $user = [
168
            'uid' => 0,
169
            'name' => $username,
170
            'pass' => $random->name(16),
171
            'mail' => "[email protected]",
172
            'roles' => [
173
                DRUPAL_AUTHENTICATED_RID => 'authenticated user',
174
            ],
175
        ];
176
177
        $user = (object) $user;
178
179
        if (!empty($fields)) {
180
            $entity = new EntityDrupalWrapper('user');
181
            $required = $entity->getRequiredFields();
182
183
            // Fill fields. Field can be found by name or label.
184
            foreach ($fields as $field_name => $value) {
185
                $field_info = $entity->getFieldInfo($field_name);
186
187
                if (!empty($field_info)) {
188
                    $field_name = $field_info['field_name'];
189
                }
190
191
                $user->$field_name = $value;
192
193
                // Remove field from $required if it was there and filled.
194
                unset($required[$field_name]);
195
            }
196
197
            // Throw an exception when one of required fields was not filled.
198
            if (!empty($required)) {
199
                throw new \Exception(sprintf(
200
                    'The following fields "%s" are required and has not filled.',
201
                    implode('", "', $required)
202
                ));
203
            }
204
        }
205
206
        if (isset($user->name)) {
207
            $existing_user = user_load_by_name($user->name);
208
209
            if (!empty($existing_user)) {
210
                user_delete($existing_user->uid);
211
            }
212
        }
213
214
        // $this->user always exist but when no user created it has "false" as a value.
215
        // Variable stored to another because RawDrupalContext::userCreate() will modify
216
        // it and this will affect for future actions.
217
        if (!empty($this->user)) {
218
            $tmp = $this->user;
219
        }
220
221
        $this->userCreate($user);
222
223
        if (isset($tmp)) {
224
            $this->user = $tmp;
225
        }
226
227
        return $user;
228
    }
229
}
230