Vector is split into 2 skins

A new vector-2022 skin is added. This will be the eventual home
of the new Vector skin when we are ready to migrate.

Please see SkinVector class for the migration plan to simulate this
as part of testing.

Bug: T291098
Change-Id: Ibaddf94a5bfb5e21bbbaf1e0aa1b343a3f566d2d
This commit is contained in:
jdlrobson 2021-09-09 15:13:48 -07:00
parent 9684566e4f
commit 7d2d50873f
14 changed files with 402 additions and 59 deletions

View File

@ -3,6 +3,7 @@
"authors": []
},
"skinname-vector": "Vector",
"skinname-vector-2022": "Vector 2022",
"vector-skin-desc": "Modern version of MonoBook with fresh look and many usability improvements",
"prefs-vector-enable-vector-1-label": "Use Legacy Vector",
"prefs-vector-enable-vector-1-help": "Over the next few years, we will be gradually updating the Vector skin. Legacy Vector will allow you to view the old version of Vector (as of December 2019). To learn more about the updates, go to our [[mw:Reading/Web/Desktop_Improvements|project page]].",

View File

@ -16,6 +16,7 @@
]
},
"skinname-vector": "{{name}}",
"skinname-vector-2022": "{{name}}",
"vector-skin-desc": "{{desc|what=skin|name=Vector|url=https://www.mediawiki.org/wiki/Skin:Vector}}",
"prefs-vector-enable-vector-1-label": "Label for the checkbox to force Legacy Vector operation accessible via Special:Preferences. When this checkbox is enabled, the December 2019 of Vector is used. When this checkbox is disabled, the actively developed version of Vector is used instead.",
"prefs-vector-enable-vector-1-help": "Detail explaining the operation of the prefs-vector-enable-vector-1-label checkbox.",

View File

