wiki.techinc.nl/tests/phpunit/includes/TitleUrlTest.php
daniel 737d733aff Introduce TitleUrlTests
Change-Id: I26e2e06ed3aa179a0b517d5df032ebf659fefd6e
2021-09-08 07:48:45 +00:00

1049 lines
30 KiB
PHP

<?php
use MediaWiki\Tests\Unit\DummyServicesTrait;
/**
* @group Database
*
* @covers Title::getLocalURL
* @covers Title::getLinkURL
* @covers Title::getFullURL
* @covers Title::getFullUrlForRedirect
* @covers Title::getCanonicalURL
* @covers Title::getInternalURL
*/
class TitleUrlTest extends MediaWikiLangTestCase {
use DummyServicesTrait;
protected function setUp(): void {
parent::setUp();
$this->setMwGlobals( [
'wgServer' => '//m.xx.wiki.test',
'wgCanonicalServer' => 'https://xx.wiki.test',
'wgInternalServer' => 'http://app23.internal',
'wgArticlePath' => '/wiki/$1',
'wgExternalInterwikiFragmentMode' => 'html5',
'wgFragmentMode' => [ 'legacy', 'html5' ],
'wgMainPageIsDomainRoot' => true,
'wgActionPaths' => [ 'edit' => '/m/edit/$1' ],
'wgVariantArticlePath' => '/$2/$1',
'wgScriptPath' => '/m',
'wgScript' => '/m/index.php',
'wgUsePigLatinVariant' => true,
] );
// Some tests use interwikis - define valid prefixes and their configuration
// DummyServicesTrait::getDummyInterwikiLookup
$interwikiLookup = $this->getDummyInterwikiLookup( [
[ 'iw_prefix' => 'acme', 'iw_url' => 'https://acme.test/$1' ],
[ 'iw_prefix' => 'yy', 'iw_url' => '//yy.wiki.test/wiki/$1', 'iw_local' => true ]
] );
$this->setService( 'InterwikiLookup', $interwikiLookup );
$this->clearHook( 'GetFullURL' );
$this->clearHook( 'GetLocalURL__Article' );
$this->clearHook( 'GetLocalURL__Internal' );
$this->clearHook( 'GetLocalURL' );
$this->clearHook( 'GetInternalURL' );
$this->clearHook( 'GetCanonicalURL' );
}
protected function tearDown(): void {
Title::clearCaches();
parent::tearDown();
}
public function testUrlsForSimpleTitle() {
$title = Title::makeTitle( NS_USER, 'Göatee' );
$name = $title->getPrefixedURL();
$query = [ 'x' => 'one two', 'y' => '#' ];
$queryString = 'x=one+two&y=%23';
// Test getLocalURL()
$this->assertSame(
'/wiki/' . $name,
$title->getLocalURL(),
'getLocalURL()'
);
$this->assertSame(
'/m/index.php?title=' . $name . '&' . $queryString,
$title->getLocalURL( $query ),
'getLocalURL( array )'
);
$this->assertSame(
'/m/index.php?title=' . $name . '&' . $queryString,
$title->getLocalURL( $queryString ),
'getLocalURL( string )'
);
// Test getFullURL()
$this->assertSame(
'//m.xx.wiki.test/wiki/' . $name,
$title->getFullURL(),
'getFullURL()'
);
$this->assertSame(
'//m.xx.wiki.test/m/index.php?title=' . $name . '&' . $queryString,
$title->getFullURL( $query ),
'getFullURL( array )'
);
$this->assertSame(
'https://xx.wiki.test/wiki/' . $name,
$title->getFullURL( [], false, PROTO_CANONICAL ),
'getFullURL() with PROTO_CANONICAL'
);
$this->assertSame(
'http://m.xx.wiki.test/wiki/' . $name,
$title->getFullURL( [], false, PROTO_HTTP ),
'getFullURL() with PROTO_HTTP'
);
$this->assertSame(
'http://app23.internal/wiki/' . $name,
$title->getFullURL( [], false, PROTO_INTERNAL ),
'getFullURL() with PROTO_INTERNAL'
);
// Test getFullUrlForRedirect()
// Note that it uses PROTO_CURRENT per default, which is 'http' for tests
$this->assertSame(
'http://m.xx.wiki.test/wiki/' . $name,
$title->getFullUrlForRedirect(),
'getFullUrlForRedirect()'
);
$this->assertSame(
'http://m.xx.wiki.test/m/index.php?title=' . $name . '&' . $queryString,
$title->getFullUrlForRedirect( $query ),
'getFullUrlForRedirect( array )'
);
$this->assertSame(
'//m.xx.wiki.test/wiki/' . $name,
$title->getFullUrlForRedirect( [], PROTO_RELATIVE ),
'getFullUrlForRedirect() with PROTO_RELATIVE'
);
$this->assertSame(
'https://xx.wiki.test/wiki/' . $name,
$title->getFullUrlForRedirect( [], PROTO_CANONICAL ),
'getFullUrlForRedirect() with PROTO_CANONICAL'
);
$this->assertSame(
'http://app23.internal/wiki/' . $name,
$title->getFullUrlForRedirect( [], PROTO_INTERNAL ),
'getFullUrlForRedirect() with PROTO_INTERNAL'
);
// Test getLinkURL()
$this->assertSame(
'/wiki/' . $name,
$title->getLinkURL(),
'getLinkURL()'
);
$this->assertSame(
'/m/index.php?title=' . $name . '&' . $queryString,
$title->getLinkURL( $query ),
'getLinkURL( array )'
);
$this->assertSame(
'/m/index.php?title=' . $name . '&' . $queryString,
$title->getLinkURL( $queryString ),
'getLinkURL( string )'
);
$this->assertSame(
'//m.xx.wiki.test/wiki/' . $name,
$title->getLinkURL( [], false, PROTO_RELATIVE ),
'getLinkURL() with PROTO_RELATIVE'
);
$this->assertSame(
'http://m.xx.wiki.test/wiki/' . $name,
$title->getLinkURL( [], false, PROTO_CURRENT ),
'getLinkURL() with PROTO_CURRENT'
);
$this->assertSame(
'https://m.xx.wiki.test/wiki/' . $name,
$title->getLinkURL( [], false, PROTO_HTTPS ),
'getLinkURL() with PROTO_HTTPS'
);
$this->assertSame(
'https://xx.wiki.test/wiki/' . $name,
$title->getLinkURL( [], false, PROTO_CANONICAL ),
'getLinkURL() with PROTO_CANONICAL'
);
$this->assertSame(
'http://app23.internal/wiki/' . $name,
$title->getLinkURL( [], false, PROTO_INTERNAL ),
'getLinkURL() with PROTO_INTERNAL'
);
$this->assertSame(
'http://app23.internal/m/index.php?title=' . $name . '&' . $queryString,
$title->getLinkURL( $query, false, PROTO_INTERNAL ),
'getLinkURL( array ) with PROTO_INTERNAL'
);
// Test getInternalURL()
$this->assertSame(
'http://app23.internal/wiki/' . $name,
$title->getInternalURL(),
'getInternalURL()'
);
$this->assertSame(
'http://app23.internal/m/index.php?title=' . $name . '&' . $queryString,
$title->getInternalURL( $query ),
'getInternalURL( array )'
);
$this->assertSame(
'http://app23.internal/m/index.php?title=' . $name . '&' . $queryString,
$title->getInternalURL( $queryString ),
'getInternalURL( string )'
);
// Test getCanonicalURL()
$this->assertSame(
'https://xx.wiki.test/wiki/' . $name,
$title->getCanonicalURL(),
'getCanonicalURL()'
);
$this->assertSame(
'https://xx.wiki.test/m/index.php?title=' . $name . '&' . $queryString,
$title->getCanonicalURL( $query ),
'getCanonicalURL( array )'
);
$this->assertSame(
'https://xx.wiki.test/m/index.php?title=' . $name . '&' . $queryString,
$title->getCanonicalURL( $queryString ),
'getCanonicalURL( string )'
);
}
public function testUrlsWithActionPath() {
$title = Title::makeTitle( NS_USER, 'Göatee' );
$name = $title->getPrefixedURL();
$query1 = [ 'action' => 'edit' ];
$query2 = [ 'x' => 'one two', 'y' => '#' ];
$queryString = 'x=one+two&y=%23';
// Test getLocalURL()
$this->assertSame(
'/m/edit/' . $name,
$title->getLocalURL( $query1 ),
'getLocalURL( array )'
);
$this->assertSame(
'/m/edit/' . $name . '?' . $queryString,
$title->getLocalURL( $query1 + $query2 ),
'getLocalURL( array + array )'
);
// Test getFullURL()
$this->assertSame(
'//m.xx.wiki.test/m/edit/' . $name . '?' . $queryString,
$title->getFullURL( $query1 + $query2 ),
'getFullURL( array )'
);
// Test getFullUrlForRedirect()
// Note that it uses PROTO_CURRENT per default, which is 'http' for tests
$this->assertSame(
'http://m.xx.wiki.test/m/edit/' . $name . '?' . $queryString,
$title->getFullUrlForRedirect( $query1 + $query2 ),
'getFullUrlForRedirect( array )'
);
// Test getLinkURL()
$this->assertSame(
'/m/edit/' . $name . '?' . $queryString,
$title->getLinkURL( $query1 + $query2 ),
'getLinkURL( array + array )'
);
// Test getInternalURL()
$this->assertSame(
'http://app23.internal/m/edit/' . $name . '?' . $queryString,
$title->getInternalURL( $query1 + $query2 ),
'getInternalURL( array )'
);
// Test getCanonicalURL()
$this->assertSame(
'https://xx.wiki.test/m/edit/' . $name . '?' . $queryString,
$title->getCanonicalURL( $query1 + $query2 ),
'getCanonicalURL( array )'
);
}
public function testUrlsWithVariantPath() {
$title = Title::makeTitle( NS_USER, 'Göatee' );
$name = $title->getPrefixedURL();
$query1 = [ 'variant' => 'en-x-piglatin' ];
$query2 = [ 'x' => 'one two', 'y' => '#' ];
$queryString = 'x=one+two&y=%23';
// Test getLocalURL()
$this->assertSame(
'/en-x-piglatin/' . $name,
$title->getLocalURL( $query1 ),
'getLocalURL( array )'
);
$this->assertSame( // NOTE: this could as well apply the variant path
'/m/index.php?title=' . $name . '&variant=en-x-piglatin&' . $queryString,
$title->getLocalURL( $query1 + $query2 ),
'getLocalURL( array + array )'
);
// Test getFullURL()
$this->assertSame(
'//m.xx.wiki.test/en-x-piglatin/' . $name,
$title->getFullURL( $query1 ),
'getFullURL( array )'
);
// Test getFullUrlForRedirect()
// Note that it uses PROTO_CURRENT per default, which is 'http' for tests
$this->assertSame(
'http://m.xx.wiki.test/en-x-piglatin/' . $name,
$title->getFullUrlForRedirect( $query1 ),
'getFullUrlForRedirect( array )'
);
// Test getLinkURL()
$this->assertSame(
'/en-x-piglatin/' . $name,
$title->getLinkURL( $query1 ),
'getLinkURL( array + array )'
);
// Test getInternalURL()
$this->assertSame(
'http://app23.internal/en-x-piglatin/' . $name,
$title->getInternalURL( $query1 ),
'getInternalURL( array )'
);
// Test getCanonicalURL()
$this->assertSame(
'https://xx.wiki.test/en-x-piglatin/' . $name,
$title->getCanonicalURL( $query1 ),
'getCanonicalURL( array )'
);
}
public function testUrlsForMainPage() {
$title = Title::newMainPage();
$name = $title->getPrefixedURL();
$query = [ 'x' => 'one two', 'y' => '#' ];
$queryString = 'x=one+two&y=%23';
// Test getLocalURL()
$this->assertSame(
'/',
$title->getLocalURL(),
'getLocalURL()'
);
$this->assertSame(
'/m/index.php?title=' . $name . '&' . $queryString,
$title->getLocalURL( $query ),
'getLocalURL( array )'
);
// Test getFullURL()
$this->assertSame(
'//m.xx.wiki.test/',
$title->getFullURL(),
'getFullURL()'
);
$this->assertSame(
'//m.xx.wiki.test/m/index.php?title=' . $name . '&' . $queryString,
$title->getFullURL( $query ),
'getFullURL( array )'
);
// Test getFullUrlForRedirect()
// Note that it uses PROTO_CURRENT per default, which is 'http' for tests
$this->assertSame(
'http://m.xx.wiki.test/',
$title->getFullUrlForRedirect(),
'getFullUrlForRedirect()'
);
$this->assertSame(
'http://m.xx.wiki.test/m/index.php?title=' . $name . '&' . $queryString,
$title->getFullUrlForRedirect( $query ),
'getFullUrlForRedirect( array )'
);
// Test getLinkURL()
$this->assertSame(
'/',
$title->getLinkURL(),
'getLinkURL()'
);
$this->assertSame(
'/m/index.php?title=' . $name . '&' . $queryString,
$title->getLinkURL( $query ),
'getLinkURL( array )'
);
// Test getInternalURL()
$this->assertSame(
'http://app23.internal/',
$title->getInternalURL(),
'getInternalURL()'
);
$this->assertSame(
'http://app23.internal/m/index.php?title=' . $name . '&' . $queryString,
$title->getInternalURL( $query ),
'getInternalURL( array )'
);
// Test getCanonicalURL()
$this->assertSame(
'https://xx.wiki.test/',
$title->getCanonicalURL(),
'getCanonicalURL()'
);
$this->assertSame(
'https://xx.wiki.test/m/index.php?title=' . $name . '&' . $queryString,
$title->getCanonicalURL( $query ),
'getCanonicalURL( array )'
);
}
public function testUrlsForTitleWithFragment() {
$title = Title::makeTitle( NS_USER, 'Göatee', 'Sectiön' );
$name = $title->getPrefixedURL();
$fragment = 'Secti.C3.B6n';
$query = [ 'x' => 'one two', 'y' => '#' ];
$queryString = 'x=one+two&y=%23';
// Test getLocalURL() ignores fragment
$this->assertSame(
'/wiki/' . $name,
$title->getLocalURL(),
'getLocalURL()'
);
$this->assertSame(
'/m/index.php?title=' . $name . '&' . $queryString,
$title->getLocalURL( $query ),
'getLocalURL( array )'
);
// Test getFullURL() includes fragment
$this->assertSame(
'//m.xx.wiki.test/wiki/' . $name . '#' . $fragment,
$title->getFullURL(),
'getFullURL()'
);
$this->assertSame(
'//m.xx.wiki.test/m/index.php?title=' . $name . '&' . $queryString . '#' . $fragment,
$title->getFullURL( $query ),
'getFullURL( array )'
);
$this->assertSame(
'https://xx.wiki.test/wiki/' . $name . '#' . $fragment,
$title->getFullURL( [], false, PROTO_CANONICAL ),
'getFullURL() with PROTO_CANONICAL'
);
// Test getFullUrlForRedirect() includes fragment
$this->assertSame(
'http://m.xx.wiki.test/wiki/' . $name . '#' . $fragment,
$title->getFullUrlForRedirect(),
'getFullUrlForRedirect()'
);
$this->assertSame(
'http://m.xx.wiki.test/m/index.php?title=' . $name . '&' . $queryString . '#' . $fragment,
$title->getFullUrlForRedirect( $query ),
'getFullUrlForRedirect( array )'
);
$this->assertSame(
'//m.xx.wiki.test/wiki/' . $name . '#' . $fragment,
$title->getFullUrlForRedirect( [], PROTO_RELATIVE ),
'getFullUrlForRedirect() with PROTO_RELATIVE'
);
// Test getLinkURL() includes fragment
$this->assertSame(
'/wiki/' . $name . '#' . $fragment,
$title->getLinkURL(),
'getLinkURL()'
);
$this->assertSame(
'/m/index.php?title=' . $name . '&' . $queryString . '#' . $fragment,
$title->getLinkURL( $query ),
'getLinkURL( array )'
);
$this->assertSame(
'//m.xx.wiki.test/wiki/' . $name . '#' . $fragment,
$title->getLinkURL( [], false, PROTO_RELATIVE ),
'getLinkURL() with PROTO_RELATIVE'
);
// Test getInternalURL() ignores fragment
$this->assertSame(
'http://app23.internal/wiki/' . $name,
$title->getInternalURL(),
'getInternalURL()'
);
$this->assertSame(
'http://app23.internal/m/index.php?title=' . $name . '&' . $queryString,
$title->getInternalURL( $query ),
'getInternalURL( array )'
);
// Test getCanonicalURL() includes fragment
$this->assertSame(
'https://xx.wiki.test/wiki/' . $name . '#' . $fragment,
$title->getCanonicalURL(),
'getCanonicalURL()'
);
$this->assertSame(
'https://xx.wiki.test/m/index.php?title=' . $name . '&' . $queryString . '#' . $fragment,
$title->getCanonicalURL( $query ),
'getCanonicalURL( array )'
);
// Test $wgFragmentMode
$this->setMwGlobals( 'wgFragmentMode', [ 'html5', 'legacy' ] );
$fragment = 'Sectiön';
$this->assertSame(
'//m.xx.wiki.test/wiki/' . $name . '#' . $fragment,
$title->getFullURL(),
'getFullURL()'
);
$this->assertSame(
'/wiki/' . $name . '#' . $fragment,
$title->getLinkURL(),
'getLinkURL()'
);
}
public function testUrlsWithFragmentOnly() {
$title = Title::makeTitle( NS_MAIN, '', 'Jümp' );
$fragment = Sanitizer::escapeIdForLink( 'Jümp' );
$query = [ 'x' => 'one two', 'y' => '#' ];
$queryString = 'x=one+two&y=%23';
// Test getLocalURL() ignores fragment
$this->assertSame( // NOTE: not useful, may change!
'/wiki/',
$title->getLocalURL(),
'getLocalURL()'
);
$this->assertSame( // NOTE: not useful, may change!
'/m/index.php?title=&' . $queryString,
$title->getLocalURL( $query ),
'getLocalURL( array )'
);
// Test getFullURL() includes fragment
$this->assertSame( // NOTE: not useful, may change!
'//m.xx.wiki.test/wiki/#' . $fragment,
$title->getFullURL(),
'getFullURL()'
);
$this->assertSame( // NOTE: not useful, may change!
'//m.xx.wiki.test/m/index.php?title=&' . $queryString . '#' . $fragment,
$title->getFullURL( $query ),
'getFullURL( array )'
);
$this->assertSame( // NOTE: not useful, may change!
'https://xx.wiki.test/wiki/#' . $fragment,
$title->getFullURL( [], false, PROTO_CANONICAL ),
'getFullURL() with PROTO_CANONICAL'
);
// Test getFullUrlForRedirect() includes fragment
$this->assertSame( // NOTE: not useful, may change!
'http://m.xx.wiki.test/wiki/#' . $fragment,
$title->getFullUrlForRedirect(),
'getFullUrlForRedirect()'
);
$this->assertSame( // NOTE: not useful, may change!
'http://m.xx.wiki.test/m/index.php?title=&' . $queryString . '#' . $fragment,
$title->getFullUrlForRedirect( $query ),
'getFullUrlForRedirect( array )'
);
$this->assertSame( // NOTE: not useful, may change!
'//m.xx.wiki.test/wiki/#' . $fragment,
$title->getFullUrlForRedirect( [], PROTO_RELATIVE ),
'getFullUrlForRedirect() with PROTO_RELATIVE'
);
// Test getLinkURL()
$this->assertSame( // NOTE: this is the one useful way to handle a fragment jump
'#' . $fragment,
$title->getLinkURL(),
'getLinkURL()'
);
$this->assertSame(
'#' . $fragment, // NOTE: not useful, may change!
$title->getLinkURL( $query ),
'getLinkURL( array )'
);
$this->assertSame( // NOTE: not useful, may change!
'//m.xx.wiki.test/wiki/#' . $fragment,
$title->getLinkURL( [], false, PROTO_RELATIVE ),
'getLinkURL() with PROTO_RELATIVE'
);
$this->assertSame( // NOTE: not useful, may change!
'https://xx.wiki.test/m/index.php?title=&' . $queryString . '#' . $fragment,
$title->getLinkURL( $query, false, PROTO_CANONICAL ),
'getLinkURL() with PROTO_RELATIVE'
);
// Test getInternalURL() ignores fragment
$this->assertSame( // NOTE: not useful, may change!
'http://app23.internal/wiki/',
$title->getInternalURL(),
'getInternalURL()'
);
$this->assertSame( // NOTE: not useful, may change!
'http://app23.internal/m/index.php?title=&' . $queryString,
$title->getInternalURL( $query ),
'getInternalURL( array )'
);
// Test getCanonicalURL() includes fragment
$this->assertSame( // NOTE: not useful, may change!
'https://xx.wiki.test/wiki/#' . $fragment,
$title->getCanonicalURL(),
'getCanonicalURL()'
);
$this->assertSame( // NOTE: not useful, may change!
'https://xx.wiki.test/m/index.php?title=&' . $queryString . '#' . $fragment,
$title->getCanonicalURL( $query ),
'getCanonicalURL( array )'
);
}
public function testUrlsForUnknownInterwiki() {
// the "xyzzy" prefix is not known
$title = Title::makeTitle( NS_MAIN, 'Foobär', '', 'xyzzy' );
$name = $title->getPrefixedURL();
$query = [ 'x' => 'one two', 'y' => '#' ];
$queryString = 'x=one+two&y=%23';
// Test getLocalURL()
$this->assertSame(
'/wiki/' . $name,
$title->getLocalURL(),
'getLocalURL()'
);
$this->assertSame(
'/m/index.php?title=' . $name . '&' . $queryString,
$title->getLocalURL( $query ),
'getLocalURL( array )'
);
// Test getFullURL()
$this->assertSame(
'//m.xx.wiki.test/wiki/' . $name,
$title->getFullURL(),
'getFullURL()'
);
$this->assertSame(
'//m.xx.wiki.test/m/index.php?title=' . $name . '&' . $queryString,
$title->getFullURL( $query ),
'getFullURL( array )'
);
$this->assertSame(
'https://m.xx.wiki.test/wiki/' . $name,
$title->getFullURL( [], false, PROTO_HTTPS ),
'getFullURL( array ) with PROTO_HTTPS'
);
// Test getFullUrlForRedirect()
// Note that it uses PROTO_CURRENT per default, which is 'http' for tests
$this->assertSame(
'http://m.xx.wiki.test/wiki/Special:GoToInterwiki/' . $name,
$title->getFullUrlForRedirect(),
'getFullUrlForRedirect()'
);
$this->assertSame(
'http://m.xx.wiki.test/m/index.php?title=Special:GoToInterwiki/'
. $name . '&' . $queryString,
$title->getFullUrlForRedirect( $query ),
'getFullUrlForRedirect( array )'
);
// Test getLinkURL()
$this->assertSame( // NOTE: could also just be '/wiki/...'
'//m.xx.wiki.test/wiki/' . $name,
$title->getLinkURL(),
'getLinkURL()'
);
$this->assertSame( // NOTE: could also just be '/m/...'
'//m.xx.wiki.test/m/index.php?title=' . $name . '&' . $queryString,
$title->getLinkURL( $query ),
'getLinkURL( array )'
);
// Test getInternalURL()
$this->assertSame(
'http://app23.internal/wiki/' . $name,
$title->getInternalURL(),
'getInternalURL()'
);
$this->assertSame(
'http://app23.internal/m/index.php?title=' . $name . '&' . $queryString,
$title->getInternalURL( $query ),
'getInternalURL( array )'
);
// Test getCanonicalURL()
$this->assertSame(
'https://xx.wiki.test/wiki/' . $name,
$title->getCanonicalURL(),
'getCanonicalURL()'
);
$this->assertSame(
'https://xx.wiki.test/m/index.php?title=' . $name . '&' . $queryString,
$title->getCanonicalURL( $query ),
'getCanonicalURL( array )'
);
}
public function testUrlsForExternalInterwikiWithFragment() {
// the "acme" prefix is a known external interwiki prefix
$title = Title::makeTitle( NS_MAIN, 'fröbnitz/foo+bar', 'Sectiön', 'acme' );
$section = 'Sectiön';
// NOTE: The "/" should remain unencoded even in interwiki links
$name = wfUrlencode( $title->getDBkey() );
$query = [ 'x' => 'one two+three', 'y' => '#' ];
$queryString = 'x=one+two%2Bthree&y=%23';
// Test getLocalURL()
$this->assertSame(
'https://acme.test/' . $name,
$title->getLocalURL(),
'getLocalURL()'
);
$this->assertSame(
'https://acme.test/' . $name . '?' . $queryString,
$title->getLocalURL( $query ),
'getLocalURL( array )'
);
// Test getFullURL()
$this->assertSame(
'https://acme.test/' . $name . '#' . $section,
$title->getFullURL(),
'getFullURL()'
);
$this->assertSame(
'https://acme.test/' . $name . '?' . $queryString . '#' . $section,
$title->getFullURL( $query ),
'getFullURL( array )'
);
$this->assertSame( // should not trigger action path
'https://acme.test/' . $name . '?action=edit#' . $section,
$title->getFullURL( [ 'action' => 'edit' ] ),
'getFullURL( array )'
);
$this->assertSame( // should not trigger variant path
'https://acme.test/' . $name . '?variant=en-x-piglatin#' . $section,
$title->getFullURL( [ 'variant' => 'en-x-piglatin' ] ),
'getFullURL( array )'
);
// Test getFullUrlForRedirect()
// Note that it uses PROTO_CURRENT per default, which is 'http' for tests
$this->assertSame(
'http://m.xx.wiki.test/wiki/Special:GoToInterwiki/acme:' . $name,
$title->getFullUrlForRedirect(),
'getFullUrlForRedirect()'
);
$this->assertSame(
'http://m.xx.wiki.test/m/index.php?title=Special:GoToInterwiki/acme:'
. $name . '&' . $queryString,
$title->getFullUrlForRedirect( $query ),
'getFullUrlForRedirect( array )'
);
// Test getLinkURL() includes fragment
$this->assertSame(
'https://acme.test/' . $name . '#' . $section,
$title->getLinkURL(),
'getLinkURL()'
);
$this->assertSame(
'https://acme.test/' . $name . '?' . $queryString . '#' . $section,
$title->getLinkURL( $query ),
'getLinkURL( array )'
);
// Test getInternalURL() ignores fragment
$this->assertSame( // NOTE: the current behavior is just wrong.
'http://app23.internalhttps//acme.test/' . $name,
$title->getInternalURL(),
'getInternalURL()'
);
$this->assertSame( // NOTE: the current behavior is just wrong.
'http://app23.internalhttps//acme.test/' . $name . '?' . $queryString,
$title->getInternalURL( $query ),
'getInternalURL( array )'
);
// Test getCanonicalURL() includes fragment
$this->assertSame(
'https://acme.test/' . $name . '#' . $section,
$title->getCanonicalURL(),
'getCanonicalURL()'
);
$this->assertSame(
'https://acme.test/' . $name . '?' . $queryString . '#' . $section,
$title->getCanonicalURL( $query ),
'getCanonicalURL( array )'
);
// Test $wgFragmentMode
$this->setMwGlobals( 'wgFragmentMode', [ 'html5', 'legacy' ] );
$this->setMwGlobals( 'wgExternalInterwikiFragmentMode', 'legacy' );
$section = 'Secti.C3.B6n';
$this->assertSame(
'https://acme.test/' . $name . '#' . $section,
$title->getFullURL(),
'getFullURL()'
);
$this->assertSame(
'https://acme.test/' . $name . '#' . $section,
$title->getLinkURL(),
'getLinkURL()'
);
}
public function testUrlsForLocalInterwikiWithFragment() {
// the "yy" prefix is a known local interwiki prefix
$title = Title::makeTitle( NS_MAIN, 'fröbnitz', 'Sectiön', 'yy' );
$name = wfUrlencode( $title->getDBkey() );
// local interwikis use $wgFragmentMode, not $wgExternalInterwikiFragmentMode
$section = 'Secti.C3.B6n';
$query = [ 'x' => 'one two', 'y' => '#' ];
$queryString = 'x=one+two&y=%23';
// Test getLocalURL()
$this->assertSame(
'//yy.wiki.test/wiki/' . $name,
$title->getLocalURL(),
'getLocalURL()'
);
$this->assertSame(
'//yy.wiki.test/wiki/' . $name . '?' . $queryString,
$title->getLocalURL( $query ),
'getLocalURL( array )'
);
// Test getFullURL()
$this->assertSame(
'//yy.wiki.test/wiki/' . $name . '#' . $section,
$title->getFullURL(),
'getFullURL()'
);
$this->assertSame(
'//yy.wiki.test/wiki/' . $name . '?' . $queryString . '#' . $section,
$title->getFullURL( $query ),
'getFullURL( array )'
);
$this->assertSame(
'https://yy.wiki.test/wiki/' . $name . '#' . $section,
$title->getFullURL( [], false, PROTO_HTTPS ),
'getFullURL( array ) with PROTO_HTTPS'
);
$this->assertSame(
'https://yy.wiki.test/wiki/' . $name . '#' . $section,
$title->getFullURL( [], false, PROTO_CANONICAL ),
'getFullURL( array ) with PROTO_CANONICAL'
);
$this->assertSame(
'http://yy.wiki.test/wiki/' . $name . '#' . $section,
$title->getFullURL( [], false, PROTO_INTERNAL ),
'getFullURL( array ) with PROTO_INTERNAL'
);
$this->assertSame( // NOTE: could as well use action path
'//yy.wiki.test/wiki/' . $name . '?action=edit#' . $section,
$title->getFullURL( [ 'action' => 'edit' ] ),
'getFullURL( array )'
);
$this->assertSame( // NOTE: could as well use variant path
'//yy.wiki.test/wiki/' . $name . '?variant=en-x-piglatin#' . $section,
$title->getFullURL( [ 'variant' => 'en-x-piglatin' ] ),
'getFullURL( array )'
);
// Test getFullUrlForRedirect()
// Note that it uses PROTO_CURRENT per default, which is 'http' for tests
$this->assertSame(
'http://m.xx.wiki.test/wiki/Special:GoToInterwiki/yy:' . $name,
$title->getFullUrlForRedirect(),
'getFullUrlForRedirect()'
);
$this->assertSame(
'http://m.xx.wiki.test/m/index.php?title=Special:GoToInterwiki/yy:'
. $name . '&' . $queryString,
$title->getFullUrlForRedirect( $query ),
'getFullUrlForRedirect( array )'
);
// Test getLinkURL() includes fragment
$this->assertSame(
'//yy.wiki.test/wiki/' . $name . '#' . $section,
$title->getLinkURL(),
'getLinkURL()'
);
$this->assertSame(
'//yy.wiki.test/wiki/' . $name . '?' . $queryString . '#' . $section,
$title->getLinkURL( $query ),
'getLinkURL( array )'
);
$this->assertSame(
'https://yy.wiki.test/wiki/' . $name . '?' . $queryString . '#' . $section,
$title->getLinkURL( $query, false, PROTO_CANONICAL ),
'getLinkURL( array ) with PROTO_CANONICAL'
);
$this->assertSame(
'http://yy.wiki.test/wiki/' . $name . '?' . $queryString . '#' . $section,
$title->getLinkURL( $query, false, PROTO_INTERNAL ),
'getLinkURL( array ) with PROTO_INTERNAL'
);
$this->assertSame(
'https://yy.wiki.test/wiki/' . $name . '?' . $queryString . '#' . $section,
$title->getLinkURL( $query, false, PROTO_HTTPS ),
'getLinkURL( array ) with PROTO_HTTPS'
);
// Test getInternalURL() ignores fragment
$this->assertSame( // NOTE: the current behavior is just wrong.
'http://app23.internal//yy.wiki.test/wiki/' . $name,
$title->getInternalURL(),
'getInternalURL()'
);
$this->assertSame( // NOTE: the current behavior is just wrong.
'http://app23.internal//yy.wiki.test/wiki/' . $name . '?' . $queryString,
$title->getInternalURL( $query ),
'getInternalURL( array )'
);
// Test getCanonicalURL() includes fragment
$this->assertSame(
'https://yy.wiki.test/wiki/' . $name . '#' . $section,
$title->getCanonicalURL(),
'getCanonicalURL()'
);
$this->assertSame(
'https://yy.wiki.test/wiki/' . $name . '?' . $queryString . '#' . $section,
$title->getCanonicalURL( $query ),
'getCanonicalURL( array )'
);
// Test $wgFragmentMode
$this->setMwGlobals( 'wgFragmentMode', [ 'html5', 'legacy' ] );
$this->setMwGlobals( 'wgExternalInterwikiFragmentMode', 'legacy' );
$section = 'Sectiön';
$this->assertSame(
'//yy.wiki.test/wiki/' . $name . '#' . $section,
$title->getFullURL(),
'getFullURL()'
);
$this->assertSame(
'//yy.wiki.test/wiki/' . $name . '#' . $section,
$title->getLinkURL(),
'getLinkURL()'
);
}
public function testUrlsWithHttpsPort() {
$title = Title::makeTitle( NS_USER, 'Göatee' );
$name = $title->getPrefixedURL();
// NOTE: $wgHttpsPort is only supported if $wgCanonicalServer does not use HTTPS
$this->setMwGlobals( 'wgCanonicalServer', 'http://xx.wiki.test' );
$this->setMwGlobals( 'wgHttpsPort', '4444' );
// Test getFullURL()
$this->assertSame(
'//m.xx.wiki.test/wiki/' . $name,
$title->getFullURL( [], false, PROTO_RELATIVE ),
'getFullURL() with PROTO_RELATIVE'
);
$this->assertSame(
'http://xx.wiki.test/wiki/' . $name,
$title->getFullURL( [], false, PROTO_CANONICAL ),
'getFullURL() with PROTO_CANONICAL'
);
$this->assertSame(
'http://m.xx.wiki.test/wiki/' . $name,
$title->getFullURL( [], false, PROTO_HTTP ),
'getFullURL() with PROTO_HTTP'
);
$this->assertSame(
'https://m.xx.wiki.test:4444/wiki/' . $name,
$title->getFullURL( [], false, PROTO_HTTPS ),
'getFullURL() with PROTO_HTTP'
);
$this->assertSame(
'http://app23.internal/wiki/' . $name,
$title->getFullURL( [], false, PROTO_INTERNAL ),
'getFullURL() with PROTO_INTERNAL'
);
// Test getFullUrlForRedirect()
$this->assertSame(
'//m.xx.wiki.test/wiki/' . $name,
$title->getFullUrlForRedirect( [], PROTO_RELATIVE ),
'getFullUrlForRedirect() with PROTO_RELATIVE'
);
$this->assertSame(
'https://m.xx.wiki.test:4444/wiki/' . $name,
$title->getFullUrlForRedirect( [], PROTO_HTTPS ),
'getFullUrlForRedirect() with PROTO_HTTPS'
);
// Test getLinkURL()
$this->assertSame(
'//m.xx.wiki.test/wiki/' . $name,
$title->getLinkURL( [], false, PROTO_RELATIVE ),
'getLinkURL() with PROTO_RELATIVE'
);
$this->assertSame(
'https://m.xx.wiki.test:4444/wiki/' . $name,
$title->getLinkURL( [], false, PROTO_HTTPS ),
'getLinkURL() with PROTO_HTTPS'
);
$this->assertSame(
'http://xx.wiki.test/wiki/' . $name,
$title->getLinkURL( [], false, PROTO_CANONICAL ),
'getLinkURL() with PROTO_CANONICAL'
);
$this->assertSame(
'http://app23.internal/wiki/' . $name,
$title->getLinkURL( [], false, PROTO_INTERNAL ),
'getLinkURL() with PROTO_INTERNAL'
);
// Test getInternalURL()
$this->assertSame(
'http://app23.internal/wiki/' . $name,
$title->getInternalURL(),
'getInternalURL()'
);
// Test getCanonicalURL()
$this->assertSame(
'http://xx.wiki.test/wiki/' . $name,
$title->getCanonicalURL(),
'getCanonicalURL()'
);
}
}