Completed
Pull Request — develop (#450)
by ANTHONIUS
06:55
created

UserContext::__construct()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 15
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 2 Features 0
Metric Value
dl 0
loc 15
rs 9.4285
c 2
b 2
f 0
cc 2
eloc 10
nc 2
nop 1
1
<?php
2
/**
3
 * YAWIK
4
 *
5
 * @filesource
6
 * @license MIT
7
 * @copyright  2013 - 2017 Cross Solution <http://cross-solution.de>
8
 */
9
10
namespace Yawik\Behat;
11
12
use Auth\Entity\User as User;
13
use Auth\Entity\UserInterface;
14
use Auth\Listener\Events\AuthEvent;
15
use Auth\Repository\User as UserRepository;
16
use Auth\Service\Register;
17
use Behat\Behat\Context\Context;
18
use Behat\Behat\Hook\Scope\BeforeScenarioScope;
19
use Behat\Behat\Tester\Exception\PendingException;
20
use Behat\Gherkin\Node\TableNode;
21
use Behat\MinkExtension\Context\MinkContext;
22
use Behat\Testwork\Hook\Scope\AfterSuiteScope;
23
use Core\Entity\Permissions;
24
use Doctrine\Common\Util\Inflector;
25
use Doctrine\ODM\MongoDB\Event\LifecycleEventArgs;
26
use Doctrine\ODM\MongoDB\Events;
27
use Geo\Service\Photon;
28
use Organizations\Entity\Organization;
29
use Organizations\Entity\OrganizationName;
30
use Organizations\Repository\Organization as OrganizationRepository;
31
use Zend\Stdlib\ArrayObject;
32
33
class UserContext implements Context
34
{
35
	/**
36
	 * @var CoreContext
37
	 */
38
	private $coreContext;
39
	
40
	/**
41
	 * @var MinkContext
42
	 */
43
	private $minkContext;
44
	
45
	/**
46
	 * @var User
47
	 */
48
	private $currentUser;
49
	
50
	/**
51
	 * @var User[]
52
	 */
53
	static private $users = [];
54
	
55
	/**
56
	 * @var UserRepository
57
	 */
58
	static private $userRepo;
59
	
60
	/**
61
	 * @var string
62
	 */
63
	static private $currentSession;
0 ignored issues
show
Unused Code introduced by
The property $currentSession is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
64
	
65
	private $socialLoginInfo = [];
66
	
67
	/**
68
	 * @var UserInterface
69
	 */
70
	private $loggedInUser;
71
	
72
	public function __construct($parameters=[])
73
	{
74
		$defaultLoginInfo = [
75
			'facebook' => [
76
				'email' => getenv('FACEBOOK_USER_EMAIL'),
77
				'pass' => getenv('FACEBOOK_USER_PASSWORD')
78
			],
79
			'linkedin' => [
80
				'session_key-login' => getenv('LINKEDIN_USER_EMAIL'),
81
				'session_password-login' => getenv('LINKEDIN_USER_PASSWORD')
82
			],
83
		];
84
		$socialLoginConfig = isset($parameters['social_login_info']) ? $parameters['social_login_info']:[];
85
		$this->socialLoginInfo = array_merge($defaultLoginInfo,$socialLoginConfig);
86
	}
87
	
88
	/**
89
	 * @AfterSuite
90
	 * @param AfterSuiteScope $scope
91
	 */
92
	static public function afterSuite(AfterSuiteScope $scope)
0 ignored issues
show
Coding Style introduced by
As per PSR2, the static declaration should come after the visibility declaration.
Loading history...
93
	{
94
		$repo = static::$userRepo;
0 ignored issues
show
Bug introduced by
Since $userRepo is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self, or increasing the visibility of $userRepo to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return static::$someVariable;
    }
}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass { }

YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class SomeClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return self::$someVariable; // self works fine with private.
    }
}
Loading history...
95
		foreach(static::$users as $user){
0 ignored issues
show
Bug introduced by
Since $users is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self, or increasing the visibility of $users to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return static::$someVariable;
    }
}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass { }

YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class SomeClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return self::$someVariable; // self works fine with private.
    }
}
Loading history...
96
			if($repo->findByLogin($user->getLogin())){
97
				try{
98
					JobContext::removeJobByUser($user);
99
					$repo->remove($user,true);
100
				}catch (\Exception $e){
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
101
				
102
				}
103
			}
104
		}
105
	}
106
	
107
	/**
108
	 * @BeforeScenario
109
	 * @param BeforeScenarioScope $scope
110
	 */
111
	public function beforeScenario(BeforeScenarioScope $scope)
112
	{
113
		$this->minkContext = $scope->getEnvironment()->getContext(MinkContext::class);
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Behat\Testwork\Environment\Environment as the method getContext() does only exist in the following implementations of said interface: Behat\Behat\Context\Envi...lizedContextEnvironment, FriendsOfBehat\ContextSe...ntextServiceEnvironment.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
114
		$this->coreContext = $scope->getEnvironment()->getContext(CoreContext::class);
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Behat\Testwork\Environment\Environment as the method getContext() does only exist in the following implementations of said interface: Behat\Behat\Context\Envi...lizedContextEnvironment, FriendsOfBehat\ContextSe...ntextServiceEnvironment.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
115
		static::$userRepo = $this->getUserRepository();
0 ignored issues
show
Bug introduced by
Since $userRepo is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self, or increasing the visibility of $userRepo to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return static::$someVariable;
    }
}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass { }

YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class SomeClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return self::$someVariable; // self works fine with private.
    }
}
Loading history...
116
	}
117
	
118
	/**
119
	 * @return User
120
	 */
121
	public function getCurrentUser()
122
	{
123
		return $this->currentUser;
124
	}
125
	
126
	/**
127
	 * @When I fill in login form with :provider user
128
	 */
129
	public function iSignInWithSocialUser($provider)
130
	{
131
		$provider = strtolower($provider);
132
		$mink = $this->minkContext;
133
		foreach($this->socialLoginInfo[$provider] as $field=>$value){
134
			$mink->fillField($field,$value);
135
		}
136
	}
137
	
138
	/**
139
	 * @Given I am logged in as a recruiter
140
	 * @Given I am logged in as a recruiter with :organization as organization
141
	 */
142
	public function iAmLoggedInAsARecruiter($organization=null)
143
	{
144
		$user = $this->thereIsAUserIdentifiedBy(
145
			'[email protected]',
146
			'test',User::ROLE_RECRUITER,
147
			'Test Recruiter',
148
			$organization
149
		);
150
		$this->startLogin($user,'test');
0 ignored issues
show
Bug introduced by
It seems like $user defined by $this->thereIsAUserIdent...ruiter', $organization) on line 144 can also be of type object<Core\Entity\EntityInterface>; however, Yawik\Behat\UserContext::startLogin() does only seem to accept object<Auth\Entity\UserInterface>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
151
	}
152
	
153
	/**
154
	 * @Given I don't have :login user
155
	 * @param string $login
156
	 */
157
	public function iDonTHaveUser($login)
158
	{
159
		$repo = $this->getUserRepository();
160
		$user=$repo->findByLogin($login);
161
		if($user instanceof UserInterface){
162
			$repo->remove($user,true);
163
		}
164
	}
165
	
166
	/**
167
	 * @Given I have a :role with the following:
168
	 * @param $role
169
	 * @param TableNode $fields
170
	 */
171
	public function iHaveUserWithTheFollowing($role,TableNode $fields)
