mirror of
https://gerrit.wikimedia.org/r/mediawiki/skins/Vector.git
synced 2024-12-01 02:37:05 +00:00
4449235516
I177dad88 introduced the skin version user preference field and associated configuration values. Per T242381, the field is to presented as a checkbox with the implied storage type of a boolean where a string is needed. A PreferencesFormPreSave hook handler was added to adapt values of either data type to the other. While this was a neat solution to a minor nit, the adapter's implementation is incompatible with the GlobalPreferences extension as the PreferencesFormPreSave hook isn't run whilst saving global preferences. Rather than adding an equivalent hook to the GlobalPreferences extension, create a custom field based on a checkbox with the adapter included. This allows us to: - Separate the business logic concerned with preserving the user's VectorSkinVersion preference if they've simply disabled Vector from the adapter - Simplify the adapter's implementation - Forego adding hooks to the GlobalPreferences codebase Additional changes: - Replace repeated string literals with equivalent constants in tests/phpunit/integration/VectorHooksTest.php Bug: T258493 Change-Id: I628435a4ad676f55534191b8c10147be28be5d73
242 lines
6.6 KiB
PHP
242 lines
6.6 KiB
PHP
<?php
|
|
/*
|
|
* @file
|
|
* @ingroup skins
|
|
*/
|
|
|
|
use Vector\Constants;
|
|
use Vector\FeatureManagement\FeatureManager;
|
|
use Vector\Hooks;
|
|
use Vector\HTMLForm\Fields\HTMLLegacySkinVersionField;
|
|
|
|
const SKIN_PREFS_SECTION = 'rendering/skin/skin-prefs';
|
|
|
|
/**
|
|
* Integration tests for Vector Hooks.
|
|
*
|
|
* @group Vector
|
|
* @coversDefaultClass \Vector\Hooks
|
|
*/
|
|
class VectorHooksTest extends \MediaWikiTestCase {
|
|
/**
|
|
* @covers ::onGetPreferences
|
|
*/
|
|
public function testOnGetPreferencesShowPreferencesDisabled() {
|
|
$config = new HashConfig( [
|
|
'VectorShowSkinPreferences' => false,
|
|
] );
|
|
$this->setService( 'Vector.Config', $config );
|
|
|
|
$prefs = [];
|
|
Hooks::onGetPreferences( $this->getTestUser()->getUser(), $prefs );
|
|
$this->assertSame( $prefs, [], 'No preferences are added.' );
|
|
}
|
|
|
|
private function setFeatureLatestSkinVersionIsEnabled( $isEnabled ) {
|
|
$featureManager = new FeatureManager();
|
|
$featureManager->registerSimpleRequirement( Constants::REQUIREMENT_LATEST_SKIN_VERSION, $isEnabled );
|
|
$featureManager->registerFeature( Constants::FEATURE_LATEST_SKIN, [
|
|
Constants::REQUIREMENT_LATEST_SKIN_VERSION
|
|
] );
|
|
|
|
$this->setService( Constants::SERVICE_FEATURE_MANAGER, $featureManager );
|
|
}
|
|
|
|
/**
|
|
* @covers ::onGetPreferences
|
|
*/
|
|
public function testOnGetPreferencesShowPreferencesEnabledSkinSectionFoundLegacy() {
|
|
$isLegacy = true;
|
|
$this->setFeatureLatestSkinVersionIsEnabled( !$isLegacy );
|
|
|
|
$prefs = [
|
|
'foo' => [],
|
|
'skin' => [],
|
|
'bar' => []
|
|
];
|
|
Hooks::onGetPreferences( $this->getTestUser()->getUser(), $prefs );
|
|
$this->assertEquals(
|
|
$prefs,
|
|
[
|
|
'foo' => [],
|
|
'skin' => [],
|
|
'VectorSkinVersion' => [
|
|
'class' => HTMLLegacySkinVersionField::class,
|
|
'label-message' => 'prefs-vector-enable-vector-1-label',
|
|
'help-message' => 'prefs-vector-enable-vector-1-help',
|
|
'section' => SKIN_PREFS_SECTION,
|
|
'default' => $isLegacy,
|
|
'hide-if' => [ '!==', 'wpskin', Constants::SKIN_NAME ]
|
|
],
|
|
'VectorSidebarVisible' => [
|
|
'type' => 'api',
|
|
'default' => true
|
|
],
|
|
'bar' => [],
|
|
],
|
|
'Preferences are inserted directly after skin.'
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @covers ::onGetPreferences
|
|
*/
|
|
public function testOnGetPreferencesShowPreferencesEnabledSkinSectionMissingLegacy() {
|
|
$isLegacy = false;
|
|
$this->setFeatureLatestSkinVersionIsEnabled( !$isLegacy );
|
|
|
|
$prefs = [
|
|
'foo' => [],
|
|
'bar' => []
|
|
];
|
|
Hooks::onGetPreferences( $this->getTestUser()->getUser(), $prefs );
|
|
$this->assertEquals(
|
|
$prefs,
|
|
[
|
|
'foo' => [],
|
|
'bar' => [],
|
|
'VectorSkinVersion' => [
|
|
'class' => HTMLLegacySkinVersionField::class,
|
|
'label-message' => 'prefs-vector-enable-vector-1-label',
|
|
'help-message' => 'prefs-vector-enable-vector-1-help',
|
|
'section' => SKIN_PREFS_SECTION,
|
|
'default' => $isLegacy,
|
|
'hide-if' => [ '!==', 'wpskin', Constants::SKIN_NAME ]
|
|
],
|
|
'VectorSidebarVisible' => [
|
|
'type' => 'api',
|
|
'default' => true
|
|
],
|
|
],
|
|
'Preferences are appended.'
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @covers ::onPreferencesFormPreSave
|
|
*/
|
|
public function testOnPreferencesFormPreSaveVectorEnabledLegacyNewPreference() {
|
|
$formData = [
|
|
'skin' => 'vector',
|
|
'VectorSkinVersion' => Constants::SKIN_VERSION_LEGACY,
|
|
];
|
|
$form = $this->createMock( HTMLForm::class );
|
|
$user = $this->createMock( \User::class );
|
|
$user->expects( $this->never() )
|
|
->method( 'setOption' );
|
|
$result = true;
|
|
$oldPreferences = [];
|
|
|
|
Hooks::onPreferencesFormPreSave( $formData, $form, $user, $result, $oldPreferences );
|
|
}
|
|
|
|
/**
|
|
* @covers ::onPreferencesFormPreSave
|
|
*/
|
|
public function testOnPreferencesFormPreSaveVectorDisabledNoOldPreference() {
|
|
$formData = [
|
|
'VectorSkinVersion' => Constants::SKIN_VERSION_LATEST,
|
|
];
|
|
$form = $this->createMock( HTMLForm::class );
|
|
$user = $this->createMock( \User::class );
|
|
$user->expects( $this->never() )
|
|
->method( 'setOption' );
|
|
$result = true;
|
|
$oldPreferences = [];
|
|
|
|
Hooks::onPreferencesFormPreSave( $formData, $form, $user, $result, $oldPreferences );
|
|
}
|
|
|
|
/**
|
|
* @covers ::onPreferencesFormPreSave
|
|
*/
|
|
public function testOnPreferencesFormPreSaveVectorDisabledOldPreference() {
|
|
$formData = [
|
|
'VectorSkinVersion' => Constants::SKIN_VERSION_LATEST,
|
|
];
|
|
$form = $this->createMock( HTMLForm::class );
|
|
$user = $this->createMock( \User::class );
|
|
$user->expects( $this->once() )
|
|
->method( 'setOption' )
|
|
->with( 'VectorSkinVersion', 'old' );
|
|
$result = true;
|
|
$oldPreferences = [
|
|
'VectorSkinVersion' => 'old',
|
|
];
|
|
|
|
Hooks::onPreferencesFormPreSave( $formData, $form, $user, $result, $oldPreferences );
|
|
}
|
|
|
|
/**
|
|
* @covers ::onLocalUserCreated
|
|
*/
|
|
public function testOnLocalUserCreatedLegacy() {
|
|
$config = new HashConfig( [
|
|
'VectorDefaultSkinVersionForNewAccounts' => Constants::SKIN_VERSION_LEGACY,
|
|
] );
|
|
$this->setService( 'Vector.Config', $config );
|
|
|
|
$user = $this->createMock( \User::class );
|
|
$user->expects( $this->once() )
|
|
->method( 'setOption' )
|
|
->with( 'VectorSkinVersion', Constants::SKIN_VERSION_LEGACY );
|
|
$isAutoCreated = false;
|
|
Hooks::onLocalUserCreated( $user, $isAutoCreated );
|
|
}
|
|
|
|
/**
|
|
* @covers ::onLocalUserCreated
|
|
*/
|
|
public function testOnLocalUserCreatedLatest() {
|
|
$config = new HashConfig( [
|
|
'VectorDefaultSkinVersionForNewAccounts' => Constants::SKIN_VERSION_LATEST,
|
|
] );
|
|
$this->setService( 'Vector.Config', $config );
|
|
|
|
$user = $this->createMock( \User::class );
|
|
$user->expects( $this->once() )
|
|
->method( 'setOption' )
|
|
->with( 'VectorSkinVersion', Constants::SKIN_VERSION_LATEST );
|
|
$isAutoCreated = false;
|
|
Hooks::onLocalUserCreated( $user, $isAutoCreated );
|
|
}
|
|
|
|
/**
|
|
* @covers ::onSkinTemplateNavigation
|
|
*/
|
|
public function testOnSkinTemplateNavigation() {
|
|
$this->setMwGlobals( [
|
|
'wgVectorUseIconWatch' => true
|
|
] );
|
|
$skin = new SkinVector( [ 'name' => 'vector' ] );
|
|
$skin->getContext()->setTitle( Title::newFromText( 'Foo' ) );
|
|
$contentNavWatch = [
|
|
'actions' => [
|
|
'watch' => [ 'class' => 'watch' ],
|
|
]
|
|
];
|
|
$contentNavUnWatch = [
|
|
'actions' => [
|
|
'move' => [ 'class' => 'move' ],
|
|
'unwatch' => [],
|
|
],
|
|
];
|
|
|
|
Hooks::onSkinTemplateNavigation( $skin, $contentNavUnWatch );
|
|
Hooks::onSkinTemplateNavigation( $skin, $contentNavWatch );
|
|
|
|
$this->assertTrue(
|
|
strpos( $contentNavWatch['views']['watch']['class'], 'icon' ) !== false,
|
|
'Watch list items require an "icon" class'
|
|
);
|
|
$this->assertTrue(
|
|
strpos( $contentNavUnWatch['views']['unwatch']['class'], 'icon' ) !== false,
|
|
'Unwatch list items require an "icon" class'
|
|
);
|
|
$this->assertFalse(
|
|
strpos( $contentNavUnWatch['actions']['move']['class'], 'icon' ) !== false,
|
|
'List item other than watch or unwatch should not have an "icon" class'
|
|
);
|
|
}
|
|
}
|