MDL-49497 curl: Allow configurable User-Agent.
[moodle.git] / lib / tests / filelib_test.php
CommitLineData
a3d5830a
PS
1<?php
2// This file is part of Moodle - http://moodle.org/
3//
4// Moodle is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// Moodle is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
16
a3d5830a
PS
17/**
18 * Unit tests for /lib/filelib.php.
19 *
20 * @package core_files
21 * @category phpunit
22 * @copyright 2009 Jerome Mouneyrac
23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24 */
25
26defined('MOODLE_INTERNAL') || die();
27
28global $CFG;
29require_once($CFG->libdir . '/filelib.php');
ac29403e 30require_once($CFG->dirroot . '/repository/lib.php');
a3d5830a 31
1d987cb7 32class core_filelib_testcase extends advanced_testcase {
a3d5830a
PS
33 public function test_format_postdata_for_curlcall() {
34
1d987cb7
PS
35 // POST params with just simple types.
36 $postdatatoconvert = array( 'userid' => 1, 'roleid' => 22, 'name' => 'john');
a3d5830a
PS
37 $expectedresult = "userid=1&roleid=22&name=john";
38 $postdata = format_postdata_for_curlcall($postdatatoconvert);
1d987cb7 39 $this->assertEquals($expectedresult, $postdata);
a3d5830a 40
1d987cb7
PS
41 // POST params with a string containing & character.
42 $postdatatoconvert = array( 'name' => 'john&emilie', 'roleid' => 22);
43 $expectedresult = "name=john%26emilie&roleid=22"; // Urlencode: '%26' => '&'.
a3d5830a 44 $postdata = format_postdata_for_curlcall($postdatatoconvert);
1d987cb7 45 $this->assertEquals($expectedresult, $postdata);
a3d5830a 46
1d987cb7
PS
47 // POST params with an empty value.
48 $postdatatoconvert = array( 'name' => null, 'roleid' => 22);
a3d5830a
PS
49 $expectedresult = "name=&roleid=22";
50 $postdata = format_postdata_for_curlcall($postdatatoconvert);
1d987cb7 51 $this->assertEquals($expectedresult, $postdata);
a3d5830a 52
1d987cb7
PS
53 // POST params with complex types.
54 $postdatatoconvert = array( 'users' => array(
a3d5830a
PS
55 array(
56 'id' => 2,
57 'customfields' => array(
58 array
59 (
60 'type' => 'Color',
61 'value' => 'violet'
62 )
63 )
64 )
65 )
66 );
67 $expectedresult = "users[0][id]=2&users[0][customfields][0][type]=Color&users[0][customfields][0][value]=violet";
68 $postdata = format_postdata_for_curlcall($postdatatoconvert);
1d987cb7 69 $this->assertEquals($expectedresult, $postdata);
a3d5830a 70
1d987cb7 71 // POST params with other complex types.
a3d5830a
PS
72 $postdatatoconvert = array ('members' =>
73 array(
74 array('groupid' => 1, 'userid' => 1)
75 , array('groupid' => 1, 'userid' => 2)
76 )
77 );
78 $expectedresult = "members[0][groupid]=1&members[0][userid]=1&members[1][groupid]=1&members[1][userid]=2";
79 $postdata = format_postdata_for_curlcall($postdatatoconvert);
1d987cb7 80 $this->assertEquals($expectedresult, $postdata);
a3d5830a
PS
81 }
82
83 public function test_download_file_content() {
35ea5db0
PS
84 global $CFG;
85
86 // Test http success first.
a9d2f1b4 87 $testhtml = $this->getExternalTestFileUrl('/test.html');
35ea5db0
PS
88
89 $contents = download_file_content($testhtml);
90 $this->assertSame('47250a973d1b88d9445f94db4ef2c97a', md5($contents));
91
92 $tofile = "$CFG->tempdir/test.html";
93 @unlink($tofile);
94 $result = download_file_content($testhtml, null, null, false, 300, 20, false, $tofile);
95 $this->assertTrue($result);
96 $this->assertFileExists($tofile);
1d987cb7 97 $this->assertSame(file_get_contents($tofile), $contents);
35ea5db0
PS
98 @unlink($tofile);
99
100 $result = download_file_content($testhtml, null, null, false, 300, 20, false, null, true);
101 $this->assertSame($contents, $result);
102
103 $response = download_file_content($testhtml, null, null, true);
104 $this->assertInstanceOf('stdClass', $response);
105 $this->assertSame('200', $response->status);
106 $this->assertTrue(is_array($response->headers));
846f6fbe 107 $this->assertRegExp('|^HTTP/1\.[01] 200 OK$|', rtrim($response->response_code));
35ea5db0
PS
108 $this->assertSame($contents, $response->results);
109 $this->assertSame('', $response->error);
110
35ea5db0 111 // Test https success.
a9d2f1b4 112 $testhtml = $this->getExternalTestFileUrl('/test.html', true);
35ea5db0
PS
113
114 $contents = download_file_content($testhtml, null, null, false, 300, 20, true);
115 $this->assertSame('47250a973d1b88d9445f94db4ef2c97a', md5($contents));
116
117 $contents = download_file_content($testhtml);
118 $this->assertSame('47250a973d1b88d9445f94db4ef2c97a', md5($contents));
119
35ea5db0 120 // Now 404.
a9d2f1b4 121 $testhtml = $this->getExternalTestFileUrl('/test.html_nonexistent');
35ea5db0
PS
122
123 $contents = download_file_content($testhtml);
124 $this->assertFalse($contents);
125 $this->assertDebuggingCalled();
126
127 $response = download_file_content($testhtml, null, null, true);
128 $this->assertInstanceOf('stdClass', $response);
129 $this->assertSame('404', $response->status);
130 $this->assertTrue(is_array($response->headers));
846f6fbe 131 $this->assertRegExp('|^HTTP/1\.[01] 404 Not Found$|', rtrim($response->response_code));
b1652d6b 132 // Do not test the response starts with DOCTYPE here because some servers may return different headers.
35ea5db0
PS
133 $this->assertSame('', $response->error);
134
35ea5db0 135 // Invalid url.
a9d2f1b4
PS
136 $testhtml = $this->getExternalTestFileUrl('/test.html');
137 $testhtml = str_replace('http://', 'ftp://', $testhtml);
35ea5db0 138
a3d5830a 139 $contents = download_file_content($testhtml);
35ea5db0
PS
140 $this->assertFalse($contents);
141
35ea5db0 142 // Test standard redirects.
a9d2f1b4 143 $testurl = $this->getExternalTestFileUrl('/test_redir.php');
35ea5db0
PS
144
145 $contents = download_file_content("$testurl?redir=2");
146 $this->assertSame('done', $contents);
147
148 $response = download_file_content("$testurl?redir=2", null, null, true);
149 $this->assertInstanceOf('stdClass', $response);
150 $this->assertSame('200', $response->status);
151 $this->assertTrue(is_array($response->headers));
846f6fbe 152 $this->assertRegExp('|^HTTP/1\.[01] 200 OK$|', rtrim($response->response_code));
35ea5db0
PS
153 $this->assertSame('done', $response->results);
154 $this->assertSame('', $response->error);
155
a9d2f1b4 156 // Commented out this block if there are performance problems.
1d987cb7 157 /*
35ea5db0
PS
158 $contents = download_file_content("$testurl?redir=6");
159 $this->assertFalse(false, $contents);
160 $this->assertDebuggingCalled();
35ea5db0
PS
161 $response = download_file_content("$testurl?redir=6", null, null, true);
162 $this->assertInstanceOf('stdClass', $response);
163 $this->assertSame('0', $response->status);
164 $this->assertTrue(is_array($response->headers));
165 $this->assertFalse($response->results);
166 $this->assertNotEmpty($response->error);
1d987cb7 167 */
35ea5db0
PS
168
169 // Test relative redirects.
a9d2f1b4 170 $testurl = $this->getExternalTestFileUrl('/test_relative_redir.php');
35ea5db0
PS
171
172 $contents = download_file_content("$testurl");
173 $this->assertSame('done', $contents);
174
175 $contents = download_file_content("$testurl?unused=xxx");
176 $this->assertSame('done', $contents);
177 }
178
179 /**
74c4405b 180 * Test curl basics.
35ea5db0 181 */
74c4405b 182 public function test_curl_basics() {
35ea5db0
PS
183 global $CFG;
184
74c4405b 185 // Test HTTP success.
a9d2f1b4 186 $testhtml = $this->getExternalTestFileUrl('/test.html');
35ea5db0
PS
187
188 $curl = new curl();
189 $contents = $curl->get($testhtml);
190 $this->assertSame('47250a973d1b88d9445f94db4ef2c97a', md5($contents));
191 $this->assertSame(0, $curl->get_errno());
192
193 $curl = new curl();
194 $tofile = "$CFG->tempdir/test.html";
195 @unlink($tofile);
196 $fp = fopen($tofile, 'w');
197 $result = $curl->get($testhtml, array(), array('CURLOPT_FILE'=>$fp));
198 $this->assertTrue($result);
199 fclose($fp);
200 $this->assertFileExists($tofile);
201 $this->assertSame($contents, file_get_contents($tofile));
202 @unlink($tofile);
203
204 $curl = new curl();
205 $tofile = "$CFG->tempdir/test.html";
206 @unlink($tofile);
207 $result = $curl->download_one($testhtml, array(), array('filepath'=>$tofile));
208 $this->assertTrue($result);
209 $this->assertFileExists($tofile);
210 $this->assertSame($contents, file_get_contents($tofile));
211 @unlink($tofile);
212
74c4405b
FM
213 // Test 404 request.
214 $curl = new curl();
215 $contents = $curl->get($this->getExternalTestFileUrl('/i.do.not.exist'));
216 $response = $curl->getResponse();
217 $this->assertSame('404 Not Found', reset($response));
218 $this->assertSame(0, $curl->get_errno());
219 }
220
221 public function test_curl_redirects() {
222 global $CFG;
223
35ea5db0 224 // Test full URL redirects.
a9d2f1b4 225 $testurl = $this->getExternalTestFileUrl('/test_redir.php');
35ea5db0
PS
226
227 $curl = new curl();
228 $contents = $curl->get("$testurl?redir=2", array(), array('CURLOPT_MAXREDIRS'=>2));
74c4405b
FM
229 $response = $curl->getResponse();
230 $this->assertSame('200 OK', reset($response));
35ea5db0
PS
231 $this->assertSame(0, $curl->get_errno());
232 $this->assertSame(2, $curl->info['redirect_count']);
233 $this->assertSame('done', $contents);
234
235 $curl = new curl();
236 $curl->emulateredirects = true;
237 $contents = $curl->get("$testurl?redir=2", array(), array('CURLOPT_MAXREDIRS'=>2));
74c4405b
FM
238 $response = $curl->getResponse();
239 $this->assertSame('200 OK', reset($response));
35ea5db0
PS
240 $this->assertSame(0, $curl->get_errno());
241 $this->assertSame(2, $curl->info['redirect_count']);
242 $this->assertSame('done', $contents);
243
90048c7c
TH
244 // This test was failing for people behind Squid proxies. Squid does not
245 // fully support HTTP 1.1, so converts things to HTTP 1.0, where the name
246 // of the status code is different.
247 reset($response);
248 if (key($response) === 'HTTP/1.0') {
249 $responsecode302 = '302 Moved Temporarily';
250 } else {
251 $responsecode302 = '302 Found';
252 }
253
35ea5db0
PS
254 $curl = new curl();
255 $contents = $curl->get("$testurl?redir=3", array(), array('CURLOPT_FOLLOWLOCATION'=>0));
74c4405b 256 $response = $curl->getResponse();
90048c7c 257 $this->assertSame($responsecode302, reset($response));
35ea5db0
PS
258 $this->assertSame(0, $curl->get_errno());
259 $this->assertSame(302, $curl->info['http_code']);
260 $this->assertSame('', $contents);
261
262 $curl = new curl();
263 $curl->emulateredirects = true;
264 $contents = $curl->get("$testurl?redir=3", array(), array('CURLOPT_FOLLOWLOCATION'=>0));
74c4405b 265 $response = $curl->getResponse();
90048c7c 266 $this->assertSame($responsecode302, reset($response));
35ea5db0
PS
267 $this->assertSame(0, $curl->get_errno());
268 $this->assertSame(302, $curl->info['http_code']);
269 $this->assertSame('', $contents);
270
271 $curl = new curl();
272 $contents = $curl->get("$testurl?redir=2", array(), array('CURLOPT_MAXREDIRS'=>1));
273 $this->assertSame(CURLE_TOO_MANY_REDIRECTS, $curl->get_errno());
274 $this->assertNotEmpty($contents);
275
276 $curl = new curl();
277 $curl->emulateredirects = true;
278 $contents = $curl->get("$testurl?redir=2", array(), array('CURLOPT_MAXREDIRS'=>1));
279 $this->assertSame(CURLE_TOO_MANY_REDIRECTS, $curl->get_errno());
280 $this->assertNotEmpty($contents);
281
282 $curl = new curl();
283 $tofile = "$CFG->tempdir/test.html";
284 @unlink($tofile);
285 $fp = fopen($tofile, 'w');
286 $result = $curl->get("$testurl?redir=1", array(), array('CURLOPT_FILE'=>$fp));
287 $this->assertTrue($result);
288 fclose($fp);
289 $this->assertFileExists($tofile);
290 $this->assertSame('done', file_get_contents($tofile));
291 @unlink($tofile);
292
293 $curl = new curl();
294 $curl->emulateredirects = true;
295 $tofile = "$CFG->tempdir/test.html";
296 @unlink($tofile);
297 $fp = fopen($tofile, 'w');
298 $result = $curl->get("$testurl?redir=1", array(), array('CURLOPT_FILE'=>$fp));
299 $this->assertTrue($result);
300 fclose($fp);
301 $this->assertFileExists($tofile);
302 $this->assertSame('done', file_get_contents($tofile));
303 @unlink($tofile);
304
305 $curl = new curl();
306 $tofile = "$CFG->tempdir/test.html";
307 @unlink($tofile);
308 $result = $curl->download_one("$testurl?redir=1", array(), array('filepath'=>$tofile));
309 $this->assertTrue($result);
310 $this->assertFileExists($tofile);
311 $this->assertSame('done', file_get_contents($tofile));
312 @unlink($tofile);
313
314 $curl = new curl();
315 $curl->emulateredirects = true;
316 $tofile = "$CFG->tempdir/test.html";
317 @unlink($tofile);
318 $result = $curl->download_one("$testurl?redir=1", array(), array('filepath'=>$tofile));
319 $this->assertTrue($result);
320 $this->assertFileExists($tofile);
321 $this->assertSame('done', file_get_contents($tofile));
322 @unlink($tofile);
74c4405b 323 }
35ea5db0 324
74c4405b 325 public function test_curl_relative_redirects() {
35ea5db0 326 // Test relative location redirects.
a9d2f1b4 327 $testurl = $this->getExternalTestFileUrl('/test_relative_redir.php');
35ea5db0
PS
328
329 $curl = new curl();
330 $contents = $curl->get($testurl);
74c4405b
FM
331 $response = $curl->getResponse();
332 $this->assertSame('200 OK', reset($response));
35ea5db0
PS
333 $this->assertSame(0, $curl->get_errno());
334 $this->assertSame(1, $curl->info['redirect_count']);
335 $this->assertSame('done', $contents);
336
337 $curl = new curl();
338 $curl->emulateredirects = true;
339 $contents = $curl->get($testurl);
74c4405b
FM
340 $response = $curl->getResponse();
341 $this->assertSame('200 OK', reset($response));
35ea5db0
PS
342 $this->assertSame(0, $curl->get_errno());
343 $this->assertSame(1, $curl->info['redirect_count']);
344 $this->assertSame('done', $contents);
345
35ea5db0 346 // Test different redirect types.
a9d2f1b4 347 $testurl = $this->getExternalTestFileUrl('/test_relative_redir.php');
35ea5db0
PS
348
349 $curl = new curl();
350 $contents = $curl->get("$testurl?type=301");
74c4405b
FM
351 $response = $curl->getResponse();
352 $this->assertSame('200 OK', reset($response));
35ea5db0
PS
353 $this->assertSame(0, $curl->get_errno());
354 $this->assertSame(1, $curl->info['redirect_count']);
355 $this->assertSame('done', $contents);
356
357 $curl = new curl();
358 $curl->emulateredirects = true;
359 $contents = $curl->get("$testurl?type=301");
74c4405b
FM
360 $response = $curl->getResponse();
361 $this->assertSame('200 OK', reset($response));
35ea5db0
PS
362 $this->assertSame(0, $curl->get_errno());
363 $this->assertSame(1, $curl->info['redirect_count']);
364 $this->assertSame('done', $contents);
365
366 $curl = new curl();
367 $contents = $curl->get("$testurl?type=302");
74c4405b
FM
368 $response = $curl->getResponse();
369 $this->assertSame('200 OK', reset($response));
35ea5db0
PS
370 $this->assertSame(0, $curl->get_errno());
371 $this->assertSame(1, $curl->info['redirect_count']);
372 $this->assertSame('done', $contents);
373
374 $curl = new curl();
375 $curl->emulateredirects = true;
376 $contents = $curl->get("$testurl?type=302");
74c4405b
FM
377 $response = $curl->getResponse();
378 $this->assertSame('200 OK', reset($response));
35ea5db0
PS
379 $this->assertSame(0, $curl->get_errno());
380 $this->assertSame(1, $curl->info['redirect_count']);
381 $this->assertSame('done', $contents);
382
383 $curl = new curl();
384 $contents = $curl->get("$testurl?type=303");
74c4405b
FM
385 $response = $curl->getResponse();
386 $this->assertSame('200 OK', reset($response));
35ea5db0
PS
387 $this->assertSame(0, $curl->get_errno());
388 $this->assertSame(1, $curl->info['redirect_count']);
389 $this->assertSame('done', $contents);
390
391 $curl = new curl();
392 $curl->emulateredirects = true;
393 $contents = $curl->get("$testurl?type=303");
74c4405b
FM
394 $response = $curl->getResponse();
395 $this->assertSame('200 OK', reset($response));
35ea5db0
PS
396 $this->assertSame(0, $curl->get_errno());
397 $this->assertSame(1, $curl->info['redirect_count']);
398 $this->assertSame('done', $contents);
399
400 $curl = new curl();
401 $contents = $curl->get("$testurl?type=307");
74c4405b
FM
402 $response = $curl->getResponse();
403 $this->assertSame('200 OK', reset($response));
35ea5db0
PS
404 $this->assertSame(0, $curl->get_errno());
405 $this->assertSame(1, $curl->info['redirect_count']);
406 $this->assertSame('done', $contents);
407
408 $curl = new curl();
409 $curl->emulateredirects = true;
410 $contents = $curl->get("$testurl?type=307");
74c4405b
FM
411 $response = $curl->getResponse();
412 $this->assertSame('200 OK', reset($response));
35ea5db0
PS
413 $this->assertSame(0, $curl->get_errno());
414 $this->assertSame(1, $curl->info['redirect_count']);
415 $this->assertSame('done', $contents);
416
417 $curl = new curl();
418 $contents = $curl->get("$testurl?type=308");
74c4405b
FM
419 $response = $curl->getResponse();
420 $this->assertSame('200 OK', reset($response));
35ea5db0
PS
421 $this->assertSame(0, $curl->get_errno());
422 $this->assertSame(1, $curl->info['redirect_count']);
423 $this->assertSame('done', $contents);
424
425 $curl = new curl();
426 $curl->emulateredirects = true;
427 $contents = $curl->get("$testurl?type=308");
74c4405b
FM
428 $response = $curl->getResponse();
429 $this->assertSame('200 OK', reset($response));
35ea5db0
PS
430 $this->assertSame(0, $curl->get_errno());
431 $this->assertSame(1, $curl->info['redirect_count']);
432 $this->assertSame('done', $contents);
ba72e295 433
74c4405b
FM
434 }
435
436 public function test_curl_proxybypass() {
437 global $CFG;
438 $testurl = $this->getExternalTestFileUrl('/test.html');
439
ba72e295
FM
440 $oldproxy = $CFG->proxyhost;
441 $oldproxybypass = $CFG->proxybypass;
442
443 // Test without proxy bypass and inaccessible proxy.
444 $CFG->proxyhost = 'i.do.not.exist';
445 $CFG->proxybypass = '';
446 $curl = new curl();
74c4405b 447 $contents = $curl->get($testurl);
ba72e295
FM
448 $this->assertNotEquals(0, $curl->get_errno());
449 $this->assertNotEquals('47250a973d1b88d9445f94db4ef2c97a', md5($contents));
450
451 // Test with proxy bypass.
74c4405b
FM
452 $testurlhost = parse_url($testurl, PHP_URL_HOST);
453 $CFG->proxybypass = $testurlhost;
ba72e295 454 $curl = new curl();
74c4405b 455 $contents = $curl->get($testurl);
ba72e295
FM
456 $this->assertSame(0, $curl->get_errno());
457 $this->assertSame('47250a973d1b88d9445f94db4ef2c97a', md5($contents));
458
459 $CFG->proxyhost = $oldproxy;
460 $CFG->proxybypass = $oldproxybypass;
a3d5830a 461 }
67233725 462
74c4405b
FM
463 public function test_curl_post() {
464 $testurl = $this->getExternalTestFileUrl('/test_post.php');
102230b2
FM
465
466 // Test post request.
467 $curl = new curl();
74c4405b 468 $contents = $curl->post($testurl, 'data=moodletest');
102230b2
FM
469 $response = $curl->getResponse();
470 $this->assertSame('200 OK', reset($response));
471 $this->assertSame(0, $curl->get_errno());
472 $this->assertSame('OK', $contents);
473
474 // Test 100 requests.
475 $curl = new curl();
476 $curl->setHeader('Expect: 100-continue');
74c4405b 477 $contents = $curl->post($testurl, 'data=moodletest');
102230b2
FM
478 $response = $curl->getResponse();
479 $this->assertSame('200 OK', reset($response));
480 $this->assertSame(0, $curl->get_errno());
481 $this->assertSame('OK', $contents);
482 }
483
218d751d
FM
484 public function test_curl_file() {
485 $this->resetAfterTest();
486 $testurl = $this->getExternalTestFileUrl('/test_file.php');
487
488 $fs = get_file_storage();
489 $filerecord = array(
490 'contextid' => context_system::instance()->id,
491 'component' => 'test',
492 'filearea' => 'curl_post',
493 'itemid' => 0,
494 'filepath' => '/',
495 'filename' => 'test.txt'
496 );
497 $teststring = 'moodletest';
498 $testfile = $fs->create_file_from_string($filerecord, $teststring);
499
500 // Test post with file.
501 $data = array('testfile' => $testfile);
502 $curl = new curl();
503 $contents = $curl->post($testurl, $data);
504 $this->assertSame('OK', $contents);
505 }
506
38a73bf4
FM
507 public function test_curl_protocols() {
508
509 // HTTP and HTTPS requests were verified in previous requests. Now check
510 // that we can selectively disable some protocols.
511 $curl = new curl();
512
513 // Other protocols than HTTP(S) are disabled by default.
514 $testurl = 'file:///';
515 $curl->get($testurl);
516 $this->assertNotEmpty($curl->error);
517 $this->assertEquals(CURLE_UNSUPPORTED_PROTOCOL, $curl->errno);
518
519 $testurl = 'ftp://nowhere';
520 $curl->get($testurl);
521 $this->assertNotEmpty($curl->error);
522 $this->assertEquals(CURLE_UNSUPPORTED_PROTOCOL, $curl->errno);
523
524 $testurl = 'telnet://somewhere';
525 $curl->get($testurl);
526 $this->assertNotEmpty($curl->error);
527 $this->assertEquals(CURLE_UNSUPPORTED_PROTOCOL, $curl->errno);
528
529 // Protocols are also disabled during redirections.
530 $testurl = $this->getExternalTestFileUrl('/test_redir_proto.php');
531 $curl->get($testurl, array('proto' => 'file'));
532 $this->assertNotEmpty($curl->error);
533 $this->assertEquals(CURLE_UNSUPPORTED_PROTOCOL, $curl->errno);
534
535 $testurl = $this->getExternalTestFileUrl('/test_redir_proto.php');
536 $curl->get($testurl, array('proto' => 'ftp'));
537 $this->assertNotEmpty($curl->error);
538 $this->assertEquals(CURLE_UNSUPPORTED_PROTOCOL, $curl->errno);
539
540 $testurl = $this->getExternalTestFileUrl('/test_redir_proto.php');
541 $curl->get($testurl, array('proto' => 'telnet'));
542 $this->assertNotEmpty($curl->error);
543 $this->assertEquals(CURLE_UNSUPPORTED_PROTOCOL, $curl->errno);
544 }
545
67233725
DC
546 /**
547 * Testing prepare draft area
548 *
549 * @copyright 2012 Dongsheng Cai {@link http://dongsheng.org}
550 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
551 */
552 public function test_prepare_draft_area() {
553 global $USER, $DB;
554
555 $this->resetAfterTest(true);
556
557 $generator = $this->getDataGenerator();
558 $user = $generator->create_user();
559 $usercontext = context_user::instance($user->id);
560 $USER = $DB->get_record('user', array('id'=>$user->id));
561
7051415c
DC
562 $repositorypluginname = 'user';
563
564 $args = array();
565 $args['type'] = $repositorypluginname;
566 $repos = repository::get_instances($args);
567 $userrepository = reset($repos);
568 $this->assertInstanceOf('repository', $userrepository);
67233725
DC
569
570 $fs = get_file_storage();
7051415c 571
67233725
DC
572 $syscontext = context_system::instance();
573 $component = 'core';
574 $filearea = 'unittest';
575 $itemid = 0;
576 $filepath = '/';
577 $filename = 'test.txt';
578 $sourcefield = 'Copyright stuff';
579
580 $filerecord = array(
581 'contextid' => $syscontext->id,
582 'component' => $component,
583 'filearea' => $filearea,
584 'itemid' => $itemid,
585 'filepath' => $filepath,
586 'filename' => $filename,
587 'source' => $sourcefield,
588 );
589 $ref = $fs->pack_reference($filerecord);
67233725 590 $originalfile = $fs->create_file_from_string($filerecord, 'Test content');
67233725
DC
591 $fileid = $originalfile->get_id();
592 $this->assertInstanceOf('stored_file', $originalfile);
593
1d987cb7 594 // Create a user private file.
7051415c
DC
595 $userfilerecord = new stdClass;
596 $userfilerecord->contextid = $usercontext->id;
597 $userfilerecord->component = 'user';
598 $userfilerecord->filearea = 'private';
599 $userfilerecord->itemid = 0;
600 $userfilerecord->filepath = '/';
601 $userfilerecord->filename = 'userfile.txt';
602 $userfilerecord->source = 'test';
603 $userfile = $fs->create_file_from_string($userfilerecord, 'User file content');
604 $userfileref = $fs->pack_reference($userfilerecord);
605
606 $filerefrecord = clone((object)$filerecord);
607 $filerefrecord->filename = 'testref.txt';
1d987cb7
PS
608
609 // Create a file reference.
7051415c
DC
610 $fileref = $fs->create_file_from_reference($filerefrecord, $userrepository->id, $userfileref);
611 $this->assertInstanceOf('stored_file', $fileref);
291a3d1f 612 $this->assertEquals($userrepository->id, $fileref->get_repository_id());
1d987cb7 613 $this->assertSame($userfile->get_contenthash(), $fileref->get_contenthash());
7051415c
DC
614 $this->assertEquals($userfile->get_filesize(), $fileref->get_filesize());
615 $this->assertRegExp('#' . $userfile->get_filename(). '$#', $fileref->get_reference_details());
616
67233725
DC
617 $draftitemid = 0;
618 file_prepare_draft_area($draftitemid, $syscontext->id, $component, $filearea, $itemid);
619
620 $draftfiles = $fs->get_area_files($usercontext->id, 'user', 'draft', $draftitemid);
1d987cb7 621 $this->assertCount(3, $draftfiles);
67233725
DC
622
623 $draftfile = $fs->get_file($usercontext->id, 'user', 'draft', $draftitemid, $filepath, $filename);
624 $source = unserialize($draftfile->get_source());
1d987cb7
PS
625 $this->assertSame($ref, $source->original);
626 $this->assertSame($sourcefield, $source->source);
67233725 627
7051415c
DC
628 $draftfileref = $fs->get_file($usercontext->id, 'user', 'draft', $draftitemid, $filepath, $filerefrecord->filename);
629 $this->assertInstanceOf('stored_file', $draftfileref);
1d987cb7 630 $this->assertTrue($draftfileref->is_external_file());
67233725 631
1d987cb7 632 // Change some information.
67233725
DC
633 $author = 'Dongsheng Cai';
634 $draftfile->set_author($author);
7051415c 635 $newsourcefield = 'Get from Flickr';
67233725
DC
636 $license = 'GPLv3';
637 $draftfile->set_license($license);
1d987cb7 638 // If you want to really just change source field, do this.
67233725
DC
639 $source = unserialize($draftfile->get_source());
640 $newsourcefield = 'From flickr';
641 $source->source = $newsourcefield;
642 $draftfile->set_source(serialize($source));
643
1d987cb7 644 // Save changed file.
67233725
DC
645 file_save_draft_area_files($draftitemid, $syscontext->id, $component, $filearea, $itemid);
646
647 $file = $fs->get_file($syscontext->id, $component, $filearea, $itemid, $filepath, $filename);
648
1d987cb7 649 // Make sure it's the original file id.
67233725
DC
650 $this->assertEquals($fileid, $file->get_id());
651 $this->assertInstanceOf('stored_file', $file);
1d987cb7
PS
652 $this->assertSame($author, $file->get_author());
653 $this->assertSame($license, $file->get_license());
67233725
DC
654 $this->assertEquals($newsourcefield, $file->get_source());
655 }
61506a0a
DC
656
657 /**
1d987cb7 658 * Testing deleting original files.
61506a0a
DC
659 *
660 * @copyright 2012 Dongsheng Cai {@link http://dongsheng.org}
661 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
662 */
663 public function test_delete_original_file_from_draft() {
664 global $USER, $DB;
665
666 $this->resetAfterTest(true);
667
668 $generator = $this->getDataGenerator();
669 $user = $generator->create_user();
670 $usercontext = context_user::instance($user->id);
671 $USER = $DB->get_record('user', array('id'=>$user->id));
672
673 $repositorypluginname = 'user';
674
675 $args = array();
676 $args['type'] = $repositorypluginname;
677 $repos = repository::get_instances($args);
678 $userrepository = reset($repos);
679 $this->assertInstanceOf('repository', $userrepository);
680
681 $fs = get_file_storage();
682 $syscontext = context_system::instance();
683
684 $filecontent = 'User file content';
685
1d987cb7 686 // Create a user private file.
61506a0a
DC
687 $userfilerecord = new stdClass;
688 $userfilerecord->contextid = $usercontext->id;
689 $userfilerecord->component = 'user';
690 $userfilerecord->filearea = 'private';
691 $userfilerecord->itemid = 0;
692 $userfilerecord->filepath = '/';
693 $userfilerecord->filename = 'userfile.txt';
694 $userfilerecord->source = 'test';
695 $userfile = $fs->create_file_from_string($userfilerecord, $filecontent);
696 $userfileref = $fs->pack_reference($userfilerecord);
697 $contenthash = $userfile->get_contenthash();
698
699 $filerecord = array(
700 'contextid' => $syscontext->id,
701 'component' => 'core',
702 'filearea' => 'phpunit',
703 'itemid' => 0,
704 'filepath' => '/',
705 'filename' => 'test.txt',
706 );
1d987cb7 707 // Create a file reference.
61506a0a
DC
708 $fileref = $fs->create_file_from_reference($filerecord, $userrepository->id, $userfileref);
709 $this->assertInstanceOf('stored_file', $fileref);
291a3d1f 710 $this->assertEquals($userrepository->id, $fileref->get_repository_id());
1d987cb7 711 $this->assertSame($userfile->get_contenthash(), $fileref->get_contenthash());
61506a0a
DC
712 $this->assertEquals($userfile->get_filesize(), $fileref->get_filesize());
713 $this->assertRegExp('#' . $userfile->get_filename(). '$#', $fileref->get_reference_details());
714
715 $draftitemid = 0;
716 file_prepare_draft_area($draftitemid, $usercontext->id, 'user', 'private', 0);
717 $draftfiles = $fs->get_area_files($usercontext->id, 'user', 'draft', $draftitemid);
1d987cb7 718 $this->assertCount(2, $draftfiles);
61506a0a
DC
719 $draftfile = $fs->get_file($usercontext->id, 'user', 'draft', $draftitemid, $userfilerecord->filepath, $userfilerecord->filename);
720 $draftfile->delete();
1d987cb7 721 // Save changed file.
61506a0a
DC
722 file_save_draft_area_files($draftitemid, $usercontext->id, 'user', 'private', 0);
723
1d987cb7 724 // The file reference should be a regular moodle file now.
61506a0a 725 $fileref = $fs->get_file($syscontext->id, 'core', 'phpunit', 0, '/', 'test.txt');
1d987cb7
PS
726 $this->assertFalse($fileref->is_external_file());
727 $this->assertSame($contenthash, $fileref->get_contenthash());
61506a0a
DC
728 $this->assertEquals($filecontent, $fileref->get_content());
729 }
85cb4b65 730
731 /**
732 * Tests the strip_double_headers function in the curl class.
733 */
734 public function test_curl_strip_double_headers() {
735 // Example from issue tracker.
736 $mdl30648example = <<<EOF
737HTTP/1.0 407 Proxy Authentication Required
738Server: squid/2.7.STABLE9
739Date: Thu, 08 Dec 2011 14:44:33 GMT
740Content-Type: text/html
741Content-Length: 1275
742X-Squid-Error: ERR_CACHE_ACCESS_DENIED 0
743Proxy-Authenticate: Basic realm="Squid proxy-caching web server"
744X-Cache: MISS from homer.lancs.ac.uk
745X-Cache-Lookup: NONE from homer.lancs.ac.uk:3128
746Via: 1.0 homer.lancs.ac.uk:3128 (squid/2.7.STABLE9)
747Connection: close
748
749HTTP/1.0 200 OK
750Server: Apache
751X-Lb-Nocache: true
c3a3f540 752Cache-Control: private, max-age=15, no-transform
85cb4b65 753ETag: "4d69af5d8ba873ea9192c489e151bd7b"
754Content-Type: text/html
755Date: Thu, 08 Dec 2011 14:44:53 GMT
756Set-Cookie: BBC-UID=c4de2e109c8df6a51de627cee11b214bd4fb6054a030222488317afb31b343360MoodleBot/1.0; expires=Mon, 07-Dec-15 14:44:53 GMT; path=/; domain=bbc.co.uk
757X-Cache-Action: MISS
758X-Cache-Age: 0
759Vary: Cookie,X-Country,X-Ip-is-uk-combined,X-Ip-is-advertise-combined,X-Ip_is_uk_combined,X-Ip_is_advertise_combined, X-GeoIP
760X-Cache: MISS from ww
761
762<html>...
763EOF;
764 $mdl30648expected = <<<EOF
765HTTP/1.0 200 OK
766Server: Apache
767X-Lb-Nocache: true
c3a3f540 768Cache-Control: private, max-age=15, no-transform
85cb4b65 769ETag: "4d69af5d8ba873ea9192c489e151bd7b"
770Content-Type: text/html
771Date: Thu, 08 Dec 2011 14:44:53 GMT
772Set-Cookie: BBC-UID=c4de2e109c8df6a51de627cee11b214bd4fb6054a030222488317afb31b343360MoodleBot/1.0; expires=Mon, 07-Dec-15 14:44:53 GMT; path=/; domain=bbc.co.uk
773X-Cache-Action: MISS
774X-Cache-Age: 0
775Vary: Cookie,X-Country,X-Ip-is-uk-combined,X-Ip-is-advertise-combined,X-Ip_is_uk_combined,X-Ip_is_advertise_combined, X-GeoIP
776X-Cache: MISS from ww
777
778<html>...
779EOF;
780 // For HTTP, replace the \n with \r\n.
781 $mdl30648example = preg_replace("~(?!<\r)\n~", "\r\n", $mdl30648example);
782 $mdl30648expected = preg_replace("~(?!<\r)\n~", "\r\n", $mdl30648expected);
783
784 // Test stripping works OK.
1d987cb7 785 $this->assertSame($mdl30648expected, curl::strip_double_headers($mdl30648example));
85cb4b65 786 // Test it does nothing to the 'plain' data.
1d987cb7 787 $this->assertSame($mdl30648expected, curl::strip_double_headers($mdl30648expected));
85cb4b65 788
789 // Example from OU proxy.
790 $httpsexample = <<<EOF
791HTTP/1.0 200 Connection established
792
793HTTP/1.1 200 OK
794Date: Fri, 22 Feb 2013 17:14:23 GMT
795Server: Apache/2
796X-Powered-By: PHP/5.3.3-7+squeeze14
797Content-Type: text/xml
798Connection: close
799Content-Encoding: gzip
800Transfer-Encoding: chunked
801
802<?xml version="1.0" encoding="ISO-8859-1" ?>
803<rss version="2.0">...
804EOF;
805 $httpsexpected = <<<EOF
806HTTP/1.1 200 OK
807Date: Fri, 22 Feb 2013 17:14:23 GMT
808Server: Apache/2
809X-Powered-By: PHP/5.3.3-7+squeeze14
810Content-Type: text/xml
811Connection: close
812Content-Encoding: gzip
813Transfer-Encoding: chunked
814
815<?xml version="1.0" encoding="ISO-8859-1" ?>
816<rss version="2.0">...
817EOF;
818 // For HTTP, replace the \n with \r\n.
819 $httpsexample = preg_replace("~(?!<\r)\n~", "\r\n", $httpsexample);
820 $httpsexpected = preg_replace("~(?!<\r)\n~", "\r\n", $httpsexpected);
821
822 // Test stripping works OK.
1d987cb7 823 $this->assertSame($httpsexpected, curl::strip_double_headers($httpsexample));
85cb4b65 824 // Test it does nothing to the 'plain' data.
1d987cb7 825 $this->assertSame($httpsexpected, curl::strip_double_headers($httpsexpected));
85cb4b65 826 }
91fed57a 827
828 /**
829 * Tests the get_mimetype_description function.
830 */
831 public function test_get_mimetype_description() {
832 $this->resetAfterTest();
833
834 // Test example type (.doc).
835 $this->assertEquals(get_string('application/msword', 'mimetypes'),
836 get_mimetype_description(array('filename' => 'test.doc')));
837
838 // Test an unknown file type.
839 $this->assertEquals(get_string('document/unknown', 'mimetypes'),
840 get_mimetype_description(array('filename' => 'test.frog')));
841
842 // Test a custom filetype with no lang string specified.
843 core_filetypes::add_type('frog', 'application/x-frog', 'document');
844 $this->assertEquals('application/x-frog',
845 get_mimetype_description(array('filename' => 'test.frog')));
846
847 // Test custom description.
848 core_filetypes::update_type('frog', 'frog', 'application/x-frog', 'document',
849 array(), '', 'Froggy file');
850 $this->assertEquals('Froggy file',
851 get_mimetype_description(array('filename' => 'test.frog')));
852
853 // Test custom description using multilang filter.
854 filter_set_global_state('multilang', TEXTFILTER_ON);
855 filter_set_applies_to_strings('multilang', true);
856 core_filetypes::update_type('frog', 'frog', 'application/x-frog', 'document',
857 array(), '', '<span lang="en" class="multilang">Green amphibian</span>' .
858 '<span lang="fr" class="multilang">Amphibian vert</span>');
859 $this->assertEquals('Green amphibian',
860 get_mimetype_description(array('filename' => 'test.frog')));
861 }
862
863 /**
864 * Tests the get_mimetypes_array function.
865 */
866 public function test_get_mimetypes_array() {
867 $mimeinfo = get_mimetypes_array();
868
869 // Test example MIME type (doc).
870 $this->assertEquals('application/msword', $mimeinfo['doc']['type']);
871 $this->assertEquals('document', $mimeinfo['doc']['icon']);
872 $this->assertEquals(array('document'), $mimeinfo['doc']['groups']);
873 $this->assertFalse(isset($mimeinfo['doc']['string']));
874 $this->assertFalse(isset($mimeinfo['doc']['defaulticon']));
875 $this->assertFalse(isset($mimeinfo['doc']['customdescription']));
876
877 // Check the less common fields using other examples.
878 $this->assertEquals('image', $mimeinfo['png']['string']);
879 $this->assertEquals(true, $mimeinfo['txt']['defaulticon']);
880 }
a3d5830a 881}