172
	{
173
		$normalizedFields = [
174
			'login' => '[email protected]',
175
			'fullname' => 'Test Login',
176
			'role' => User::ROLE_USER,
177
			'password' => 'test',
178
			'organization' => 'Cross Solution'
179
		];
180
		foreach($fields->getRowsHash() as $field=>$value){
181
			$field = Inflector::camelize($field);
182
			$normalizedFields[$field] = $value;
183
		}
184
		
185
		$this->thereIsAUserIdentifiedBy(
186
			$normalizedFields['login'],
187
			$normalizedFields['password'],
188
			$role,
189
			$normalizedFields['fullname'],
190
			$normalizedFields['organization']
191
		);
192
		
193
	}
194
	
195
	/**
196
	 * @Given I am logged in as an administrator
197
	 */
198
	public function iAmLoggedInAsAnAdmin()
199
	{
200
		$user = $this->thereIsAUserIdentifiedBy('[email protected]','test',User::ROLE_ADMIN);
201
		$this->startLogin($user,'test');
0 ignored issues
show
Bug introduced by
It seems like $user defined by $this->thereIsAUserIdent...ntity\User::ROLE_ADMIN) on line 200 can also be of type object<Core\Entity\EntityInterface>; however, Yawik\Behat\UserContext::startLogin() does only seem to accept object<Auth\Entity\UserInterface>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
202
	}
203
	
204
	private function startLogin(UserInterface $user, $password)
205
	{
206
		$currentUser = $this->currentUser;
207
		if(!is_object($currentUser) || $user->getId()!=$currentUser->getId()){
208
			$this->iWantToLogIn();
209
			$this->iSpecifyTheUsernameAs($user->getLogin());
210
			$this->iSpecifyThePasswordAs($password);
211
			$this->iLogIn();
212
			$this->currentUser = $user;
0 ignored issues
show
Documentation Bug introduced by
$user is of type object<Auth\Entity\UserInterface>, but the property $currentUser was declared to be of type object<Auth\Entity\User>. Are you sure that you always receive this specific sub-class here, or does it make sense to add an instanceof check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a given class or a super-class is assigned to a property that is type hinted more strictly.

Either this assignment is in error or an instanceof check should be added for that assignment.

class Alien {}

class Dalek extends Alien {}

class Plot
{
    /** @var  Dalek */
    public $villain;
}

$alien = new Alien();
$plot = new Plot();
if ($alien instanceof Dalek) {
    $plot->villain = $alien;
}
Loading history...
213
		}
214
	}
215
	
216
	/**
217
	 * @return UserRepository
218
	 */
219
	public function getUserRepository()
220
	{
221
		return $this->coreContext->getRepositories()->get('Auth\Entity\User');
222
	}
223
	
224
	/**
225
	 * @Given there is a user :email identified by :password
226
	 */
227
	public function thereIsAUserIdentifiedBy($email, $password,$role=User::ROLE_RECRUITER,$fullname="Test Recruiter",$organization=null)
228
	{
229
		$repo = $this->getUserRepository();
230
		if(!is_object($user=$repo->findByEmail($email))){
231
			$user = $this->createUser($email,$password,$role,$fullname,$organization);
0 ignored issues
show
Unused Code introduced by
The call to UserContext::createUser() has too many arguments starting with $organization.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
232
		}
233
		
234
		if(!is_null($organization)){
235
			$this->iHaveMainOrganization($user,$organization);
0 ignored issues
show
Bug introduced by
It seems like $user can also be of type object<Core\Entity\EntityInterface>; however, Yawik\Behat\UserContext::iHaveMainOrganization() does only seem to accept object<Auth\Entity\UserInterface>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
236
		}
237
		$this->addCreatedUser($user);
0 ignored issues
show
Bug introduced by
It seems like $user can also be of type object<Core\Entity\EntityInterface>; however, Yawik\Behat\UserContext::addCreatedUser() does only seem to accept object<Auth\Entity\UserInterface>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
238
		return $user;
239
	}
240
	
241
	/**
242
	 * @param $email
243
	 * @param $password
244
	 * @param $username
245
	 * @param string $fullname
246
	 * @param string $role
247
	 *
248
	 * @return \Auth\Entity\UserInterface
0 ignored issues
show
Documentation introduced by
Should the return type not be \Core\Entity\EntityInterface?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
249
	 */
