Page MenuHomeWickedGov Phorge

MobileContextTest.php
No OneTemporary

Size
15 KB
Referenced Files
None
Subscribers
None

MobileContextTest.php

<?php
use MediaWiki\Context\MutableContext;
use MediaWiki\Context\RequestContext;
use MediaWiki\MainConfigNames;
use MediaWiki\Request\FauxRequest;
use MediaWiki\SpecialPage\SpecialPage;
use MediaWiki\Title\Title;
use MediaWiki\Utils\UrlUtils;
use MobileFrontend\Tests\Utils;
/**
* @group MobileFrontend
*/
class MobileContextTest extends MediaWikiIntegrationTestCase {
/**
* PHP 5.3.2 introduces the ReflectionMethod::setAccessible() method to allow the invocation of
* protected and private methods directly through the Reflection API
*
* @param string $name
* @return ReflectionMethod
*/
protected static function getMethod( $name ) {
$class = new ReflectionClass( MobileContext::class );
$method = $class->getMethod( $name );
$method->setAccessible( true );
return $method;
}
protected function tearDown(): void {
parent::tearDown();
MobileContext::resetInstanceForTesting();
}
/**
* @param string $url
* @param array $cookies
* @return MobileContext
*/
private function makeContext( $url = '/', $cookies = [] ) {
$services = $this->getServiceContainer();
$urlUtils = $services->getUrlUtils();
$query = [];
if ( $url ) {
$params = $urlUtils->parse( $urlUtils->expand( $url, PROTO_CURRENT ) ?? '' );
if ( isset( $params['query'] ) ) {
$query = wfCgiToArray( $params['query'] );
}
}
$request = new FauxRequest( $query );
$request->setRequestURL( $url );
$request->setCookies( $cookies, '' );
MobileContext::resetInstanceForTesting();
/** @var MobileContext $instance */
$instance = $services->getService( 'MobileFrontend.Context' );
/** @var MutableContext $context */
$context = $instance->getContext();
$context->setRequest( $request );
return $instance;
}
/**
* @covers MobileContext::hasMobileDomain
*/
public function testHasMobileDomain() {
// not configured
$this->overrideConfigValues( [
'MobileUrlCallback' => null,
] );
$this->overrideConfigValue( MainConfigNames::Server, '//en.wikipedia.org' );
$context = $this->makeContext();
$this->assertFalse( $context->hasMobileDomain() );
// callback
$this->overrideConfigValues( [
'MobileUrlCallback' => [ Utils::class, 'mobileUrlCallback' ],
] );
$this->overrideConfigValue( MainConfigNames::Server, '//en.wikipedia.org' );
$context = $this->makeContext();
$this->assertTrue( $context->hasMobileDomain() );
// When a domain is returned unchanged, there is no mobile domain.
$this->overrideConfigValue( MainConfigNames::Server, '//wikitech.wikimedia.org' );
$context = $this->makeContext();
$this->assertFalse( $context->hasMobileDomain() );
}
/**
* @covers MobileContext::getMobileUrl
*/
public function testGetMobileUrl() {
$this->overrideConfigValues( [
'MFMobileHeader' => 'X-Subdomain',
MainConfigNames::Server => '//en.wikipedia.org',
'MobileUrlCallback' => [ Utils::class, 'mobileUrlCallback' ],
] );
$context = $this->makeContext();
$context->getRequest()->setHeader( 'X-Subdomain', 'M' );
$this->assertEquals(
'http://en.m.wikipedia.org/wiki/Article',
$context->getMobileUrl( 'http://en.wikipedia.org/wiki/Article' )
);
$this->assertEquals(
'//en.m.wikipedia.org/wiki/Article',
$context->getMobileUrl( '//en.wikipedia.org/wiki/Article' )
);
// test local Urls - task T107505
$this->assertEquals(
'http://en.m.wikipedia.org/wiki/Article',
$context->getMobileUrl( '/wiki/Article' )
);
// test other wikis
$this->assertEquals(
'http://de.m.wiktionary.org/wiki/Article',
$context->getMobileUrl( 'http://de.wiktionary.org/wiki/Article' )
);
$this->assertEquals(
'http://m.wikidata.org/wiki/Q1',
$context->getMobileUrl( 'http://www.wikidata.org/wiki/Q1' )
);
$this->assertEquals(
'http://wikitech.wikimedia.org/wiki/Main_Page',
$context->getMobileUrl( 'http://wikitech.wikimedia.org/wiki/Main_Page' )
);
}
/**
* @covers MobileContext::usingMobileDomain
*/
public function testUsingMobileDomain() {
$this->overrideConfigValues( [
'MFMobileHeader' => 'X-Subdomain',
'MobileUrlCallback' => [ Utils::class, 'mobileUrlCallback' ],
] );
$context = $this->makeContext();
$this->assertFalse( $context->usingMobileDomain() );
$context->getRequest()->setHeader( 'X-Subdomain', 'M' );
$this->assertTrue( $context->usingMobileDomain() );
}
/**
* @covers MobileContext::updateDesktopUrlQuery
* @dataProvider updateDesktopUrlQueryProvider
*/
public function testUpdateDesktopUrlQuery( $mobile, $desktop ) {
$updateDesktopUrlQuery = self::getMethod( "updateDesktopUrlQuery" );
$urlUtils = $this->getServiceContainer()->getUrlUtils();
$parsedUrl = $urlUtils->parse( $mobile );
$updateDesktopUrlQuery->invokeArgs( $this->makeContext(), [ &$parsedUrl ] );
$url = UrlUtils::assemble( $parsedUrl );
$this->assertEquals( $desktop, $url );
}
public static function updateDesktopUrlQueryProvider() {
$baseUrl = 'http://en.m.wikipedia.org/wiki/Gustavus_Airport';
return [
[
$baseUrl . '?useformat=mobile&mobileaction=toggle_desktop_view',
$baseUrl . '?mobileaction=toggle_desktop_view'
],
];
}
/**
* @covers MobileContext::updateDesktopUrlHost
* @dataProvider updateDesktopUrlHostProvider
*/
public function testUpdateDesktopUrlHost( $mobile, $desktop, $server ) {
$updateDesktopUrlHost = self::getMethod( "updateDesktopUrlHost" );
$this->overrideConfigValues( [
MainConfigNames::Server => $server,
'MobileUrlCallback' => [ Utils::class, 'mobileUrlCallback' ],
] );
$urlUtils = $this->getServiceContainer()->getUrlUtils();
$parsedUrl = $urlUtils->parse( $mobile );
$updateDesktopUrlHost->invokeArgs(
$this->makeContext(),
[ &$parsedUrl ] );
$this->assertEquals( $desktop, UrlUtils::assemble( $parsedUrl ) );
}
public static function updateDesktopUrlHostProvider() {
return [
[
'http://bm.m.wikipedia.org/wiki/' . urlencode( 'Nyɛ_fɔlɔ' ),
'http://bm.wikipedia.org/wiki/' . urlencode( 'Nyɛ_fɔlɔ' ),
'//bm.wikipedia.org',
],
[
'http://en.m.wikipedia.org/wiki/Gustavus_Airport',
'http://en.wikipedia.org/wiki/Gustavus_Airport',
'//en.wikipedia.org',
],
];
}
/**
* A null title shouldn't result in a fatal exception - bug T142914
* @covers MobileContext::shouldDisplayMobileView
* @covers MobileContext::shouldDisplayMobileViewInternal
* @covers MobileContext::getUseFormat
*/
public function testRedirectMobileEnabledPages() {
$this->setMwGlobals( [
'wgTitle' => null,
] );
$mobileContext = $this->makeContext();
$mobileContext->getRequest()->setVal( 'action', 'history' );
$mobileContext->getRequest()->setVal( 'useformat', 'mobile' );
$this->assertTrue( $mobileContext->shouldDisplayMobileView() );
}
/**
* @covers MobileContext::getMobileAction
* @dataProvider getMobileActionProvider
*/
public function testGetMobileAction( $mobileaction = null ) {
$context = $this->makeContext();
if ( $mobileaction === null ) {
$assert = '';
} else {
$context->getRequest()->setVal( 'mobileaction', $mobileaction );
$assert = $mobileaction;
}
$this->assertEquals( $assert, $context->getMobileAction() );
}
public static function getMobileActionProvider() {
return [
[ null ],
[ 'view_normal_site' ],
];
}
/**
* @covers MobileContext::getUseFormatCookieExpiry
*/
public function testGetUseFormatCookieExpiry() {
$getUseFormatCookieExpiry = self::getMethod( 'getUseFormatCookieExpiry' );
$context = $this->makeContext();
$startTime = time();
$this->overrideConfigValue( 'MobileFrontendFormatCookieExpiry', 60 );
$mfCookieExpected = $startTime + 60;
$this->assertTrue(
$mfCookieExpected == $getUseFormatCookieExpiry->invokeArgs(
$context,
[ $startTime ]
),
'Using MobileFrontend expiry.'
);
$this->overrideConfigValue( 'MobileFrontendFormatCookieExpiry', null );
$defaultMWCookieExpected = $startTime +
$this->getServiceContainer()->getMainConfig()->get( MainConfigNames::CookieExpiration );
$this->assertTrue(
$defaultMWCookieExpected == $getUseFormatCookieExpiry->invokeArgs(
$context,
[ $startTime ]
),
'Using default MediaWiki cookie expiry.'
);
}
/**
* @covers MobileContext::getStopMobileRedirectCookieDomain
*/
public function testGetStopMobileRedirectCookieDomain() {
$context = $this->makeContext();
$this->overrideConfigValues( [
'MFStopRedirectCookieHost' => null,
MainConfigNames::Server => 'http://en.wikipedia.org',
] );
$this->assertEquals( '.wikipedia.org', $context->getStopMobileRedirectCookieDomain() );
$this->overrideConfigValue( 'MFStopRedirectCookieHost', 'foo.bar.baz' );
$this->assertEquals( 'foo.bar.baz', $context->getStopMobileRedirectCookieDomain() );
}
/**
* @covers MobileContext::isLocalUrl
*/
public function testIsLocalUrl() {
$server = $this->getServiceContainer()->getMainConfig()->get( MainConfigNames::Server );
$context = $this->makeContext();
$this->assertTrue( $context->isLocalUrl( $server ) );
$this->assertFalse( $context->isLocalUrl( 'http://www.google.com' ) );
}
/**
* @covers MobileContext::getAnalyticsLogItems
* @dataProvider addAnalyticsLogItemProvider
*/
public function testAddAnalyticsLogItem( $key, array $inputs, $expected ) {
$context = $this->makeContext();
foreach ( $inputs as $input => $val ) {
$context->addAnalyticsLogItem( $key, $val );
}
$context->addAnalyticsLogItem( $key, $val );
$logItems = $context->getAnalyticsLogItems();
$trimmedKey = trim( $key );
$this->assertTrue( isset( $logItems[$trimmedKey] ) );
$this->assertEquals( $expected, $logItems[$trimmedKey] );
}
public static function addAnalyticsLogItemProvider() {
return [
[ 'mf-m', [ 'a' ], 'a' ],
[ ' mf-m', [ 'b ' ], 'b' ],
[ 'mf-m', [ 'a', 'b' ], 'a,b' ],
[ 'mf-m', [ 'a', 'b' ], 'a,b' ],
];
}
/**
* @covers MobileContext::getXAnalyticsHeader
* @dataProvider getXAnalyticsHeaderProvider
*/
public function testGetXAnalyticsHeader( $existingHeader, $logItems, $expectedHeader ) {
$context = $this->makeContext();
foreach ( $logItems as $key => $val ) {
$context->addAnalyticsLogItem( $key, $val );
}
if ( $existingHeader ) {
$context->getRequest()->response()->header( 'X-Analytics: ' . $existingHeader, true );
}
$this->assertEquals( $expectedHeader, $context->getXAnalyticsHeader() );
}
public static function getXAnalyticsHeaderProvider() {
return [
[
null,
[ 'mf-m' => 'a', 'zot' => '123' ],
'X-Analytics: mf-m=a;zot=123',
],
// check key/val trimming
[
null,
[ ' foo' => ' bar ', 'baz' => ' blat ' ],
'X-Analytics: foo=bar;baz=blat'
],
// check urlencoding key/val pairs
[
null,
[ 'foo' => 'bar baz', 'blat' => '$blammo' ],
'X-Analytics: foo=bar+baz;blat=%24blammo'
],
// check handling of existing header value
[
'existing=value; another=item',
[ 'mf-m' => 'a', 'zot' => '123' ],
'X-Analytics: existing=value;another=item;mf-m=a;zot=123',
],
];
}
/**
* @covers MobileContext::addAnalyticsLogItemFromXAnalytics
* @dataProvider addAnalyticsLogItemFromXAnalyticsProvider
*/
public function testAddAnalyticsLogItemFromXAnalytics( $analyticsItem, $key, $val ) {
$context = $this->makeContext();
$context->addAnalyticsLogItemFromXAnalytics( $analyticsItem );
$logItems = $context->getAnalyticsLogItems();
$this->assertTrue( isset( $logItems[$key] ) );
$this->assertEquals( $val, $logItems[$key] );
}
public static function addAnalyticsLogItemFromXAnalyticsProvider() {
return [
[ 'mf-m=a', 'mf-m', 'a' ],
// check key/val trimming
[ ' mf-m=a ', 'mf-m', 'a' ],
[ 'mf-m=a,b', 'mf-m', 'a,b' ],
// check urldecode
[ 'foo=bar+%24blat', 'foo', 'bar $blat' ],
];
}
/**
* @covers MobileContext::isBetaGroupMember
* @dataProvider optInProvider
*/
public function testOptIn( array $cookies, $isBeta, $enabledInSettings ) {
$this->overrideConfigValue( 'MFEnableBeta', $enabledInSettings );
$mobileContext = $this->makeContext( '/', $cookies );
$this->assertEquals( $isBeta, $mobileContext->isBetaGroupMember() );
}
public static function optInProvider() {
return [
[ [], false, true ],
[ [ MobileContext::OPTIN_COOKIE_NAME => MobileContext::MODE_BETA ], true, true ],
[ [ MobileContext::OPTIN_COOKIE_NAME => 'foobar' ], false, true ],
[ [], false, false ],
[ [ MobileContext::OPTIN_COOKIE_NAME => MobileContext::MODE_BETA ], false, false ],
[ [ MobileContext::OPTIN_COOKIE_NAME => 'foobar' ], false, false ],
];
}
/**
* @covers MobileContext::checkToggleView
* @covers MobileContext::doToggling
* @dataProvider provideToggleView
*/
public function testToggleView( $page, $url, $urlCallback, $expectedLocation ) {
$this->overrideConfigValues( [
'MobileUrlCallback' => $urlCallback,
MainConfigNames::Server => '//en.wikipedia.org',
// 'wgArticlePath' => '/wiki/$1',
MainConfigNames::ScriptPath => '/wiki',
] );
$context = $this->makeContext( $url );
$context->getContext()->setTitle( Title::newFromText( $page ) );
$context->checkToggleView();
$context->doToggling();
$location = $context->getOutput()->getRedirect();
$this->assertEquals( $expectedLocation, $location );
}
public static function provideToggleView() {
$mobileUrlCallback = [ Utils::class, 'mobileUrlCallback' ];
return [
[ 'Foo', '/', null, '' ],
[ 'Foo', '/', $mobileUrlCallback, '' ],
[ 'Main Page', '/wiki/Main_Page', null, '' ],
[ 'Main Page', '/wiki/Main_Page', $mobileUrlCallback, '' ],
[ 'Main Page', '/wiki/Main_Page?useformat=mobile', null, '' ],
[ 'Main Page', '/wiki/Main_Page?useformat=mobile', $mobileUrlCallback, '' ],
[ 'Main Page', '/wiki/Main_Page?useformat=desktop', null, '' ],
[ 'Main Page', '/wiki/Main_Page?useformat=desktop', $mobileUrlCallback, '' ],
[ 'Foo', '/?mobileaction=toggle_view_desktop', null, '' ],
[ 'Foo', '/?mobileaction=toggle_view_mobile', null, '' ],
[ 'Page', '/wiki/Page?mobileaction=toggle_view_desktop', null, '' ],
/*
FIXME: works locally but fails in Jerkins
[ 'Main Page', '/?mobileaction=toggle_view_desktop',
$mobileUrlCallback, 'http://en.wikipedia.org/wiki/Main_Page' ],
[ 'Main Page', '/?mobileaction=toggle_view_mobile',
$mobileUrlCallback, 'http://en.m.wikipedia.org/wiki/Main_Page' ],
[ 'Page', '/wiki/Page?mobileaction=toggle_view_mobile',
$mobileUrlCallback, 'http://en.m.wikipedia.org/wiki/Page' ],
[ 'Page', '/wiki/Page?mobileaction=toggle_view_desktop',
$mobileUrlCallback, 'http://en.wikipedia.org/wiki/Page' ],
[ 'Special:Foo', '/wiki/index.php?title=Special:Foo&bar=baz&mobileaction=toggle_view_desktop',
$mobileUrlCallback, 'http://en.wikipedia.org/w/index.php?title=Special:Foo&bar=baz' ],
[ 'Special:Foo', '/wiki/index.php?title=Special%3AFoo&bar=baz&mobileaction=toggle_view_mobile',
$mobileUrlCallback, 'http://en.m.wikipedia.org/w/index.php?title=Special:Foo&bar=baz' ],
[ 'Page', '/wiki/index.php?title=Page&mobileaction=toggle_view_desktop',
$mobileUrlCallback, 'http://en.wikipedia.org/wiki/Page', ],
[ 'Page', '/wiki/index.php?title=Page&mobileaction=toggle_view_mobile',
$mobileUrlCallback, 'http://en.m.wikipedia.org/wiki/Page', ],
*/
];
}
/**
* @codeCoverageIgnore
* @coversNothing
*/
public function testT73329() {
$services = $this->getServiceContainer();
$services->resetServiceForTesting( 'SpecialPageFactory' );
RequestContext::resetMain();
$req = new FauxRequest(
[ 'title' => 'Special:Search', 'mobileaction' => 'toggle_view_mobile' ]
);
$req->setRequestURL( '/w/index.php?title=Special:Search&mobileaction=toggle_view_mobile' );
RequestContext::getMain()->setRequest( $req );
MobileContext::resetInstanceForTesting();
$this->setMwGlobals( 'wgTitle', null );
SpecialPage::getTitleFor( 'Search' );
$this->assertTrue( true, 'In case of failure this test just crashes' );
}
}

File Metadata

Mime Type
text/x-php
Expires
Tue, Aug 18, 23:38 (6 h, 10 m ago)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
d1/d4/40ad890d20068f20b39ccc040f80
Default Alt Text
MobileContextTest.php (15 KB)

Event Timeline