Closed michaelarnauts closed 9 months ago
I'm a bit confused though. This would resolve the exception for sure, but in your specific test case it will not work as expected. Since sessions are not actually used in the console application.
As far as I can tell the code should work for custom storage backends, any reason why you explicitly check for it and exclude it?
I'm a bit confused though. This would resolve the exception for sure, but in your specific test case it will not work as expected. Since sessions are not actually used in the console application.
As far as I can tell the code should work for custom storage backends, any reason why you explicitly check for it and exclude it?
I'm testing a REST application with enableSession set to false;
'user' => [
'identityClass' => common\models\UserIdentity::class,
'enableSession' => false,
'loginUrl' => null,
],
In my tests, I set a Bearer token to login as a specific user. I can now use this like this (simplified).
$I->haveHttpHeader('Content-Type', 'application/json');
$I->setUpAuthentication('admin');
// make calls as admin
$friend = $I->haveFriend('friend');
$friend->does(function (FunctionalTester $I) {
$I->haveHttpHeader('Content-Type', 'application/json');
$I->setUpAuthentication('user');
// make calls as user
});
The $I->setupAuthentication()
generates a token and eventually does a $I->amBearerAuthenticated($token)
Hmm, but if you are not really using sessions, why even use the friend workflow?
$I->haveHttpHeader('Content-Type', 'application/json');
$I->setUpAuthentication('admin');
// make calls as admin
$I->setUpAuthentication('user');
// make calls as user
This would work just as well right? I'm happy merging this btw, but I feel it's not very descriptive of what's happening. Since there is actually no session stuff and I'm pretty sure that even outside the haveFriend
closure your bearer authentication will persist and you'll not be an admin.
In big caps my expectation of what'll happen:
$I->haveHttpHeader('Content-Type', 'application/json');
$I->setUpAuthentication('admin');
// YOU ARE NOW ADMIN
$friend = $I->haveFriend('friend');
$friend->does(function (FunctionalTester $I) {
$I->haveHttpHeader('Content-Type', 'application/json');
$I->setUpAuthentication('user');
// YOU ARE NOW USER
});
// YOU ARE STILL USER
Hmm, it actually works as expected. I'm using another token inside the closure. I suppose inside the closure, there is a new FunctionalTester instance with fresh empty headers.
Some (simplified) debug log:
I send post "/api/admin-call"
[Request] POST http://localhost:8080/index-test.php/api/admin-call []
[Request Headers] {"Authorization":"Bearer ey...4EgaIJAGeikPCriXHo"}
FRIEND DOES ---
I have http header "Content-Type","application/json"
Codeception\Lib\Friend: does "Closure"
I am bearer authenticated "ey..."
I send post "/api/user-call"
[Request] POST http://localhost:8080/index-test.php/api/user-call []
[Request Headers] {"Content-Type":"application/json","Authorization":"Bearer ey.._OtZ0K5fFi21o"}
--- FRIEND FINISHED
I send post "/api/admin-call"
[Request] POST http://localhost:8080/index-test.php/api/admin-call []
[Request Headers] {"Authorization":"Bearer ey...4EgaIJAGeikPCriXHo"}
Ah, of course; the backup session function not only backs up the session but also the client context and headers:
/**
* Return the session content for future restoring. Implements MultiSession.
* @return array backup data
*/
public function _backupSession(): array
{
if (isset(Yii::$app) && Yii::$app->session->useCustomStorage) {
throw new ModuleException($this, "Yii2 MultiSession only supports the default session backend.");
}
return [
'clientContext' => $this->client->getContext(),
'headers' => $this->headers,
'cookie' => isset($_COOKIE) ? $_COOKIE : [],
'session' => isset($_SESSION) ? $_SESSION : [],
];
}
@samdark can you trigger / do a release? It's not automated and I don't know the release process.
@samdark @SamMousa Can we do a release with this change?
When using
$I->haveFriend()
, my tests would fail with the following error.This is because the code in
_backupSession()
didn't check if we actually have aYii::$app->session
before accessingYii::$app->session->useCustomStorage
.This PR fixes this and allows me to run my tests.
See #2 and #3