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