Completed
Pull Request — develop (#462)
by ANTHONIUS
07:17
created

UserContext::iDonTHaveUser()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 8
rs 9.4285
cc 2
eloc 5
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\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 have user with the following:
154
     *
155
     *
156
     */
157
	public function iHaveRecruiterWithOrganization(TableNode $tableNode)
158
    {
159
        $rows = $tableNode->getRowsHash();
160
161
        $this->thereIsAUserIdentifiedBy(
162
            $rows['email'],
163
            'test',
164
            User::ROLE_RECRUITER,
165
            $rows['name'],
166
            $rows['organization']
167
        );
168
    }
169
170
    /**
171
     * @Given I am logged out
172
     */
173
    public function iHaveLoggedOut()
174
    {
175
        $url = $this->minkContext->locatePath('/logout');
176
        $this->minkContext->getSession()->visit($url);
177
    }
178
179
	
180
	/**
181
	 * @Given I don't have :login user
182
	 * @param string $login
183
	 */
184
	public function iDonTHaveUser($login)
185
	{
186
		$repo = $this->getUserRepository();
187
		$user=$repo->findByLogin($login);
188
		if($user instanceof UserInterface){
189
			$repo->remove($user,true);
190
		}
191
	}
192
	
193
	/**
194
	 * @Given I have a :role with the following:
195
	 * @param $role
196
	 * @param TableNode $fields
197
	 */
198
	public function iHaveUserWithTheFollowing($role,TableNode $fields)
199
	{
200
		$normalizedFields = [
201
			'login' => '[email protected]',
202
			'fullname' => 'Test Login',
203
			'role' => User::ROLE_USER,
204
			'password' => 'test',
205
			'organization' => 'Cross Solution'
206
		];
207
		foreach($fields->getRowsHash() as $field=>$value){
208
			$field = Inflector::camelize($field);
209
			$normalizedFields[$field] = $value;
210
		}
211
		
212
		$this->thereIsAUserIdentifiedBy(
213
			$normalizedFields['login'],
214
			$normalizedFields['password'],
215
			$role,
216
			$normalizedFields['fullname'],
217
			$normalizedFields['organization']
218
		);
219
		
220
	}
221
	
222
	/**
223
	 * @Given I am logged in as an administrator
224
	 */
225
	public function iAmLoggedInAsAnAdmin()
226
	{
227
		$user = $this->thereIsAUserIdentifiedBy('[email protected]','test',User::ROLE_ADMIN);
228
		$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 227 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...
229
	}
230
	
231
	private function startLogin(UserInterface $user, $password)
232
	{
233
		$currentUser = $this->currentUser;
234
		if(!is_object($currentUser) || $user->getId()!=$currentUser->getId()){
235
			$this->iWantToLogIn();
236
			$this->iSpecifyTheUsernameAs($user->getLogin());
237
			$this->iSpecifyThePasswordAs($password);
238
			$this->iLogIn();
239
			$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...
240
		}
241
	}
242
	
243
	/**
244
	 * @return UserRepository
245
	 */
246
	public function getUserRepository()
247
	{
248
		return $this->coreContext->getRepositories()->get('Auth\Entity\User');
249
	}
250
	
251
	/**
252
	 * @Given there is a user :email identified by :password
253
	 */
254
	public function thereIsAUserIdentifiedBy($email, $password,$role=User::ROLE_RECRUITER,$fullname="Test Recruiter",$organization=null)
255
	{
256
		$repo = $this->getUserRepository();
257
		if(!is_object($user=$repo->findByEmail($email))){
258
			$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...
259
		}
260
		
261
		if(!is_null($organization)){
262
			$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...
263
		}
264
		$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...
265
		$repo->getDocumentManager()->refresh($user);
266
		return $user;
267
	}
268
	
269
	/**
270
	 * @param $email
271
	 * @param $password
272
	 * @param $username
273
	 * @param string $fullname
274
	 * @param string $role
275
	 *
276
	 * @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...
277
	 */
278
	public function createUser($email,$password,$role=User::ROLE_RECRUITER,$fullname="Test Recruiter")
279
	{
280
		/* @var Register $service */
281
		/* @var User $user */
282
		$repo = $this->getUserRepository();
283
		$user = $repo->create([]);
284
		$user->setLogin($email);
285
		$user->setPassword($password);
286
		$user->setRole($role);
287
		$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...
288
		
289
		$expFullName = explode(' ',$fullname);
290
		$info = $user->getInfo();
291
		$info->setFirstName(array_shift($expFullName));
292
		$info->setLastName(count($expFullName)>0 ? implode(' ',$expFullName):'');
293
		$info->setEmail($email);
294
		$info->setEmailVerified(true);
295
		$repo->store($user);
296
		$repo->getDocumentManager()->refresh($user);
297
		
298
		$eventArgs = new LifecycleEventArgs($user, $repo->getDocumentManager());
299
		$repo->getDocumentManager()->getEventManager()->dispatchEvent(
300
			Events::postLoad,
301
			$eventArgs
302
		);
303
		/* @var \Core\EventManager\EventManager $events */
304
		/* @var \Auth\Listener\Events\AuthEvent $event */
305
		//@TODO: [Behat] event not working in travis
306
		//$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...
307
		//$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...
308
		//$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...
309
		//$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...
310
		return $user;
311
	}
312
	
313
	/**
314
	 * @When I have :organization as my main organization
315
	 * @param $orgName
316
	 */
317
	public function iHaveMainOrganization(UserInterface $user,$orgName)
318
	{
319
		/* @var $repoOrganization OrganizationRepository */
320
		$repoOrganization = $this->coreContext->getRepositories()->get('Organizations/Organization');
321
		$result = $repoOrganization->findByName($orgName);
322
		$organization = count($result) > 0 ? $result[0]:null;
323 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...
324
			$organization = new Organization();
325
			$organizationName = new OrganizationName($orgName);
326
			$organization->setOrganizationName($organizationName);
327
		}
328
        $organization->setProfileSetting(Organization::PROFILE_ALWAYS_ENABLE);
329
        $permissions = $organization->getPermissions();
330
        $permissions->grant($user,Permissions::PERMISSION_ALL);
331
332
        $organization->setUser($user);
333
        $repoOrganization->store($organization);
334
        $repoOrganization->getDocumentManager()->refresh($organization);
335
336
        $this->mainOrganization = $organization;
337
	}
