51fe9793ce5b0d00e96110627b01da508f96feb6
[lhc/web/wiklou.git] / maintenance / tests / UploadFromChunksTest.php
1 <?php
2
3 require_once( "ApiSetup.php" );
4
5 class UploadFromChunksTest extends ApiSetup {
6
7 function setUp() {
8 global $wgEnableUploads;
9
10 $wgEnableUploads = true;
11 parent::setup();
12
13 ini_set( 'file_loads', 1 );
14 ini_set( 'log_errors', 1 );
15 ini_set( 'error_reporting', 1 );
16 ini_set( 'display_errors', 1 );
17 }
18
19 function makeChunk( $content ) {
20 $file = tempnam( wfTempDir(), "" );
21 $fh = fopen( $file, "w" );
22 if ( $fh == false ) {
23 $this->markTestIncomplete( "Couldn't open $file!\n" );
24 return;
25 }
26 fwrite( $fh, $content );
27 fclose( $fh );
28
29 $_FILES['chunk']['tmp_name'] = $file;
30 $_FILES['chunk']['size'] = 3;
31 $_FILES['chunk']['error'] = null;
32 $_FILES['chunk']['name'] = "test.txt";
33 }
34
35 function cleanChunk() {
36 if ( file_exists( $_FILES['chunk']['tmp_name'] ) )
37 unlink( $_FILES['chunk']['tmp_name'] );
38 }
39
40 function doApiRequest( $params, $data = null ) {
41 $session = isset( $data[2] ) ? $data[2] : array();
42 $_SESSION = $session;
43
44 $req = new FauxRequest( $params, true, $session );
45 $module = new ApiMain( $req, true );
46 $module->execute();
47
48 return array( $module->getResultData(), $req, $_SESSION );
49 }
50
51 function testGetTitle() {
52 $filename = tempnam( wfTempDir(), "" );
53 $c = new UploadFromChunks();
54 $c->initialize( false, "temp.txt", null, $filename, 0, null );
55 $this->assertEquals( null, $c->getTitle() );
56
57 $c = new UploadFromChunks();
58 $c->initialize( false, "temp.png", null, $filename, 0, null );
59 $this->assertEquals( Title::makeTitleSafe( NS_FILE, "Temp.png" ), $c->getTitle() );
60 }
61
62 function testLogin() {
63 $data = $this->doApiRequest( array(
64 'action' => 'login',
65 'lgname' => self::$userName,
66 'lgpassword' => self::$passWord ) );
67 $this->assertArrayHasKey( "login", $data[0] );
68 $this->assertArrayHasKey( "result", $data[0]['login'] );
69 $this->assertEquals( "Success", $data[0]['login']['result'] );
70 $this->assertArrayHasKey( 'lgtoken', $data[0]['login'] );
71
72 return $data;
73 }
74
75 /**
76 * @depends testLogin
77 */
78 function testSetupChunkSession( $data ) {
79 global $wgUser;
80 $wgUser = User::newFromName( self::$userName );
81 $wgUser->load();
82 $data[2]['wsEditToken'] = $data[2]['wsToken'];
83 $token = md5( $data[2]['wsToken'] ) . EDIT_TOKEN_SUFFIX;
84 $exception = false;
85
86 $data = $this->doApiRequest( array(
87 'filename' => 'tmp.txt',
88 'action' => 'upload',
89 'enablechunks' => true,
90 'token' => $token ), $data );
91 $this->assertArrayHasKey( 'uploadUrl', $data[0] );
92 $this->assertRegexp( '/action=upload/', $data[0]['uploadUrl'] );
93 $this->assertRegexp( '/enablechunks=true/', $data[0]['uploadUrl'] );
94 $this->assertRegexp( '/format=json/', $data[0]['uploadUrl'] );
95 $this->assertRegexp( '/chunksession=/', $data[0]['uploadUrl'] );
96 $this->assertRegexp( '/token=/', $data[0]['uploadUrl'] );
97
98 return $data;
99 }
100
101 /**
102 * @depends testSetupChunkSession
103 */
104 function testAppendChunkTypeBanned( $data ) {
105 global $wgUser;
106 $wgUser = User::newFromName( self::$userName );
107
108 $url = $data[0]['uploadUrl'];
109 $params = wfCgiToArray( substr( $url, strpos( $url, "?" ) ) );
110
111 $size = 0;
112 for ( $i = 0; $i < 4; $i++ ) {
113 $this->makeChunk( "123" );
114 $size += $_FILES['chunk']['size'];
115
116 $data = $this->doApiRequest( $params, $data );
117 $this->assertArrayHasKey( "result", $data[0] );
118 $this->assertTrue( (bool)$data[0]["result"] );
119
120 $this->assertArrayHasKey( "filesize", $data[0] );
121 $this->assertEquals( $size, $data[0]['filesize'] );
122
123 $this->cleanChunk();
124 }
125
126 $data['param'] = $params;
127 return $data;
128 }
129
130 /**
131 * @depends testLogin
132 */
133 function testInvalidSessionKey( $data ) {
134 global $wgUser;
135 $wgUser = User::newFromName( self::$userName );
136 $wgUser->load();
137 $data[2]['wsEditToken'] = $data[2]['wsToken'];
138 $token = md5( $data[2]['wsToken'] ) . EDIT_TOKEN_SUFFIX;
139 $exception = false;
140
141 try {
142 $this->doApiRequest( array(
143 'action' => 'upload',
144 'enablechunks' => true,
145 'token' => $token,
146 'chunksession' => 'bogus' ), $data );
147 } catch ( UsageException $e ) {
148 $exception = true;
149 $this->assertEquals( "Not a valid session key", $e->getMessage() );
150 }
151
152 $this->assertTrue( $exception, "Got exception" );
153 }
154
155 function testPerformUploadInitError() {
156 global $wgUser;
157 $wgUser = User::newFromId( 1 );
158
159 $req = new FauxRequest(
160 array(
161 'action' => 'upload',
162 'enablechunks' => 'false',
163 'sessionkey' => '1',
164 'filename' => 'test.png',
165 ) );
166 $module = new ApiMain( $req, true );
167 $gotException = false;
168 try {
169 $module->execute();
170 } catch ( UsageException $e ) {
171 $this->assertEquals( "The token parameter must be set", $e->getMessage() );
172 $gotException = true;
173 }
174
175 $this->assertTrue( $gotException );
176 }
177
178 /**
179 * @depends testAppendChunkTypeBanned
180 */
181 function testUploadChunkDoneTypeBanned( $data ) {
182 global $wgUser;
183 $wgUser = User::newFromName( self::$userName );
184 $token = $wgUser->editToken();
185 $params = $data['param'];
186 $params['done'] = 1;
187
188 $this->makeChunk( "123" );
189
190 $gotException = false;
191 try {
192 $data = $this->doApiRequest( $params, $data );
193 } catch ( UsageException $e ) {
194 $this->assertEquals( "This type of file is banned",
195 $e->getMessage() );
196 $gotException = true;
197 }
198 $this->cleanChunk();
199 $this->assertTrue( $gotException );
200 }
201
202 /**
203 * @depends testLogin
204 */
205 function testUploadChunkDoneDuplicate( $data ) {
206 global $wgUser, $wgVerifyMimeType;
207
208 $wgVerifyMimeType = false;
209 $wgUser = User::newFromName( self::$userName );
210 $data[2]['wsEditToken'] = $data[2]['wsToken'];
211 $token = md5( $data[2]['wsToken'] ) . EDIT_TOKEN_SUFFIX;
212 $data = $this->doApiRequest( array(
213 'filename' => 'tmp.png',
214 'action' => 'upload',
215 'enablechunks' => true,
216 'token' => $token ), $data );
217
218 $url = $data[0]['uploadUrl'];
219 $params = wfCgiToArray( substr( $url, strpos( $url, "?" ) ) );
220 $size = 0;
221 for ( $i = 0; $i < 4; $i++ ) {
222 $this->makeChunk( "123" );
223 $size += $_FILES['chunk']['size'];
224
225 $data = $this->doApiRequest( $params, $data );
226 $this->assertArrayHasKey( "result", $data[0] );
227 $this->assertTrue( (bool)$data[0]["result"] );
228
229 $this->assertArrayHasKey( "filesize", $data[0] );
230 $this->assertEquals( $size, $data[0]['filesize'] );
231
232 $this->cleanChunk();
233 }
234
235 $params['done'] = true;
236
237 $this->makeChunk( "123" );
238 $data = $this->doApiRequest( $params, $data );
239 $this->cleanChunk();
240
241 $this->assertArrayHasKey( 'upload', $data[0] );
242 $this->assertArrayHasKey( 'result', $data[0]['upload'] );
243 $this->assertEquals( 'Warning', $data[0]['upload']['result'] );
244
245 $this->assertArrayHasKey( 'warnings', $data[0]['upload'] );
246 $this->assertArrayHasKey( 'exists',
247 $data[0]['upload']['warnings'] );
248 $this->assertEquals( 'Tmp.png',
249 $data[0]['upload']['warnings']['exists'] );
250
251 }
252
253 /**
254 * @depends testLogin
255 */
256 function testUploadChunkDoneGood( $data ) {
257 global $wgUser, $wgVerifyMimeType;
258 $wgVerifyMimeType = false;
259
260 $id = Title::newFromText( "Twar.png", NS_FILE )->getArticleID();
261
262 $oldFile = Article::newFromID( $id );
263 if ( $oldFile ) {
264 $oldFile->doDeleteArticle();
265 $oldFile->doPurge();
266 }
267 $oldFile = wfFindFile( "Twar.png" );
268 if ( $oldFile ) {
269 $oldFile->delete();
270 }
271
272 $wgUser = User::newFromName( self::$userName );
273 $data[2]['wsEditToken'] = $data[2]['wsToken'];
274 $token = md5( $data[2]['wsToken'] ) . EDIT_TOKEN_SUFFIX;
275 $data = $this->doApiRequest( array(
276 'filename' => 'twar.png',
277 'action' => 'upload',
278 'enablechunks' => true,
279 'token' => $token ), $data );
280
281 $url = $data[0]['uploadUrl'];
282 $params = wfCgiToArray( substr( $url, strpos( $url, "?" ) ) );
283 $size = 0;
284 for ( $i = 0; $i < 5; $i++ ) {
285 $this->makeChunk( "123" );
286 $size += $_FILES['chunk']['size'];
287
288 $data = $this->doApiRequest( $params, $data );
289 $this->assertArrayHasKey( "result", $data[0] );
290 $this->assertTrue( (bool)$data[0]["result"] );
291
292 $this->assertArrayHasKey( "filesize", $data[0] );
293 $this->assertEquals( $size, $data[0]['filesize'] );
294
295 $this->cleanChunk();
296 }
297
298 $params['done'] = true;
299
300 $this->makeChunk( "456" );
301 $data = $this->doApiRequest( $params, $data );
302
303 $this->cleanChunk();
304
305 if ( isset( $data[0]['upload'] ) ) {
306 $this->markTestSkipped( "Please run 'php maintenance/deleteArchivedFiles.php --delete --force' and 'php maintenance/deleteArchivedRevisions.php --delete'" );
307 }
308
309 $this->assertArrayHasKey( 'result', $data[0] );
310 $this->assertEquals( 1, $data[0]['result'] );
311
312 $this->assertArrayHasKey( 'done', $data[0] );
313 $this->assertEquals( 1, $data[0]['done'] );
314
315 $this->assertArrayHasKey( 'resultUrl', $data[0] );
316 $this->assertRegExp( '/File:Twar.png/', $data[0]['resultUrl'] );
317 }
318 }