Merge changes I9d2b148e,Iccf6ea81
[lhc/web/wiklou.git] / tests / phpunit / includes / upload / UploadFromUrlTest.php
1 <?php
2
3 /**
4 * @group Broken
5 * @group Upload
6 */
7 class UploadFromUrlTest extends ApiTestCase {
8
9 protected function setUp() {
10 global $wgEnableUploads, $wgAllowCopyUploads, $wgAllowAsyncCopyUploads;
11 parent::setUp();
12
13 $wgEnableUploads = true;
14 $wgAllowCopyUploads = true;
15 $wgAllowAsyncCopyUploads = true;
16 wfSetupSession();
17
18 if ( wfLocalFile( 'UploadFromUrlTest.png' )->exists() ) {
19 $this->deleteFile( 'UploadFromUrlTest.png' );
20 }
21 }
22
23 protected function doApiRequest( array $params, array $unused = null, $appendModule = false, User $user = null ) {
24 $sessionId = session_id();
25 session_write_close();
26
27 $req = new FauxRequest( $params, true, $_SESSION );
28 $module = new ApiMain( $req, true );
29 $module->execute();
30
31 wfSetupSession( $sessionId );
32 return array( $module->getResultData(), $req );
33 }
34
35 /**
36 * Ensure that the job queue is empty before continuing
37 */
38 public function testClearQueue() {
39 $job = Job::pop();
40 while ( $job ) {
41 $job = Job::pop();
42 }
43 $this->assertFalse( $job );
44 }
45
46 /**
47 * @todo Document why we test login, since the $wgUser hack used doesn't
48 * require login
49 */
50 public function testLogin() {
51 $data = $this->doApiRequest( array(
52 'action' => 'login',
53 'lgname' => $this->user->userName,
54 'lgpassword' => $this->user->passWord ) );
55 $this->assertArrayHasKey( "login", $data[0] );
56 $this->assertArrayHasKey( "result", $data[0]['login'] );
57 $this->assertEquals( "NeedToken", $data[0]['login']['result'] );
58 $token = $data[0]['login']['token'];
59
60 $data = $this->doApiRequest( array(
61 'action' => 'login',
62 "lgtoken" => $token,
63 'lgname' => $this->user->userName,
64 'lgpassword' => $this->user->passWord ) );
65
66 $this->assertArrayHasKey( "login", $data[0] );
67 $this->assertArrayHasKey( "result", $data[0]['login'] );
68 $this->assertEquals( "Success", $data[0]['login']['result'] );
69 $this->assertArrayHasKey( 'lgtoken', $data[0]['login'] );
70
71 return $data;
72 }
73
74 /**
75 * @depends testLogin
76 * @depends testClearQueue
77 */
78 public function testSetupUrlDownload( $data ) {
79 $token = $this->user->getEditToken();
80 $exception = false;
81
82 try {
83 $this->doApiRequest( array(
84 'action' => 'upload',
85 ) );
86 } catch ( UsageException $e ) {
87 $exception = true;
88 $this->assertEquals( "The token parameter must be set", $e->getMessage() );
89 }
90 $this->assertTrue( $exception, "Got exception" );
91
92 $exception = false;
93 try {
94 $this->doApiRequest( array(
95 'action' => 'upload',
96 'token' => $token,
97 ), $data );
98 } catch ( UsageException $e ) {
99 $exception = true;
100 $this->assertEquals( "One of the parameters sessionkey, file, url, statuskey is required",
101 $e->getMessage() );
102 }
103 $this->assertTrue( $exception, "Got exception" );
104
105 $exception = false;
106 try {
107 $this->doApiRequest( array(
108 'action' => 'upload',
109 'url' => 'http://www.example.com/test.png',
110 'token' => $token,
111 ), $data );
112 } catch ( UsageException $e ) {
113 $exception = true;
114 $this->assertEquals( "The filename parameter must be set", $e->getMessage() );
115 }
116 $this->assertTrue( $exception, "Got exception" );
117
118 $this->user->removeGroup( 'sysop' );
119 $exception = false;
120 try {
121 $this->doApiRequest( array(
122 'action' => 'upload',
123 'url' => 'http://www.example.com/test.png',
124 'filename' => 'UploadFromUrlTest.png',
125 'token' => $token,
126 ), $data );
127 } catch ( UsageException $e ) {
128 $exception = true;
129 $this->assertEquals( "Permission denied", $e->getMessage() );
130 }
131 $this->assertTrue( $exception, "Got exception" );
132
133 $this->user->addGroup( 'sysop' );
134 $data = $this->doApiRequest( array(
135 'action' => 'upload',
136 'url' => 'http://bits.wikimedia.org/skins-1.5/common/images/poweredby_mediawiki_88x31.png',
137 'asyncdownload' => 1,
138 'filename' => 'UploadFromUrlTest.png',
139 'token' => $token,
140 ), $data );
141
142 $this->assertEquals( $data[0]['upload']['result'], 'Queued', 'Queued upload' );
143
144 $job = Job::pop();
145 $this->assertThat( $job, $this->isInstanceOf( 'UploadFromUrlJob' ), 'Queued upload inserted' );
146 }
147
148 /**
149 * @depends testLogin
150 * @depends testClearQueue
151 */
152 public function testAsyncUpload( $data ) {
153 $token = $this->user->getEditToken();
154
155 $this->user->addGroup( 'users' );
156
157 $data = $this->doAsyncUpload( $token, true );
158 $this->assertEquals( $data[0]['upload']['result'], 'Success' );
159 $this->assertEquals( $data[0]['upload']['filename'], 'UploadFromUrlTest.png' );
160 $this->assertTrue( wfLocalFile( $data[0]['upload']['filename'] )->exists() );
161
162 $this->deleteFile( 'UploadFromUrlTest.png' );
163
164 return $data;
165 }
166
167 /**
168 * @depends testLogin
169 * @depends testClearQueue
170 */
171 public function testAsyncUploadWarning( $data ) {
172 $token = $this->user->getEditToken();
173
174 $this->user->addGroup( 'users' );
175
176
177 $data = $this->doAsyncUpload( $token );
178
179 $this->assertEquals( $data[0]['upload']['result'], 'Warning' );
180 $this->assertTrue( isset( $data[0]['upload']['sessionkey'] ) );
181
182 $data = $this->doApiRequest( array(
183 'action' => 'upload',
184 'sessionkey' => $data[0]['upload']['sessionkey'],
185 'filename' => 'UploadFromUrlTest.png',
186 'ignorewarnings' => 1,
187 'token' => $token,
188 ) );
189 $this->assertEquals( $data[0]['upload']['result'], 'Success' );
190 $this->assertEquals( $data[0]['upload']['filename'], 'UploadFromUrlTest.png' );
191 $this->assertTrue( wfLocalFile( $data[0]['upload']['filename'] )->exists() );
192
193 $this->deleteFile( 'UploadFromUrlTest.png' );
194
195 return $data;
196 }
197
198 /**
199 * @depends testLogin
200 * @depends testClearQueue
201 */
202 public function testSyncDownload( $data ) {
203 $token = $this->user->getEditToken();
204
205 $job = Job::pop();
206 $this->assertFalse( $job, 'Starting with an empty jobqueue' );
207
208 $this->user->addGroup( 'users' );
209 $data = $this->doApiRequest( array(
210 'action' => 'upload',
211 'filename' => 'UploadFromUrlTest.png',
212 'url' => 'http://bits.wikimedia.org/skins-1.5/common/images/poweredby_mediawiki_88x31.png',
213 'ignorewarnings' => true,
214 'token' => $token,
215 ), $data );
216
217 $job = Job::pop();
218 $this->assertFalse( $job );
219
220 $this->assertEquals( 'Success', $data[0]['upload']['result'] );
221 $this->deleteFile( 'UploadFromUrlTest.png' );
222
223 return $data;
224 }
225
226 public function testLeaveMessage() {
227 $token = $this->user->user->getEditToken();
228
229 $talk = $this->user->user->getTalkPage();
230 if ( $talk->exists() ) {
231 $page = WikiPage::factory( $talk );
232 $page->doDeleteArticle( '' );
233 }
234
235 $this->assertFalse( (bool)$talk->getArticleID( Title::GAID_FOR_UPDATE ), 'User talk does not exist' );
236
237 $data = $this->doApiRequest( array(
238 'action' => 'upload',
239 'filename' => 'UploadFromUrlTest.png',
240 'url' => 'http://bits.wikimedia.org/skins-1.5/common/images/poweredby_mediawiki_88x31.png',
241 'asyncdownload' => 1,
242 'token' => $token,
243 'leavemessage' => 1,
244 'ignorewarnings' => 1,
245 ) );
246
247 $job = Job::pop();
248 $this->assertEquals( 'UploadFromUrlJob', get_class( $job ) );
249 $job->run();
250
251 $this->assertTrue( wfLocalFile( 'UploadFromUrlTest.png' )->exists() );
252 $this->assertTrue( (bool)$talk->getArticleID( Title::GAID_FOR_UPDATE ), 'User talk exists' );
253
254 $this->deleteFile( 'UploadFromUrlTest.png' );
255
256 $talkRev = Revision::newFromTitle( $talk );
257 $talkSize = $talkRev->getSize();
258
259 $exception = false;
260 try {
261 $data = $this->doApiRequest( array(
262 'action' => 'upload',
263 'filename' => 'UploadFromUrlTest.png',
264 'url' => 'http://bits.wikimedia.org/skins-1.5/common/images/poweredby_mediawiki_88x31.png',
265 'asyncdownload' => 1,
266 'token' => $token,
267 'leavemessage' => 1,
268 ) );
269 } catch ( UsageException $e ) {
270 $exception = true;
271 $this->assertEquals( 'Using leavemessage without ignorewarnings is not supported', $e->getMessage() );
272 }
273 $this->assertTrue( $exception );
274
275 $job = Job::pop();
276 $this->assertFalse( $job );
277
278 return;
279
280 /*
281 // Broken until using leavemessage with ignorewarnings is supported
282 $job->run();
283
284 $this->assertFalse( wfLocalFile( 'UploadFromUrlTest.png' )->exists() );
285
286 $talkRev = Revision::newFromTitle( $talk );
287 $this->assertTrue( $talkRev->getSize() > $talkSize, 'New message left' );
288 */
289 }
290
291 /**
292 * Helper function to perform an async upload, execute the job and fetch
293 * the status
294 *
295 * @return array The result of action=upload&statuskey=key
296 */
297 private function doAsyncUpload( $token, $ignoreWarnings = false, $leaveMessage = false ) {
298 $params = array(
299 'action' => 'upload',
300 'filename' => 'UploadFromUrlTest.png',
301 'url' => 'http://bits.wikimedia.org/skins-1.5/common/images/poweredby_mediawiki_88x31.png',
302 'asyncdownload' => 1,
303 'token' => $token,
304 );
305 if ( $ignoreWarnings ) {
306 $params['ignorewarnings'] = 1;
307 }
308 if ( $leaveMessage ) {
309 $params['leavemessage'] = 1;
310 }
311
312 $data = $this->doApiRequest( $params );
313 $this->assertEquals( $data[0]['upload']['result'], 'Queued' );
314 $this->assertTrue( isset( $data[0]['upload']['statuskey'] ) );
315 $statusKey = $data[0]['upload']['statuskey'];
316
317 $job = Job::pop();
318 $this->assertEquals( 'UploadFromUrlJob', get_class( $job ) );
319
320 $status = $job->run();
321 $this->assertTrue( $status );
322
323 $data = $this->doApiRequest( array(
324 'action' => 'upload',
325 'statuskey' => $statusKey,
326 'token' => $token,
327 ) );
328
329 return $data;
330 }
331
332
333 /**
334 *
335 */
336 protected function deleteFile( $name ) {
337 $t = Title::newFromText( $name, NS_FILE );
338 $this->assertTrue($t->exists(), "File '$name' exists");
339
340 if ( $t->exists() ) {
341 $file = wfFindFile( $name, array( 'ignoreRedirect' => true ) );
342 $empty = "";
343 FileDeleteForm::doDelete( $t, $file, $empty, "none", true );
344 $page = WikiPage::factory( $t );
345 $page->doDeleteArticle( "testing" );
346 }
347 $t = Title::newFromText( $name, NS_FILE );
348
349 $this->assertFalse($t->exists(), "File '$name' was deleted");
350 }
351 }