4135c182c54a54c44b82978d2f8d869914fdedba
[moodle.git] / lib / simpletest / portfolio_testclass.php
1 <?php
3 ///////////////////////////////////////////////////////////////////////////
4 //                                                                       //
5 // NOTICE OF COPYRIGHT                                                   //
6 //                                                                       //
7 // Moodle - Modular Object-Oriented Dynamic Learning Environment         //
8 //          http://moodle.org                                            //
9 //                                                                       //
10 // Copyright (C) 1999 onwards Martin Dougiamas  http://dougiamas.com     //
11 //                                                                       //
12 // This program is free software; you can redistribute it and/or modify  //
13 // it under the terms of the GNU General Public License as published by  //
14 // the Free Software Foundation; either version 2 of the License, or     //
15 // (at your option) any later version.                                   //
16 //                                                                       //
17 // This program is distributed in the hope that it will be useful,       //
18 // but WITHOUT ANY WARRANTY; without even the implied warranty of        //
19 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         //
20 // GNU General Public License for more details:                          //
21 //                                                                       //
22 //          http://www.gnu.org/copyleft/gpl.html                         //
23 //                                                                       //
24 ///////////////////////////////////////////////////////////////////////////
26 /**
27  * Unit tests for  ../portfoliolib.php.
28  *
29  * @author nicolasconnault@gmail.com
30  * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
31  * @package moodlecore
32  */
34 if (!defined('MOODLE_INTERNAL')) {
35     die('Direct access to this script is forbidden.');    ///  It must be included from a Moodle page
36 }
38 require_once("$CFG->libdir/portfoliolib.php");
39 require_once("$CFG->libdir/portfolio/exporter.php");
40 require_once("$CFG->libdir/portfolio/plugin.php");
41 require_once("$CFG->dirroot/$CFG->admin/generator.php");
43 class portfolio_plugin_test extends portfolio_plugin_push_base {
44     public function expected_time($callertime){
45         return $callertime;
46     }
48     public function prepare_package() {
49         return true;
50     }
52     public function send_package() {
53         return true;
54     }
56     public function get_interactive_continue_url() {
57         return '';
58     }
60     public static function get_name() {
61         return '';
62     }
63 }
65 class portfolio_caller_test extends portfolio_caller_base {
66     private $content;
68     public function __construct($content) {
69         $this->content = $content;
70     }
72     public function expected_time() {
73         return PORTFOLIO_TIME_LOW;
74     }
76     public function get_navigation() {
77         $extranav = array('name' => 'Test caller class', 'link' => $this->get_return_url());
78         return array($extranav, 'test');
79     }
81     public function get_sha1(){
82         return sha1($this->content);
83     }
85     public function prepare_package() {
87     }
89     public function get_return_url() {
90         return '';
91     }
93     public function check_permissions() {
94         return true;
95     }
97     public static function display_name() {
98         return "Test caller subclass";
99     }
101     public function load_data() {
103     }
105     public static function expected_callbackargs() {
106         return array();
107     }
108     public static function base_supported_formats() {
109         return array(PORTFOLIO_FORMAT_RICH, PORTFOLIO_FORMAT_FILE);
110     }
111     public function set_context($PAGE) {
112         $PAGE->set_context(get_system_context());
113     }
116 class portfolio_exporter_test extends portfolio_exporter {
117     private $files;
119     public function write_new_file($content, $name) {
120         if (empty($this->files)) {
121             $this->files = array();
122         }
123         $this->files[] = new portfolio_fake_file($content, $name);
124     }
126     public function copy_existing_file($oldfile) {
127         throw new portfolio_exception('notimplemented', 'portfolio', 'files api test');
128     }
130     public function get_tempfiles() {
131         return $this->files;
132     }
134     public function zip_tempfiles() {
135         return new portfolio_fake_file('fake content zipfile', 'portfolio-export.zip');
136     }
139 /**
140 * this should be REMOVED when we have proper faking of the files api
141 */
142 class portfolio_fake_file {
144     private $name;
145     private $content;
146     private $hash;
147     private $size;
149     public function __construct($content, $name) {
150         $this->content = $content;
151         $this->name = $name;
152         $this->hash = sha1($content);
153         $this->size = strlen($content);
154     }
156     public function get_contenthash() {
157         return $this->hash;
158     }
160     public function get_filename() {
161         return $this->name;
162     }
164     public function get_filesize() {
165         return $this->size;
166     }
169 /**
170  * The following two classes are full mocks: none of their methods do anything, including their constructor.
171  * They can be instantiated directly with no params (new portfolio_caller_test())
172  */
173 Mock::generate('portfolio_caller_test', 'mock_caller');
174 Mock::generate('portfolio_plugin_test', 'mock_plugin');
176 /**
177  * Partial mocks work as normal except the methods listed in the 3rd param, which are mocked.
178  * They are instantiated by passing $this to the constructor within the test case class.
179  */
180 Mock::generatePartial('portfolio_plugin_test', 'partialmock_plugin', array('send_package'));
181 Mock::generatePartial('portfolio_exporter_test', 'partialmock_exporter', array('process_stage_confirm',
182                                                                                'process_stage_cleanup',
183                                                                                'log_transfer',
184                                                                                'save',
185                                                                                'rewaken_object'));
188 // Generate a mock class for each plugin subclass present
189 $portfolio_plugins = get_list_of_plugins('portfolio');
190 foreach ($portfolio_plugins as $plugin) {
191     require_once($CFG->dirroot . "/portfolio/$plugin/lib.php");
192     Mock::generatePartial("portfolio_plugin_$plugin", "partialmock_plugin_$plugin", array('send_package'));
195 class portfoliolib_test extends FakeDBUnitTestCase {
197     function setup() {
198         parent::setup();
199     }
201     function test_construct_dupe_instance() {
202         $gotexception = false;
203         try {
204             $plugin1 = portfolio_plugin_base::create_instance('download', 'download1', array());
205             $plugin2 = portfolio_plugin_base::create_instance('download', 'download2', array());
206             $test1 = new portfolio_plugin_download($plugin1->get('id'));
207         } catch (portfolio_exception $e) {
208             $this->assertEqual('multipledisallowed', $e->errorcode);
209             $gotexception = true;
210         }
211         $this->assertTrue($gotexception);
212     }
214     /**
215     * does everything we need to set up a new caller
216     * so each subclass doesn't have to implement this
217     *
218     * @param string $class name of caller class to generate (this class def must be already loaded)
219     * @param array $callbackargs the arguments to pass the constructor of the caller
220     * @param int $userid a userid the subclass has generated
221     *
222     * @return portfolio_caller_base subclass
223     */
224     protected function setup_caller($class, $callbackargs, $user=null) {
225         global $DB;
226         $caller = new $class($callbackargs);
227         $caller->set('exporter', new partialmock_exporter($this));
228         if (is_numeric($user)) {
229             $user = $DB->get_record('user', array('id' => $user));
230         }
231         if (is_object($user)) {
232             $caller->set('user', $user);
233         }
234         $caller->load_data();
235         // set any format
236         $caller->get('exporter')->set('format', array_shift($caller->supported_formats()));
237         return $caller;
238     }
240     public function test_caller_with_plugins() {
241         if (!empty($this->caller)) {
242             $plugins = get_list_of_plugins('portfolio');
244             foreach ($plugins as $plugin) {
245                 // Instantiate a fake plugin instance
246                 $plugin_class = "partialmock_plugin_$plugin";
247                 $plugin = new $plugin_class($this);
249                 // figure out our format intersection and test all of them.
250                 $formats = portfolio_supported_formats_intersect($this->caller->supported_formats(), $plugin->supported_formats());
251                 if (count($formats) == 0) {
252                     // bail. no common formats.
253                     continue;
254                 }
256                 foreach ($formats as $format) {
257                     // Create a new fake exporter
258                     $exporter =& $this->caller->get('exporter'); // new partialmock_exporter(&$this);
259                     $exporter->set('caller', $this->caller);
260                     $exporter->set('instance', $plugin);
261                     $exporter->set('format', $format);
262                     $this->caller->set_export_config(array('format' => $format));
263                     $plugin->set_export_config(array('format' => $format));
264                     $exporter->set('user', $this->caller->get('user'));
266                     $exception = false;
267                     try {
268                         $exporter->process_stage_package();
269                     } catch (Exception $e) {
270                         $exception = $e->getMessage();
271                     }
273                     $this->assertFalse($exception, "Unwanted exception: $exception");
274                 }
275             }
276         }
277     }