* …
=== Deprecations in 1.34 ===
-* The MWNamespace class is deprecated. Use MediaWikiServices::getNamespaceInfo.
+* The MWNamespace class is deprecated. Use NamespaceInfo.
* ExtensionRegistry->load() is deprecated, as it breaks dependency checking.
Instead, use ->queue().
* User::isBlocked() is deprecated since it does not tell you if the user is
RevisionLookup::getPreviousRevision and RevisionLookup::getNextRevision.
* The Title parameter to RevisionLookup::getPreviousRevision and
RevisionLookup::getNextRevision is deprecated and should be omitted.
+* MWHttpRequest::factory is deprecated. Use HttpRequestFactory.
+* The Http class is deprecated. For the request, get, and post methods, use
+ HttpRequestFactory. For isValidURI, use MWHttpRequest::isValidURI. For
+ getProxy, use (string)$wgHTTPProxy. For createMultiClient, construct a
+ MultiHttpClient directly.
+* Http::$httpEngine is deprecated and has no replacement. The default 'guzzle'
+ engine will eventually be made the only engine for HTTP requests.
=== Other changes in 1.34 ===
* …
/**
* Proxy to use for CURL requests.
*/
-$wgHTTPProxy = false;
+$wgHTTPProxy = '';
/**
* Local virtual hosts.
use Psr\Log\LoggerInterface;
use MediaWiki\Logger\LoggerFactory;
+use MediaWiki\MediaWikiServices;
/**
* Send information about this MediaWiki instance to MediaWiki.org.
$json = FormatJson::encode( $data );
$queryString = rawurlencode( str_replace( ' ', '\u0020', $json ) ) . ';';
$url = 'https://www.mediawiki.org/beacon/event?' . $queryString;
- return Http::post( $url ) !== false;
+ return MediaWikiServices::getInstance()->getHttpRequestFactory()->post( $url ) !== null;
}
/**
},
'GenderCache' => function ( MediaWikiServices $services ) : GenderCache {
- return new GenderCache();
+ return new GenderCache( $services->getNamespaceInfo() );
},
'HttpRequestFactory' =>
},
'NamespaceInfo' => function ( MediaWikiServices $services ) : NamespaceInfo {
- return new NamespaceInfo( $services->getMainConfig() );
+ return new NamespaceInfo( new ServiceOptions( NamespaceInfo::$constructorOptions,
+ $services->getMainConfig() ) );
},
'NameTableStoreFactory' => function ( MediaWikiServices $services ) : NameTableStoreFactory {
DefaultPreferencesFactory::$constructorOptions, $services->getMainConfig() ),
$services->getContentLanguage(),
AuthManager::singleton(),
- $services->getLinkRendererFactory()->create()
+ $services->getLinkRendererFactory()->create(),
+ $services->getNamespaceInfo()
);
$factory->setLogger( LoggerFactory::getInstance( 'preferences' ) );
protected $misses = 0;
protected $missLimit = 1000;
+ /** @var NamespaceInfo */
+ private $nsInfo;
+
+ public function __construct( NamespaceInfo $nsInfo = null ) {
+ $this->nsInfo = $nsInfo ?? MediaWikiServices::getInstance()->getNamespaceInfo();
+ }
+
/**
* @deprecated in 1.28 see MediaWikiServices::getInstance()->getGenderCache()
* @return GenderCache
public function doLinkBatch( $data, $caller = '' ) {
$users = [];
foreach ( $data as $ns => $pagenames ) {
- if ( !MWNamespace::hasGenderDistinction( $ns ) ) {
+ if ( !$this->nsInfo->hasGenderDistinction( $ns ) ) {
continue;
}
foreach ( array_keys( $pagenames ) as $username ) {
if ( !$titleObj ) {
continue;
}
- if ( !MWNamespace::hasGenderDistinction( $titleObj->getNamespace() ) ) {
+ if ( !$this->nsInfo->hasGenderDistinction( $titleObj->getNamespace() ) ) {
continue;
}
$users[] = $titleObj->getText();
* @file
*/
+use MediaWiki\MediaWikiServices;
+
/**
* Example class for HTTP accessible external objects.
* Only supports reading, not storing.
*/
class ExternalStoreHttp extends ExternalStoreMedium {
public function fetchFromURL( $url ) {
- return Http::get( $url, [], __METHOD__ );
+ return MediaWikiServices::getInstance()->getHttpRequestFactory()->
+ get( $url, [], __METHOD__ );
}
public function store( $location, $data ) {
}
/**
- * Like a Http:get request, but with custom User-Agent.
- * @see Http::get
+ * Like a HttpRequestFactory::get request, but with custom User-Agent.
+ * @see HttpRequestFactory::get
+ * @todo Can this use HttpRequestFactory::get() but just pass the 'userAgent' option?
* @param string $url
* @param string $timeout
* @param array $options
$this->repo->descriptionCacheExpiry ?: $cache::TTL_UNCACHEABLE,
function ( $oldValue, &$ttl, array &$setOpts ) use ( $renderUrl, $fname ) {
wfDebug( "Fetching shared description from $renderUrl\n" );
- $res = Http::get( $renderUrl, [], $fname );
+ $res = MediaWikiServices::getInstance()->getHttpRequestFactory()->
+ get( $renderUrl, [], $fname );
if ( !$res ) {
$ttl = WANObjectCache::TTL_UNCACHEABLE;
}
$this->repo->descriptionCacheExpiry ?: $cache::TTL_UNCACHEABLE,
function ( $oldValue, &$ttl, array &$setOpts ) use ( $renderUrl, $fname ) {
wfDebug( "Fetching shared description from $renderUrl\n" );
- $res = Http::get( $renderUrl, [], $fname );
+ $res = MediaWikiServices::getInstance()->getHttpRequestFactory()->
+ get( $renderUrl, [], $fname );
if ( !$res ) {
$ttl = WANObjectCache::TTL_UNCACHEABLE;
}
protected $curlOptions = [];
protected $headerText = "";
+ /**
+ * @throws RuntimeException
+ */
+ public function __construct() {
+ if ( !function_exists( 'curl_init' ) ) {
+ throw new RuntimeException(
+ __METHOD__ . ': curl (https://www.php.net/curl) is not installed' );
+ }
+
+ parent::__construct( ...func_get_args() );
+ }
+
/**
* @param resource $fh
* @param string $content
/**
* @param string $url Url to use. If protocol-relative, will be expanded to an http:// URL
- * @param array $options (optional) extra params to pass (see Http::request())
+ * @param array $options (optional) extra params to pass (see HttpRequestFactory::create())
* @param string $caller The method making this request, for profiling
* @param Profiler|null $profiler An instance of the profiler for profiling, or null
* @throws Exception
*/
use MediaWiki\Logger\LoggerFactory;
+use MediaWiki\MediaWikiServices;
/**
* Various HTTP related functions
+ * @deprecated since 1.34
* @ingroup HTTP
*/
class Http {
- public static $httpEngine = false;
+ /** @deprecated since 1.34, just use the default engine */
+ public static $httpEngine = null;
/**
* Perform an HTTP request
*
+ * @deprecated since 1.34, use HttpRequestFactory::request()
+ *
* @param string $method HTTP method. Usually GET/POST
* @param string $url Full URL to act on. If protocol-relative, will be expanded to an http:// URL
- * @param array $options Options to pass to MWHttpRequest object.
- * Possible keys for the array:
- * - timeout Timeout length in seconds
- * - connectTimeout Timeout for connection, in seconds (curl only)
- * - postData An array of key-value pairs or a url-encoded form data
- * - proxy The proxy to use.
- * Otherwise it will use $wgHTTPProxy (if set)
- * Otherwise it will use the environment variable "http_proxy" (if set)
- * - noProxy Don't use any proxy at all. Takes precedence over proxy value(s).
- * - sslVerifyHost Verify hostname against certificate
- * - sslVerifyCert Verify SSL certificate
- * - caInfo Provide CA information
- * - maxRedirects Maximum number of redirects to follow (defaults to 5)
- * - followRedirects Whether to follow redirects (defaults to false).
- * Note: this should only be used when the target URL is trusted,
- * to avoid attacks on intranet services accessible by HTTP.
- * - userAgent A user agent, if you want to override the default
- * MediaWiki/$wgVersion
- * - logger A \Psr\Logger\LoggerInterface instance for debug logging
- * - username Username for HTTP Basic Authentication
- * - password Password for HTTP Basic Authentication
- * - originalRequest Information about the original request (as a WebRequest object or
- * an associative array with 'ip' and 'userAgent').
+ * @param array $options Options to pass to MWHttpRequest object. See HttpRequestFactory::create
+ * docs
* @param string $caller The method making this request, for profiling
* @return string|bool (bool)false on failure or a string on success
*/
public static function request( $method, $url, array $options = [], $caller = __METHOD__ ) {
- $logger = LoggerFactory::getInstance( 'http' );
- $logger->debug( "$method: $url" );
-
- $options['method'] = strtoupper( $method );
-
- if ( !isset( $options['timeout'] ) ) {
- $options['timeout'] = 'default';
- }
- if ( !isset( $options['connectTimeout'] ) ) {
- $options['connectTimeout'] = 'default';
- }
-
- $req = MWHttpRequest::factory( $url, $options, $caller );
- $status = $req->execute();
-
- if ( $status->isOK() ) {
- return $req->getContent();
- } else {
- $errors = $status->getErrorsByType( 'error' );
- $logger->warning( Status::wrap( $status )->getWikiText( false, false, 'en' ),
- [ 'error' => $errors, 'caller' => $caller, 'content' => $req->getContent() ] );
- return false;
- }
+ $ret = MediaWikiServices::getInstance()->getHttpRequestFactory()->request(
+ $method, $url, $options, $caller );
+ return is_string( $ret ) ? $ret : false;
}
/**
* Simple wrapper for Http::request( 'GET' )
- * @see Http::request()
+ *
+ * @deprecated since 1.34, use HttpRequestFactory::get()
+ *
* @since 1.25 Second parameter $timeout removed. Second parameter
* is now $options which can be given a 'timeout'
*
/**
* Simple wrapper for Http::request( 'POST' )
- * @see Http::request()
+ *
+ * @deprecated since 1.34, use HttpRequestFactory::post()
*
* @param string $url
* @param array $options
/**
* A standard user-agent we can use for external requests.
+ *
+ * @deprecated since 1.34, use HttpRequestFactory::getUserAgent()
* @return string
*/
public static function userAgent() {
- global $wgVersion;
- return "MediaWiki/$wgVersion";
+ return MediaWikiServices::getInstance()->getHttpRequestFactory()->getUserAgent();
}
/**
*
* @todo FIXME this is wildly inaccurate and fails to actually check most stuff
*
+ * @deprecated since 1.34, use MWHttpRequest::isValidURI
* @param string $uri URI to check for validity
* @return bool
*/
public static function isValidURI( $uri ) {
- return (bool)preg_match(
- '/^https?:\/\/[^\/\s]\S*$/D',
- $uri
- );
+ return MWHttpRequest::isValidURI( $uri );
}
/**
* Gets the relevant proxy from $wgHTTPProxy
*
- * @return mixed The proxy address or an empty string if not set.
+ * @deprecated since 1.34, use $wgHTTPProxy directly
+ * @return string The proxy address or an empty string if not set.
*/
public static function getProxy() {
- global $wgHTTPProxy;
+ wfDeprecated( __METHOD__, '1.34' );
- if ( $wgHTTPProxy ) {
- return $wgHTTPProxy;
- }
-
- return "";
+ global $wgHTTPProxy;
+ return (string)$wgHTTPProxy;
}
/**
* Get a configured MultiHttpClient
+ *
+ * @deprecated since 1.34, construct it directly
* @param array $options
* @return MultiHttpClient
*/
public static function createMultiClient( array $options = [] ) {
+ wfDeprecated( __METHOD__, '1.34' );
+
global $wgHTTPConnectTimeout, $wgHTTPTimeout, $wgHTTPProxy;
return new MultiHttpClient( $options + [
namespace MediaWiki\Http;
use CurlHttpRequest;
-use DomainException;
+use GuzzleHttpRequest;
use Http;
use MediaWiki\Logger\LoggerFactory;
use MWHttpRequest;
use PhpHttpRequest;
use Profiler;
-use GuzzleHttpRequest;
+use RuntimeException;
+use Status;
/**
* Factory creating MWHttpRequest objects.
*/
class HttpRequestFactory {
-
/**
* Generate a new MWHttpRequest object
* @param string $url Url to use
- * @param array $options (optional) extra params to pass (see Http::request())
+ * @param array $options Possible keys for the array:
+ * - timeout Timeout length in seconds
+ * - connectTimeout Timeout for connection, in seconds (curl only)
+ * - postData An array of key-value pairs or a url-encoded form data
+ * - proxy The proxy to use.
+ * Otherwise it will use $wgHTTPProxy (if set)
+ * Otherwise it will use the environment variable "http_proxy" (if set)
+ * - noProxy Don't use any proxy at all. Takes precedence over proxy value(s).
+ * - sslVerifyHost Verify hostname against certificate
+ * - sslVerifyCert Verify SSL certificate
+ * - caInfo Provide CA information
+ * - maxRedirects Maximum number of redirects to follow (defaults to 5)
+ * - followRedirects Whether to follow redirects (defaults to false).
+ * Note: this should only be used when the target URL is trusted,
+ * to avoid attacks on intranet services accessible by HTTP.
+ * - userAgent A user agent, if you want to override the default
+ * MediaWiki/$wgVersion
+ * - logger A \Psr\Logger\LoggerInterface instance for debug logging
+ * - username Username for HTTP Basic Authentication
+ * - password Password for HTTP Basic Authentication
+ * - originalRequest Information about the original request (as a WebRequest object or
+ * an associative array with 'ip' and 'userAgent').
* @param string $caller The method making this request, for profiling
- * @throws DomainException
+ * @throws RuntimeException
* @return MWHttpRequest
* @see MWHttpRequest::__construct
*/
public function create( $url, array $options = [], $caller = __METHOD__ ) {
if ( !Http::$httpEngine ) {
Http::$httpEngine = 'guzzle';
- } elseif ( Http::$httpEngine == 'curl' && !function_exists( 'curl_init' ) ) {
- throw new DomainException( __METHOD__ . ': curl (https://www.php.net/curl) is not ' .
- 'installed, but Http::$httpEngine is set to "curl"' );
}
if ( !isset( $options['logger'] ) ) {
case 'curl':
return new CurlHttpRequest( $url, $options, $caller, Profiler::instance() );
case 'php':
- if ( !wfIniGetBool( 'allow_url_fopen' ) ) {
- throw new DomainException( __METHOD__ . ': allow_url_fopen ' .
- 'needs to be enabled for pure PHP http requests to ' .
- 'work. If possible, curl should be used instead. See ' .
- 'https://www.php.net/curl.'
- );
- }
return new PhpHttpRequest( $url, $options, $caller, Profiler::instance() );
default:
- throw new DomainException( __METHOD__ . ': The setting of Http::$httpEngine is not valid.' );
+ throw new RuntimeException( __METHOD__ . ': The requested engine is not valid.' );
}
}
return function_exists( 'curl_init' ) || wfIniGetBool( 'allow_url_fopen' );
}
+ /**
+ * Perform an HTTP request
+ *
+ * @since 1.34
+ * @param string $method HTTP method. Usually GET/POST
+ * @param string $url Full URL to act on. If protocol-relative, will be expanded to an http://
+ * URL
+ * @param array $options See HttpRequestFactory::create
+ * @param string $caller The method making this request, for profiling
+ * @return string|null null on failure or a string on success
+ */
+ public function request( $method, $url, array $options = [], $caller = __METHOD__ ) {
+ $logger = LoggerFactory::getInstance( 'http' );
+ $logger->debug( "$method: $url" );
+
+ $options['method'] = strtoupper( $method );
+
+ if ( !isset( $options['timeout'] ) ) {
+ $options['timeout'] = 'default';
+ }
+ if ( !isset( $options['connectTimeout'] ) ) {
+ $options['connectTimeout'] = 'default';
+ }
+
+ $req = $this->create( $url, $options, $caller );
+ $status = $req->execute();
+
+ if ( $status->isOK() ) {
+ return $req->getContent();
+ } else {
+ $errors = $status->getErrorsByType( 'error' );
+ $logger->warning( Status::wrap( $status )->getWikiText( false, false, 'en' ),
+ [ 'error' => $errors, 'caller' => $caller, 'content' => $req->getContent() ] );
+ return null;
+ }
+ }
+
+ /**
+ * Simple wrapper for request( 'GET' ), parameters have same meaning as for request()
+ *
+ * @since 1.34
+ * @param string $url
+ * @param array $options
+ * @param string $caller
+ * @return string|null
+ */
+ public function get( $url, array $options = [], $caller = __METHOD__ ) {
+ $this->request( 'GET', $url, $options, $caller );
+ }
+
+ /**
+ * Simple wrapper for request( 'POST' ), parameters have same meaning as for request()
+ *
+ * @since 1.34
+ * @param string $url
+ * @param array $options
+ * @param string $caller
+ * @return string|null
+ */
+ public function post( $url, array $options = [], $caller = __METHOD__ ) {
+ $this->request( 'POST', $url, $options, $caller );
+ }
+
+ /**
+ * @return string
+ */
+ public function getUserAgent() {
+ global $wgVersion;
+
+ return "MediaWiki/$wgVersion";
+ }
}
/**
* @param string $url Url to use. If protocol-relative, will be expanded to an http:// URL
- * @param array $options (optional) extra params to pass (see Http::request())
+ * @param array $options (optional) extra params to pass (see HttpRequestFactory::create())
* @param string $caller The method making this request, for profiling
* @param Profiler|null $profiler An instance of the profiler for profiling, or null
* @throws Exception
/**
* Generate a new request object
- * Deprecated: @see HttpRequestFactory::create
+ * @deprecated since 1.34, use HttpRequestFactory instead
* @param string $url Url to use
- * @param array|null $options (optional) extra params to pass (see Http::request())
+ * @param array|null $options (optional) extra params to pass (see HttpRequestFactory::create())
* @param string $caller The method making this request, for profiling
* @throws DomainException
* @return MWHttpRequest
if ( self::isLocalURL( $this->url ) || $this->noProxy ) {
$this->proxy = '';
} else {
- $this->proxy = Http::getProxy();
+ global $wgHTTPProxy;
+ $this->proxy = (string)$wgHTTPProxy;
}
}
$this->reqHeaders['X-Forwarded-For'] = $originalRequest['ip'];
$this->reqHeaders['X-Original-User-Agent'] = $originalRequest['userAgent'];
}
+
+ /**
+ * Check that the given URI is a valid one.
+ *
+ * This hardcodes a small set of protocols only, because we want to
+ * deterministically reject protocols not supported by all HTTP-transport
+ * methods.
+ *
+ * "file://" specifically must not be allowed, for security reasons
+ * (see <https://www.mediawiki.org/wiki/Special:Code/MediaWiki/r67684>).
+ *
+ * @todo FIXME this is wildly inaccurate and fails to actually check most stuff
+ *
+ * @since 1.34
+ * @param string $uri URI to check for validity
+ * @return bool
+ */
+ public static function isValidURI( $uri ) {
+ return (bool)preg_match(
+ '/^https?:\/\/[^\/\s]\S*$/D',
+ $uri
+ );
+ }
}
private $fopenErrors = [];
+ public function __construct() {
+ if ( !wfIniGetBool( 'allow_url_fopen' ) ) {
+ throw new RuntimeException( __METHOD__ . ': allow_url_fopen needs to be enabled for ' .
+ 'pure PHP http requests to work. If possible, curl should be used instead. See ' .
+ 'https://www.php.net/curl.'
+ );
+ }
+
+ parent::__construct( ...func_get_args() );
+ }
+
/**
* @param string $url
* @return string
# quicker and sorts out user-agent problems which might
# otherwise prevent importing from large sites, such
# as the Wikimedia cluster, etc.
- $data = Http::request(
+ $data = MediaWikiServices::getInstance()->getHttpRequestFactory()->request(
$method,
$url,
[
<?php
+use MediaWiki\MediaWikiServices;
use Psr\Log\LoggerInterface;
/**
// @todo FIXME!
$src = $wikiRevision->getSrc();
- $data = Http::get( $src, [], __METHOD__ );
+ $data = MediaWikiServices::getInstance()->getHttpRequestFactory()->
+ get( $src, [], __METHOD__ );
if ( !$data ) {
$this->logger->debug( "IMPORT: couldn't fetch source $src\n" );
fclose( $f );
}
try {
- $text = Http::get( $url . $file, [ 'timeout' => 3 ], __METHOD__ );
+ $text = MediaWikiServices::getInstance()->getHttpRequestFactory()->
+ get( $url . $file, [ 'timeout' => 3 ], __METHOD__ );
} catch ( Exception $e ) {
- // Http::get throws with allow_url_fopen = false and no curl extension.
+ // HttpRequestFactory::get can throw with allow_url_fopen = false and no curl
+ // extension.
$text = null;
}
unlink( $dir . $file );
use MediaWiki\MediaWikiServices;
use MessageLocalizer;
use MWException;
-use MWNamespace;
use MWTimestamp;
+use NamespaceInfo;
use OutputPage;
use Parser;
use ParserOptions;
/** @var LinkRenderer */
protected $linkRenderer;
+ /** @var NamespaceInfo */
+ protected $nsInfo;
+
/**
* TODO Make this a const when we drop HHVM support (T192166)
*
];
/**
+ * Do not call this directly. Get it from MediaWikiServices.
+ *
* @param array|Config $options Config accepted for backwards compatibility
* @param Language $contLang
* @param AuthManager $authManager
* @param LinkRenderer $linkRenderer
+ * @param NamespaceInfo|null $nsInfo
*/
public function __construct(
$options,
Language $contLang,
AuthManager $authManager,
- LinkRenderer $linkRenderer
+ LinkRenderer $linkRenderer,
+ NamespaceInfo $nsInfo = null
) {
if ( $options instanceof Config ) {
wfDeprecated( __METHOD__ . ' with Config parameter', '1.34' );
$options->assertRequiredOptions( self::$constructorOptions );
+ if ( !$nsInfo ) {
+ wfDeprecated( __METHOD__ . ' with no NamespaceInfo argument', '1.34' );
+ $nsInfo = MediaWikiServices::getInstance()->getNamespaceInfo();
+ }
$this->options = $options;
$this->contLang = $contLang;
$this->authManager = $authManager;
$this->linkRenderer = $linkRenderer;
+ $this->nsInfo = $nsInfo;
$this->logger = new NullLogger();
}
* @param array &$defaultPreferences
*/
protected function searchPreferences( &$defaultPreferences ) {
- foreach ( MWNamespace::getValidNamespaces() as $n ) {
+ foreach ( $this->nsInfo->getValidNamespaces() as $n ) {
$defaultPreferences['searchNs' . $n] = [
'type' => 'api',
];
* @file
*/
+use MediaWiki\Config\ServiceOptions;
+
/**
* This is a utility class for dealing with namespaces that encodes all the "magic" behaviors of
* them based on index. The textual names of the namespaces are handled by Language.php.
/** @var int[]|null Valid namespaces cache */
private $validNamespaces = null;
- /** @var Config */
- private $config;
+ /** @var ServiceOptions */
+ private $options;
+
+ /**
+ * TODO Make this const when HHVM support is dropped (T192166)
+ *
+ * @since 1.34
+ * @var array
+ */
+ public static $constructorOptions = [
+ 'AllowImageMoving',
+ 'CanonicalNamespaceNames',
+ 'CapitalLinkOverrides',
+ 'CapitalLinks',
+ 'ContentNamespaces',
+ 'ExtraNamespaces',
+ 'ExtraSignatureNamespaces',
+ 'NamespaceContentModels',
+ 'NamespaceProtection',
+ 'NamespacesWithSubpages',
+ 'NonincludableNamespaces',
+ 'RestrictionLevels',
+ ];
/**
- * @param Config $config
+ * @param ServiceOptions $options
*/
- public function __construct( Config $config ) {
- $this->config = $config;
+ public function __construct( ServiceOptions $options ) {
+ $options->assertRequiredOptions( self::$constructorOptions );
+ $this->options = $options;
}
/**
*/
public function isMovable( $index ) {
$result = !( $index < NS_MAIN ||
- ( $index == NS_FILE && !$this->config->get( 'AllowImageMoving' ) ) );
+ ( $index == NS_FILE && !$this->options->get( 'AllowImageMoving' ) ) );
/**
* @since 1.20
public function getCanonicalNamespaces() {
if ( $this->canonicalNamespaces === null ) {
$this->canonicalNamespaces =
- [ NS_MAIN => '' ] + $this->config->get( 'CanonicalNamespaceNames' );
+ [ NS_MAIN => '' ] + $this->options->get( 'CanonicalNamespaceNames' );
$this->canonicalNamespaces +=
ExtensionRegistry::getInstance()->getAttribute( 'ExtensionNamespaces' );
- if ( is_array( $this->config->get( 'ExtraNamespaces' ) ) ) {
- $this->canonicalNamespaces += $this->config->get( 'ExtraNamespaces' );
+ if ( is_array( $this->options->get( 'ExtraNamespaces' ) ) ) {
+ $this->canonicalNamespaces += $this->options->get( 'ExtraNamespaces' );
}
Hooks::run( 'CanonicalNamespaces', [ &$this->canonicalNamespaces ] );
}
* @return bool
*/
public function isContent( $index ) {
- return $index == NS_MAIN || in_array( $index, $this->config->get( 'ContentNamespaces' ) );
+ return $index == NS_MAIN || in_array( $index, $this->options->get( 'ContentNamespaces' ) );
}
/**
*/
public function wantSignatures( $index ) {
return $this->isTalk( $index ) ||
- in_array( $index, $this->config->get( 'ExtraSignatureNamespaces' ) );
+ in_array( $index, $this->options->get( 'ExtraSignatureNamespaces' ) );
}
/**
* @return bool
*/
public function hasSubpages( $index ) {
- return !empty( $this->config->get( 'NamespacesWithSubpages' )[$index] );
+ return !empty( $this->options->get( 'NamespacesWithSubpages' )[$index] );
}
/**
* @return array Array of namespace indices
*/
public function getContentNamespaces() {
- $contentNamespaces = $this->config->get( 'ContentNamespaces' );
+ $contentNamespaces = $this->options->get( 'ContentNamespaces' );
if ( !is_array( $contentNamespaces ) || $contentNamespaces === [] ) {
return [ NS_MAIN ];
} elseif ( !in_array( NS_MAIN, $contentNamespaces ) ) {
if ( in_array( $index, $this->alwaysCapitalizedNamespaces ) ) {
return true;
}
- $overrides = $this->config->get( 'CapitalLinkOverrides' );
+ $overrides = $this->options->get( 'CapitalLinkOverrides' );
if ( isset( $overrides[$index] ) ) {
// CapitalLinkOverrides is explicitly set
return $overrides[$index];
}
// Default to the global setting
- return $this->config->get( 'CapitalLinks' );
+ return $this->options->get( 'CapitalLinks' );
}
/**
* @return bool
*/
public function isNonincludable( $index ) {
- $namespaces = $this->config->get( 'NonincludableNamespaces' );
+ $namespaces = $this->options->get( 'NonincludableNamespaces' );
return $namespaces && in_array( $index, $namespaces );
}
* @return null|string Default model name for the given namespace, if set
*/
public function getNamespaceContentModel( $index ) {
- return $this->config->get( 'NamespaceContentModels' )[$index] ?? null;
+ return $this->options->get( 'NamespaceContentModels' )[$index] ?? null;
}
/**
* @return array
*/
public function getRestrictionLevels( $index, User $user = null ) {
- if ( !isset( $this->config->get( 'NamespaceProtection' )[$index] ) ) {
+ if ( !isset( $this->options->get( 'NamespaceProtection' )[$index] ) ) {
// All levels are valid if there's no namespace restriction.
// But still filter by user, if necessary
- $levels = $this->config->get( 'RestrictionLevels' );
+ $levels = $this->options->get( 'RestrictionLevels' );
if ( $user ) {
$levels = array_values( array_filter( $levels, function ( $level ) use ( $user ) {
$right = $level;
// First, get the list of groups that can edit this namespace.
$namespaceGroups = [];
$combine = 'array_merge';
- foreach ( (array)$this->config->get( 'NamespaceProtection' )[$index] as $right ) {
+ foreach ( (array)$this->options->get( 'NamespaceProtection' )[$index] as $right ) {
if ( $right == 'sysop' ) {
$right = 'editprotected'; // BC
}
// group that can edit the namespace but would be blocked by the
// restriction.
$usableLevels = [ '' ];
- foreach ( $this->config->get( 'RestrictionLevels' ) as $level ) {
+ foreach ( $this->options->get( 'RestrictionLevels' ) as $level ) {
$right = $level;
if ( $right == 'sysop' ) {
$right = 'editprotected'; // BC
* @author Platonides
*/
+use MediaWiki\MediaWikiServices;
+
require_once __DIR__ . '/Benchmarker.php';
/**
}
private function doRequest( $proto ) {
- Http::get( "$proto://localhost/", [], __METHOD__ );
+ MediaWikiServices::getInstance()->getHttpRequestFactory()->
+ get( "$proto://localhost/", [], __METHOD__ );
}
// bench function 1
* @author Antoine Musso <hashar at free dot fr>
*/
+use MediaWiki\MediaWikiServices;
+
require_once __DIR__ . '/Maintenance.php';
/**
$retval = [];
while ( true ) {
- $json = Http::get(
+ $json = MediaWikiServices::getInstance()->getHttpRequestFactory()->get(
wfAppendQuery( 'https://www.mediawiki.org/w/api.php', $params ),
[],
__METHOD__
* @ingroup Maintenance
*/
+use MediaWiki\MediaWikiServices;
+
require_once __DIR__ . '/Maintenance.php';
/**
$url = wfAppendQuery( $baseUrl, [
'action' => 'raw',
'title' => "MediaWiki:{$page}" ] );
- $text = Http::get( $url, [], __METHOD__ );
+ $text = MediaWikiServices::getInstance()->getHttpRequestFactory()->
+ get( $url, [], __METHOD__ );
$wikiPage = WikiPage::factory( $title );
$content = ContentHandler::makeContent( $text, $wikiPage->getTitle() );
while ( true ) {
$url = wfAppendQuery( $baseUrl, $data );
- $strResult = Http::get( $url, [], __METHOD__ );
+ $strResult = MediaWikiServices::getInstance()->getHttpRequestFactory()->
+ get( $url, [], __METHOD__ );
$result = FormatJson::decode( $strResult, true );
$page = null;
$url = rtrim( $this->source, '?' ) . '?' . $url;
}
- $json = Http::get( $url );
+ $json = MediaWikiServices::getInstance()->getHttpRequestFactory()->get( $url );
$data = json_decode( $json, true );
if ( is_array( $data ) ) {
<?php
+use MediaWiki\MediaWikiServices;
use Wikimedia\TestingAccessWrapper;
abstract class MWHttpRequestTestCase extends PHPUnit\Framework\TestCase {
protected static $httpEngine;
protected $oldHttpEngine;
+ /** @var HttpRequestFactory */
+ private $factory;
+
public function setUp() {
parent::setUp();
$this->oldHttpEngine = Http::$httpEngine;
Http::$httpEngine = static::$httpEngine;
+ $this->factory = MediaWikiServices::getInstance()->getHttpRequestFactory();
+
try {
- $request = MWHttpRequest::factory( 'null:' );
- } catch ( DomainException $e ) {
+ $request = $factory->create( 'null:' );
+ } catch ( RuntimeException $e ) {
$this->markTestSkipped( static::$httpEngine . ' engine not supported' );
}
// --------------------
public function testIsRedirect() {
- $request = MWHttpRequest::factory( 'http://httpbin.org/get' );
+ $request = $this->factory->create( 'http://httpbin.org/get' );
$status = $request->execute();
$this->assertTrue( $status->isGood() );
$this->assertFalse( $request->isRedirect() );
- $request = MWHttpRequest::factory( 'http://httpbin.org/redirect/1' );
+ $request = $this->factory->create( 'http://httpbin.org/redirect/1' );
$status = $request->execute();
$this->assertTrue( $status->isGood() );
$this->assertTrue( $request->isRedirect() );
}
public function testgetFinalUrl() {
- $request = MWHttpRequest::factory( 'http://httpbin.org/redirect/3' );
+ $request = $this->factory->create( 'http://httpbin.org/redirect/3' );
if ( !$request->canFollowRedirects() ) {
$this->markTestSkipped( 'cannot follow redirects' );
}
$this->assertTrue( $status->isGood() );
$this->assertNotSame( 'http://httpbin.org/get', $request->getFinalUrl() );
- $request = MWHttpRequest::factory( 'http://httpbin.org/redirect/3', [ 'followRedirects'
+ $request = $this->factory->create( 'http://httpbin.org/redirect/3', [ 'followRedirects'
=> true ] );
$status = $request->execute();
$this->assertTrue( $status->isGood() );
$this->assertSame( 'http://httpbin.org/get', $request->getFinalUrl() );
$this->assertResponseFieldValue( 'url', 'http://httpbin.org/get', $request );
- $request = MWHttpRequest::factory( 'http://httpbin.org/redirect/3', [ 'followRedirects'
+ $request = $this->factory->create( 'http://httpbin.org/redirect/3', [ 'followRedirects'
=> true ] );
$status = $request->execute();
$this->assertTrue( $status->isGood() );
return;
}
- $request = MWHttpRequest::factory( 'http://httpbin.org/redirect/3', [ 'followRedirects'
+ $request = $this->factory->create( 'http://httpbin.org/redirect/3', [ 'followRedirects'
=> true, 'maxRedirects' => 1 ] );
$status = $request->execute();
$this->assertTrue( $status->isGood() );
}
public function testSetCookie() {
- $request = MWHttpRequest::factory( 'http://httpbin.org/cookies' );
+ $request = $this->factory->create( 'http://httpbin.org/cookies' );
$request->setCookie( 'foo', 'bar' );
$request->setCookie( 'foo2', 'bar2', [ 'domain' => 'example.com' ] );
$status = $request->execute();
}
public function testSetCookieJar() {
- $request = MWHttpRequest::factory( 'http://httpbin.org/cookies' );
+ $request = $this->factory->create( 'http://httpbin.org/cookies' );
$cookieJar = new CookieJar();
$cookieJar->setCookie( 'foo', 'bar', [ 'domain' => 'httpbin.org' ] );
$cookieJar->setCookie( 'foo2', 'bar2', [ 'domain' => 'example.com' ] );
$this->assertTrue( $status->isGood() );
$this->assertResponseFieldValue( 'cookies', [ 'foo' => 'bar' ], $request );
- $request = MWHttpRequest::factory( 'http://httpbin.org/cookies/set?foo=bar' );
+ $request = $this->factory->create( 'http://httpbin.org/cookies/set?foo=bar' );
$cookieJar = new CookieJar();
$request->setCookieJar( $cookieJar );
$status = $request->execute();
$this->markTestIncomplete( 'CookieJar does not handle deletion' );
- // $request = MWHttpRequest::factory( 'http://httpbin.org/cookies/delete?foo' );
+ // $request = $this->factory->create( 'http://httpbin.org/cookies/delete?foo' );
// $cookieJar = new CookieJar();
// $cookieJar->setCookie( 'foo', 'bar', [ 'domain' => 'httpbin.org' ] );
// $cookieJar->setCookie( 'foo2', 'bar2', [ 'domain' => 'httpbin.org' ] );
}
public function testGetResponseHeaders() {
- $request = MWHttpRequest::factory( 'http://httpbin.org/response-headers?Foo=bar' );
+ $request = $this->factory->create( 'http://httpbin.org/response-headers?Foo=bar' );
$status = $request->execute();
$this->assertTrue( $status->isGood() );
$headers = array_change_key_case( $request->getResponseHeaders(), CASE_LOWER );
}
public function testSetHeader() {
- $request = MWHttpRequest::factory( 'http://httpbin.org/headers' );
+ $request = $this->factory->create( 'http://httpbin.org/headers' );
$request->setHeader( 'Foo', 'bar' );
$status = $request->execute();
$this->assertTrue( $status->isGood() );
}
public function testGetStatus() {
- $request = MWHttpRequest::factory( 'http://httpbin.org/status/418' );
+ $request = $this->factory->create( 'http://httpbin.org/status/418' );
$status = $request->execute();
$this->assertFalse( $status->isOK() );
$this->assertSame( $request->getStatus(), 418 );
}
public function testSetUserAgent() {
- $request = MWHttpRequest::factory( 'http://httpbin.org/user-agent' );
+ $request = $this->factory->create( 'http://httpbin.org/user-agent' );
$request->setUserAgent( 'foo' );
$status = $request->execute();
$this->assertTrue( $status->isGood() );
}
public function testSetData() {
- $request = MWHttpRequest::factory( 'http://httpbin.org/post', [ 'method' => 'POST' ] );
+ $request = $this->factory->create( 'http://httpbin.org/post', [ 'method' => 'POST' ] );
$request->setData( [ 'foo' => 'bar', 'foo2' => 'bar2' ] );
$status = $request->execute();
$this->assertTrue( $status->isGood() );
return;
}
- $request = MWHttpRequest::factory( 'http://httpbin.org/ip' );
+ $request = $this->factory->create( 'http://httpbin.org/ip' );
$data = '';
$request->setCallback( function ( $fh, $content ) use ( &$data ) {
$data .= $content;
}
public function testBasicAuthentication() {
- $request = MWHttpRequest::factory( 'http://httpbin.org/basic-auth/user/pass', [
+ $request = $this->factory->create( 'http://httpbin.org/basic-auth/user/pass', [
'username' => 'user',
'password' => 'pass',
] );
$this->assertTrue( $status->isGood() );
$this->assertResponseFieldValue( 'authenticated', true, $request );
- $request = MWHttpRequest::factory( 'http://httpbin.org/basic-auth/user/pass', [
+ $request = $this->factory->create( 'http://httpbin.org/basic-auth/user/pass', [
'username' => 'user',
'password' => 'wrongpass',
] );
}
public function testFactoryDefaults() {
- $request = MWHttpRequest::factory( 'http://acme.test' );
+ $request = $this->factory->create( 'http://acme.test' );
$this->assertInstanceOf( MWHttpRequest::class, $request );
}
/**
* Reset the Title-related services that need resetting
* for each test
+ *
+ * @todo We need to reset all services on every test
*/
private function resetTitleServices() {
$services = MediaWikiServices::getInstance();
$services->resetServiceForTesting( '_MediaWikiTitleCodec' );
$services->resetServiceForTesting( 'LinkRenderer' );
$services->resetServiceForTesting( 'LinkRendererFactory' );
+ $services->resetServiceForTesting( 'NamespaceInfo' );
}
/**
]
] );
+ // Reset services since we modified $wgLocalInterwikis
$this->overrideMwServices();
}
<?php
+use MediaWiki\MediaWikiServices;
use Wikimedia\TestingAccessWrapper;
/**
$url = $this->backend->getFileHttpUrl( [ 'src' => $source ] );
if ( $url !== null ) { // supported
- $data = Http::request( "GET", $url, [], __METHOD__ );
+ $data = MediaWikiServices::getInstance()->getHttpRequestFactory()->
+ get( $url, [], __METHOD__ );
$this->assertEquals( $content, $data,
"HTTP GET of URL has right contents ($backendName)." );
}
* @covers Http::getProxy
*/
public function testGetProxy() {
+ $this->hideDeprecated( 'Http::getProxy' );
+
$this->setMwGlobals( 'wgHTTPProxy', false );
$this->assertEquals(
'',
* @return DefaultPreferencesFactory
*/
protected function getPreferencesFactory() {
+ $mockNsInfo = $this->createMock( NamespaceInfo::class );
+ $mockNsInfo->method( 'getValidNamespaces' )->willReturn( [
+ NS_MAIN, NS_TALK, NS_USER, NS_USER_TALK
+ ] );
+ $mockNsInfo->expects( $this->never() )
+ ->method( $this->anythingBut( 'getValidNamespaces', '__destruct' ) );
+
return new DefaultPreferencesFactory(
new ServiceOptions( DefaultPreferencesFactory::$constructorOptions, $this->config ),
new Language(),
AuthManager::singleton(),
- MediaWikiServices::getInstance()->getLinkRenderer()
+ MediaWikiServices::getInstance()->getLinkRenderer(),
+ $mockNsInfo
);
}
* @file
*/
-use MediaWiki\MediaWikiServices;
+use MediaWiki\Config\ServiceOptions;
class NamespaceInfoTest extends MediaWikiTestCase {
-
- /** @var NamespaceInfo */
- private $obj;
-
- protected function setUp() {
- parent::setUp();
-
- $this->setMwGlobals( [
- 'wgContentNamespaces' => [ NS_MAIN ],
- 'wgNamespacesWithSubpages' => [
+ private function newObj( array $options = [] ) : NamespaceInfo {
+ $defaults = [
+ 'AllowImageMoving' => true,
+ 'CanonicalNamespaceNames' => [
+ NS_TALK => 'Talk',
+ NS_USER => 'User',
+ NS_USER_TALK => 'User_talk',
+ NS_SPECIAL => 'Special',
+ NS_MEDIA => 'Media',
+ ],
+ 'CapitalLinkOverrides' => [],
+ 'CapitalLinks' => true,
+ 'ContentNamespaces' => [ NS_MAIN ],
+ 'ExtraNamespaces' => [],
+ 'ExtraSignatureNamespaces' => [],
+ 'NamespaceContentModels' => [],
+ 'NamespaceProtection' => [],
+ 'NamespacesWithSubpages' => [
NS_TALK => true,
NS_USER => true,
NS_USER_TALK => true,
],
- 'wgCapitalLinks' => true,
- 'wgCapitalLinkOverrides' => [],
- 'wgNonincludableNamespaces' => [],
- ] );
-
- $this->obj = MediaWikiServices::getInstance()->getNamespaceInfo();
+ 'NonincludableNamespaces' => [],
+ 'RestrictionLevels' => [ '', 'autoconfirmed', 'sysop' ],
+ ];
+ return new NamespaceInfo(
+ new ServiceOptions( NamespaceInfo::$constructorOptions, $options, $defaults ) );
}
/**
- * @todo Write more texts, handle $wgAllowImageMoving setting
+ * @todo Write more tests, handle $wgAllowImageMoving setting
* @covers NamespaceInfo::isMovable
*/
public function testIsMovable() {
- $this->assertFalse( $this->obj->isMovable( NS_SPECIAL ) );
+ $this->assertFalse( $this->newObj()->isMovable( NS_SPECIAL ) );
}
private function assertIsSubject( $ns ) {
- $this->assertTrue( $this->obj->isSubject( $ns ) );
+ $this->assertTrue( $this->newObj()->isSubject( $ns ) );
}
private function assertIsNotSubject( $ns ) {
- $this->assertFalse( $this->obj->isSubject( $ns ) );
+ $this->assertFalse(
+ $this->newObj()->isSubject( $ns ) );
}
/**
- * Please make sure to change testIsTalk() if you change the assertions below
+ * @param int $ns
+ * @param bool $expected
+ * @dataProvider provideIsSubject
* @covers NamespaceInfo::isSubject
*/
- public function testIsSubject() {
- // Special namespaces
- $this->assertIsSubject( NS_MEDIA );
- $this->assertIsSubject( NS_SPECIAL );
-
- // Subject pages
- $this->assertIsSubject( NS_MAIN );
- $this->assertIsSubject( NS_USER );
- $this->assertIsSubject( 100 ); # user defined
-
- // Talk pages
- $this->assertIsNotSubject( NS_TALK );
- $this->assertIsNotSubject( NS_USER_TALK );
- $this->assertIsNotSubject( 101 ); # user defined
- }
-
- private function assertIsTalk( $ns ) {
- $this->assertTrue( $this->obj->isTalk( $ns ) );
- }
-
- private function assertIsNotTalk( $ns ) {
- $this->assertFalse( $this->obj->isTalk( $ns ) );
+ public function testIsSubject( $ns, $expected ) {
+ $this->assertSame( $expected, $this->newObj()->isSubject( $ns ) );
}
/**
- * Reverse of testIsSubject().
- * Please update testIsSubject() if you change assertions below
+ * @param int $ns
+ * @param bool $expected
+ * @dataProvider provideIsSubject
* @covers NamespaceInfo::isTalk
*/
- public function testIsTalk() {
- // Special namespaces
- $this->assertIsNotTalk( NS_MEDIA );
- $this->assertIsNotTalk( NS_SPECIAL );
+ public function testIsTalk( $ns, $expected ) {
+ $this->assertSame( !$expected, $this->newObj()->isTalk( $ns ) );
+ }
- // Subject pages
- $this->assertIsNotTalk( NS_MAIN );
- $this->assertIsNotTalk( NS_USER );
- $this->assertIsNotTalk( 100 ); # user defined
+ public function provideIsSubject() {
+ return [
+ // Special namespaces
+ [ NS_MEDIA, true ],
+ [ NS_SPECIAL, true ],
- // Talk pages
- $this->assertIsTalk( NS_TALK );
- $this->assertIsTalk( NS_USER_TALK );
- $this->assertIsTalk( 101 ); # user defined
+ // Subject pages
+ [ NS_MAIN, true ],
+ [ NS_USER, true ],
+ [ 100, true ],
+
+ // Talk pages
+ [ NS_TALK, false ],
+ [ NS_USER_TALK, false ],
+ [ 101, false ],
+ ];
}
/**
*/
public function testGetSubject() {
// Special namespaces are their own subjects
- $this->assertEquals( NS_MEDIA, $this->obj->getSubject( NS_MEDIA ) );
- $this->assertEquals( NS_SPECIAL, $this->obj->getSubject( NS_SPECIAL ) );
+ $obj = $this->newObj();
+ $this->assertEquals( NS_MEDIA, $obj->getSubject( NS_MEDIA ) );
+ $this->assertEquals( NS_SPECIAL, $obj->getSubject( NS_SPECIAL ) );
- $this->assertEquals( NS_MAIN, $this->obj->getSubject( NS_TALK ) );
- $this->assertEquals( NS_USER, $this->obj->getSubject( NS_USER_TALK ) );
+ $this->assertEquals( NS_MAIN, $obj->getSubject( NS_TALK ) );
+ $this->assertEquals( NS_USER, $obj->getSubject( NS_USER_TALK ) );
}
/**
* @covers NamespaceInfo::getTalk
*/
public function testGetTalk() {
- $this->assertEquals( NS_TALK, $this->obj->getTalk( NS_MAIN ) );
- $this->assertEquals( NS_TALK, $this->obj->getTalk( NS_TALK ) );
- $this->assertEquals( NS_USER_TALK, $this->obj->getTalk( NS_USER ) );
- $this->assertEquals( NS_USER_TALK, $this->obj->getTalk( NS_USER_TALK ) );
+ $obj = $this->newObj();
+ $this->assertEquals( NS_TALK, $obj->getTalk( NS_MAIN ) );
+ $this->assertEquals( NS_TALK, $obj->getTalk( NS_TALK ) );
+ $this->assertEquals( NS_USER_TALK, $obj->getTalk( NS_USER ) );
+ $this->assertEquals( NS_USER_TALK, $obj->getTalk( NS_USER_TALK ) );
}
/**
* @covers NamespaceInfo::getTalk
*/
public function testGetTalkExceptionsForNsMedia() {
- $this->assertNull( $this->obj->getTalk( NS_MEDIA ) );
+ $this->assertNull( $this->newObj()->getTalk( NS_MEDIA ) );
}
/**
* @covers NamespaceInfo::getTalk
*/
public function testGetTalkExceptionsForNsSpecial() {
- $this->assertNull( $this->obj->getTalk( NS_SPECIAL ) );
+ $this->assertNull( $this->newObj()->getTalk( NS_SPECIAL ) );
}
/**
* @covers NamespaceInfo::getAssociated
*/
public function testGetAssociated() {
- $this->assertEquals( NS_TALK, $this->obj->getAssociated( NS_MAIN ) );
- $this->assertEquals( NS_MAIN, $this->obj->getAssociated( NS_TALK ) );
+ $this->assertEquals( NS_TALK, $this->newObj()->getAssociated( NS_MAIN ) );
+ $this->assertEquals( NS_MAIN, $this->newObj()->getAssociated( NS_TALK ) );
}
# ## Exceptions with getAssociated()
* @covers NamespaceInfo::getAssociated
*/
public function testGetAssociatedExceptionsForNsMedia() {
- $this->assertNull( $this->obj->getAssociated( NS_MEDIA ) );
+ $this->assertNull( $this->newObj()->getAssociated( NS_MEDIA ) );
}
/**
* @covers NamespaceInfo::getAssociated
*/
public function testGetAssociatedExceptionsForNsSpecial() {
- $this->assertNull( $this->obj->getAssociated( NS_SPECIAL ) );
+ $this->assertNull( $this->newObj()->getAssociated( NS_SPECIAL ) );
}
/**
* @covers NamespaceInfo::equals
*/
public function testEquals() {
- $this->assertTrue( $this->obj->equals( NS_MAIN, NS_MAIN ) );
- $this->assertTrue( $this->obj->equals( NS_MAIN, 0 ) ); // In case we make NS_MAIN 'MAIN'
- $this->assertTrue( $this->obj->equals( NS_USER, NS_USER ) );
- $this->assertTrue( $this->obj->equals( NS_USER, 2 ) );
- $this->assertTrue( $this->obj->equals( NS_USER_TALK, NS_USER_TALK ) );
- $this->assertTrue( $this->obj->equals( NS_SPECIAL, NS_SPECIAL ) );
- $this->assertFalse( $this->obj->equals( NS_MAIN, NS_TALK ) );
- $this->assertFalse( $this->obj->equals( NS_USER, NS_USER_TALK ) );
- $this->assertFalse( $this->obj->equals( NS_PROJECT, NS_TEMPLATE ) );
+ $obj = $this->newObj();
+ $this->assertTrue( $obj->equals( NS_MAIN, NS_MAIN ) );
+ $this->assertTrue( $obj->equals( NS_MAIN, 0 ) ); // In case we make NS_MAIN 'MAIN'
+ $this->assertTrue( $obj->equals( NS_USER, NS_USER ) );
+ $this->assertTrue( $obj->equals( NS_USER, 2 ) );
+ $this->assertTrue( $obj->equals( NS_USER_TALK, NS_USER_TALK ) );
+ $this->assertTrue( $obj->equals( NS_SPECIAL, NS_SPECIAL ) );
+ $this->assertFalse( $obj->equals( NS_MAIN, NS_TALK ) );
+ $this->assertFalse( $obj->equals( NS_USER, NS_USER_TALK ) );
+ $this->assertFalse( $obj->equals( NS_PROJECT, NS_TEMPLATE ) );
}
/**
+ * @param int $ns1
+ * @param int $ns2
+ * @param bool $expected
+ * @dataProvider provideSubjectEquals
* @covers NamespaceInfo::subjectEquals
*/
- public function testSubjectEquals() {
- $this->assertSameSubject( NS_MAIN, NS_MAIN );
- $this->assertSameSubject( NS_MAIN, 0 ); // In case we make NS_MAIN 'MAIN'
- $this->assertSameSubject( NS_USER, NS_USER );
- $this->assertSameSubject( NS_USER, 2 );
- $this->assertSameSubject( NS_USER_TALK, NS_USER_TALK );
- $this->assertSameSubject( NS_SPECIAL, NS_SPECIAL );
- $this->assertSameSubject( NS_MAIN, NS_TALK );
- $this->assertSameSubject( NS_USER, NS_USER_TALK );
+ public function testSubjectEquals( $ns1, $ns2, $expected ) {
+ $this->assertSame( $expected, $this->newObj()->subjectEquals( $ns1, $ns2 ) );
+ }
- $this->assertDifferentSubject( NS_PROJECT, NS_TEMPLATE );
- $this->assertDifferentSubject( NS_SPECIAL, NS_MAIN );
+ public function provideSubjectEquals() {
+ return [
+ [ NS_MAIN, NS_MAIN, true ],
+ // In case we make NS_MAIN 'MAIN'
+ [ NS_MAIN, 0, true ],
+ [ NS_USER, NS_USER, true ],
+ [ NS_USER, 2, true ],
+ [ NS_USER_TALK, NS_USER_TALK, true ],
+ [ NS_SPECIAL, NS_SPECIAL, true ],
+ [ NS_MAIN, NS_TALK, true ],
+ [ NS_USER, NS_USER_TALK, true ],
+
+ [ NS_PROJECT, NS_TEMPLATE, false ],
+ [ NS_SPECIAL, NS_MAIN, false ],
+ [ NS_MEDIA, NS_SPECIAL, false ],
+ [ NS_SPECIAL, NS_MEDIA, false ],
+ ];
}
/**
- * @covers NamespaceInfo::subjectEquals
+ * @dataProvider provideHasTalkNamespace
+ * @covers NamespaceInfo::hasTalkNamespace
+ *
+ * @param int $ns
+ * @param bool $expected
*/
- public function testSpecialAndMediaAreDifferentSubjects() {
- $this->assertDifferentSubject(
- NS_MEDIA, NS_SPECIAL,
- "NS_MEDIA and NS_SPECIAL are different subject namespaces"
- );
- $this->assertDifferentSubject(
- NS_SPECIAL, NS_MEDIA,
- "NS_SPECIAL and NS_MEDIA are different subject namespaces"
- );
+ public function testHasTalkNamespace( $ns, $expected ) {
+ $this->assertSame( $expected, $this->newObj()->hasTalkNamespace( $ns ) );
}
public function provideHasTalkNamespace() {
}
/**
- * @dataProvider provideHasTalkNamespace
- * @covers NamespaceInfo::hasTalkNamespace
- *
- * @param int $index
+ * @param int $ns
* @param bool $expected
+ * @param array $contentNamespaces
+ * @covers NamespaceInfo::isContent
+ * @dataProvider provideIsContent
*/
- public function testHasTalkNamespace( $index, $expected ) {
- $actual = $this->obj->hasTalkNamespace( $index );
- $this->assertSame( $actual, $expected, "NS $index" );
+ public function testIsContent( $ns, $expected, $contentNamespaces = [ NS_MAIN ] ) {
+ $obj = $this->newObj( [ 'ContentNamespaces' => $contentNamespaces ] );
+ $this->assertSame( $expected, $obj->isContent( $ns ) );
}
- private function assertIsContent( $ns ) {
- $this->assertTrue( $this->obj->isContent( $ns ) );
- }
-
- private function assertIsNotContent( $ns ) {
- $this->assertFalse( $this->obj->isContent( $ns ) );
+ public function provideIsContent() {
+ return [
+ [ NS_MAIN, true ],
+ [ NS_MEDIA, false ],
+ [ NS_SPECIAL, false ],
+ [ NS_TALK, false ],
+ [ NS_USER, false ],
+ [ NS_CATEGORY, false ],
+ [ 100, false ],
+ [ 100, true, [ NS_MAIN, 100, 252 ] ],
+ [ 252, true, [ NS_MAIN, 100, 252 ] ],
+ [ NS_MAIN, true, [ NS_MAIN, 100, 252 ] ],
+ // NS_MAIN is always content
+ [ NS_MAIN, true, [] ],
+ ];
}
/**
- * @covers NamespaceInfo::isContent
+ * @param int $ns
+ * @param bool $expected
+ * @covers NamespaceInfo::isWatchable
+ * @dataProvider provideIsWatchable
*/
- public function testIsContent() {
- // NS_MAIN is a content namespace per DefaultSettings.php
- // and per function definition.
-
- $this->assertIsContent( NS_MAIN );
-
- // Other namespaces which are not expected to be content
-
- $this->assertIsNotContent( NS_MEDIA );
- $this->assertIsNotContent( NS_SPECIAL );
- $this->assertIsNotContent( NS_TALK );
- $this->assertIsNotContent( NS_USER );
- $this->assertIsNotContent( NS_CATEGORY );
- $this->assertIsNotContent( 100 );
+ public function testIsWatchable( $ns, $expected ) {
+ $this->assertSame( $expected, $this->newObj()->isWatchable( $ns ) );
}
- /**
- * Similar to testIsContent() but alters the $wgContentNamespaces
- * global variable.
- * @covers NamespaceInfo::isContent
- */
- public function testIsContentAdvanced() {
- global $wgContentNamespaces;
-
- // Test that user defined namespace #252 is not content
- $this->assertIsNotContent( 252 );
-
- // Bless namespace # 252 as a content namespace
- $wgContentNamespaces[] = 252;
-
- $this->assertIsContent( 252 );
-
- // Makes sure NS_MAIN was not impacted
- $this->assertIsContent( NS_MAIN );
- }
+ public function provideIsWatchable() {
+ return [
+ // Specials namespaces are not watchable
+ [ NS_MEDIA, false ],
+ [ NS_SPECIAL, false ],
- private function assertIsWatchable( $ns ) {
- $this->assertTrue( $this->obj->isWatchable( $ns ) );
- }
+ // Core defined namespaces are watchables
+ [ NS_MAIN, true ],
+ [ NS_TALK, true ],
- private function assertIsNotWatchable( $ns ) {
- $this->assertFalse( $this->obj->isWatchable( $ns ) );
+ // Additional, user defined namespaces are watchables
+ [ 100, true ],
+ [ 101, true ],
+ ];
}
/**
- * @covers NamespaceInfo::isWatchable
+ * @param int $ns
+ * @param int $expected
+ * @param array|null $namespacesWithSubpages To pass to constructor
+ * @covers NamespaceInfo::hasSubpages
+ * @dataProvider provideHasSubpages
*/
- public function testIsWatchable() {
- // Specials namespaces are not watchable
- $this->assertIsNotWatchable( NS_MEDIA );
- $this->assertIsNotWatchable( NS_SPECIAL );
-
- // Core defined namespaces are watchables
- $this->assertIsWatchable( NS_MAIN );
- $this->assertIsWatchable( NS_TALK );
-
- // Additional, user defined namespaces are watchables
- $this->assertIsWatchable( 100 );
- $this->assertIsWatchable( 101 );
+ public function testHasSubpages( $ns, $expected, array $namespacesWithSubpages = null ) {
+ $obj = $this->newObj( $namespacesWithSubpages
+ ? [ 'NamespacesWithSubpages' => $namespacesWithSubpages ]
+ : [] );
+ $this->assertSame( $expected, $obj->hasSubpages( $ns ) );
}
- private function assertHasSubpages( $ns ) {
- $this->assertTrue( $this->obj->hasSubpages( $ns ) );
- }
+ public function provideHasSubpages() {
+ return [
+ // Special namespaces:
+ [ NS_MEDIA, false ],
+ [ NS_SPECIAL, false ],
- private function assertHasNotSubpages( $ns ) {
- $this->assertFalse( $this->obj->hasSubpages( $ns ) );
+ // Namespaces without subpages
+ [ NS_MAIN, false ],
+ [ NS_MAIN, true, [ NS_MAIN => true ] ],
+ [ NS_MAIN, false, [ NS_MAIN => false ] ],
+
+ // Some namespaces with subpages
+ [ NS_TALK, true ],
+ [ NS_USER, true ],
+ [ NS_USER_TALK, true ],
+ ];
}
/**
- * @covers NamespaceInfo::hasSubpages
+ * @param $contentNamespaces To pass to constructor
+ * @param array $expected
+ * @dataProvider provideGetContentNamespaces
+ * @covers NamespaceInfo::getContentNamespaces
*/
- public function testHasSubpages() {
- global $wgNamespacesWithSubpages;
-
- // Special namespaces:
- $this->assertHasNotSubpages( NS_MEDIA );
- $this->assertHasNotSubpages( NS_SPECIAL );
+ public function testGetContentNamespaces( $contentNamespaces, array $expected ) {
+ $obj = $this->newObj( [ 'ContentNamespaces' => $contentNamespaces ] );
+ $this->assertSame( $expected, $obj->getContentNamespaces() );
+ }
- // Namespaces without subpages
- $this->assertHasNotSubpages( NS_MAIN );
+ public function provideGetContentNamespaces() {
+ return [
+ // Non-array
+ [ '', [ NS_MAIN ] ],
+ [ false, [ NS_MAIN ] ],
+ [ null, [ NS_MAIN ] ],
+ [ 5, [ NS_MAIN ] ],
- $wgNamespacesWithSubpages[NS_MAIN] = true;
- $this->assertHasSubpages( NS_MAIN );
+ // Empty array
+ [ [], [ NS_MAIN ] ],
- $wgNamespacesWithSubpages[NS_MAIN] = false;
- $this->assertHasNotSubpages( NS_MAIN );
+ // NS_MAIN is forced to be content even if unwanted
+ [ [ NS_USER, NS_CATEGORY ], [ NS_MAIN, NS_USER, NS_CATEGORY ] ],
- // Some namespaces with subpages
- $this->assertHasSubpages( NS_TALK );
- $this->assertHasSubpages( NS_USER );
- $this->assertHasSubpages( NS_USER_TALK );
- }
-
- /**
- * @covers NamespaceInfo::getContentNamespaces
- */
- public function testGetContentNamespaces() {
- global $wgContentNamespaces;
-
- $this->assertEquals(
- [ NS_MAIN ],
- $this->obj->getContentNamespaces(),
- '$wgContentNamespaces is an array with only NS_MAIN by default'
- );
-
- # test !is_array( $wgcontentNamespaces )
- $wgContentNamespaces = '';
- $this->assertEquals( [ NS_MAIN ], $this->obj->getContentNamespaces() );
-
- $wgContentNamespaces = false;
- $this->assertEquals( [ NS_MAIN ], $this->obj->getContentNamespaces() );
-
- $wgContentNamespaces = null;
- $this->assertEquals( [ NS_MAIN ], $this->obj->getContentNamespaces() );
-
- $wgContentNamespaces = 5;
- $this->assertEquals( [ NS_MAIN ], $this->obj->getContentNamespaces() );
-
- # test $wgContentNamespaces === []
- $wgContentNamespaces = [];
- $this->assertEquals( [ NS_MAIN ], $this->obj->getContentNamespaces() );
-
- # test !in_array( NS_MAIN, $wgContentNamespaces )
- $wgContentNamespaces = [ NS_USER, NS_CATEGORY ];
- $this->assertEquals(
- [ NS_MAIN, NS_USER, NS_CATEGORY ],
- $this->obj->getContentNamespaces(),
- 'NS_MAIN is forced in $wgContentNamespaces even if unwanted'
- );
-
- # test other cases, return $wgcontentNamespaces as is
- $wgContentNamespaces = [ NS_MAIN ];
- $this->assertEquals(
- [ NS_MAIN ],
- $this->obj->getContentNamespaces()
- );
-
- $wgContentNamespaces = [ NS_MAIN, NS_USER, NS_CATEGORY ];
- $this->assertEquals(
- [ NS_MAIN, NS_USER, NS_CATEGORY ],
- $this->obj->getContentNamespaces()
- );
+ // In other cases, return as-is
+ [ [ NS_MAIN ], [ NS_MAIN ] ],
+ [ [ NS_MAIN, NS_USER, NS_CATEGORY ], [ NS_MAIN, NS_USER, NS_CATEGORY ] ],
+ ];
}
/**
* @covers NamespaceInfo::getSubjectNamespaces
*/
public function testGetSubjectNamespaces() {
- $subjectsNS = $this->obj->getSubjectNamespaces();
+ $subjectsNS = $this->newObj()->getSubjectNamespaces();
$this->assertContains( NS_MAIN, $subjectsNS,
"Talk namespaces should have NS_MAIN" );
$this->assertNotContains( NS_TALK, $subjectsNS,
* @covers NamespaceInfo::getTalkNamespaces
*/
public function testGetTalkNamespaces() {
- $talkNS = $this->obj->getTalkNamespaces();
+ $talkNS = $this->newObj()->getTalkNamespaces();
$this->assertContains( NS_TALK, $talkNS,
"Subject namespaces should have NS_TALK" );
$this->assertNotContains( NS_MAIN, $talkNS,
"Subject namespaces should not have NS_SPECIAL" );
}
- private function assertIsCapitalized( $ns ) {
- $this->assertTrue( $this->obj->isCapitalized( $ns ) );
- }
-
- private function assertIsNotCapitalized( $ns ) {
- $this->assertFalse( $this->obj->isCapitalized( $ns ) );
- }
-
/**
- * Some namespaces are always capitalized per code definition
- * in NamespaceInfo::$alwaysCapitalizedNamespaces
- * @covers NamespaceInfo::isCapitalized
- */
- public function testIsCapitalizedHardcodedAssertions() {
- // NS_MEDIA and NS_FILE are treated the same
- $this->assertEquals(
- $this->obj->isCapitalized( NS_MEDIA ),
- $this->obj->isCapitalized( NS_FILE ),
- 'NS_MEDIA and NS_FILE have same capitalization rendering'
- );
-
- // Boths are capitalized by default
- $this->assertIsCapitalized( NS_MEDIA );
- $this->assertIsCapitalized( NS_FILE );
-
- // Always capitalized namespaces
- // @see NamespaceInfo::$alwaysCapitalizedNamespaces
- $this->assertIsCapitalized( NS_SPECIAL );
- $this->assertIsCapitalized( NS_USER );
- $this->assertIsCapitalized( NS_MEDIAWIKI );
- }
-
- /**
- * Follows up for testIsCapitalizedHardcodedAssertions() but alter the
- * global $wgCapitalLink setting to have extended coverage.
- *
- * NamespaceInfo::isCapitalized() rely on two global settings:
- * $wgCapitalLinkOverrides = []; by default
- * $wgCapitalLinks = true; by default
- * This function test $wgCapitalLinks
- *
- * Global setting correctness is tested against the NS_PROJECT and
- * NS_PROJECT_TALK namespaces since they are not hardcoded nor specials
+ * @param int $ns
+ * @param bool $expected
+ * @param bool $capitalLinks To pass to constructor
+ * @param array $capitalLinkOverrides To pass to constructor
+ * @dataProvider provideIsCapitalized
* @covers NamespaceInfo::isCapitalized
*/
- public function testIsCapitalizedWithWgCapitalLinks() {
- $this->assertIsCapitalized( NS_PROJECT );
- $this->assertIsCapitalized( NS_PROJECT_TALK );
-
- $this->setMwGlobals( 'wgCapitalLinks', false );
-
- // hardcoded namespaces (see above function) are still capitalized:
- $this->assertIsCapitalized( NS_SPECIAL );
- $this->assertIsCapitalized( NS_USER );
- $this->assertIsCapitalized( NS_MEDIAWIKI );
-
- // setting is correctly applied
- $this->assertIsNotCapitalized( NS_PROJECT );
- $this->assertIsNotCapitalized( NS_PROJECT_TALK );
+ public function testIsCapitalized(
+ $ns, $expected, $capitalLinks = true, array $capitalLinkOverrides = []
+ ) {
+ $obj = $this->newObj( [
+ 'CapitalLinks' => $capitalLinks,
+ 'CapitalLinkOverrides' => $capitalLinkOverrides,
+ ] );
+ $this->assertSame( $expected, $obj->isCapitalized( $ns ) );
}
- /**
- * Counter part for NamespaceInfo::testIsCapitalizedWithWgCapitalLinks() now
- * testing the $wgCapitalLinkOverrides global.
- *
- * @todo split groups of assertions in autonomous testing functions
- * @covers NamespaceInfo::isCapitalized
- */
- public function testIsCapitalizedWithWgCapitalLinkOverrides() {
- global $wgCapitalLinkOverrides;
-
- // Test default settings
- $this->assertIsCapitalized( NS_PROJECT );
- $this->assertIsCapitalized( NS_PROJECT_TALK );
-
- // hardcoded namespaces (see above function) are capitalized:
- $this->assertIsCapitalized( NS_SPECIAL );
- $this->assertIsCapitalized( NS_USER );
- $this->assertIsCapitalized( NS_MEDIAWIKI );
-
- // Hardcoded namespaces remains capitalized
- $wgCapitalLinkOverrides[NS_SPECIAL] = false;
- $wgCapitalLinkOverrides[NS_USER] = false;
- $wgCapitalLinkOverrides[NS_MEDIAWIKI] = false;
-
- $this->assertIsCapitalized( NS_SPECIAL );
- $this->assertIsCapitalized( NS_USER );
- $this->assertIsCapitalized( NS_MEDIAWIKI );
-
- $wgCapitalLinkOverrides[NS_PROJECT] = false;
- $this->assertIsNotCapitalized( NS_PROJECT );
-
- $wgCapitalLinkOverrides[NS_PROJECT] = true;
- $this->assertIsCapitalized( NS_PROJECT );
-
- unset( $wgCapitalLinkOverrides[NS_PROJECT] );
- $this->assertIsCapitalized( NS_PROJECT );
+ public function provideIsCapitalized() {
+ return [
+ // Test default settings
+ [ NS_PROJECT, true ],
+ [ NS_PROJECT_TALK, true ],
+ [ NS_MEDIA, true ],
+ [ NS_FILE, true ],
+
+ // Always capitalized no matter what
+ [ NS_SPECIAL, true, false ],
+ [ NS_USER, true, false ],
+ [ NS_MEDIAWIKI, true, false ],
+
+ // Even with an override too
+ [ NS_SPECIAL, true, false, [ NS_SPECIAL => false ] ],
+ [ NS_USER, true, false, [ NS_USER => false ] ],
+ [ NS_MEDIAWIKI, true, false, [ NS_MEDIAWIKI => false ] ],
+
+ // Overrides work for other namespaces
+ [ NS_PROJECT, false, true, [ NS_PROJECT => false ] ],
+ [ NS_PROJECT, true, false, [ NS_PROJECT => true ] ],
+
+ // NS_MEDIA is treated like NS_FILE, and ignores NS_MEDIA overrides
+ [ NS_MEDIA, false, true, [ NS_FILE => false, NS_MEDIA => true ] ],
+ [ NS_MEDIA, true, false, [ NS_FILE => true, NS_MEDIA => false ] ],
+ [ NS_FILE, false, true, [ NS_FILE => false, NS_MEDIA => true ] ],
+ [ NS_FILE, true, false, [ NS_FILE => true, NS_MEDIA => false ] ],
+ ];
}
/**
* @covers NamespaceInfo::hasGenderDistinction
*/
public function testHasGenderDistinction() {
+ $obj = $this->newObj();
+
// Namespaces with gender distinctions
- $this->assertTrue( $this->obj->hasGenderDistinction( NS_USER ) );
- $this->assertTrue( $this->obj->hasGenderDistinction( NS_USER_TALK ) );
+ $this->assertTrue( $obj->hasGenderDistinction( NS_USER ) );
+ $this->assertTrue( $obj->hasGenderDistinction( NS_USER_TALK ) );
// Other ones, "genderless"
- $this->assertFalse( $this->obj->hasGenderDistinction( NS_MEDIA ) );
- $this->assertFalse( $this->obj->hasGenderDistinction( NS_SPECIAL ) );
- $this->assertFalse( $this->obj->hasGenderDistinction( NS_MAIN ) );
- $this->assertFalse( $this->obj->hasGenderDistinction( NS_TALK ) );
+ $this->assertFalse( $obj->hasGenderDistinction( NS_MEDIA ) );
+ $this->assertFalse( $obj->hasGenderDistinction( NS_SPECIAL ) );
+ $this->assertFalse( $obj->hasGenderDistinction( NS_MAIN ) );
+ $this->assertFalse( $obj->hasGenderDistinction( NS_TALK ) );
}
/**
* @covers NamespaceInfo::isNonincludable
*/
public function testIsNonincludable() {
- global $wgNonincludableNamespaces;
-
- $wgNonincludableNamespaces = [ NS_USER ];
-
- $this->assertTrue( $this->obj->isNonincludable( NS_USER ) );
- $this->assertFalse( $this->obj->isNonincludable( NS_TEMPLATE ) );
- }
-
- private function assertSameSubject( $ns1, $ns2, $msg = '' ) {
- $this->assertTrue( $this->obj->subjectEquals( $ns1, $ns2 ), $msg );
+ $obj = $this->newObj( [ 'NonincludableNamespaces' => [ NS_USER ] ] );
+ $this->assertTrue( $obj->isNonincludable( NS_USER ) );
+ $this->assertFalse( $obj->isNonincludable( NS_TEMPLATE ) );
}
- private function assertDifferentSubject( $ns1, $ns2, $msg = '' ) {
- $this->assertFalse( $this->obj->subjectEquals( $ns1, $ns2 ), $msg );
+ /**
+ * @dataProvider provideGetCategoryLinkType
+ * @covers NamespaceInfo::getCategoryLinkType
+ *
+ * @param int $ns
+ * @param string $expected
+ */
+ public function testGetCategoryLinkType( $ns, $expected ) {
+ $this->assertSame( $expected, $this->newObj()->getCategoryLinkType( $ns ) );
}
public function provideGetCategoryLinkType() {
[ 101, 'page' ],
];
}
-
- /**
- * @dataProvider provideGetCategoryLinkType
- * @covers NamespaceInfo::getCategoryLinkType
- *
- * @param int $index
- * @param string $expected
- */
- public function testGetCategoryLinkType( $index, $expected ) {
- $actual = $this->obj->getCategoryLinkType( $index );
- $this->assertSame( $expected, $actual, "NS $index" );
- }
}
const Page = require( 'wdio-mediawiki/Page' ),
- Api = require( 'wdio-mediawiki/Api' );
+ Api = require( 'wdio-mediawiki/Api' ),
+ Util = require( 'wdio-mediawiki/Util' );
class HistoryPage extends Page {
get heading() { return browser.element( '#firstHeading' ); }
super.openTitle( title, { action: 'history' } );
}
+ toggleRollbackConfirmationSetting( enable ) {
+ Util.waitForModuleState( 'mediawiki.api', 'ready', 5000 );
+ return browser.execute( function ( enable ) {
+ return new mw.Api().saveOption(
+ 'showrollbackconfirmation',
+ enable ? '1' : '0'
+ );
+ }, enable );
+ }
+
vandalizePage( name, content ) {
let vandalUsername = 'Evil_' + browser.options.username;
// Enable rollback confirmation for admin user
// Requires user to log in again, handled by deleteCookie() call in beforeEach function
UserLoginPage.loginAdmin();
-
- UserLoginPage.waitForScriptsToBeReady();
- browser.execute( function () {
- return ( new mw.Api() ).saveOption(
- 'showrollbackconfirmation',
- '1'
- );
- } );
+ HistoryPage.toggleRollbackConfirmationSetting( true );
} );
beforeEach( function () {
// Disable rollback confirmation for admin user
// Requires user to log in again, handled by deleteCookie() call in beforeEach function
UserLoginPage.loginAdmin();
-
- UserLoginPage.waitForScriptsToBeReady();
- browser.execute( function () {
- return ( new mw.Api() ).saveOption(
- 'showrollbackconfirmation',
- '0'
- );
- } );
+ HistoryPage.toggleRollbackConfirmationSetting( false );
} );
beforeEach( function () {
-const Page = require( './Page' ),
- Util = require( 'wdio-mediawiki/Util' );
+const Page = require( './Page' );
class LoginPage extends Page {
get username() { return browser.element( '#wpName1' ); }
loginAdmin() {
this.login( browser.options.username, browser.options.password );
}
-
- waitForScriptsToBeReady() {
- Util.waitForModuleState( 'mediawiki.api' );
- }
}
module.exports = new LoginPage();