RawUserContext::createUserWithRoles()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 11
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 11
ccs 0
cts 7
cp 0
rs 9.4285
cc 2
eloc 6
nc 2
nop 2
crap 6
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
// Utils.
10
use Drupal\TqExtension\Utils\BaseEntity;
11
use Drupal\TqExtension\Utils\Database\FetchField;
12
use Drupal\TqExtension\Utils\EntityDrupalWrapper;
13
14
class RawUserContext extends RawTqContext
15
{
16
    use BaseEntity;
17
18
    /**
19
     * {@inheritdoc}
20
     */
21
    protected function entityType()
22
    {
23
        return 'user';
24
    }
25
26
    /**
27
     * {@inheritdoc}
28
     */
29
    public function getCurrentId()
30
    {
31
        return empty($this->user->uid) ? 0 : $this->user->uid;
0 ignored issues
show
Documentation introduced by
The property user does not exist on object<Drupal\TqExtensio...xt\User\RawUserContext>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
32
    }
33
34
    /**
35
     * @param string $column
36
     *   Column of a "users" table.
37
     * @param string $value
38
     *   Expected value in column.
39
     *
40
     * @return int
41
     */
42
    public function getIdByArguments($column, $value)
43
    {
44
        return (new FetchField('users', 'uid'))
45
            ->condition($column, $value)
46
            ->execute();
47
    }
48
49
    /**
50
     * @param string $roles
51
     *   Necessary user roles separated by comma.
52
     * @param array $fields
53
     *
54
     * @return \stdClass
55
     */
56
    public function createUserWithRoles($roles, array $fields = [])
57
    {
58
        $user = $this->createTestUser($fields);
59
        $driver = $this->getDriver();
60
61
        foreach (array_map('trim', explode(',', $roles)) as $role) {
62
            $driver->userAddRole($user, $role);
63
        }
64
65
        return $user;
66
    }
67
68
    /**
69
     * @throws \Exception
70
     */
71
    public function loginUser()
72
    {
73
        $this->logoutUser();
74
75
        if (empty($this->user)) {
0 ignored issues
show
Documentation introduced by
The property user does not exist on object<Drupal\TqExtensio...xt\User\RawUserContext>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
76
            throw new \Exception('Tried to login without a user.');
77
        }
78
79
        $this->fillLoginForm([
80
            'username' => $this->user->name,
0 ignored issues
show
Documentation introduced by
The property user does not exist on object<Drupal\TqExtensio...xt\User\RawUserContext>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
81
            'password' => $this->user->pass,
0 ignored issues
show
Documentation introduced by
The property user does not exist on object<Drupal\TqExtensio...xt\User\RawUserContext>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
82
        ]);
83
    }
84
85
    /**
86
     * @param array $props
87
     *   An array with two keys: "username" and "password". Both of them are required.
88
     * @param string $message
89
     *   An error message, that will be thrown when user cannot be authenticated.
90
     *
91
     * @throws \Behat\Mink\Exception\ElementNotFoundException
92
     *   When one of a fields cannot be not found.
93
     * @throws \Exception
94
     *   When login process failed.
95
     * @throws \WebDriver\Exception\NoSuchElement
96
     *   When log in button cannot be found.
97
     */
98
    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...
99
    {
100
        $this->visitPath('/user/login');
101
        $formContext = $this->getFormContext();
102
103
        foreach (['username', 'password'] as $prop) {
104
            $formContext->fillField($this->getDrupalText($prop . '_field'), $props[$prop]);
105
        }
106
107
        $this->getWorkingElement()->pressButton($this->getDrupalText('log_in'));
108
109
        if (!$this->isLoggedIn()) {
110
            if (empty($message)) {
111
                $message = sprintf(
112
                    'Failed to login as a user "%s" with password "%s".',
113
                    $props['username'],
114
                    $props['password']
115
                );
116
            }
117
118
            throw new \Exception($message);
119
        }
120
121
        $GLOBALS['user'] = $this->user = user_load_by_name($props['username']);
0 ignored issues
show
Documentation introduced by
The property user does not exist on object<Drupal\TqExtensio...xt\User\RawUserContext>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
122
    }
123
124
    /**
125
     * Cookies are set when at least one page of the site has been visited. This
126
     * action done in "beforeScenario" hook of TqContext.
127
     *
128
     * @see TqContext::beforeScenario()
129
     *
130
     * @return bool
131
     */
132
    public function isLoggedIn()
133
    {
134
        $cookieName = session_name();
135
        $cookie = $this->getSession()->getCookie($cookieName);
136
137
        if (null !== $cookie) {
138
            $this->getSession('goutte')->setCookie($cookieName, $cookie);
139
140
            return true;
141
        }
142
143
        return false;
144
    }
145
146
    public function logoutUser()
147
    {
148
        if ($this->isLoggedIn()) {
149
            $this->logout();
150
        }
151
    }
152
153
    /**
154
     * @param array $fields
155
     *   Additional data for user account.
156
     *
157
     * @throws \Exception
158
     *
159
     * @return \stdClass
160
     */
161
    public function createTestUser(array $fields = [])
162
    {
163
        $random = $this->getRandom();
164
        $username = $random->name(8);
165
        $user = [
166
            'uid' => 0,
167
            'name' => $username,
168
            'pass' => $random->name(16),
169
            'mail' => "[email protected]",
170
            'roles' => [
171
                DRUPAL_AUTHENTICATED_RID => 'authenticated user',
172
            ],
173
        ];
174
175
        $user = (object) $user;
176
177
        if (!empty($fields)) {
178
            $entity = new EntityDrupalWrapper('user');
179
            $required = $entity->getRequiredFields();
180
181
            // Fill fields. Field can be found by name or label.
182
            foreach ($fields as $field_name => $value) {
183
                $field_info = $entity->getFieldInfo($field_name);
184
185
                if (!empty($field_info)) {
186
                    $field_name = $field_info['field_name'];
187
                }
188
189
                $user->$field_name = $value;
190
191
                // Remove field from $required if it was there and filled.
192
                unset($required[$field_name]);
193
            }
194
195
            // Throw an exception when one of required fields was not filled.
196
            if (!empty($required)) {
197
                throw new \Exception(sprintf(
198
                    'The following fields "%s" are required and has not filled.',
199
                    implode('", "', $required)
200
                ));
201
            }
202
        }
203
204
        if (isset($user->name)) {
205
            $existing_user = user_load_by_name($user->name);
206
207
            if (!empty($existing_user)) {
208
                user_delete($existing_user->uid);
209
            }
210
        }
211
212
        // $this->user always exist but when no user created it has "false" as a value.
213
        // Variable stored to another because RawDrupalContext::userCreate() will modify
214
        // it and this will affect for future actions.
215
        if (!empty($this->user)) {
0 ignored issues
show
Documentation introduced by
The property user does not exist on object<Drupal\TqExtensio...xt\User\RawUserContext>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
216
            $tmp = $this->user;
0 ignored issues
show
Documentation introduced by
The property user does not exist on object<Drupal\TqExtensio...xt\User\RawUserContext>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
217
        }
218
219
        $this->userCreate($user);
220
221
        if (isset($tmp)) {
222
            $this->user = $tmp;
0 ignored issues
show
Documentation introduced by
The property user does not exist on object<Drupal\TqExtensio...xt\User\RawUserContext>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
223
        }
224
225
        return $user;
226
    }
227
}
228