Completed
Push — develop ( 09456b...2094a2 )
by Mathias
14s queued 10s
created

UserContext::afterSuite()   A

Complexity

Conditions 4
Paths 6

Size

Total Lines 15
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
dl 0
loc 15
rs 9.2
c 1
b 1
f 0
cc 4
eloc 9
nc 6
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\Repository\User as UserRepository;
15
use Auth\Service\Register;
16
use Behat\Behat\Context\Context;
17
use Behat\Behat\Hook\Scope\BeforeScenarioScope;
18
use Behat\Gherkin\Node\TableNode;
19
use Behat\MinkExtension\Context\MinkContext;
20
use Core\Entity\Permissions;
21
use Doctrine\Common\Util\Inflector;
22
use Doctrine\ODM\MongoDB\DocumentManager;
23
use Doctrine\ODM\MongoDB\Event\LifecycleEventArgs;
24
use Doctrine\ODM\MongoDB\Events;
25
use Organizations\Entity\Organization;
26
use Organizations\Entity\OrganizationName;
27
use Organizations\Repository\Organization as OrganizationRepository;
28
use Yawik\Behat\Exception\FailedExpectationException;
29
30
class UserContext implements Context
31
{
32
    use CommonContextTrait;
33
	
34
	/**
35
	 * @var User[]
36
	 */
37
	static private $users = [];
38
	
39
	/**
40
	 * @var UserRepository
41
	 */
42
	static private $userRepo;
43
	
44
	private $socialLoginInfo = [];
45
46
    /**
47
     * @var DocumentManager
48
     */
49
	static private $dm;
50
	
51
	/**
52
	 * @var UserInterface
53
	 */
54
	private $loggedInUser;
55
56
    /**
57
     * @var Organization
58
     */
59
	private $mainOrganization;
60
61
    /**
62
     * @var User
63
     */
64
    protected $currentUser;
65
	
66
	public function __construct($parameters=[])
67
	{
68
		$defaultLoginInfo = [
69
			'facebook' => [
70
				'email' => getenv('FACEBOOK_USER_EMAIL'),
71
				'pass' => getenv('FACEBOOK_USER_PASSWORD')
72
			],
73
			'linkedin' => [
74
				'session_key-login' => getenv('LINKEDIN_USER_EMAIL'),
75
				'session_password-login' => getenv('LINKEDIN_USER_PASSWORD')
76
			],
77
		];
78
		$socialLoginConfig = isset($parameters['social_login_info']) ? $parameters['social_login_info']:[];
79
		$this->socialLoginInfo = array_merge($defaultLoginInfo,$socialLoginConfig);
80
	}
81
82
    /**
83
     * Empty all data every each tests
84
     *
85
     * @AfterSuite
86
     */
87
	static public function tearDown()
0 ignored issues
show
Coding Style introduced by
As per PSR2, the static declaration should come after the visibility declaration.
Loading history...
88
    {
89
        $dm = static::$dm;
0 ignored issues
show
Bug introduced by
Since $dm is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self, or increasing the visibility of $dm 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...
90
91
        $documents = [
92
            'Applications\Entity\Application',
93
            'Cv\Entity\Cv',
94
            'Jobs\Entity\Job',
95
            'Organizations\Entity\Organization',
96
            'Auth\Entity\User',
97
            'Jobs\Entity\Category',
98
            'Auth\Entity\UserImage',
99
            'Organizations\Entity\OrganizationName',
100
        ];
101
        foreach($documents as $document){
102
            $dm->createQueryBuilder($document)
103
                ->remove()
104
                ->getQuery()
105
                ->execute()
106
            ;
107
        }
108
    }
109
110
	/**
111
	 * @BeforeScenario
112
	 * @param BeforeScenarioScope $scope
113
	 */
114
	public function beforeScenario(BeforeScenarioScope $scope)
115
	{
116
		$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...
117
		$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...
118
		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...
119
		static::$dm = $this->getUserRepository()->getDocumentManager();
0 ignored issues
show
Bug introduced by
Since $dm is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self, or increasing the visibility of $dm 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...
120
	}
121
	
122
	/**
123
	 * @When I fill in login form with :provider user
124
	 */
125
	public function iSignInWithSocialUser($provider)
126
	{
127
		$provider = strtolower($provider);
128
		$mink = $this->minkContext;
129
		foreach($this->socialLoginInfo[$provider] as $field=>$value){
130
			$mink->fillField($field,$value);
131
		}
132
	}
133
	
134
	/**
135
	 * @Given I am logged in as a recruiter
136
	 * @Given I am logged in as a recruiter with :organization as organization
137
	 */
138
	public function iAmLoggedInAsARecruiter($organization=null)
139
	{
140
		$user = $this->thereIsAUserIdentifiedBy(
141
			'[email protected]',
142
			'test',User::ROLE_RECRUITER,
143
			'Test Recruiter',
144
			$organization
145
		);
146
		$this->startLogin($user,'test');
0 ignored issues
show
Bug introduced by
It seems like $user defined by $this->thereIsAUserIdent...ruiter', $organization) on line 140 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...
147
		if(!is_null($organization)){
148
            $this->iHaveMainOrganization($user,$organization);
0 ignored issues
show
Bug introduced by
It seems like $user defined by $this->thereIsAUserIdent...ruiter', $organization) on line 140 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...
149
        }
150
	}
151
152
    /**
153
     * @Given I am logged out
154
     */
155
    public function iHaveLoggedOut()
156
    {
157
        $url = $this->minkContext->locatePath('/logout');
158
        $this->minkContext->getSession()->visit($url);
159
    }
160
161
	
162
	/**
163
	 * @Given I don't have :login user
164
	 * @param string $login
165
	 */
166
	public function iDonTHaveUser($login)
167
	{
168
		$repo = $this->getUserRepository();
169
		$user=$repo->findByLogin($login);
170
		if($user instanceof UserInterface){
171
			$repo->remove($user,true);
172
		}
173
	}
174
	
175
	/**
176
	 * @Given I have a :role with the following:
177
     * @Given I have an :role with the following:
178
     *
179
	 * @param $role
180
	 * @param TableNode $fields
181
	 */
182
	public function iHaveUserWithTheFollowing($role,TableNode $fields)
183
	{
184
		$normalizedFields = [
185
			'login' => '[email protected]',
186
			'fullName' => 'Test Login',
187
			'role' => $role,
188
			'password' => 'test',
189
			'organization' => 'Cross Solution'
190
		];
191
		foreach($fields->getRowsHash() as $field=>$value){
192
			$field = Inflector::camelize($field);
193
			$normalizedFields[$field] = $value;
194
		}
195
		
196
		$this->thereIsAUserIdentifiedBy(
197
			$normalizedFields['login'],
198
			$normalizedFields['password'],
199
			$role,
200
			$normalizedFields['fullName'],
201
			$normalizedFields['organization']
202
		);
203
		
204
	}
205
	
206
	/**
207
	 * @Given I am logged in as an administrator
208
	 */
209
	public function iAmLoggedInAsAnAdmin()
210
	{
211
		$user = $this->thereIsAUserIdentifiedBy('[email protected]','test',User::ROLE_ADMIN);
212
		$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 211 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...
213
	}
214
	
215
	private function startLogin(UserInterface $user, $password)
216
	{
217
		$currentUser = $this->currentUser;
218
		if(!is_object($currentUser) || $user->getId()!=$currentUser->getId()){
219
			$this->iWantToLogIn();
220
			$this->iSpecifyTheUsernameAs($user->getLogin());
221
			$this->iSpecifyThePasswordAs($password);
222
			$this->iLogIn();
223
			$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...
224
		}
225
	}
226
	
227
	/**
228
	 * @return UserRepository
229
	 */
230
	public function getUserRepository()
231
	{
232
		return $this->coreContext->getRepositories()->get('Auth\Entity\User');
233
	}
234
	
235
	/**
236
	 * @Given there is a user :email identified by :password
237
	 */
238
	public function thereIsAUserIdentifiedBy($email, $password,$role=User::ROLE_RECRUITER,$fullname="Test Recruiter",$organization=null)
239
	{
240
		$repo = $this->getUserRepository();
241
		if(!is_object($user=$repo->findByEmail($email))){
242
			$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...
243
		}
244
		
245
		if(!is_null($organization)){
246
			$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...
247
		}
248
		$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...
249
		$repo->getDocumentManager()->refresh($user);
250
		return $user;
251
	}
252
	
253
	/**
254
	 * @param $email
255
	 * @param $password
256
	 * @param $username
257
	 * @param string $fullname
258
	 * @param string $role
259
	 *
260
	 * @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...
261
	 */
262
	public function createUser($email,$password,$role=User::ROLE_RECRUITER,$fullname="Test Recruiter")
263
	{
264
		/* @var Register $service */
265
		/* @var User $user */
266
		$repo = $this->getUserRepository();
267
		$user = $repo->create([]);
268
		$user->setLogin($email);
269
		$user->setPassword($password);
270
		$user->setRole($role);
271
		$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...
272
		
273
		$expFullName = explode(' ',$fullname);
274
		$info = $user->getInfo();
275
		$info->setFirstName(array_shift($expFullName));
276
		$info->setLastName(count($expFullName)>0 ? implode(' ',$expFullName):'');
277
		$info->setEmail($email);
278
		$info->setEmailVerified(true);
279
		$repo->store($user);
280
		$repo->getDocumentManager()->refresh($user);
281
		
282
		$eventArgs = new LifecycleEventArgs($user, $repo->getDocumentManager());
283
		$repo->getDocumentManager()->getEventManager()->dispatchEvent(
284
			Events::postLoad,
285
			$eventArgs
286
		);
287
		/* @var \Core\EventManager\EventManager $events */
288
		/* @var \Auth\Listener\Events\AuthEvent $event */
289
		//@TODO: [Behat] event not working in travis
290
		//$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...
291
		//$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...
292
		//$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...
293
		//$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...
294
		return $user;
295
	}
296
	
297
	/**
298
	 * @When I have :organization as my main organization
299
	 * @param $orgName
300
	 */
301
	public function iHaveMainOrganization(UserInterface $user,$orgName)
302
	{
303
		/* @var $repoOrganization OrganizationRepository */
304
		$repoOrganization = $this->coreContext->getRepositories()->get('Organizations/Organization');
305
		$result = $repoOrganization->findByName($orgName);
306
		$organization = count($result) > 0 ? $result[0]:null;
307 View Code Duplication
		if(!$organization instanceof Organization){
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
308
			$organization = new Organization();
309
			$organizationName = new OrganizationName($orgName);
310
			$organization->setOrganizationName($organizationName);
311
		}
312
        $organization->setProfileSetting(Organization::PROFILE_ALWAYS_ENABLE);
313
        $permissions = $organization->getPermissions();
314
        $permissions->grant($user,Permissions::PERMISSION_ALL);
315
316
        $organization->setUser($user);
317
        $repoOrganization->store($organization);
318
        $repoOrganization->getDocumentManager()->refresh($organization);
319
320
        $this->mainOrganization = $organization;
321
	}
322
323
    /**
324
     * @return Organization
325
     */
326
    public function getMainOrganization()
327
    {
328
        return $this->mainOrganization;
329
    }
330
331
	/**
332
	 * @When I want to log in
333
	 */
334
	public function iWantToLogIn()
335
	{
336
		$session = $this->minkContext->getSession();
337
		$url = $this->buildUrl('lang/auth');
338
		$session->visit($url);
339
	}
340
	
341
	/**
342
	 * @When I specify the username as :username
343
	 */
344
	public function iSpecifyTheUsernameAs($username)
345
	{
346
		$this->minkContext->fillField('Login name',$username);
347
	}
348
	
349
	/**
350
	 * @When I specify the password as :password
351
	 */
352
	public function iSpecifyThePasswordAs($password)
353
	{
354
		$this->minkContext->fillField('Password',$password);
355
	}
356
	
357
	/**
358
	 * @Given I am logged in as :username identified by :password
359
	 */
360
	public function iAmLoggedInAsIdentifiedBy($username, $password)
361
	{
362
		$repo = $this->getUserRepository();
363
		$user = $repo->findByLogin($username);
364
		
365
		if(!$user instanceof User){
366
			throw new \Exception(sprintf('There is no user with this login: "%s"',$username));
367
		}
368
		$this->iWantToLogIn();
369
		$this->iSpecifyTheUsernameAs($username);
370
		$this->iSpecifyThePasswordAs($password);
371
		$this->iLogIn();
372
        $this->currentUser = $user;
373
	}
374
	
375
	/**
376
	 * @When I log in
377
	 */
378
	public function iLogIn()
379
	{
380
		$this->minkContext->pressButton('login');
381
	}
382
	
383
	/**
384
	 * @When I press logout link
385
	 */
386
	public function iPressLogoutLink()
387
	{
388
		$url = $this->buildUrl('auth-logout');
389
		$this->visit($url);
390
	}
391
	
392
	/**
393
	 * @Given I log in with username :username and password :password
394
	 */
395
	public function iLogInWith($username, $password)
396
	{
397
		$repo = $this->getUserRepository();
398
		$user = $repo->findByLogin($username);
399
		$this->iWantToLogIn();
400
		$this->iSpecifyTheUsernameAs($username);
401
		$this->iSpecifyThePasswordAs($password);
402
		$this->iLogIn();
403
		$this->loggedInUser = $user;
404
	}
405
	
406
	/**
407
	 * @When I go to profile page
408
	 */
409
	public function iGoToProfilePage()
410
	{
411
		$url = $this->buildUrl('lang/my');
412
		$this->visit($url);
413
	}
414
	
415
	/**
416
	 * @Given there is a user with the following:
417
	 */
418
	public function thereIsAUserWithTheFollowing(TableNode $table)
419
	{
420
		$repo = $this->getUserRepository();
421
		$data = $table->getRowsHash();
422
		$email = isset($data['email']) ? $data['email']:'[email protected]';
423
		$password = isset($data['password']) ? $data['password']:'test';
424
		$fullname = isset($data['fullname']) ? $data['fullname']:'Test User';
425
		$role = isset($data['role']) ? $data['role']:User::ROLE_RECRUITER;
426
		
427
		if(!is_object($user=$repo->findByLogin($email))){
428
			$user = $this->createUser($email,$password,$role,$fullname);
429
		}
430
		$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...
431
		$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...
432
	}
433
	
434
	private function addCreatedUser(UserInterface $user)
435
	{
436
		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...
437
			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...
438
		}
439
	}
440
	
441
	/**
442
	 * @When I want to change my password
443
	 */
444
	public function iWantToChangeMyPassword()
445
	{
446
		$url = $this->buildUrl('lang/my-password');
447
		$this->visit($url);
448
	}
449
450
    /**
451
     * @return User
452
     * @throws FailedExpectationException
453
     */
454
	public function getCurrentUser()
455
    {
456
        if(!$this->currentUser instanceof User){
457
            throw new FailedExpectationException('Need to login first before use this step');
458
        }
459
        return $this->currentUser;
460
    }
461
}
462
463