summaryrefslogtreecommitdiff
path: root/www/wiki/tests/phpunit/includes/api/ApiMoveTest.php
diff options
context:
space:
mode:
Diffstat (limited to 'www/wiki/tests/phpunit/includes/api/ApiMoveTest.php')
-rw-r--r--www/wiki/tests/phpunit/includes/api/ApiMoveTest.php393
1 files changed, 393 insertions, 0 deletions
diff --git a/www/wiki/tests/phpunit/includes/api/ApiMoveTest.php b/www/wiki/tests/phpunit/includes/api/ApiMoveTest.php
new file mode 100644
index 00000000..fb697ffd
--- /dev/null
+++ b/www/wiki/tests/phpunit/includes/api/ApiMoveTest.php
@@ -0,0 +1,393 @@
+<?php
+
+/**
+ * @group API
+ * @group Database
+ * @group medium
+ *
+ * @covers ApiMove
+ */
+class ApiMoveTest extends ApiTestCase {
+ /**
+ * @param string $from Prefixed name of source
+ * @param string $to Prefixed name of destination
+ * @param string $id Page id of the page to move
+ * @param array|string|null $opts Options: 'noredirect' to expect no redirect
+ */
+ protected function assertMoved( $from, $to, $id, $opts = null ) {
+ $opts = (array)$opts;
+
+ $fromTitle = Title::newFromText( $from );
+ $toTitle = Title::newFromText( $to );
+
+ $this->assertTrue( $toTitle->exists(),
+ "Destination {$toTitle->getPrefixedText()} does not exist" );
+
+ if ( in_array( 'noredirect', $opts ) ) {
+ $this->assertFalse( $fromTitle->exists(),
+ "Source {$fromTitle->getPrefixedText()} exists" );
+ } else {
+ $this->assertTrue( $fromTitle->exists(),
+ "Source {$fromTitle->getPrefixedText()} does not exist" );
+ $this->assertTrue( $fromTitle->isRedirect(),
+ "Source {$fromTitle->getPrefixedText()} is not a redirect" );
+
+ $target = Revision::newFromTitle( $fromTitle )->getContent()->getRedirectTarget();
+ $this->assertSame( $toTitle->getPrefixedText(), $target->getPrefixedText() );
+ }
+
+ $this->assertSame( $id, $toTitle->getArticleId() );
+ }
+
+ /**
+ * Shortcut function to create a page and return its id.
+ *
+ * @param string $name Page to create
+ * @return int ID of created page
+ */
+ protected function createPage( $name ) {
+ return $this->editPage( $name, 'Content' )->value['revision']->getPage();
+ }
+
+ public function testFromWithFromid() {
+ $this->setExpectedException( ApiUsageException::class,
+ 'The parameters "from" and "fromid" can not be used together.' );
+
+ $this->doApiRequestWithToken( [
+ 'action' => 'move',
+ 'from' => 'Some page',
+ 'fromid' => 123,
+ 'to' => 'Some other page',
+ ] );
+ }
+
+ public function testMove() {
+ $name = ucfirst( __FUNCTION__ );
+
+ $id = $this->createPage( $name );
+
+ $res = $this->doApiRequestWithToken( [
+ 'action' => 'move',
+ 'from' => $name,
+ 'to' => "$name 2",
+ ] );
+
+ $this->assertMoved( $name, "$name 2", $id );
+ $this->assertArrayNotHasKey( 'warnings', $res[0] );
+ }
+
+ public function testMoveById() {
+ $name = ucfirst( __FUNCTION__ );
+
+ $id = $this->createPage( $name );
+
+ $res = $this->doApiRequestWithToken( [
+ 'action' => 'move',
+ 'fromid' => $id,
+ 'to' => "$name 2",
+ ] );
+
+ $this->assertMoved( $name, "$name 2", $id );
+ $this->assertArrayNotHasKey( 'warnings', $res[0] );
+ }
+
+ public function testMoveNonexistent() {
+ $this->setExpectedException( ApiUsageException::class,
+ "The page you specified doesn't exist." );
+
+ $this->doApiRequestWithToken( [
+ 'action' => 'move',
+ 'from' => 'Nonexistent page',
+ 'to' => 'Different page'
+ ] );
+ }
+
+ public function testMoveNonexistentId() {
+ $this->setExpectedException( ApiUsageException::class,
+ 'There is no page with ID 2147483647.' );
+
+ $this->doApiRequestWithToken( [
+ 'action' => 'move',
+ 'fromid' => pow( 2, 31 ) - 1,
+ 'to' => 'Different page',
+ ] );
+ }
+
+ public function testMoveToInvalidPageName() {
+ $this->setExpectedException( ApiUsageException::class, 'Bad title "[".' );
+
+ $name = ucfirst( __FUNCTION__ );
+ $id = $this->createPage( $name );
+
+ try {
+ $this->doApiRequestWithToken( [
+ 'action' => 'move',
+ 'from' => $name,
+ 'to' => '[',
+ ] );
+ } finally {
+ $this->assertSame( $id, Title::newFromText( $name )->getArticleId() );
+ }
+ }
+
+ // @todo File moving
+
+ public function testPingLimiter() {
+ global $wgRateLimits;
+
+ $this->setExpectedException( ApiUsageException::class,
+ "You've exceeded your rate limit. Please wait some time and try again." );
+
+ $name = ucfirst( __FUNCTION__ );
+
+ $this->setMwGlobals( 'wgMainCacheType', 'hash' );
+
+ $this->stashMwGlobals( 'wgRateLimits' );
+ $wgRateLimits['move'] = [ '&can-bypass' => false, 'user' => [ 1, 60 ] ];
+
+ $id = $this->createPage( $name );
+
+ $res = $this->doApiRequestWithToken( [
+ 'action' => 'move',
+ 'from' => $name,
+ 'to' => "$name 2",
+ ] );
+
+ $this->assertMoved( $name, "$name 2", $id );
+ $this->assertArrayNotHasKey( 'warnings', $res[0] );
+
+ try {
+ $this->doApiRequestWithToken( [
+ 'action' => 'move',
+ 'from' => "$name 2",
+ 'to' => "$name 3",
+ ] );
+ } finally {
+ $this->assertSame( $id, Title::newFromText( "$name 2" )->getArticleId() );
+ $this->assertFalse( Title::newFromText( "$name 3" )->exists(),
+ "\"$name 3\" should not exist" );
+ }
+ }
+
+ public function testTagsNoPermission() {
+ $this->setExpectedException( ApiUsageException::class,
+ 'You do not have permission to apply change tags along with your changes.' );
+
+ $name = ucfirst( __FUNCTION__ );
+
+ ChangeTags::defineTag( 'custom tag' );
+
+ $this->setGroupPermissions( 'user', 'applychangetags', false );
+
+ $id = $this->createPage( $name );
+
+ try {
+ $this->doApiRequestWithToken( [
+ 'action' => 'move',
+ 'from' => $name,
+ 'to' => "$name 2",
+ 'tags' => 'custom tag',
+ ] );
+ } finally {
+ $this->assertSame( $id, Title::newFromText( $name )->getArticleId() );
+ $this->assertFalse( Title::newFromText( "$name 2" )->exists(),
+ "\"$name 2\" should not exist" );
+ }
+ }
+
+ public function testSelfMove() {
+ $this->setExpectedException( ApiUsageException::class,
+ 'The title is the same; cannot move a page over itself.' );
+
+ $name = ucfirst( __FUNCTION__ );
+ $this->createPage( $name );
+
+ $this->doApiRequestWithToken( [
+ 'action' => 'move',
+ 'from' => $name,
+ 'to' => $name,
+ ] );
+ }
+
+ public function testMoveTalk() {
+ $name = ucfirst( __FUNCTION__ );
+
+ $id = $this->createPage( $name );
+ $talkId = $this->createPage( "Talk:$name" );
+
+ $res = $this->doApiRequestWithToken( [
+ 'action' => 'move',
+ 'from' => $name,
+ 'to' => "$name 2",
+ 'movetalk' => '',
+ ] );
+
+ $this->assertMoved( $name, "$name 2", $id );
+ $this->assertMoved( "Talk:$name", "Talk:$name 2", $talkId );
+
+ $this->assertArrayNotHasKey( 'warnings', $res[0] );
+ }
+
+ public function testMoveTalkFailed() {
+ $name = ucfirst( __FUNCTION__ );
+
+ $id = $this->createPage( $name );
+ $talkId = $this->createPage( "Talk:$name" );
+ $talkDestinationId = $this->createPage( "Talk:$name 2" );
+
+ $res = $this->doApiRequestWithToken( [
+ 'action' => 'move',
+ 'from' => $name,
+ 'to' => "$name 2",
+ 'movetalk' => '',
+ ] );
+
+ $this->assertMoved( $name, "$name 2", $id );
+ $this->assertSame( $talkId, Title::newFromText( "Talk:$name" )->getArticleId() );
+ $this->assertSame( $talkDestinationId,
+ Title::newFromText( "Talk:$name 2" )->getArticleId() );
+ $this->assertSame( [ [
+ 'message' => 'articleexists',
+ 'params' => [],
+ 'code' => 'articleexists',
+ 'type' => 'error',
+ ] ], $res[0]['move']['talkmove-errors'] );
+
+ $this->assertArrayNotHasKey( 'warnings', $res[0] );
+ }
+
+ public function testMoveSubpages() {
+ global $wgNamespacesWithSubpages;
+
+ $name = ucfirst( __FUNCTION__ );
+
+ $this->stashMwGlobals( 'wgNamespacesWithSubpages' );
+ $wgNamespacesWithSubpages[NS_MAIN] = true;
+
+ $pages = [ $name, "$name/1", "$name/2", "Talk:$name", "Talk:$name/1", "Talk:$name/3" ];
+ $ids = [];
+ foreach ( array_merge( $pages, [ "$name/error", "$name 2/error" ] ) as $page ) {
+ $ids[$page] = $this->createPage( $page );
+ }
+
+ $res = $this->doApiRequestWithToken( [
+ 'action' => 'move',
+ 'from' => $name,
+ 'to' => "$name 2",
+ 'movetalk' => '',
+ 'movesubpages' => '',
+ ] );
+
+ foreach ( $pages as $page ) {
+ $this->assertMoved( $page, str_replace( $name, "$name 2", $page ), $ids[$page] );
+ }
+
+ $this->assertSame( $ids["$name/error"],
+ Title::newFromText( "$name/error" )->getArticleId() );
+ $this->assertSame( $ids["$name 2/error"],
+ Title::newFromText( "$name 2/error" )->getArticleId() );
+
+ $results = array_merge( $res[0]['move']['subpages'], $res[0]['move']['subpages-talk'] );
+ foreach ( $results as $arr ) {
+ if ( $arr['from'] === "$name/error" ) {
+ $this->assertSame( [ [
+ 'message' => 'articleexists',
+ 'params' => [],
+ 'code' => 'articleexists',
+ 'type' => 'error'
+ ] ], $arr['errors'] );
+ } else {
+ $this->assertSame( str_replace( $name, "$name 2", $arr['from'] ), $arr['to'] );
+ }
+ $this->assertCount( 2, $arr );
+ }
+
+ $this->assertArrayNotHasKey( 'warnings', $res[0] );
+ }
+
+ public function testMoveNoPermission() {
+ $this->setExpectedException( ApiUsageException::class,
+ 'You must be a registered user and [[Special:UserLogin|logged in]] to move a page.' );
+
+ $name = ucfirst( __FUNCTION__ );
+
+ $id = $this->createPage( $name );
+
+ $user = new User();
+
+ try {
+ $this->doApiRequestWithToken( [
+ 'action' => 'move',
+ 'from' => $name,
+ 'to' => "$name 2",
+ ], null, $user );
+ } finally {
+ $this->assertSame( $id, Title::newFromText( "$name" )->getArticleId() );
+ $this->assertFalse( Title::newFromText( "$name 2" )->exists(),
+ "\"$name 2\" should not exist" );
+ }
+ }
+
+ public function testSuppressRedirect() {
+ $name = ucfirst( __FUNCTION__ );
+
+ $id = $this->createPage( $name );
+
+ $res = $this->doApiRequestWithToken( [
+ 'action' => 'move',
+ 'from' => $name,
+ 'to' => "$name 2",
+ 'noredirect' => '',
+ ] );
+
+ $this->assertMoved( $name, "$name 2", $id, 'noredirect' );
+ $this->assertArrayNotHasKey( 'warnings', $res[0] );
+ }
+
+ public function testSuppressRedirectNoPermission() {
+ $name = ucfirst( __FUNCTION__ );
+
+ $this->setGroupPermissions( 'sysop', 'suppressredirect', false );
+
+ $id = $this->createPage( $name );
+
+ $res = $this->doApiRequestWithToken( [
+ 'action' => 'move',
+ 'from' => $name,
+ 'to' => "$name 2",
+ 'noredirect' => '',
+ ] );
+
+ $this->assertMoved( $name, "$name 2", $id );
+ $this->assertArrayNotHasKey( 'warnings', $res[0] );
+ }
+
+ public function testMoveSubpagesError() {
+ $name = ucfirst( __FUNCTION__ );
+
+ // Subpages are allowed in talk but not main
+ $idBase = $this->createPage( "Talk:$name" );
+ $idSub = $this->createPage( "Talk:$name/1" );
+
+ $res = $this->doApiRequestWithToken( [
+ 'action' => 'move',
+ 'from' => "Talk:$name",
+ 'to' => $name,
+ 'movesubpages' => '',
+ ] );
+
+ $this->assertMoved( "Talk:$name", $name, $idBase );
+ $this->assertSame( $idSub, Title::newFromText( "Talk:$name/1" )->getArticleId() );
+ $this->assertFalse( Title::newFromText( "$name/1" )->exists(),
+ "\"$name/1\" should not exist" );
+
+ $this->assertSame( [ 'errors' => [ [
+ 'message' => 'namespace-nosubpages',
+ 'params' => [ '' ],
+ 'code' => 'namespace-nosubpages',
+ 'type' => 'error',
+ ] ] ], $res[0]['move']['subpages'] );
+
+ $this->assertArrayNotHasKey( 'warnings', $res[0] );
+ }
+}