Bonjour,
Je me forme au framework Yii et je suis parvenu à connecter/déconnecter un utilisateur. Lorsque l’utilisateur se connecte, son pseudo s’affiche sur la page. Jusque-là pas de problème. En revanche, dans les tests fonctionnels (avec Sélénium), le test $this->assertTextPresent( Yii::app()->user->pseudo, ‘mon_pseudo’ ) plante systématiquement avec le message “La propriété « CWebUser.pseudo » est indéfinie.”.
Je ne comprends pas pourquoi, alors que le test $this->assertTrue( Yii::app()->user->isGuest passe bien (le login s’est bien passé) et que l’affichage du pseudo sur la page se passe normalement (visuellement) pendant l’exécution de Sélénium (donc que la propriété “pseudo” existe bien dans UserIdentity).
Ci-dessous, mon code source, si vous voulez bien m’aider à comprendre.
Merci d’avance
La classe UserIdentity :
class UserIdentity extends CUserIdentity {
private $_id; // id de l'utilisateur dans la table Account
/**
* Authenticates a user.
* @return boolean whether authentication succeeds.
*/
public function authenticate() {
$record = Account::model()->findByAttributes( array( 'pseudo' => $this->username ) );
if( $record === null ) {
$this->errorCode = self::ERROR_USERNAME_INVALID;
}
else if( $record->password !== crypt( $this->password, $record->password ) ) {
$this->errorCode = self::ERROR_PASSWORD_INVALID;
}
else {
$this->_id = $record->id;
$this->setState( 'pseudo', $this->username );
$this->errorCode = self::ERROR_NONE;
}
return ! $this->errorCode;
}
public function getId() {
return $this->_id;
}
}
Le modèle :
class LoginForm extends CFormModel
{
public $username;
public $password;
public $rememberMe;
private $_identity;
/**
* Declares the validation rules.
* The rules state that username and password are required,
* and password needs to be authenticated.
*/
public function rules() {
return array(
// username and password are required
array( 'username, password', 'required' ),
// rememberMe needs to be a boolean
array( 'rememberMe', 'boolean' ),
// password needs to be authenticated
array( 'password', 'authenticate' ),
);
}
/**
* Declares attribute labels.
*/
public function attributeLabels() {
return array(
'username' => 'Pseudo',
'password' => 'Mot de passe',
'rememberMe' => 'Mémoriser ces informations',
);
}
/**
* Authenticates the password.
* This is the 'authenticate' validator as declared in rules().
*/
public function authenticate( $attribute, $params ) {
if( ! $this->hasErrors() ) {
$this->_identity = new UserIdentity( $this->username, $this->password );
if( ! $this->_identity->authenticate() )
$this->addError( 'password', 'Incorrect username or password.' );
}
}
/**
* Logs in the user using the given username and password in the model.
* @return boolean whether login is successful
*/
public function login() {
if( $this->_identity === null ) {
$this->_identity = new UserIdentity( $this->username, $this->password );
$this->_identity->authenticate();
}
if( $this->_identity->errorCode === UserIdentity::ERROR_NONE ) {
$duration = $this->rememberMe ? 3600*24*30 : 0; // 30 days
Yii::app()->user->login( $this->_identity, $duration );
return true;
}
else
return false;
}
}
La fixture :
return array(
'first_user' => array(
'pseudo' => 'first_pseudo',
'password' => crypt( 'first_password' ),
),
'my_user' => array(
'pseudo' => 'mon_pseudo',
'password' => crypt( 'mon_password' ),
),
);
Les tests fonctionnels
class SiteTest extends WebTestCase {
public $fixtures = array(
'accounts' => 'Account',
);
public function testLoginLogout() {
$this->open( '' );
$this->click( 'id=login_link' );
$this->waitForVisible( 'id=login_popup' );
$this->type( 'id=LoginForm_username', 'mon_pseudo' );
$this->type( 'id=LoginForm_password', 'mon_password' );
$this->click( 'id=login_button_ok' );
$this->waitForVisible( 'id=logout_link' );
$this->assertTrue( Yii::app()->user->isGuest, "Utilisateur connecté" ); // => OK
$this->assertTextPresent( $this->accounts['my_user']['pseudo'], 'mon_pseudo' ); // => OK
$this->assertTextPresent( Yii::app()->user->pseudo, 'mon_pseudo' ); // => NOK "Propriété pseudo indéfinie"
}
}