@ -14,7 +14,13 @@ final class Constants {
* This is tightly coupled to the ConfigRegistry field in skin.json.
* @var string
*/
public const SKIN_NAME = 'vector';
public const SKIN_NAME_MODERN = 'vector-2022';
/**
* This is tightly coupled to the ConfigRegistry field in skin.json.
* @var string
*/
public const SKIN_NAME_LEGACY = 'vector';
// These are tightly coupled to PREF_KEY_SKIN_VERSION and skin.json's configs. See skin.json for
// documentation.
@ -69,6 +75,11 @@ final class Constants {
public const CONFIG_KEY_DEFAULT_SIDEBAR_VISIBLE_FOR_ANONYMOUS_USER =
'VectorDefaultSidebarVisibleForAnonymousUser';
/**
* @var string
*/
public const PREF_KEY_SKIN = 'skin';
/**
* @var string
*/

View File

@ -10,7 +10,6 @@ use ResourceLoaderContext;
use RuntimeException;
use Skin;
use SkinTemplate;
use SkinVector;
use Title;
use User;
use Vector\HTMLForm\Fields\HTMLLegacySkinVersionField;
@ -24,6 +23,19 @@ use Vector\HTMLForm\Fields\HTMLLegacySkinVersionField;
* @internal
*/
class Hooks {
/**
* Checks if the current skin is a variant of Vector
*
* @param string $skinName
* @return bool
*/
private static function isVectorSkin( string $skinName ): bool {
return (
$skinName === Constants::SKIN_NAME_LEGACY ||
$skinName === Constants::SKIN_NAME_MODERN
);
}
/**
* @param Config $config
* @return array
@ -355,7 +367,8 @@ class Hooks {
}
/**
* Add Vector preferences to the user's Special:Preferences page directly underneath skins.
* Add Vector preferences to the user's Special:Preferences page directly underneath skins
* provided that $wgVectorSkinMigrationMode is not enabled.
*
* @param User $user User whose preferences are being modified.
* @param array[] &$prefs Preferences description array, to be fed to a HTMLForm object.
@ -366,6 +379,16 @@ class Hooks {
return;
}
// If migration mode was enabled, and the skin version is set to modern,
// switch over the skin.
if ( self::isMigrationMode() && !self::isSkinVersionLegacy() ) {
MediaWikiServices::getInstance()->getUserOptionsManager()->setOption(
$user,
Constants::PREF_KEY_SKIN,
Constants::SKIN_NAME_MODERN
);
}
// Preferences to add.
$vectorPrefs = [
Constants::PREF_KEY_SKIN_VERSION => [
@ -380,7 +403,9 @@ class Hooks {
'default' => self::isSkinVersionLegacy(),
// Only show this section when the Vector skin is checked. The JavaScript client also uses
// this state to determine whether to show or hide the whole section.
'hide-if' => [ '!==', 'wpskin', Constants::SKIN_NAME ],
// If migration mode is enabled, the section is always hidden.
'hide-if' => self::isMigrationMode() ? [ '!==', 'wpskin', '0' ] :
[ '!==', 'wpskin', Constants::SKIN_NAME_LEGACY ],
],
Constants::PREF_KEY_SIDEBAR_VISIBLE => [
'type' => 'api',
@ -389,7 +414,9 @@ class Hooks {
];
// Seek the skin preference section to add Vector preferences just below it.
$skinSectionIndex = array_search( 'skin', array_keys( $prefs ) );
$skinSectionIndex = array_search(
Constants::PREF_KEY_SKIN, array_keys( $prefs )
);
if ( $skinSectionIndex !== false ) {
// Skin preference section found. Inject Vector skin-specific preferences just below it.
// This pattern can be found in Popups too. See T246162.
@ -408,25 +435,41 @@ class Hooks {
* presentation of skin version to a version string. That is, a single preference change by the
* user may trigger two writes: a boolean followed by a string.
*
* @param array $formData Form data submitted by user
* @param array &$formData Form data submitted by user
* @param HTMLForm $form A preferences form
* @param User $user Logged-in user
* @param bool &$result Variable defining is form save successful
* @param array $oldPreferences
*/
public static function onPreferencesFormPreSave(
array $formData,
array &$formData,
HTMLForm $form,
User $user,
&$result,
$oldPreferences
) {
$isVectorEnabled = ( $formData[ 'skin' ] ?? '' ) === Constants::SKIN_NAME;
$userManager = MediaWikiServices::getInstance()->getUserOptionsManager();
$skinVersion = $formData[ Constants::PREF_KEY_SKIN_VERSION ] ?? '';
$skin = $formData[ Constants::PREF_KEY_SKIN ] ?? '';
$isVectorEnabled = self::isVectorSkin( $skin );
if (
self::isMigrationMode() &&
$skin === Constants::SKIN_NAME_LEGACY &&
$skinVersion === Constants::SKIN_VERSION_LATEST
) {
// Mismatch between skin and version. Use skin.
$userManager->setOption(
$user,
Constants::PREF_KEY_SKIN_VERSION,
Constants::SKIN_VERSION_LEGACY
);
}
if ( !$isVectorEnabled && array_key_exists( Constants::PREF_KEY_SKIN_VERSION, $oldPreferences ) ) {
// The setting was cleared. However, this is likely because a different skin was chosen and
// the skin version preference was hidden.
MediaWikiServices::getInstance()->getUserOptionsManager()->setOption(
$userManager->setOption(
$user,
Constants::PREF_KEY_SKIN_VERSION,
$oldPreferences[ Constants::PREF_KEY_SKIN_VERSION ]
@ -434,6 +477,15 @@ class Hooks {
}
}
/**
* Check whether we can start migrating users to use skin preference.
*
* @return bool
*/
private static function isMigrationMode(): bool {
return self::getConfig( 'VectorSkinMigrationMode' );
}
/**
* Called one time when initializing a users preferences for a newly created account.
*
@ -442,13 +494,24 @@ class Hooks {
*/
public static function onLocalUserCreated( User $user, $isAutoCreated ) {
$default = self::getConfig( Constants::CONFIG_KEY_DEFAULT_SKIN_VERSION_FOR_NEW_ACCOUNTS );
$optionsManager = MediaWikiServices::getInstance()->getUserOptionsManager();
// Permanently set the default preference. The user can later change this preference, however,
// self::onLocalUserCreated() will not be executed for that account again.
MediaWikiServices::getInstance()->getUserOptionsManager()->setOption(
$optionsManager->setOption(
$user,
Constants::PREF_KEY_SKIN_VERSION,
$default
);
// Also set the skin key if migration mode is enabled.
if ( self::isMigrationMode() ) {
$optionsManager->setOption(
$user,
Constants::PREF_KEY_SKIN,
$default === Constants::SKIN_VERSION_LEGACY ?
Constants::SKIN_NAME_LEGACY : Constants::SKIN_NAME_MODERN
);
}
}
/**
@ -460,7 +523,8 @@ class Hooks {
* @param string[] &$bodyAttrs
*/
public static function onOutputPageBodyAttributes( OutputPage $out, Skin $sk, &$bodyAttrs ) {
if ( !$sk instanceof SkinVector ) {
$skinName = $out->getSkin()->getSkinName();
if ( !self::isVectorSkin( $skinName ) ) {
return;
}
@ -474,6 +538,10 @@ class Hooks {
// list.
if ( self::isSkinVersionLegacy() ) {
$bodyAttrs['class'] .= ' skin-vector-legacy';
} else {
// The modern Vector skin must also carry skin-vector for compatibility with older
// skins.
$bodyAttrs['class'] .= ' skin-vector';
}
// Determine the search widget treatment to send to the user
@ -578,7 +646,8 @@ class Hooks {
* @param OutputPage $out OutputPage instance calling the hook
*/
public static function onMakeGlobalVariablesScript( &$vars, OutputPage $out ) {
if ( !$out->getSkin() instanceof SkinVector ) {
$skin = $out->getSkin();
if ( !self::isVectorSkin( $skin->getSkinName() ) ) {
return;
}

View File

@ -33,7 +33,7 @@ use Vector\SkinVersionLookup;
return [
Constants::SERVICE_CONFIG => static function ( MediaWikiServices $services ) {
return $services->getService( 'ConfigFactory' )->makeConfig( Constants::SKIN_NAME );
return $services->getService( 'ConfigFactory' )->makeConfig( Constants::SKIN_NAME_LEGACY );
},
Constants::SERVICE_FEATURE_MANAGER => static function ( MediaWikiServices $services ) {
$featureManager = new FeatureManager();

View File

@ -28,11 +28,39 @@ use Vector\Hooks;
use Vector\VectorServices;
/**
* Skin subclass for Vector
* Skin subclass for Vector that may be the new or old version of Vector.
*
* @ingroup Skins
* Skins extending SkinVector are not supported
*
* @package Vector
* @internal
*
* # Migration Plan (please remove stages when done)
*
* Stage 1:
* In future when we are ready to transition to two separate skins in this order:
* - Use $wgSkipSkins to hide vector-2022.
* - Remove skippable field from the `vector-2022` skin version. This will defer the code to the
* configuration option wgSkipSkins
* - Set $wgVectorSkinMigrationMode = true and unset the Vector entry in wgSkipSkins
* - for one wiki, to trial run. This will expose Vector in preferences. The new Vector will show
* as Vector (2022) to begin with and the skin version preference will be hidden.
* - Check VectorPrefDiffInstrumentation instrumentation is still working.
*
* Stage 2:
* - Set $wgVectorSkinMigrationMode = true for all wikis and update skin preference labels
* (See Iebe60b560069c8cfcdeed3f5986b8be35501dcbc). This will hide the skin version
* preference, and update the skin preference instead.
* - We will set $wgDefaultSkin = 'vector-2022'; for desktop improvements wikis.
* - Run script that updates prefs table, migrating any rows where skin=vector AND
* skinversion = 2 to skin=vector22, skinversion=2
*
* Stage 3:
* - Move all modern code into SkinVector22.
* - Move legacy skin code from SkinVector to SkinVectorLegacy.
* - Update skin.json `vector` key to point to SkinVectorLegacy.
* - SkinVector left as alias if necessary.
*/
class SkinVector extends SkinMustache {
/** @var null|array for caching purposes */
@ -127,7 +155,11 @@ class SkinVector extends SkinMustache {
*
* @return bool
*/
private function isLegacy(): bool {
protected function isLegacy(): bool {
$options = $this->getOptions();
if ( $options['name'] === Constants::SKIN_NAME_MODERN ) {
return false;
}
$isLatestSkinFeatureEnabled = MediaWikiServices::getInstance()
->getService( Constants::SERVICE_FEATURE_MANAGER )
->isFeatureEnabled( Constants::FEATURE_LATEST_SKIN );
@ -399,8 +431,11 @@ class SkinVector extends SkinMustache {
public function getDefaultModules() {
// FIXME: Do not repeat this pattern. Will be addressed in T291098.
if ( $this->isLegacy() ) {
$this->options['scripts'] = [ 'skins.vector.legacy.js' ];
$this->options['styles'] = [ 'skins.vector.styles.legacy' ];
$this->options['scripts'] = SkinVectorLegacy::getScriptsOption();
$this->options['styles'] = SkinVectorLegacy::getStylesOption();
} else {
$this->options['scripts'] = SkinVector22::getScriptsOption();
$this->options['styles'] = SkinVector22::getStylesOption();
}
return parent::getDefaultModules();
}
@ -413,7 +448,7 @@ class SkinVector extends SkinMustache {
*/
public function generateHTML() {
if ( $this->isLegacy() ) {
$this->options['template'] = 'skin-legacy';
$this->options['template'] = SkinVectorLegacy::getTemplateOption();
if ( $this->isTableOfContentsVisibleInSidebar() ) {
throw new RuntimeException(
'The table of contents flag cannot safely be applied without ' .

54
includes/SkinVector22.php Normal file
View File

@ -0,0 +1,54 @@
<?php
/**
* @ingroup Skins
* @package Vector
* @internal
*/
class SkinVector22 extends SkinVector {
/**
* @inheritDoc
*/
public function __construct( $options = [] ) {
$options += [
'template' => self::getTemplateOption(),
'scripts' => self::getScriptsOption(),
'styles' => self::getStylesOption(),
];
parent::__construct( $options );
}
/**
* Temporary static function while we deprecate SkinVector class.
*
* @return string
*/
public static function getTemplateOption() {
return 'skin';
}
/**
* Temporary static function while we deprecate SkinVector class.
*
* @return array
*/
public static function getScriptsOption() {
return [
'skins.vector.js',
'skins.vector.es6',
];
}
/**
* Temporary static function while we deprecate SkinVector class.
*
* @return array
*/
public static function getStylesOption() {
return [
'mediawiki.ui.button',
'skins.vector.styles',
'skins.vector.icons',
'mediawiki.ui.icon',
];
}
}

View File

@ -0,0 +1,51 @@
<?php
/**
* @ingroup Skins
* @package Vector
* @internal
*/
class SkinVectorLegacy extends SkinVector {
/**
* @inheritDoc
*/
public function __construct( $options = [] ) {
$options += [
'template' => self::getTemplateOption(),
'scripts' => self::getScriptsOption(),
'styles' => self::getStylesOption(),
];
parent::__construct( $options );
}
/**
* Temporary static function while we deprecate SkinVector class.
*
* @return string
*/
public static function getTemplateOption() {
return 'skin-legacy';
}
/**
* Temporary static function while we deprecate SkinVector class.
*
* @return array
*/
public static function getScriptsOption() {
return [
'skins.vector.legacy.js',
];
}
/**
* Temporary static function while we deprecate SkinVector class.
*
* @return array
*/
public static function getStylesOption() {
return [
'skins.vector.styles.legacy',
];
}
}

View File

@ -107,6 +107,9 @@ final class SkinVersionLookup {
* @throws \ConfigException
*/
public function getVersion(): string {
// If skin key is not vector, then version should be considered legacy.
// If skin is "Vector" invoke additional skin versioning detection.
// Obtain the skin version from the 1) `useskinversion` URL query parameter override, 2) the
// user preference, 3) the configured default for logged in users, 4) or the site default.
//
@ -114,19 +117,40 @@ final class SkinVersionLookup {
// sessions are unavailable at that time so it's not possible to determine whether the
// preference is for a logged in user or an anonymous user. Since new users are known to have
// had their user preferences initialized in `Hooks::onLocalUserCreated()`, that means all
// subsequent requests to `UserOptionsLookup->getOption()` that do not have a preference set
//are either existing accounts or anonymous users. Login state makes the distinction.
// subsequent requests to `User->getOption()` that do not have a preference set are either
// existing accounts or anonymous users. Login state makes the distinction.
$skin = $this->userOptionsLookup->getOption(
$this->user,
Constants::PREF_KEY_SKIN
);
if ( $skin === Constants::SKIN_NAME_MODERN ) {
return Constants::SKIN_VERSION_LATEST;
}
$skinVersionPref = $this->userOptionsLookup->getOption(
$this->user,
Constants::PREF_KEY_SKIN_VERSION,
$this->config->get(
$this->user->isRegistered()
? Constants::CONFIG_KEY_DEFAULT_SKIN_VERSION_FOR_EXISTING_ACCOUNTS
: Constants::CONFIG_KEY_DEFAULT_SKIN_VERSION
)
);
// If we are in migration mode, we must check the skin version preference.
if ( $this->config->get( 'VectorSkinMigrationMode' ) ) {
if (
$skin === Constants::SKIN_NAME_LEGACY &&
$skinVersionPref === Constants::SKIN_VERSION_LATEST
) {
return Constants::SKIN_VERSION_LATEST;
}
return Constants::SKIN_VERSION_LEGACY;
}
return (string)$this->request->getVal(
Constants::QUERY_PARAM_SKIN_VERSION,
$this->userOptionsLookup->getOption(
$this->user,
Constants::PREF_KEY_SKIN_VERSION,
$this->config->get(
$this->user->isRegistered()
? Constants::CONFIG_KEY_DEFAULT_SKIN_VERSION_FOR_EXISTING_ACCOUNTS
: Constants::CONFIG_KEY_DEFAULT_SKIN_VERSION
)
)
$skinVersionPref
);
}
}

View File

@ -24,24 +24,53 @@
"MediaWiki": ">= 1.38.0"
},
"ValidSkinNames": {
"vector-2022": {
"class": "SkinVector22",
"skippable": true,
"args": [
{
"name": "vector-2022",
"templateDirectory": "includes/templates",
"responsive": true,
"link": {
"text-wrapper": {
"tag": "span"
}
},
"messages": [
"tooltip-p-logo",
"vector-opt-out-tooltip",
"vector-opt-out",
"vector-action-toggle-sidebar",
"vector-main-menu-tooltip",
"vector-menu-checkbox-expanded",
"vector-menu-checkbox-collapsed",
"vector-jumptosearch",
"vector-jumptocontent",
"search",
"searchbutton",
"searcharticle",
"searchsuggest-search",
"sitesubtitle",
"sitetitle",
"tagline"
]
}
]
},
"vector": {
"class": "SkinVector",
"@args": "See SkinVector::__construct for more detail.",
"args": [
{
"name": "vector",
"scripts": [
"skins.vector.es6",
"skins.vector.js"
],
"templateDirectory": "includes/templates",
"responsive": true,
"styles": [
"mediawiki.ui.button",
"skins.vector.styles",
"skins.vector.icons",
"mediawiki.ui.icon"
],
"link": {
"text-wrapper": {
"tag": "span"
}
},
"messages": [
"tooltip-p-logo",
"vector-opt-out-tooltip",
@ -61,12 +90,7 @@
"sitesubtitle",
"sitetitle",
"tagline"
],
"link": {
"text-wrapper": {
"tag": "span"
}
}
]
}
]
}
@ -80,7 +104,9 @@
]
},
"AutoloadClasses": {
"SkinVector": "includes/SkinVector.php"
"SkinVector": "includes/SkinVector.php",
"SkinVectorLegacy": "includes/SkinVectorLegacy.php",
"SkinVector22": "includes/SkinVector22.php"
},
"AutoloadNamespaces": {
"Vector\\": "includes/"
@ -273,6 +299,15 @@
"remoteSkinPath": "Vector"
},
"ResourceModuleSkinStyles": {
"vector-2022": {
"+ext.echo.styles.alert": "skinStyles/ext.echo.styles.alert.less",
"+mediawiki.action.view.redirectPage": "skinStyles/mediawiki.action.view.redirectPage.less",
"+mediawiki.notification": "skinStyles/mediawiki.notification.less",
"+oojs-ui-core.styles": "skinStyles/ooui.less",
"mediawiki.special": "skinStyles/mediawiki.special.less",
"+ext.relatedArticles.readMore": "skinStyles/ext.relatedArticles.readMore.less",
"+ext.uls.compactlinks": "skinStyles/ext.uls.compactlinks.less"
},
"vector": {
"+ext.echo.styles.alert": "skinStyles/ext.echo.styles.alert.less",
"jquery.tipsy": "skinStyles/jquery.tipsy.less",
@ -350,6 +385,10 @@
"VectorUseWvuiSearch": {
"value": true
},
"VectorSkinMigrationMode": {
"value": false,
"description": "@internal. For usage to fulfil [[phab:T291098]]"
},
"VectorSearchTreatmentABTest": {
"value": false,
"description": "@var boolean Enables or disables the search treatment A/B test. See https://phabricator.wikimedia.org/T261647 and associated tasks for additional detail."

View File

@ -72,7 +72,7 @@ class HTMLLegacySkinVersionFieldTest extends \MediaWikiIntegrationTestCase {
'label-message' => 'prefs-vector-enable-vector-1-label',
'help-message' => 'prefs-vector-enable-vector-1-help',
'default' => true,
'hide-if' => [ '!==', 'wpskin', Constants::SKIN_NAME ],
'hide-if' => [ '!==', 'wpskin', Constants::SKIN_NAME_LEGACY ],
];
$skinVersionField = new HTMLLegacySkinVersionField( $params );
$checkField = new \HTMLCheckField( $params );

View File

@ -20,6 +20,7 @@
*/
use MediaWiki\User\UserOptionsLookup;
use Vector\Constants;
use Vector\SkinVersionLookup;
/**
@ -44,11 +45,14 @@ class SkinVersionLookupTest extends \MediaWikiIntegrationTestCase {
->willReturn( false );
$config = new HashConfig( [
'VectorSkinMigrationMode' => false,
'VectorDefaultSkinVersion' => '2',
'VectorDefaultSkinVersionForExistingAccounts' => '1'
] );
$userOptionsLookup = $this->getUserOptionsLookupMock( $user, '2', 'beta' );
$userOptionsLookup = $this->getUserOptionsLookupMock( $user, 'beta', [
'skin' => Constants::SKIN_NAME_LEGACY,
] );
$skinVersionLookup = new SkinVersionLookup( $request, $user, $config, $userOptionsLookup );
@ -81,11 +85,14 @@ class SkinVersionLookupTest extends \MediaWikiIntegrationTestCase {
->willReturn( false );
$config = new HashConfig( [
'VectorSkinMigrationMode' => false,
'VectorDefaultSkinVersion' => '2',
'VectorDefaultSkinVersionForExistingAccounts' => '1'
] );
$userOptionsLookup = $this->getUserOptionsLookupMock( $user, '2', 'beta' );
$userOptionsLookup = $this->getUserOptionsLookupMock( $user, 'beta', [
'skin' => Constants::SKIN_NAME_LEGACY,
] );
$skinVersionLookup = new SkinVersionLookup( $request, $user, $config, $userOptionsLookup );
@ -118,11 +125,14 @@ class SkinVersionLookupTest extends \MediaWikiIntegrationTestCase {
->willReturn( true );
$config = new HashConfig( [
'VectorSkinMigrationMode' => false,
'VectorDefaultSkinVersion' => '2',
'VectorDefaultSkinVersionForExistingAccounts' => '1'
] );
$userOptionsLookup = $this->getUserOptionsLookupMock( $user, '1', '1' );
$userOptionsLookup = $this->getUserOptionsLookupMock( $user, '1', [
'skin' => Constants::SKIN_NAME_LEGACY,
] );
$skinVersionLookup = new SkinVersionLookup( $request, $user, $config, $userOptionsLookup );
@ -138,6 +148,38 @@ class SkinVersionLookupTest extends \MediaWikiIntegrationTestCase {
);
}
/**
* @covers ::getVersion
*/
public function testSkin22() {
$request = $this->getMockBuilder( \WebRequest::class )->getMock();
$request
->method( 'getVal' )
->willReturn( '1' );
$user = $this->createMock( \User::class );
$user
->method( 'isRegistered' )
->willReturn( true );
$config = new HashConfig( [
'VectorSkinMigrationMode' => false,
'VectorDefaultSkinVersion' => '1',
'VectorDefaultSkinVersionForExistingAccounts' => '1'
] );
$userOptionsLookup = $this->getUserOptionsLookupMock( $user, '1', [
'skin' => Constants::SKIN_NAME_MODERN
] );
$skinVersionLookup = new SkinVersionLookup( $request, $user, $config, $userOptionsLookup );
$this->assertSame(
'2',
$skinVersionLookup->getVersion(),
'Using the modern skin always returns 2. Ignores skinversion query string.'
);
}
/**
* @covers ::getVersion
* @covers ::isLegacy
@ -155,11 +197,14 @@ class SkinVersionLookupTest extends \MediaWikiIntegrationTestCase {
->willReturn( false );
$config = new HashConfig( [
'VectorSkinMigrationMode' => false,
'VectorDefaultSkinVersion' => '2',
'VectorDefaultSkinVersionForExistingAccounts' => '1'
] );
$userOptionsLookup = $this->getUserOptionsLookupMock( $user, '2', '2' );
$userOptionsLookup = $this->getUserOptionsLookupMock( $user, '2', [
'skin' => Constants::SKIN_NAME_LEGACY,
] );
$skinVersionLookup = new SkinVersionLookup( $request, $user, $config, $userOptionsLookup );
@ -177,15 +222,16 @@ class SkinVersionLookupTest extends \MediaWikiIntegrationTestCase {
/**
* @param User $user
* @param mixed|null $defaultOverride
* @param mixed|null $returnVal
* @param array $returnVal
* @param array $lookup values
* @return UserOptionsLookup
*/
private function getUserOptionsLookupMock( $user, $defaultOverride, $returnVal ) {
private function getUserOptionsLookupMock( $user, $returnVal, $lookup = [] ) {
$mock = $this->createMock( UserOptionsLookup::class );
$mock->method( 'getOption' )
->with( $user, $this->anything(), $defaultOverride )
->willReturn( $returnVal );
->willReturnCallback( static function ( $user, $key ) use ( $returnVal, $lookup ) {
return $lookup[ $key ] ?? $returnVal;
} );
return $mock;
}
}

View File

@ -17,6 +17,7 @@ use Vector\HTMLForm\Fields\HTMLLegacySkinVersionField;
* @coversDefaultClass \Vector\Hooks
*/
class VectorHooksTest extends MediaWikiIntegrationTestCase {
private const HIDE_IF = [ '!==', 'wpskin', Constants::SKIN_NAME_LEGACY ];
private const SKIN_PREFS_SECTION = 'rendering/skin/skin-prefs';
@ -282,6 +283,7 @@ class VectorHooksTest extends MediaWikiIntegrationTestCase {
*/
public function testOnGetPreferencesShowPreferencesDisabled() {
$config = new HashConfig( [
'VectorSkinMigrationMode' => false,
'VectorShowSkinPreferences' => false,
] );
$this->setService( 'Vector.Config', $config );
@ -324,7 +326,7 @@ class VectorHooksTest extends MediaWikiIntegrationTestCase {
'help-message' => 'prefs-vector-enable-vector-1-help',
'section' => self::SKIN_PREFS_SECTION,
'default' => $isLegacy,
'hide-if' => [ '!==', 'wpskin', Constants::SKIN_NAME ]
'hide-if' => self::HIDE_IF,
],
'VectorSidebarVisible' => [
'type' => 'api',
@ -389,7 +391,7 @@ class VectorHooksTest extends MediaWikiIntegrationTestCase {
'help-message' => 'prefs-vector-enable-vector-1-help',
'section' => self::SKIN_PREFS_SECTION,
'default' => $isLegacy,
'hide-if' => [ '!==', 'wpskin', Constants::SKIN_NAME ]
'hide-if' => self::HIDE_IF,
],
'VectorSidebarVisible' => [
'type' => 'api',
@ -447,12 +449,17 @@ class VectorHooksTest extends MediaWikiIntegrationTestCase {
$formData = [
'VectorSkinVersion' => Constants::SKIN_VERSION_LATEST,
];
$config = new HashConfig( [
'VectorSkinMigrationMode' => false,
'VectorShowSkinPreferences' => false,
] );
$form = $this->createMock( HTMLForm::class );
$user = $this->createMock( User::class );
$userOptionsManager = $this->createMock( UserOptionsManager::class );
$userOptionsManager->expects( $this->once() )
->method( 'setOption' )
->with( $user, 'VectorSkinVersion', 'old' );
$this->setService( 'Vector.Config', $config );
$this->setService( 'UserOptionsManager', $userOptionsManager );
$result = true;
$oldPreferences = [
@ -467,6 +474,7 @@ class VectorHooksTest extends MediaWikiIntegrationTestCase {
*/
public function testOnLocalUserCreatedLegacy() {
$config = new HashConfig( [
'VectorSkinMigrationMode' => false,
'VectorDefaultSkinVersionForNewAccounts' => Constants::SKIN_VERSION_LEGACY,
] );
$this->setService( 'Vector.Config', $config );
@ -486,6 +494,7 @@ class VectorHooksTest extends MediaWikiIntegrationTestCase {
*/
public function testOnLocalUserCreatedLatest() {
$config = new HashConfig( [
'VectorSkinMigrationMode' => false,
'VectorDefaultSkinVersionForNewAccounts' => Constants::SKIN_VERSION_LATEST,
] );
$this->setService( 'Vector.Config', $config );

View File

@ -45,7 +45,10 @@ class LatestSkinVersionRequirementTest extends \MediaWikiUnitTestCase {
* @covers ::isMet
*/
public function testIsMet( $version, $expected, $msg ) {
$config = new HashConfig( [ 'VectorDefaultSkinVersionForExistingAccounts' => $version ] );
$config = new HashConfig( [
'VectorSkinMigrationMode' => false,
'VectorDefaultSkinVersionForExistingAccounts' => $version
] );
$user = $this->createMock( User::class );
$user->method( 'isRegistered' )->willReturn( true );