MDL-33509 forms: Change button type in url resource editing page
[moodle.git] / calendar / tests / event_factory_test.php
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/>.
17 /**
18  * Event factory test.
19  *
20  * @package    core_calendar
21  * @copyright  2017 Cameron Ball <cameron@cameron1729.xyz>
22  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23  */
25 defined('MOODLE_INTERNAL') || die();
27 global $CFG;
28 require_once($CFG->dirroot . '/calendar/lib.php');
30 use core_calendar\local\event\factories\event_factory;
31 use core_calendar\local\event\entities\event_interface;
33 /**
34  * Event factory testcase.
35  *
36  * @copyright 2017 Cameron Ball <cameron@cameron1729.xyz>
37  * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
38  */
39 class core_calendar_event_factory_testcase extends advanced_testcase {
40     /**
41      * Test event class getters.
42      *
43      * @dataProvider create_instance_testcases()
44      * @param \stdClass $dbrow Row from the event table.
45      * @param callable  $actioncallbackapplier     Action callback applier.
46      * @param callable  $visibilitycallbackapplier Visibility callback applier.
47      * @param callable  $bailoutcheck              Early bail out check function.
48      * @param string    $expectedclass             Class the factory is expected to produce.
49      * @param mixed     $expectedattributevalue    Expected value of the modified attribute.
50      */
51     public function test_create_instance(
52         $dbrow,
53         callable $actioncallbackapplier,
54         callable $visibilitycallbackapplier,
55         callable $bailoutcheck,
56         $expectedclass,
57         $expectedattributevalue
58     ) {
59         $this->resetAfterTest(true);
60         $this->setAdminUser();
61         $event = $this->create_event();
62         $coursecache = [];
63         $modulecache = [];
64         $factory = new event_factory(
65             $actioncallbackapplier,
66             $visibilitycallbackapplier,
67             $bailoutcheck,
68             $coursecache,
69             $modulecache
70         );
71         $dbrow->id = $event->id;
72         $instance = $factory->create_instance($dbrow);
74         if ($expectedclass) {
75             $this->assertInstanceOf($expectedclass, $instance);
76         }
78         if (is_null($expectedclass)) {
79             $this->assertNull($instance);
80         }
82         if ($expectedattributevalue) {
83             $this->assertEquals($instance->testattribute, $expectedattributevalue);
84         }
85     }
87     /**
88      * Test invalid callback exception.
89      */
90     public function test_invalid_action_callback() {
91         $this->resetAfterTest(true);
92         $this->setAdminUser();
93         $event = $this->create_event();
94         $coursecache = [];
95         $modulecache = [];
96         $factory = new event_factory(
97             function () {
98                 return 'hello';
99             },
100             function () {
101                 return true;
102             },
103             function () {
104                 return false;
105             },
106             $coursecache,
107             $modulecache
108         );
110         $this->expectException('\core_calendar\local\event\exceptions\invalid_callback_exception');
111         $factory->create_instance(
112             (object)[
113                 'id' => $event->id,
114                 'name' => 'test',
115                 'description' => 'Test description',
116                 'format' => 2,
117                 'categoryid' => 0,
118                 'courseid' => 1,
119                 'groupid' => 1,
120                 'userid' => 1,
121                 'repeatid' => 0,
122                 'modulename' => 'assign',
123                 'instance' => 1,
124                 'eventtype' => 'due',
125                 'type' => CALENDAR_EVENT_TYPE_ACTION,
126                 'timestart' => 123456789,
127                 'timeduration' => 12,
128                 'timemodified' => 123456789,
129                 'timesort' => 123456789,
130                 'visible' => 1,
131                 'subscriptionid' => 1
132             ]
133         );
134     }
136     /**
137      * Test invalid callback exception.
138      */
139     public function test_invalid_visibility_callback() {
140         $this->resetAfterTest(true);
141         $this->setAdminUser();
142         $event = $this->create_event();
143         $coursecache = [];
144         $modulecache = [];
145         $factory = new event_factory(
146             function ($event) {
147                 return $event;
148             },
149             function () {
150                 return 'asdf';
151             },
152             function () {
153                 return false;
154             },
155             $coursecache,
156             $modulecache
157         );
159         $this->expectException('\core_calendar\local\event\exceptions\invalid_callback_exception');
160         $factory->create_instance(
161             (object)[
162                 'id' => $event->id,
163                 'name' => 'test',
164                 'description' => 'Test description',
165                 'format' => 2,
166                 'categoryid' => 0,
167                 'courseid' => 1,
168                 'groupid' => 1,
169                 'userid' => 1,
170                 'repeatid' => 0,
171                 'modulename' => 'assign',
172                 'instance' => 1,
173                 'eventtype' => 'due',
174                 'type' => CALENDAR_EVENT_TYPE_ACTION,
175                 'timestart' => 123456789,
176                 'timeduration' => 12,
177                 'timemodified' => 123456789,
178                 'timesort' => 123456789,
179                 'visible' => 1,
180                 'subscriptionid' => 1
181             ]
182         );
183     }
185     /**
186      * Test invalid callback exception.
187      */
188     public function test_invalid_bail_callback() {
189         $this->resetAfterTest(true);
190         $this->setAdminUser();
191         $event = $this->create_event();
192         $coursecache = [];
193         $modulecache = [];
194         $factory = new event_factory(
195             function ($event) {
196                 return $event;
197             },
198             function () {
199                 return true;
200             },
201             function () {
202                 return 'asdf';
203             },
204             $coursecache,
205             $modulecache
206         );
208         $this->expectException('\core_calendar\local\event\exceptions\invalid_callback_exception');
209         $factory->create_instance(
210             (object)[
211                 'id' => $event->id,
212                 'name' => 'test',
213                 'description' => 'Test description',
214                 'format' => 2,
215                 'categoryid' => 0,
216                 'courseid' => 1,
217                 'groupid' => 1,
218                 'userid' => 1,
219                 'repeatid' => 0,
220                 'modulename' => 'assign',
221                 'instance' => 1,
222                 'eventtype' => 'due',
223                 'type' => CALENDAR_EVENT_TYPE_ACTION,
224                 'timestart' => 123456789,
225                 'timeduration' => 12,
226                 'timemodified' => 123456789,
227                 'timesort' => 123456789,
228                 'visible' => 1,
229                 'subscriptionid' => 1
230             ]
231         );
232     }
234     /**
235      * Test the factory's course cache.
236      */
237     public function test_course_cache() {
238         $this->resetAfterTest(true);
239         $this->setAdminUser();
240         $course = self::getDataGenerator()->create_course();
241         $event = $this->create_event(['courseid' => $course->id]);
242         $coursecache = [];
243         $modulecache = [];
244         $factory = new event_factory(
245             function ($event) {
246                 return $event;
247             },
248             function () {
249                 return true;
250             },
251             function () {
252                 return false;
253             },
254             $coursecache,
255             $modulecache
256         );
258         $instance = $factory->create_instance(
259             (object)[
260                 'id' => $event->id,
261                 'name' => 'test',
262                 'description' => 'Test description',
263                 'format' => 2,
264                 'categoryid' => 0,
265                 'courseid' => $course->id,
266                 'groupid' => 1,
267                 'userid' => 1,
268                 'repeatid' => 0,
269                 'modulename' => 'assign',
270                 'instance' => 1,
271                 'eventtype' => 'due',
272                 'type' => CALENDAR_EVENT_TYPE_ACTION,
273                 'timestart' => 123456789,
274                 'timeduration' => 12,
275                 'timemodified' => 123456789,
276                 'timesort' => 123456789,
277                 'visible' => 1,
278                 'subscriptionid' => 1
279             ]
280         );
282         $instance->get_course()->get('fullname');
283         $this->assertArrayHasKey($course->id, $coursecache);
284     }
286     /**
287      * Test the factory's module cache.
288      */
289     public function test_module_cache() {
290         $this->resetAfterTest(true);
291         $this->setAdminUser();
292         $course = self::getDataGenerator()->create_course();
293         $event = $this->create_event(['courseid' => $course->id]);
294         $plugingenerator = $this->getDataGenerator()->get_plugin_generator('mod_assign');
295         $assigninstance = $plugingenerator->create_instance(['course' => $course->id]);
297         $coursecache = [];
298         $modulecache = [];
299         $factory = new event_factory(
300             function ($event) {
301                 return $event;
302             },
303             function () {
304                 return true;
305             },
306             function () {
307                 return false;
308             },
309             $coursecache,
310             $modulecache
311         );
313         $instance = $factory->create_instance(
314             (object)[
315                 'id' => $event->id,
316                 'name' => 'test',
317                 'description' => 'Test description',
318                 'format' => 2,
319                 'categoryid' => 0,
320                 'courseid' => 0,
321                 'groupid' => 1,
322                 'userid' => 1,
323                 'repeatid' => 0,
324                 'modulename' => 'assign',
325                 'instance' => $assigninstance->id,
326                 'eventtype' => 'due',
327                 'type' => CALENDAR_EVENT_TYPE_ACTION,
328                 'timestart' => 123456789,
329                 'timeduration' => 12,
330                 'timemodified' => 123456789,
331                 'timesort' => 123456789,
332                 'visible' => 1,
333                 'subscriptionid' => 1
334             ]
335         );
337         $instance->get_course_module()->get('course');
338         $this->assertArrayHasKey('assign' . '_' . $assigninstance->id, $modulecache);
339     }
341     /**
342      * Testcases for the create instance test.
343      *
344      * @return array Array of testcases.
345      */
346     public function create_instance_testcases() {
347         return [
348             'Sample event record with event exposed' => [
349                 'dbrow' => (object)[
350                     'name' => 'Test event',
351                     'description' => 'Hello',
352                     'format' => 1,
353                     'categoryid' => 0,
354                     'courseid' => 1,
355                     'groupid' => 1,
356                     'userid' => 1,
357                     'repeatid' => 0,
358                     'modulename' => 'Test module',
359                     'instance' => 1,
360                     'eventtype' => 'Due',
361                     'type' => CALENDAR_EVENT_TYPE_ACTION,
362                     'timestart' => 123456789,
363                     'timeduration' => 123456789,
364                     'timemodified' => 123456789,
365                     'timesort' => 123456789,
366                     'visible' => true,
367                     'subscriptionid' => 1
368                 ],
369                 'actioncallbackapplier' => function(event_interface $event) {
370                     $event->testattribute = 'Hello';
371                     return $event;
372                 },
373                 'visibilitycallbackapplier' => function(event_interface $event) {
374                     return true;
375                 },
376                 'bailoutcheck' => function() {
377                     return false;
378                 },
379                 event_interface::class,
380                 'Hello'
381             ],
382             'Sample event record with event hidden' => [
383                 'dbrow' => (object)[
384                     'name' => 'Test event',
385                     'description' => 'Hello',
386                     'format' => 1,
387                     'categoryid' => 0,
388                     'courseid' => 1,
389                     'groupid' => 1,
390                     'userid' => 1,
391                     'repeatid' => 0,
392                     'modulename' => 'Test module',
393                     'instance' => 1,
394                     'eventtype' => 'Due',
395                     'type' => CALENDAR_EVENT_TYPE_ACTION,
396                     'timestart' => 123456789,
397                     'timeduration' => 123456789,
398                     'timemodified' => 123456789,
399                     'timesort' => 123456789,
400                     'visible' => true,
401                     'subscriptionid' => 1
402                 ],
403                 'actioncallbackapplier' => function(event_interface $event) {
404                     $event->testattribute = 'Hello';
405                     return $event;
406                 },
407                 'visibilitycallbackapplier' => function(event_interface $event) {
408                     return false;
409                 },
410                 'bailoutcheck' => function() {
411                     return false;
412                 },
413                 null,
414                 null
415             ],
416             'Sample event record with early bail' => [
417                 'dbrow' => (object)[
418                     'name' => 'Test event',
419                     'description' => 'Hello',
420                     'format' => 1,
421                     'categoryid' => 0,
422                     'courseid' => 1,
423                     'groupid' => 1,
424                     'userid' => 1,
425                     'repeatid' => 0,
426                     'modulename' => 'Test module',
427                     'instance' => 1,
428                     'eventtype' => 'Due',
429                     'type' => CALENDAR_EVENT_TYPE_ACTION,
430                     'timestart' => 123456789,
431                     'timeduration' => 123456789,
432                     'timemodified' => 123456789,
433                     'timesort' => 123456789,
434                     'visible' => true,
435                     'subscriptionid' => 1
436                 ],
437                 'actioncallbackapplier' => function(event_interface $event) {
438                     $event->testattribute = 'Hello';
439                     return $event;
440                 },
441                 'visibilitycallbackapplier' => function(event_interface $event) {
442                     return true;
443                 },
444                 'bailoutcheck' => function() {
445                     return true;
446                 },
447                 null,
448                 null
449             ]
450         ];
451     }
453     /**
454      * Helper function to create calendar events using the old code.
455      *
456      * @param array $properties A list of calendar event properties to set
457      * @return calendar_event
458      */
459     protected function create_event($properties = []) {
460         $record = new \stdClass();
461         $record->name = 'event name';
462         $record->eventtype = 'global';
463         $record->timestart = time();
464         $record->timeduration = 0;
465         $record->timesort = 0;
466         $record->type = 1;
467         $record->courseid = 0;
468         $record->categoryid = 0;
470         foreach ($properties as $name => $value) {
471             $record->$name = $value;
472         }
474         $event = new calendar_event($record);
475         return $event->create($record, false);
476     }