Search moodle.org's
Developer Documentation

  • Bug fixes for general core bugs in 3.7.x will end 11 May 2020 (12 months).
  • Bug fixes for security issues in 3.7.x will end 9 November 2020 (18 months) - Support has ended.
  • minimum PHP 7.1.0 Note: minimum PHP version has increased since Moodle 3.6. PHP 7.2.x and 7.3.x are supported too. PHP 7.x could have some engine limitations.
  • Differences Between: [Versions 35 and 37] [Versions 37 and 310] [Versions 37 and 311] [Versions 37 and 38] [Versions 37 and 39]

       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   * 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   */
      24  
      25  defined('MOODLE_INTERNAL') || die();
      26  
      27  global $CFG;
      28  require_once($CFG->dirroot . '/calendar/lib.php');
      29  
      30  use core_calendar\local\event\factories\event_factory;
      31  use core_calendar\local\event\entities\event_interface;
      32  
      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);
      73  
      74          if ($expectedclass) {
      75              $this->assertInstanceOf($expectedclass, $instance);
      76          }
      77  
      78          if (is_null($expectedclass)) {
      79              $this->assertNull($instance);
      80          }
      81  
      82          if ($expectedattributevalue) {
      83              $this->assertEquals($instance->testattribute, $expectedattributevalue);
      84          }
      85      }
      86  
      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          );
     109  
     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                  'location' => 'Test location',
     133              ]
     134          );
     135      }
     136  
     137      /**
     138       * Test invalid callback exception.
     139       */
     140      public function test_invalid_visibility_callback() {
     141          $this->resetAfterTest(true);
     142          $this->setAdminUser();
     143          $event = $this->create_event();
     144          $coursecache = [];
     145          $modulecache = [];
     146          $factory = new event_factory(
     147              function ($event) {
     148                  return $event;
     149              },
     150              function () {
     151                  return 'asdf';
     152              },
     153              function () {
     154                  return false;
     155              },
     156              $coursecache,
     157              $modulecache
     158          );
     159  
     160          $this->expectException('\core_calendar\local\event\exceptions\invalid_callback_exception');
     161          $factory->create_instance(
     162              (object)[
     163                  'id' => $event->id,
     164                  'name' => 'test',
     165                  'description' => 'Test description',
     166                  'format' => 2,
     167                  'categoryid' => 0,
     168                  'courseid' => 1,
     169                  'groupid' => 1,
     170                  'userid' => 1,
     171                  'repeatid' => 0,
     172                  'modulename' => 'assign',
     173                  'instance' => 1,
     174                  'eventtype' => 'due',
     175                  'type' => CALENDAR_EVENT_TYPE_ACTION,
     176                  'timestart' => 123456789,
     177                  'timeduration' => 12,
     178                  'timemodified' => 123456789,
     179                  'timesort' => 123456789,
     180                  'visible' => 1,
     181                  'subscriptionid' => 1,
     182                  'location' => 'Test location',
     183              ]
     184          );
     185      }
     186  
     187      /**
     188       * Test invalid callback exception.
     189       */
     190      public function test_invalid_bail_callback() {
     191          $this->resetAfterTest(true);
     192          $this->setAdminUser();
     193          $event = $this->create_event();
     194          $coursecache = [];
     195          $modulecache = [];
     196          $factory = new event_factory(
     197              function ($event) {
     198                  return $event;
     199              },
     200              function () {
     201                  return true;
     202              },
     203              function () {
     204                  return 'asdf';
     205              },
     206              $coursecache,
     207              $modulecache
     208          );
     209  
     210          $this->expectException('\core_calendar\local\event\exceptions\invalid_callback_exception');
     211          $factory->create_instance(
     212              (object)[
     213                  'id' => $event->id,
     214                  'name' => 'test',
     215                  'description' => 'Test description',
     216                  'format' => 2,
     217                  'categoryid' => 0,
     218                  'courseid' => 1,
     219                  'groupid' => 1,
     220                  'userid' => 1,
     221                  'repeatid' => 0,
     222                  'modulename' => 'assign',
     223                  'instance' => 1,
     224                  'eventtype' => 'due',
     225                  'type' => CALENDAR_EVENT_TYPE_ACTION,
     226                  'timestart' => 123456789,
     227                  'timeduration' => 12,
     228                  'timemodified' => 123456789,
     229                  'timesort' => 123456789,
     230                  'visible' => 1,
     231                  'subscriptionid' => 1,
     232                  'location' => 'Test location',
     233              ]
     234          );
     235      }
     236  
     237      /**
     238       * Test the factory's course cache.
     239       */
     240      public function test_course_cache() {
     241          $this->resetAfterTest(true);
     242          $this->setAdminUser();
     243          $course = self::getDataGenerator()->create_course();
     244          $event = $this->create_event(['courseid' => $course->id]);
     245          $coursecache = [];
     246          $modulecache = [];
     247          $factory = new event_factory(
     248              function ($event) {
     249                  return $event;
     250              },
     251              function () {
     252                  return true;
     253              },
     254              function () {
     255                  return false;
     256              },
     257              $coursecache,
     258              $modulecache
     259          );
     260  
     261          $instance = $factory->create_instance(
     262              (object)[
     263                  'id' => $event->id,
     264                  'name' => 'test',
     265                  'description' => 'Test description',
     266                  'format' => 2,
     267                  'categoryid' => 0,
     268                  'courseid' => $course->id,
     269                  'groupid' => 1,
     270                  'userid' => 1,
     271                  'repeatid' => 0,
     272                  'modulename' => 'assign',
     273                  'instance' => 1,
     274                  'eventtype' => 'due',
     275                  'type' => CALENDAR_EVENT_TYPE_ACTION,
     276                  'timestart' => 123456789,
     277                  'timeduration' => 12,
     278                  'timemodified' => 123456789,
     279                  'timesort' => 123456789,
     280                  'visible' => 1,
     281                  'subscriptionid' => 1,
     282                  'location' => 'Test location',
     283              ]
     284          );
     285  
     286          $instance->get_course()->get('fullname');
     287          $this->assertArrayHasKey($course->id, $coursecache);
     288      }
     289  
     290      /**
     291       * Test the factory's module cache.
     292       */
     293      public function test_module_cache() {
     294          $this->resetAfterTest(true);
     295          $this->setAdminUser();
     296          $course = self::getDataGenerator()->create_course();
     297          $event = $this->create_event(['courseid' => $course->id]);
     298          $plugingenerator = $this->getDataGenerator()->get_plugin_generator('mod_assign');
     299          $assigninstance = $plugingenerator->create_instance(['course' => $course->id]);
     300  
     301          $coursecache = [];
     302          $modulecache = [];
     303          $factory = new event_factory(
     304              function ($event) {
     305                  return $event;
     306              },
     307              function () {
     308                  return true;
     309              },
     310              function () {
     311                  return false;
     312              },
     313              $coursecache,
     314              $modulecache
     315          );
     316  
     317          $instance = $factory->create_instance(
     318              (object)[
     319                  'id' => $event->id,
     320                  'name' => 'test',
     321                  'description' => 'Test description',
     322                  'format' => 2,
     323                  'categoryid' => 0,
     324                  'courseid' => 0,
     325                  'groupid' => 1,
     326                  'userid' => 1,
     327                  'repeatid' => 0,
     328                  'modulename' => 'assign',
     329                  'instance' => $assigninstance->id,
     330                  'eventtype' => 'due',
     331                  'type' => CALENDAR_EVENT_TYPE_ACTION,
     332                  'timestart' => 123456789,
     333                  'timeduration' => 12,
     334                  'timemodified' => 123456789,
     335                  'timesort' => 123456789,
     336                  'visible' => 1,
     337                  'subscriptionid' => 1,
     338                  'location' => 'Test location',
     339              ]
     340          );
     341  
     342          $instance->get_course_module()->get('course');
     343          $this->assertArrayHasKey('assign' . '_' . $assigninstance->id, $modulecache);
     344      }
     345  
     346      /**
     347       * Testcases for the create instance test.
     348       *
     349       * @return array Array of testcases.
     350       */
     351      public function create_instance_testcases() {
     352          return [
     353              'Sample event record with event exposed' => [
     354                  'dbrow' => (object)[
     355                      'name' => 'Test event',
     356                      'description' => 'Hello',
     357                      'format' => 1,
     358                      'categoryid' => 0,
     359                      'courseid' => 1,
     360                      'groupid' => 1,
     361                      'userid' => 1,
     362                      'repeatid' => 0,
     363                      'modulename' => 'Test module',
     364                      'instance' => 1,
     365                      'eventtype' => 'Due',
     366                      'type' => CALENDAR_EVENT_TYPE_ACTION,
     367                      'timestart' => 123456789,
     368                      'timeduration' => 123456789,
     369                      'timemodified' => 123456789,
     370                      'timesort' => 123456789,
     371                      'visible' => true,
     372                      'subscriptionid' => 1,
     373                      'location' => 'Test location',
     374                  ],
     375                  'actioncallbackapplier' => function(event_interface $event) {
     376                      $event->testattribute = 'Hello';
     377                      return $event;
     378                  },
     379                  'visibilitycallbackapplier' => function(event_interface $event) {
     380                      return true;
     381                  },
     382                  'bailoutcheck' => function() {
     383                      return false;
     384                  },
     385                  event_interface::class,
     386                  'Hello'
     387              ],
     388              'Sample event record with event hidden' => [
     389                  'dbrow' => (object)[
     390                      'name' => 'Test event',
     391                      'description' => 'Hello',
     392                      'format' => 1,
     393                      'categoryid' => 0,
     394                      'courseid' => 1,
     395                      'groupid' => 1,
     396                      'userid' => 1,
     397                      'repeatid' => 0,
     398                      'modulename' => 'Test module',
     399                      'instance' => 1,
     400                      'eventtype' => 'Due',
     401                      'type' => CALENDAR_EVENT_TYPE_ACTION,
     402                      'timestart' => 123456789,
     403                      'timeduration' => 123456789,
     404                      'timemodified' => 123456789,
     405                      'timesort' => 123456789,
     406                      'visible' => true,
     407                      'subscriptionid' => 1,
     408                      'location' => 'Test location',
     409                  ],
     410                  'actioncallbackapplier' => function(event_interface $event) {
     411                      $event->testattribute = 'Hello';
     412                      return $event;
     413                  },
     414                  'visibilitycallbackapplier' => function(event_interface $event) {
     415                      return false;
     416                  },
     417                  'bailoutcheck' => function() {
     418                      return false;
     419                  },
     420                  null,
     421                  null
     422              ],
     423              'Sample event record with early bail' => [
     424                  'dbrow' => (object)[
     425                      'name' => 'Test event',
     426                      'description' => 'Hello',
     427                      'format' => 1,
     428                      'categoryid' => 0,
     429                      'courseid' => 1,
     430                      'groupid' => 1,
     431                      'userid' => 1,
     432                      'repeatid' => 0,
     433                      'modulename' => 'Test module',
     434                      'instance' => 1,
     435                      'eventtype' => 'Due',
     436                      'type' => CALENDAR_EVENT_TYPE_ACTION,
     437                      'timestart' => 123456789,
     438                      'timeduration' => 123456789,
     439                      'timemodified' => 123456789,
     440                      'timesort' => 123456789,
     441                      'visible' => true,
     442                      'subscriptionid' => 1,
     443                      'location' => 'Test location',
     444                  ],
     445                  'actioncallbackapplier' => function(event_interface $event) {
     446                      $event->testattribute = 'Hello';
     447                      return $event;
     448                  },
     449                  'visibilitycallbackapplier' => function(event_interface $event) {
     450                      return true;
     451                  },
     452                  'bailoutcheck' => function() {
     453                      return true;
     454                  },
     455                  null,
     456                  null
     457              ]
     458          ];
     459      }
     460  
     461      /**
     462       * Helper function to create calendar events using the old code.
     463       *
     464       * @param array $properties A list of calendar event properties to set
     465       * @return calendar_event
     466       */
     467      protected function create_event($properties = []) {
     468          $record = new \stdClass();
     469          $record->name = 'event name';
     470          $record->eventtype = 'global';
     471          $record->timestart = time();
     472          $record->timeduration = 0;
     473          $record->timesort = 0;
     474          $record->type = 1;
     475          $record->courseid = 0;
     476          $record->categoryid = 0;
     477  
     478          foreach ($properties as $name => $value) {
     479              $record->$name = $value;
     480          }
     481  
     482          $event = new calendar_event($record);
     483          return $event->create($record, false);
     484      }
     485  }