Merge branch 'MDL-38170-m23' of git://github.com/sammarshallou/moodle into MOODLE_23_...
[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
17
18/**
19 * Unit tests for /lib/filelib.php.
20 *
21 * @package core_files
22 * @category phpunit
23 * @copyright 2009 Jerome Mouneyrac
24 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
25 */
26
27defined('MOODLE_INTERNAL') || die();
28
29global $CFG;
30require_once($CFG->libdir . '/filelib.php');
ac29403e 31require_once($CFG->dirroot . '/repository/lib.php');
a3d5830a 32
67233725 33class filelib_testcase extends advanced_testcase {
a3d5830a
PS
34 public function test_format_postdata_for_curlcall() {
35
36 //POST params with just simple types
37 $postdatatoconvert =array( 'userid' => 1, 'roleid' => 22, 'name' => 'john');
38 $expectedresult = "userid=1&roleid=22&name=john";
39 $postdata = format_postdata_for_curlcall($postdatatoconvert);
40 $this->assertEquals($postdata, $expectedresult);
41
42 //POST params with a string containing & character
43 $postdatatoconvert =array( 'name' => 'john&emilie', 'roleid' => 22);
44 $expectedresult = "name=john%26emilie&roleid=22"; //urlencode: '%26' => '&'
45 $postdata = format_postdata_for_curlcall($postdatatoconvert);
46 $this->assertEquals($postdata, $expectedresult);
47
48 //POST params with an empty value
49 $postdatatoconvert =array( 'name' => null, 'roleid' => 22);
50 $expectedresult = "name=&roleid=22";
51 $postdata = format_postdata_for_curlcall($postdatatoconvert);
52 $this->assertEquals($postdata, $expectedresult);
53
54 //POST params with complex types
55 $postdatatoconvert =array( 'users' => array(
56 array(
57 'id' => 2,
58 'customfields' => array(
59 array
60 (
61 'type' => 'Color',
62 'value' => 'violet'
63 )
64 )
65 )
66 )
67 );
68 $expectedresult = "users[0][id]=2&users[0][customfields][0][type]=Color&users[0][customfields][0][value]=violet";
69 $postdata = format_postdata_for_curlcall($postdatatoconvert);
70 $this->assertEquals($postdata, $expectedresult);
71
72 //POST params with other complex types
73 $postdatatoconvert = array ('members' =>
74 array(
75 array('groupid' => 1, 'userid' => 1)
76 , array('groupid' => 1, 'userid' => 2)
77 )
78 );
79 $expectedresult = "members[0][groupid]=1&members[0][userid]=1&members[1][groupid]=1&members[1][userid]=2";
80 $postdata = format_postdata_for_curlcall($postdatatoconvert);
81 $this->assertEquals($postdata, $expectedresult);
82 }
83
84 public function test_download_file_content() {
85 $testhtml = "http://download.moodle.org/unittest/test.html";
86 $contents = download_file_content($testhtml);
87 $this->assertEquals('47250a973d1b88d9445f94db4ef2c97a', md5($contents));
88 }
67233725
DC
89
90 /**
91 * Testing prepare draft area
92 *
93 * @copyright 2012 Dongsheng Cai {@link http://dongsheng.org}
94 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
95 */
96 public function test_prepare_draft_area() {
97 global $USER, $DB;
98
99 $this->resetAfterTest(true);
100
101 $generator = $this->getDataGenerator();
102 $user = $generator->create_user();
103 $usercontext = context_user::instance($user->id);
104 $USER = $DB->get_record('user', array('id'=>$user->id));
105
7051415c
DC
106 $repositorypluginname = 'user';
107
108 $args = array();
109 $args['type'] = $repositorypluginname;
110 $repos = repository::get_instances($args);
111 $userrepository = reset($repos);
112 $this->assertInstanceOf('repository', $userrepository);
67233725
DC
113
114 $fs = get_file_storage();
7051415c 115
67233725
DC
116 $syscontext = context_system::instance();
117 $component = 'core';
118 $filearea = 'unittest';
119 $itemid = 0;
120 $filepath = '/';
121 $filename = 'test.txt';
122 $sourcefield = 'Copyright stuff';
123
124 $filerecord = array(
125 'contextid' => $syscontext->id,
126 'component' => $component,
127 'filearea' => $filearea,
128 'itemid' => $itemid,
129 'filepath' => $filepath,
130 'filename' => $filename,
131 'source' => $sourcefield,
132 );
133 $ref = $fs->pack_reference($filerecord);
67233725 134 $originalfile = $fs->create_file_from_string($filerecord, 'Test content');
67233725
DC
135 $fileid = $originalfile->get_id();
136 $this->assertInstanceOf('stored_file', $originalfile);
137
7051415c
DC
138 // create a user private file
139 $userfilerecord = new stdClass;
140 $userfilerecord->contextid = $usercontext->id;
141 $userfilerecord->component = 'user';
142 $userfilerecord->filearea = 'private';
143 $userfilerecord->itemid = 0;
144 $userfilerecord->filepath = '/';
145 $userfilerecord->filename = 'userfile.txt';
146 $userfilerecord->source = 'test';
147 $userfile = $fs->create_file_from_string($userfilerecord, 'User file content');
148 $userfileref = $fs->pack_reference($userfilerecord);
149
150 $filerefrecord = clone((object)$filerecord);
151 $filerefrecord->filename = 'testref.txt';
152 // create a file reference
153 $fileref = $fs->create_file_from_reference($filerefrecord, $userrepository->id, $userfileref);
154 $this->assertInstanceOf('stored_file', $fileref);
291a3d1f 155 $this->assertEquals($userrepository->id, $fileref->get_repository_id());
7051415c
DC
156 $this->assertEquals($userfile->get_contenthash(), $fileref->get_contenthash());
157 $this->assertEquals($userfile->get_filesize(), $fileref->get_filesize());
158 $this->assertRegExp('#' . $userfile->get_filename(). '$#', $fileref->get_reference_details());
159
67233725
DC
160 $draftitemid = 0;
161 file_prepare_draft_area($draftitemid, $syscontext->id, $component, $filearea, $itemid);
162
163 $draftfiles = $fs->get_area_files($usercontext->id, 'user', 'draft', $draftitemid);
7051415c 164 $this->assertEquals(3, count($draftfiles));
67233725
DC
165
166 $draftfile = $fs->get_file($usercontext->id, 'user', 'draft', $draftitemid, $filepath, $filename);
167 $source = unserialize($draftfile->get_source());
168 $this->assertEquals($ref, $source->original);
169 $this->assertEquals($sourcefield, $source->source);
170
7051415c
DC
171 $draftfileref = $fs->get_file($usercontext->id, 'user', 'draft', $draftitemid, $filepath, $filerefrecord->filename);
172 $this->assertInstanceOf('stored_file', $draftfileref);
173 $this->assertEquals(true, $draftfileref->is_external_file());
67233725
DC
174
175 // change some information
176 $author = 'Dongsheng Cai';
177 $draftfile->set_author($author);
7051415c 178 $newsourcefield = 'Get from Flickr';
67233725
DC
179 $license = 'GPLv3';
180 $draftfile->set_license($license);
181 // if you want to really just change source field, do this:
182 $source = unserialize($draftfile->get_source());
183 $newsourcefield = 'From flickr';
184 $source->source = $newsourcefield;
185 $draftfile->set_source(serialize($source));
186
187 // Save changed file
188 file_save_draft_area_files($draftitemid, $syscontext->id, $component, $filearea, $itemid);
189
190 $file = $fs->get_file($syscontext->id, $component, $filearea, $itemid, $filepath, $filename);
191
192 // Make sure it's the original file id
193 $this->assertEquals($fileid, $file->get_id());
194 $this->assertInstanceOf('stored_file', $file);
195 $this->assertEquals($author, $file->get_author());
196 $this->assertEquals($license, $file->get_license());
197 $this->assertEquals($newsourcefield, $file->get_source());
198 }
61506a0a
DC
199
200 /**
201 * Testing deleting original files
202 *
203 * @copyright 2012 Dongsheng Cai {@link http://dongsheng.org}
204 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
205 */
206 public function test_delete_original_file_from_draft() {
207 global $USER, $DB;
208
209 $this->resetAfterTest(true);
210
211 $generator = $this->getDataGenerator();
212 $user = $generator->create_user();
213 $usercontext = context_user::instance($user->id);
214 $USER = $DB->get_record('user', array('id'=>$user->id));
215
216 $repositorypluginname = 'user';
217
218 $args = array();
219 $args['type'] = $repositorypluginname;
220 $repos = repository::get_instances($args);
221 $userrepository = reset($repos);
222 $this->assertInstanceOf('repository', $userrepository);
223
224 $fs = get_file_storage();
225 $syscontext = context_system::instance();
226
227 $filecontent = 'User file content';
228
229 // create a user private file
230 $userfilerecord = new stdClass;
231 $userfilerecord->contextid = $usercontext->id;
232 $userfilerecord->component = 'user';
233 $userfilerecord->filearea = 'private';
234 $userfilerecord->itemid = 0;
235 $userfilerecord->filepath = '/';
236 $userfilerecord->filename = 'userfile.txt';
237 $userfilerecord->source = 'test';
238 $userfile = $fs->create_file_from_string($userfilerecord, $filecontent);
239 $userfileref = $fs->pack_reference($userfilerecord);
240 $contenthash = $userfile->get_contenthash();
241
242 $filerecord = array(
243 'contextid' => $syscontext->id,
244 'component' => 'core',
245 'filearea' => 'phpunit',
246 'itemid' => 0,
247 'filepath' => '/',
248 'filename' => 'test.txt',
249 );
250 // create a file reference
251 $fileref = $fs->create_file_from_reference($filerecord, $userrepository->id, $userfileref);
252 $this->assertInstanceOf('stored_file', $fileref);
291a3d1f 253 $this->assertEquals($userrepository->id, $fileref->get_repository_id());
61506a0a
DC
254 $this->assertEquals($userfile->get_contenthash(), $fileref->get_contenthash());
255 $this->assertEquals($userfile->get_filesize(), $fileref->get_filesize());
256 $this->assertRegExp('#' . $userfile->get_filename(). '$#', $fileref->get_reference_details());
257
258 $draftitemid = 0;
259 file_prepare_draft_area($draftitemid, $usercontext->id, 'user', 'private', 0);
260 $draftfiles = $fs->get_area_files($usercontext->id, 'user', 'draft', $draftitemid);
261 $this->assertEquals(2, count($draftfiles));
262 $draftfile = $fs->get_file($usercontext->id, 'user', 'draft', $draftitemid, $userfilerecord->filepath, $userfilerecord->filename);
263 $draftfile->delete();
264 // Save changed file
265 file_save_draft_area_files($draftitemid, $usercontext->id, 'user', 'private', 0);
266
267 // The file reference should be a regular moodle file now
268 $fileref = $fs->get_file($syscontext->id, 'core', 'phpunit', 0, '/', 'test.txt');
269 $this->assertEquals(false, $fileref->is_external_file());
270 $this->assertEquals($contenthash, $fileref->get_contenthash());
271 $this->assertEquals($filecontent, $fileref->get_content());
272 }
e97baa19 273
274 /**
275 * Tests the strip_double_headers function in the curl class.
276 */
277 public function test_curl_strip_double_headers() {
278 // Example from issue tracker.
279 $mdl30648example = <<<EOF
280HTTP/1.0 407 Proxy Authentication Required
281Server: squid/2.7.STABLE9
282Date: Thu, 08 Dec 2011 14:44:33 GMT
283Content-Type: text/html
284Content-Length: 1275
285X-Squid-Error: ERR_CACHE_ACCESS_DENIED 0
286Proxy-Authenticate: Basic realm="Squid proxy-caching web server"
287X-Cache: MISS from homer.lancs.ac.uk
288X-Cache-Lookup: NONE from homer.lancs.ac.uk:3128
289Via: 1.0 homer.lancs.ac.uk:3128 (squid/2.7.STABLE9)
290Connection: close
291
292HTTP/1.0 200 OK
293Server: Apache
294X-Lb-Nocache: true
295Cache-Control: private, max-age=15
296ETag: "4d69af5d8ba873ea9192c489e151bd7b"
297Content-Type: text/html
298Date: Thu, 08 Dec 2011 14:44:53 GMT
299Set-Cookie: BBC-UID=c4de2e109c8df6a51de627cee11b214bd4fb6054a030222488317afb31b343360MoodleBot/1.0; expires=Mon, 07-Dec-15 14:44:53 GMT; path=/; domain=bbc.co.uk
300X-Cache-Action: MISS
301X-Cache-Age: 0
302Vary: 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
303X-Cache: MISS from ww
304
305<html>...
306EOF;
307 $mdl30648expected = <<<EOF
308HTTP/1.0 200 OK
309Server: Apache
310X-Lb-Nocache: true
311Cache-Control: private, max-age=15
312ETag: "4d69af5d8ba873ea9192c489e151bd7b"
313Content-Type: text/html
314Date: Thu, 08 Dec 2011 14:44:53 GMT
315Set-Cookie: BBC-UID=c4de2e109c8df6a51de627cee11b214bd4fb6054a030222488317afb31b343360MoodleBot/1.0; expires=Mon, 07-Dec-15 14:44:53 GMT; path=/; domain=bbc.co.uk
316X-Cache-Action: MISS
317X-Cache-Age: 0
318Vary: 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
319X-Cache: MISS from ww
320
321<html>...
322EOF;
323 // For HTTP, replace the \n with \r\n.
324 $mdl30648example = preg_replace("~(?!<\r)\n~", "\r\n", $mdl30648example);
325 $mdl30648expected = preg_replace("~(?!<\r)\n~", "\r\n", $mdl30648expected);
326
327 // Test stripping works OK.
328 $this->assertEquals($mdl30648expected, curl::strip_double_headers($mdl30648example));
329 // Test it does nothing to the 'plain' data.
330 $this->assertEquals($mdl30648expected, curl::strip_double_headers($mdl30648expected));
331
332 // Example from OU proxy.
333 $httpsexample = <<<EOF
334HTTP/1.0 200 Connection established
335
336HTTP/1.1 200 OK
337Date: Fri, 22 Feb 2013 17:14:23 GMT
338Server: Apache/2
339X-Powered-By: PHP/5.3.3-7+squeeze14
340Content-Type: text/xml
341Connection: close
342Content-Encoding: gzip
343Transfer-Encoding: chunked
344
345<?xml version="1.0" encoding="ISO-8859-1" ?>
346<rss version="2.0">...
347EOF;
348 $httpsexpected = <<<EOF
349HTTP/1.1 200 OK
350Date: Fri, 22 Feb 2013 17:14:23 GMT
351Server: Apache/2
352X-Powered-By: PHP/5.3.3-7+squeeze14
353Content-Type: text/xml
354Connection: close
355Content-Encoding: gzip
356Transfer-Encoding: chunked
357
358<?xml version="1.0" encoding="ISO-8859-1" ?>
359<rss version="2.0">...
360EOF;
361 // For HTTP, replace the \n with \r\n.
362 $httpsexample = preg_replace("~(?!<\r)\n~", "\r\n", $httpsexample);
363 $httpsexpected = preg_replace("~(?!<\r)\n~", "\r\n", $httpsexpected);
364
365 // Test stripping works OK.
366 $this->assertEquals($httpsexpected, curl::strip_double_headers($httpsexample));
367 // Test it does nothing to the 'plain' data.
368 $this->assertEquals($httpsexpected, curl::strip_double_headers($httpsexpected));
369 }
a3d5830a 370}