Customise Special:UserLogout success message for temporary account

Why:
* When a temporary account exits their session, the
  Special:UserLogout page is loaded to indicate the success.
* However, the success page talks about the temporary account
  logging out which may cause confusion.
* Per design mocks shared on T374519, this should be modified
  to indicate that the user logged out of a temporary account.

What:
* Set 'templogout' as the page title when the user is logging out
  of a temporary account.
* Set 'logouttext-for-temporary-account' as the message shown
  for a logout success when the user is logging out from a
  temporary account
* Update mediawiki.page.ready/ready.js to add a flag to the
  URL Special:UserLogout URL that is redirected to once the
  logout API call has occured.
* Update tests for SpecialUserLogoutTest

Bug: T374519
Change-Id: Ib62cdb5ba716976321cd556aa9defe97b3446b33
This commit is contained in:
Dreamy Jazz 2024-09-11 16:12:52 +01:00
parent 7fa2b33fb4
commit ab89fff633
6 changed files with 87 additions and 6 deletions

View file

@ -459,6 +459,9 @@ class SpecialPageFactory {
],
'Userlogout' => [
'class' => SpecialUserLogout::class,
'services' => [
'TempUserConfig',
],
],
'CreateAccount' => [
'class' => SpecialCreateAccount::class,

View file

@ -26,6 +26,7 @@ use MediaWiki\Session\SessionManager;
use MediaWiki\SpecialPage\FormSpecialPage;
use MediaWiki\SpecialPage\SpecialPage;
use MediaWiki\Status\Status;
use MediaWiki\User\TempUser\TempUserConfig;
/**
* Implements Special:Userlogout
@ -39,8 +40,11 @@ class SpecialUserLogout extends FormSpecialPage {
*/
private $oldUserName;
public function __construct() {
private TempUserConfig $tempUserConfig;
public function __construct( TempUserConfig $tempUserConfig ) {
parent::__construct( 'Userlogout' );
$this->tempUserConfig = $tempUserConfig;
}
public function doesWrites() {
@ -125,7 +129,17 @@ class SpecialUserLogout extends FormSpecialPage {
$this->getRequest()->getValues( 'returnto', 'returntoquery' ) );
$out = $this->getOutput();
$out->addWikiMsg( 'logouttext', $loginURL );
$messageKey = 'logouttext';
if (
( isset( $this->oldUserName ) && $this->tempUserConfig->isTempName( $this->oldUserName ) ) ||
$this->getRequest()->getCheck( 'wasTempUser' )
) {
// Generates the message key logouttext-for-temporary-account which is used to customise the success
// message for a temporary account.
$messageKey .= '-for-temporary-account';
}
$out->addWikiMsg( $messageKey, $loginURL );
$out->returnToMain();
}
@ -137,6 +151,18 @@ class SpecialUserLogout extends FormSpecialPage {
public function requiresUnblock() {
return false;
}
public function getDescription() {
// Set the page title as "templogout" if the user is (or just was) logged in to a temporary account
if (
$this->getUser()->isTemp() ||
( isset( $this->oldUserName ) && $this->tempUserConfig->isTempName( $this->oldUserName ) ) ||
$this->getRequest()->getCheck( 'wasTempUser' )
) {
return $this->msg( 'templogout' );
}
return parent::getDescription();
}
}
/**

View file

@ -353,6 +353,7 @@
"virus-scanfailed": "scan failed (code $1)",
"virus-unknownscanner": "unknown antivirus:",
"logouttext": "<strong>You are now logged out.</strong>\n\nNote that some pages may continue to be displayed as if you were still logged in, until you clear your browser cache.",
"logouttext-for-temporary-account": "<strong>You are now logged out of your temporary account.</strong>\n\nNote that some pages may continue to be displayed as if you were still logged in, until you clear your browser cache.",
"logging-out-notify": "You are being logged out, please wait.",
"logout-failed": "Cannot log out now: $1",
"cannotlogoutnow-title": "Cannot log out now",

View file

@ -615,7 +615,8 @@
"virus-badscanner": "Used as error message. Parameters:\n* $1 - virus scanner name which is defined in the variable [[mw:Special:MyLanguage/Manual:$wgAntivirus|$wgAntivirus]].",
"virus-scanfailed": "Used as error message. \"scan\" stands for \"virus scan\". Parameters:\n* $1 - exit code of virus scanner",
"virus-unknownscanner": "Used as error message. This message is followed by the virus scanner name.",
"logouttext": "Log out message. Parameters:\n* $1 - (Unused) an URL to [[Special:Userlogin]] containing <code>returnto</code> and <code>returntoquery</code> parameters",
"logouttext": "Log out message. If the user just logged out of a temporary account, the {{msg-mw|logouttext-for-temporary-account}} message is used instead. Parameters:\n* $1 - (Unused) an URL to [[Special:Userlogin]] containing <code>returnto</code> and <code>returntoquery</code> parameters",
"logouttext-for-temporary-account": "Log out message used when the user just logged out of a temporary account. Otherwise the {{msg-mw|logouttext}} message is used instead. Parameters:\n* $1 - (Unused) an URL to [[Special:Userlogin]] containing <code>returnto</code> and <code>returntoquery</code> parameters",
"logging-out-notify": "The message when the user is being logged out.",
"logout-failed": "Message when log out fails in notification popup. Parameters:\n* $1 - Error message",
"cannotlogoutnow-title": "Error page title shown when logging out is not possible.",
@ -653,7 +654,7 @@
"logout": "Used as link text in your personal toolbox (upper right side).\n\nSee also:\n* {{msg-mw|Logout}}\n* {{msg-mw|Accesskey-pt-logout}}\n* {{msg-mw|Tooltip-pt-logout}}\n{{Identical|Log out}}",
"userlogout": "{{doc-special|UserLogout|unlisted=1}}\n{{Identical|Log out}}",
"userlogout-summary": "{{ignored}}",
"templogout": "Used as log out link text in your personal toolbox (upper right side) for temp users.",
"templogout": "Used as log out link text in your personal toolbox (upper right side) for temp users and also as the page title for [[Special:UserLogout]] when the user is (or was just) logged in to a temporary account.",
"notloggedin": "This message is displayed in the standard skin when not logged in. The message is placed above the login link in the top right corner of pages.\n\n{{Identical|Not logged in}}",
"userlogin-noaccount": "In the [[Special:Userlogin]] form, this is the text prior to button inviting user to join project.\n{{Identical|Do not have an account}}",
"userlogin-joinproject": "Text of button inviting user to create an account.\n\nSee example: [[Special:UserLogin]]",

View file

@ -192,6 +192,13 @@ $( () => {
{ tag: 'logout', autoHide: false }
);
var api = new mw.Api();
if ( mw.user.isTemp() ) {
// Indicate to the success page that the user was previously a temporary account, so that the success
// message can be customised appropriately.
const url = new URL( href );
url.searchParams.append( 'wasTempUser', 1 );
href = url;
}
api.postWithToken( 'csrf', {
action: 'logout'
} ).then(

View file

@ -4,6 +4,7 @@ use MediaWiki\Context\RequestContext;
use MediaWiki\Request\FauxRequest;
use MediaWiki\SpecialPage\SpecialPage;
use MediaWiki\Specials\SpecialUserLogout;
use MediaWiki\Tests\User\TempUser\TempUserTestTrait;
/**
* @covers \MediaWiki\Specials\SpecialUserLogout
@ -11,13 +12,15 @@ use MediaWiki\Specials\SpecialUserLogout;
*/
class SpecialUserLogoutTest extends SpecialPageTestBase {
use TempUserTestTrait;
/**
* Returns a new instance of the special page under test.
*
* @return SpecialPage
*/
protected function newSpecialPage() {
return new SpecialUserLogout();
return new SpecialUserLogout( $this->getServiceContainer()->getTempUserConfig() );
}
public function testUserLogoutComplete() {
@ -38,11 +41,51 @@ class SpecialUserLogoutTest extends SpecialPageTestBase {
$oldNameInHook = $oldName;
}
);
$this->executeSpecialPage( '', $fauxRequest, 'qqx', $user->getUser() );
[ $html ] = $this->executeSpecialPage( '', $fauxRequest, 'qqx', $user->getUser(), true );
// Check that the page title and page content are as expected for a normal user logout
$this->assertStringContainsString( '(logouttext:', $html );
$this->assertStringContainsString( '(userlogout)', $html );
$this->assertEquals(
$oldName,
$oldNameInHook,
'old name in UserLogoutComplete hook was incorrect'
);
}
public function testExecuteForTemporaryAccount() {
$this->enableAutoCreateTempUser();
$user = $this->getServiceContainer()->getTempUserCreator()->create( null, new FauxRequest() )->getUser();
$session = RequestContext::getMain()->getRequest()->getSession();
$session->setUser( $user );
$fauxRequest = new FauxRequest( [ 'wpEditToken' => $session->getToken( 'logoutToken' ) ], true, $session );
[ $html ] = $this->executeSpecialPage( '', $fauxRequest, 'qqx', $user, true );
// Check that the page title and page content are as expected for the temporary account logout
$this->assertStringContainsString( '(logouttext-for-temporary-account:', $html );
$this->assertStringContainsString( '(templogout)', $html );
}
public function testViewForTemporaryAccountAfterApiLogout() {
$user = $this->getServiceContainer()->getUserFactory()->newAnonymous( '1.2.3.4' );
$fauxRequest = new FauxRequest( [ 'wasTempUser' => 1 ] );
[ $html ] = $this->executeSpecialPage( '', $fauxRequest, 'qqx', $user, true );
// Check that the page title and page content are as expected for the temporary account logout
$this->assertStringContainsString( '(logouttext-for-temporary-account:', $html );
$this->assertStringContainsString( '(templogout)', $html );
}
public function testViewForTemporaryAccount() {
$this->enableAutoCreateTempUser();
$user = $this->getServiceContainer()->getTempUserCreator()->create( null, new FauxRequest() )->getUser();
[ $html ] = $this->executeSpecialPage( '', null, 'qqx', $user, true );
// Check that the page title is as expected for a temporary account and that the submit button is present
$this->assertStringContainsString( '(templogout)', $html );
$this->assertStringContainsString( '(htmlform-submit)', $html );
}
}