Rename JsonUnserial… to JsonDeserial…
[mediawiki.git] / tests / phpunit / includes / api / ApiDeleteTest.php
blob13c87ee0af8e32ea0ae84927e2dc5379f763ac5f
1 <?php
3 namespace MediaWiki\Tests\Api;
5 use IDBAccessObject;
6 use MediaWiki\MainConfigNames;
7 use MediaWiki\Title\Title;
8 use MediaWiki\User\User;
10 /**
11 * Tests for MediaWiki api.php?action=delete.
13 * @author Yifei He
15 * @group API
16 * @group Database
17 * @group medium
19 * @covers \ApiDelete
21 class ApiDeleteTest extends ApiTestCase {
23 protected function setUp(): void {
24 parent::setUp();
26 $this->overrideConfigValue( MainConfigNames::WatchlistExpiry, true );
29 public function testDelete() {
30 $title = Title::makeTitle( NS_HELP, 'TestDelete' );
32 // create new page
33 $this->editPage( $title, 'Some text' );
35 // test deletion
36 $apiResult = $this->doApiRequestWithToken( [
37 'action' => 'delete',
38 'title' => $title->getPrefixedText(),
39 ] )[0];
41 $this->assertArrayHasKey( 'delete', $apiResult );
42 $this->assertArrayHasKey( 'title', $apiResult['delete'] );
43 $this->assertSame( $title->getPrefixedText(), $apiResult['delete']['title'] );
44 $this->assertArrayHasKey( 'logid', $apiResult['delete'] );
46 $this->assertFalse( $title->exists( IDBAccessObject::READ_LATEST ) );
49 public function testBatchedDelete() {
50 $this->overrideConfigValue(
51 MainConfigNames::DeleteRevisionsBatchSize, 1
54 $title = Title::makeTitle( NS_HELP, 'TestBatchedDelete' );
55 for ( $i = 1; $i <= 3; $i++ ) {
56 $this->editPage( $title, "Revision $i" );
59 $apiResult = $this->doApiRequestWithToken( [
60 'action' => 'delete',
61 'title' => $title->getPrefixedText(),
62 ] )[0];
64 $this->assertArrayHasKey( 'delete', $apiResult );
65 $this->assertArrayHasKey( 'title', $apiResult['delete'] );
66 $this->assertSame( $title->getPrefixedText(), $apiResult['delete']['title'] );
67 $this->assertArrayHasKey( 'scheduled', $apiResult['delete'] );
68 $this->assertTrue( $apiResult['delete']['scheduled'] );
69 $this->assertArrayNotHasKey( 'logid', $apiResult['delete'] );
71 // Run the jobs
72 $this->runJobs();
74 $this->assertFalse( $title->exists( IDBAccessObject::READ_LATEST ) );
77 public function testDeleteNonexistent() {
78 $this->expectApiErrorCode( 'missingtitle' );
80 $this->doApiRequestWithToken( [
81 'action' => 'delete',
82 'title' => 'This page deliberately left nonexistent',
83 ] );
86 public function testDeleteAssociatedTalkPage() {
87 $title = Title::makeTitle( NS_HELP, 'TestDeleteAssociatedTalkPage' );
88 $talkPage = $title->getTalkPageIfDefined();
89 $this->editPage( $title, 'Some text' );
90 $this->editPage( $talkPage, 'Some text' );
91 $apiResult = $this->doApiRequestWithToken( [
92 'action' => 'delete',
93 'title' => $title->getPrefixedText(),
94 'deletetalk' => true,
95 ] )[0];
97 $this->assertSame( $title->getPrefixedText(), $apiResult['delete']['title'] );
98 $this->assertFalse( $talkPage->exists( IDBAccessObject::READ_LATEST ) );
101 public function testDeleteAssociatedTalkPageNonexistent() {
102 $title = Title::makeTitle( NS_HELP, 'TestDeleteAssociatedTalkPageNonexistent' );
103 $this->editPage( $title, 'Some text' );
104 $apiResult = $this->doApiRequestWithToken( [
105 'action' => 'delete',
106 'title' => $title->getPrefixedText(),
107 'deletetalk' => true,
108 ] )[0];
110 $this->assertSame( $title->getPrefixedText(), $apiResult['delete']['title'] );
111 $this->assertArrayHasKey( 'warnings', $apiResult );
114 public function testDeletionWithoutPermission() {
115 $this->expectApiErrorCode( 'permissiondenied' );
117 $title = Title::makeTitle( NS_HELP, 'TestDeletionWithoutPermission' );
119 // create new page
120 $this->editPage( $title, 'Some text' );
122 // test deletion without permission
123 try {
124 $user = new User();
125 $this->doApiRequest( [
126 'action' => 'delete',
127 'title' => $title->getPrefixedText(),
128 'token' => $user->getEditToken(),
129 ], null, null, $user );
130 } finally {
131 $this->assertTrue( $title->exists( IDBAccessObject::READ_LATEST ) );
135 public function testDeleteWithTag() {
136 $title = Title::makeTitle( NS_HELP, 'TestDeleteWithTag' );
138 $this->getServiceContainer()->getChangeTagsStore()->defineTag( 'custom tag' );
140 $this->editPage( $title, 'Some text' );
142 $this->doApiRequestWithToken( [
143 'action' => 'delete',
144 'title' => $title->getPrefixedText(),
145 'tags' => 'custom tag',
146 ] );
148 $this->assertFalse( $title->exists( IDBAccessObject::READ_LATEST ) );
150 $this->assertSame( 'custom tag', $this->getDb()->newSelectQueryBuilder()
151 ->select( 'ctd_name' )
152 ->from( 'logging' )
153 ->join( 'change_tag', null, 'ct_log_id = log_id' )
154 ->join( 'change_tag_def', null, 'ctd_id = ct_tag_id' )
155 ->where( [ 'log_namespace' => $title->getNamespace(), 'log_title' => $title->getDBkey(), ] )
156 ->caller( __METHOD__ )->fetchField() );
159 public function testDeleteWithoutTagPermission() {
160 $this->expectApiErrorCode( 'tags-apply-no-permission' );
162 $title = Title::makeTitle( NS_HELP, 'TestDeleteWithoutTagPermission' );
164 $this->getServiceContainer()->getChangeTagsStore()->defineTag( 'custom tag' );
165 $this->overrideConfigValue(
166 MainConfigNames::RevokePermissions,
167 [ 'user' => [ 'applychangetags' => true ] ]
170 $this->editPage( $title, 'Some text' );
172 try {
173 $this->doApiRequestWithToken( [
174 'action' => 'delete',
175 'title' => $title->getPrefixedText(),
176 'tags' => 'custom tag',
177 ] );
178 } finally {
179 $this->assertTrue( $title->exists( IDBAccessObject::READ_LATEST ) );
183 public function testDeleteAbortedByHook() {
184 $this->expectApiErrorCode( 'delete-hook-aborted' );
186 $title = Title::makeTitle( NS_HELP, 'TestDeleteAbortedByHook' );
188 $this->editPage( $title, 'Some text' );
190 $this->setTemporaryHook( 'ArticleDelete',
191 static function () {
192 return false;
196 try {
197 $this->doApiRequestWithToken( [ 'action' => 'delete', 'title' => $title->getPrefixedText() ] );
198 } finally {
199 $this->assertTrue( $title->exists( IDBAccessObject::READ_LATEST ) );
203 public function testDeleteWatch() {
204 $title = Title::makeTitle( NS_HELP, 'TestDeleteWatch' );
205 $page = $this->getExistingTestPage( $title );
206 $performer = $this->getTestSysop()->getUser();
207 $watchlistManager = $this->getServiceContainer()->getWatchlistManager();
209 $this->assertFalse( $watchlistManager->isWatched( $performer, $page ) );
211 $res = $this->doApiRequestWithToken(
213 'action' => 'delete',
214 'title' => $title->getPrefixedText(),
215 'watch' => '',
216 'watchlistexpiry' => '99990123000000',
218 null,
219 $performer
221 $this->assertArrayHasKey( 'delete', $res[0] );
222 $page->clear();
224 $this->assertFalse( $page->exists() );
225 $this->assertTrue( $watchlistManager->isWatched( $performer, $page ) );
226 $this->assertTrue( $watchlistManager->isTempWatched( $performer, $page ) );
229 public function testDeleteUnwatch() {
230 $title = Title::makeTitle( NS_HELP, 'TestDeleteUnwatch' );
231 $user = $this->getTestSysop()->getUser();
233 $this->editPage( $title, 'Some text' );
234 $this->assertTrue( $title->exists( IDBAccessObject::READ_LATEST ) );
235 $watchlistManager = $this->getServiceContainer()->getWatchlistManager();
236 $watchlistManager->addWatch( $user, $title );
237 $this->assertTrue( $watchlistManager->isWatched( $user, $title ) );
239 $this->doApiRequestWithToken( [
240 'action' => 'delete',
241 'title' => $title->getPrefixedText(),
242 'watchlist' => 'unwatch',
243 ] );
245 $this->assertFalse( $title->exists( IDBAccessObject::READ_LATEST ) );
246 $this->assertFalse( $watchlistManager->isWatched( $user, $title ) );