250
	public function createUser($email,$password,$role=User::ROLE_RECRUITER,$fullname="Test Recruiter")
251
	{
252
		/* @var Register $service */
253
		/* @var User $user */
254
		$repo = $this->getUserRepository();
255
		$user = $repo->create([]);
256
		$user->setLogin($email);
257
		$user->setPassword($password);
258
		$user->setRole($role);
259
		$settings = $user->getSettings('Applications');
0 ignored issues
show
Unused Code introduced by
$settings is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
260
		
261
		$expFullName = explode(' ',$fullname);
262
		$info = $user->getInfo();
263
		$info->setFirstName(array_shift($expFullName));
264
		$info->setLastName(count($expFullName)>0 ? implode(' ',$expFullName):'');
265
		$info->setEmail($email);
266
		$info->setEmailVerified(true);
267
		$repo->store($user);
268
		$repo->getDocumentManager()->refresh($user);
269
		
270
		$eventArgs = new LifecycleEventArgs($user, $repo->getDocumentManager());
271
		$repo->getDocumentManager()->getEventManager()->dispatchEvent(
272
			Events::postLoad,
273
			$eventArgs
274
		);
275
		/* @var \Core\EventManager\EventManager $events */
276
		/* @var \Auth\Listener\Events\AuthEvent $event */
277
		//@TODO: [Behat] event not working in travis
278
		//$events = $this->coreContext->getEventManager();
0 ignored issues
show
Unused Code Comprehensibility introduced by
59% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
279
		//$event  = $events->getEvent(AuthEvent::EVENT_USER_REGISTERED, $this);
0 ignored issues
show
Unused Code Comprehensibility introduced by
57% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
280
		//$event->setUser($user);
0 ignored issues
show
Unused Code Comprehensibility introduced by
86% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
281
		//$events->triggerEvent($event);
0 ignored issues
show
Unused Code Comprehensibility introduced by
86% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
282
		return $user;
283
	}
284
	
285
	/**
286
	 * @When I have :organization as my main organization
287
	 * @param $orgName
288
	 */
289
	public function iHaveMainOrganization(UserInterface $user,$orgName)
290
	{
291
		/* @var $repoOrganization OrganizationRepository */
292
		$repoOrganization = $this->coreContext->getRepositories()->get('Organizations/Organization');
293
		$organization=$repoOrganization->findByName($orgName);
294
		if(!$organization instanceof Organization){
295
			$organization = new Organization();
296
			$organizationName = new OrganizationName($orgName);
297
			$organization->setOrganizationName($organizationName);
298
			$permissions = $organization->getPermissions();
299
			$permissions->grant($user,Permissions::PERMISSION_ALL);
300
		}else {
301
			$organization->getPermissions()->grant($user,Permissions::PERMISSION_ALL);
302
		}
303
		$organization->setUser($user);
304
		$repoOrganization->store($organization);
305
		$repoOrganization->getDocumentManager()->refresh($organization);
306
	}
307
	
308
	/**
309
	 * @When I want to log in
310
	 */
311
	public function iWantToLogIn()
312
	{
313
		$session = $this->minkContext->getSession();
314
		$url = $this->minkContext->locatePath('/en/login');
315
		$session->visit($url);
316
	}
317
	
318
	/**
319
	 * @When I specify the username as :username
320
	 */
321
	public function iSpecifyTheUsernameAs($username)
322
	{
323
		$this->minkContext->fillField('Login name',$username);
324
	}
325
	
326
	/**
327
	 * @When I specify the password as :password
328
	 */
329
	public function iSpecifyThePasswordAs($password)
330
	{
331
		$this->minkContext->fillField('Password',$password);
332
	}
333
	
334
	/**
335
	 * @Given I am logged in as :username identified by :password
336
	 */
337
	public function iAmLoggedInAsIdentifiedBy($username, $password)