338
339
    /**
340
     * @return Organization
341
     */
342
    public function getMainOrganization()
343
    {
344
        return $this->mainOrganization;
345
    }
346
347
	/**
348
	 * @When I want to log in
349
	 */
350
	public function iWantToLogIn()
351
	{
352
		$session = $this->minkContext->getSession();
353
		$url = $this->buildUrl('lang/auth');
354
		$session->visit($url);
355
	}
356
	
357
	/**
358
	 * @When I specify the username as :username
359
	 */
360
	public function iSpecifyTheUsernameAs($username)
361
	{
362
		$this->minkContext->fillField('Login name',$username);
363
	}
364
	
365
	/**
366
	 * @When I specify the password as :password
367
	 */
368
	public function iSpecifyThePasswordAs($password)
369
	{
370
		$this->minkContext->fillField('Password',$password);
371
	}
372
	
373
	/**
374
	 * @Given I am logged in as :username identified by :password
375
	 */
376
	public function iAmLoggedInAsIdentifiedBy($username, $password)
377
	{
378
		$repo = $this->getUserRepository();
379
		$user = $repo->findByLogin($username);
380
		
381
		if(!$user instanceof User){
382
			throw new \Exception(sprintf('There is no user with this login: "%s"',$username));
383
		}
384
		$this->iWantToLogIn();
385
		$this->iSpecifyTheUsernameAs($username);
386
		$this->iSpecifyThePasswordAs($password);
387
		$this->iLogIn();
388
        $this->currentUser = $user;
389
	}
390
	
391
	/**
392
	 * @When I log in
393
	 */
394
	public function iLogIn()
395
	{
396
		$this->minkContext->pressButton('login');
397
	}
398
	
399
	/**
400
	 * @When I press logout link
401
	 */
402
	public function iPressLogoutLink()
403
	{
404
		$url = $this->buildUrl('auth-logout');
405
		$this->visit($url);
406
	}
407
	
408
	/**
409
	 * @Given I log in with username :username and password :password
410
	 */
411
	public function iLogInWith($username, $password)
412
	{
413
		$repo = $this->getUserRepository();
414
		$user = $repo->findByLogin($username);
415
		$this->iWantToLogIn();
416
		$this->iSpecifyTheUsernameAs($username);
417
		$this->iSpecifyThePasswordAs($password);
418
		$this->iLogIn();
419
		$this->loggedInUser = $user;
420
	}
421
	
422
	/**
423
	 * @When I go to profile page
424
	 */
425
	public function iGoToProfilePage()
426
	{
427
		$url = $this->buildUrl('lang/my');
428
		$this->visit($url);
429
	}
430
	
431
	/**
432
	 * @Given there is a user with the following:
433
	 */
434
	public function thereIsAUserWithTheFollowing(TableNode $table)
435
	{
436
		$repo = $this->getUserRepository();
437
		$data = $table->getRowsHash();
438
		$email = isset($data['email']) ? $data['email']:'[email protected]';
439
		$password = isset($data['password']) ? $data['password']:'test';
440
		$fullname = isset($data['fullname']) ? $data['fullname']:'Test User';
441
		$role = isset($data['role']) ? $data['role']:User::ROLE_RECRUITER;
442
		
443
		if(!is_object($user=$repo->findByLogin($email))){
444
			$user = $this->createUser($email,$password,$role,$fullname);
445
		}
446
		$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...
447
		$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...
448
	}
449
	
450
	private function addCreatedUser(UserInterface $user)
451
	{
452
		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...
453
			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...
454
		}
455
	}
456
	
457
	/**
458
	 * @When I want to change my password
459
	 */
460
	public function iWantToChangeMyPassword()
461
	{
462
		$url = $this->buildUrl('lang/my-password');
463
		$this->visit($url);
464
	}
465
466
    /**
467
     * @return User
468
     * @throws FailedExpectationException
469
     */
470
	public function getCurrentUser()
471
    {
472
        if(!$this->currentUser instanceof User){
473
            throw new FailedExpectationException('Need to login first before use this step');
474
        }
475
        return $this->currentUser;
476
    }
477
}
478
479