338
	{
339
		$repo = $this->getUserRepository();
340
		$user = $repo->findByLogin($username);
341
		
342
		if(!$user instanceof User){
343
			throw new \Exception(sprintf('There is no user with this login: "%s"',$username));
344
		}
345
		$this->currentUser = $user;
346
		$this->iWantToLogIn();
347
		$this->iSpecifyTheUsernameAs($username);
348
		$this->iSpecifyThePasswordAs($password);
349
		$this->iLogIn();
350
	}
351
	
352
	/**
353
	 * @When I log in
354
	 */
355
	public function iLogIn()
356
	{
357
		$this->minkContext->pressButton('login');
358
	}
359
	
360
	/**
361
	 * @When I press logout link
362
	 */
363
	public function iPressLogoutLink()
364
	{
365
		//@TODO: [ZF3] replace this with click method
366
		$url = $this->coreContext->generateUrl('/logout');
367
		$this->minkContext->visit($url);
368
	}
369
	
370
	/**
371
	 * @Given I log in with username :username and password :password
372
	 */
373
	public function iLogInWith($username, $password)
374
	{
375
		$repo = $this->getUserRepository();
376
		$user = $repo->findByLogin($username);
377
		$this->iWantToLogIn();
378
		$this->iSpecifyTheUsernameAs($username);
379
		$this->iSpecifyThePasswordAs($password);
380
		$this->iLogIn();
381
		$this->loggedInUser = $user;
382
	}
383
	
384
	/**
385
	 * @When I go to profile page
386
	 */
387
	public function iGoToProfilePage()
388
	{
389
		$url = $this->coreContext->generateUrl('/en/my/profile');
390
		$this->minkContext->visit($url);
391
	}
392
	
393
	/**
394
	 * @Given there is a user with the following:
395
	 */
396
	public function thereIsAUserWithTheFollowing(TableNode $table)
397
	{
398
		$repo = $this->getUserRepository();
399
		$data = $table->getRowsHash();
400
		$email = isset($data['email']) ? $data['email']:'[email protected]';
401
		$password = isset($data['password']) ? $data['password']:'test';
402
		$fullname = isset($data['fullname']) ? $data['fullname']:'Test User';
403
		$role = isset($data['role']) ? $data['role']:User::ROLE_RECRUITER;
404
		
405
		if(!is_object($user=$repo->findByLogin($email))){
406
			$user = $this->createUser($email,$password,$role,$fullname);
407
		}
408
		$this->currentUser = $user;
0 ignored issues
show
Documentation Bug introduced by
It seems like $user of type object<Core\Entity\EntityInterface> or object<Auth\Entity\UserInterface> is incompatible with the declared type object<Auth\Entity\User> of property $currentUser.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
409
		$this->addCreatedUser($user);
0 ignored issues
show
Bug introduced by
It seems like $user can also be of type object<Core\Entity\EntityInterface>; however, Yawik\Behat\UserContext::addCreatedUser() does only seem to accept object<Auth\Entity\UserInterface>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
410
	}
411
	
412
	private function addCreatedUser(UserInterface $user)
413
	{
414
		if(!in_array($user,static::$users)){
0 ignored issues
show
Bug introduced by
Since $users is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self, or increasing the visibility of $users to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return static::$someVariable;
    }
}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass { }

YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class SomeClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return self::$someVariable; // self works fine with private.
    }
}
Loading history...
415
			static::$users[] = $user;
0 ignored issues
show
Bug introduced by
Since $users is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self, or increasing the visibility of $users to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return static::$someVariable;
    }
}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass { }

YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class SomeClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return self::$someVariable; // self works fine with private.
    }
}
Loading history...
416
		}
417
	}
418
	
419
	/**
420
	 * @When I want to change my password
421
	 */
422
	public function iWantToChangeMyPassword()
423
	{
424
		$mink = $this->minkContext;
425
		$url = $this->coreContext->generateUrl('/en/my/password');
426
		$mink->getSession()->visit($url);
427
	}
428
	
429
}