[ Index ]

PHP Cross Reference of moodle-2.8

title

Body

[close]

/lib/tests/ -> upgradelib_test.php (source)

   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   * Unit tests for the lib/upgradelib.php library.
  19   *
  20   * @package   core
  21   * @category  phpunit
  22   * @copyright 2013 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
  23   * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  24   */
  25  
  26  defined('MOODLE_INTERNAL') || die();
  27  
  28  global $CFG;
  29  require_once($CFG->libdir.'/upgradelib.php');
  30  
  31  
  32  /**
  33   * Tests various classes and functions in upgradelib.php library.
  34   */
  35  class core_upgradelib_testcase extends advanced_testcase {
  36  
  37      /**
  38       * Test the {@link upgrade_stale_php_files_present() function
  39       */
  40      public function test_upgrade_stale_php_files_present() {
  41          // Just call the function, must return bool false always
  42          // if there aren't any old files in the codebase.
  43          $this->assertFalse(upgrade_stale_php_files_present());
  44      }
  45  
  46      /**
  47       * Test the {@link upgrade_grade_item_fix_sortorder() function with
  48       * faked duplicate sortorder data.
  49       */
  50      public function test_upgrade_grade_item_fix_sortorder() {
  51          global $DB;
  52  
  53          $this->resetAfterTest(true);
  54  
  55          // The purpose of this test is to make sure that after upgrade script
  56          // there is no duplicates in the field grade_items.sortorder (for each course)
  57          // and the result of query "SELECT id FROM grade_items WHERE courseid=? ORDER BY sortorder, id" does not change.
  58          $sequencesql = 'SELECT id FROM {grade_items} WHERE courseid=? ORDER BY sortorder, id';
  59  
  60          // Each set is used for filling the db with fake data and will be representing the result of query:
  61          // "SELECT sortorder from {grade_items} WHERE courseid=? ORDER BY id".
  62          $testsets = array(
  63              // Items that need no action.
  64              array(1,2,3),
  65              array(5,6,7),
  66              array(7,6,1,3,2,5),
  67              // Items with sortorder duplicates
  68              array(1,2,2,3,3,4,5),
  69              // Only one sortorder duplicate.
  70              array(1,1),
  71              array(3,3),
  72              // Non-sequential sortorders with one or multiple duplicates.
  73              array(3,3,7,5,6,6,9,10,8,3),
  74              array(7,7,3),
  75              array(3,4,5,3,5,4,7,1)
  76          );
  77          $origsequences = array();
  78  
  79          // Generate the data and remember the initial sequence or items.
  80          foreach ($testsets as $testset) {
  81              $course = $this->getDataGenerator()->create_course();
  82              foreach ($testset as $sortorder) {
  83                  $this->insert_fake_grade_item_sortorder($course->id, $sortorder);
  84              }
  85              $DB->get_records('grade_items');
  86              $origsequences[$course->id] = $DB->get_fieldset_sql($sequencesql, array($course->id));
  87          }
  88  
  89          $duplicatedetectionsql = "SELECT courseid, sortorder
  90                                      FROM {grade_items}
  91                                  GROUP BY courseid, sortorder
  92                                    HAVING COUNT(id) > 1";
  93  
  94          // Verify there are duplicates before we start the fix.
  95          $dupes = $DB->record_exists_sql($duplicatedetectionsql);
  96          $this->assertTrue($dupes);
  97  
  98          // Do the work.
  99          upgrade_grade_item_fix_sortorder();
 100  
 101          // Verify that no duplicates are left in the database.
 102          $dupes = $DB->record_exists_sql($duplicatedetectionsql);
 103          $this->assertFalse($dupes);
 104  
 105          // Verify that sequences are exactly the same as they were before upgrade script.
 106          $idx = 0;
 107          foreach ($origsequences as $courseid => $origsequence) {
 108              if (count(($testsets[$idx])) == count(array_unique($testsets[$idx]))) {
 109                  // If there were no duplicates for this course verify that sortorders are not modified.
 110                  $newsortorders = $DB->get_fieldset_sql("SELECT sortorder from {grade_items} WHERE courseid=? ORDER BY id", array($courseid));
 111                  $this->assertEquals($testsets[$idx], $newsortorders);
 112              }
 113              $newsequence = $DB->get_fieldset_sql($sequencesql, array($courseid));
 114              $this->assertEquals($origsequence, $newsequence,
 115                      "Sequences do not match for test set $idx : ".join(',', $testsets[$idx]));
 116              $idx++;
 117          }
 118      }
 119  
 120      /**
 121       * Populate some fake grade items into the database with specified
 122       * sortorder and course id.
 123       *
 124       * NOTE: This function doesn't make much attempt to respect the
 125       * gradebook internals, its simply used to fake some data for
 126       * testing the upgradelib function. Please don't use it for other
 127       * purposes.
 128       *
 129       * @param int $courseid id of course
 130       * @param int $sortorder numeric sorting order of item
 131       * @return stdClass grade item object from the database.
 132       */
 133      private function insert_fake_grade_item_sortorder($courseid, $sortorder) {
 134          global $DB, $CFG;
 135          require_once($CFG->libdir.'/gradelib.php');
 136  
 137          $item = new stdClass();
 138          $item->courseid = $courseid;
 139          $item->sortorder = $sortorder;
 140          $item->gradetype = GRADE_TYPE_VALUE;
 141          $item->grademin = 30;
 142          $item->grademax = 110;
 143          $item->itemnumber = 1;
 144          $item->iteminfo = '';
 145          $item->timecreated = time();
 146          $item->timemodified = time();
 147  
 148          $item->id = $DB->insert_record('grade_items', $item);
 149  
 150          return $DB->get_record('grade_items', array('id' => $item->id));
 151      }
 152  
 153      public function test_upgrade_fix_missing_root_folders() {
 154          global $DB, $SITE;
 155  
 156          $this->resetAfterTest(true);
 157  
 158          // Setup some broken data...
 159          // Create two resources (and associated file areas).
 160          $this->setAdminUser();
 161          $resource1 = $this->getDataGenerator()->get_plugin_generator('mod_resource')
 162              ->create_instance(array('course' => $SITE->id));
 163          $resource2 = $this->getDataGenerator()->get_plugin_generator('mod_resource')
 164              ->create_instance(array('course' => $SITE->id));
 165  
 166          // Delete the folder record of resource1 to simulate broken data.
 167          $context = context_module::instance($resource1->cmid);
 168          $selectargs = array('contextid' => $context->id,
 169                              'component' => 'mod_resource',
 170                              'filearea' => 'content',
 171                              'itemid' => 0);
 172  
 173          // Verify file records exist.
 174          $areafilecount = $DB->count_records('files', $selectargs);
 175          $this->assertNotEmpty($areafilecount);
 176  
 177          // Delete the folder record.
 178          $folderrecord = $selectargs;
 179          $folderrecord['filepath'] = '/';
 180          $folderrecord['filename'] = '.';
 181  
 182          // Get previous folder record.
 183          $oldrecord = $DB->get_record('files', $folderrecord);
 184          $DB->delete_records('files', $folderrecord);
 185  
 186          // Verify the folder record has been removed.
 187          $newareafilecount = $DB->count_records('files', $selectargs);
 188          $this->assertSame($newareafilecount, $areafilecount - 1);
 189  
 190          $this->assertFalse($DB->record_exists('files', $folderrecord));
 191  
 192          // Run the upgrade step!
 193          upgrade_fix_missing_root_folders();
 194  
 195          // Verify the folder record has been restored.
 196          $newareafilecount = $DB->count_records('files', $selectargs);
 197          $this->assertSame($newareafilecount, $areafilecount);
 198  
 199          $newrecord = $DB->get_record('files', $folderrecord, '*', MUST_EXIST);
 200          // Verify the hash is correctly created.
 201          $this->assertSame($oldrecord->pathnamehash, $newrecord->pathnamehash);
 202      }
 203  
 204      public function test_upgrade_fix_missing_root_folders_draft() {
 205          global $DB, $SITE;
 206  
 207          $this->resetAfterTest(true);
 208  
 209          $user = $this->getDataGenerator()->create_user();
 210          $usercontext = context_user::instance($user->id);
 211          $this->setUser($user);
 212          $resource1 = $this->getDataGenerator()->get_plugin_generator('mod_resource')
 213              ->create_instance(array('course' => $SITE->id));
 214          $context = context_module::instance($resource1->cmid);
 215          $draftitemid = 0;
 216          file_prepare_draft_area($draftitemid, $context->id, 'mod_resource', 'content', 0);
 217  
 218          $queryparams = array(
 219              'component' => 'user',
 220              'contextid' => $usercontext->id,
 221              'filearea' => 'draft',
 222              'itemid' => $draftitemid,
 223          );
 224  
 225          // Make sure there are two records in files for the draft file area and one of them has filename '.'.
 226          $records = $DB->get_records_menu('files', $queryparams, '', 'id, filename');
 227          $this->assertEquals(2, count($records));
 228          $this->assertTrue(in_array('.', $records));
 229          $originalhash = $DB->get_field('files', 'pathnamehash', $queryparams + array('filename' => '.'));
 230  
 231          // Delete record with filename '.' and make sure it does not exist any more.
 232          $DB->delete_records('files', $queryparams + array('filename' => '.'));
 233  
 234          $records = $DB->get_records_menu('files', $queryparams, '', 'id, filename');
 235          $this->assertEquals(1, count($records));
 236          $this->assertFalse(in_array('.', $records));
 237  
 238          // Run upgrade script and make sure the record is restored.
 239          upgrade_fix_missing_root_folders_draft();
 240  
 241          $records = $DB->get_records_menu('files', $queryparams, '', 'id, filename');
 242          $this->assertEquals(2, count($records));
 243          $this->assertTrue(in_array('.', $records));
 244          $newhash = $DB->get_field('files', 'pathnamehash', $queryparams + array('filename' => '.'));
 245          $this->assertEquals($originalhash, $newhash);
 246      }
 247  
 248      /**
 249       * Tests the upgrade of an individual course-module or section from the
 250       * old to new availability system. (This test does not use the database
 251       * so it can run any time.)
 252       */
 253      public function test_upgrade_availability_item() {
 254          global $CFG;
 255          $this->resetAfterTest();
 256  
 257          // This function is in the other upgradelib.
 258          require_once($CFG->libdir . '/db/upgradelib.php');
 259  
 260          // Groupmembersonly (or nothing). Show option on but ignored.
 261          // Note: This $CFG option doesn't exist any more but we are testing the
 262          // upgrade function so it did exist then...
 263          $CFG->enablegroupmembersonly = 0;
 264          $this->assertNull(
 265                  upgrade_availability_item(1, 0, 0, 0, 1, array(), array()));
 266          $CFG->enablegroupmembersonly = 1;
 267          $this->assertNull(
 268                  upgrade_availability_item(0, 0, 0, 0, 1, array(), array()));
 269          $this->assertEquals(
 270                  '{"op":"&","showc":[false],"c":[{"type":"group"}]}',
 271                  upgrade_availability_item(1, 0, 0, 0, 1, array(), array()));
 272          $this->assertEquals(
 273                  '{"op":"&","showc":[false],"c":[{"type":"grouping","id":4}]}',
 274                  upgrade_availability_item(1, 4, 0, 0, 1, array(), array()));
 275  
 276          // Dates (with show/hide options - until date always hides).
 277          $this->assertEquals(
 278                  '{"op":"&","showc":[true],"c":[{"type":"date","d":">=","t":996}]}',
 279                  upgrade_availability_item(0, 0, 996, 0, 1, array(), array()));
 280          $this->assertEquals(
 281                  '{"op":"&","showc":[false],"c":[{"type":"date","d":">=","t":997}]}',
 282                  upgrade_availability_item(0, 0, 997, 0, 0, array(), array()));
 283          $this->assertEquals(
 284                  '{"op":"&","showc":[false],"c":[{"type":"date","d":"<","t":998}]}',
 285                  upgrade_availability_item(0, 0, 0, 998, 1, array(), array()));
 286          $this->assertEquals(
 287                  '{"op":"&","showc":[true,false],"c":[' .
 288                  '{"type":"date","d":">=","t":995},{"type":"date","d":"<","t":999}]}',
 289                  upgrade_availability_item(0, 0, 995, 999, 1, array(), array()));
 290  
 291          // Grade (show option works as normal).
 292          $availrec = (object)array(
 293                  'sourcecmid' => null, 'requiredcompletion' => null,
 294                  'gradeitemid' => 13, 'grademin' => null, 'grademax' => null);
 295          $this->assertEquals(
 296                  '{"op":"&","showc":[true],"c":[{"type":"grade","id":13}]}',
 297                  upgrade_availability_item(0, 0, 0, 0, 1, array($availrec), array()));
 298          $availrec->grademin = 4.1;
 299          $this->assertEquals(
 300                  '{"op":"&","showc":[false],"c":[{"type":"grade","id":13,"min":4.10000}]}',
 301                  upgrade_availability_item(0, 0, 0, 0, 0, array($availrec), array()));
 302          $availrec->grademax = 9.9;
 303          $this->assertEquals(
 304                  '{"op":"&","showc":[true],"c":[{"type":"grade","id":13,"min":4.10000,"max":9.90000}]}',
 305                  upgrade_availability_item(0, 0, 0, 0, 1, array($availrec), array()));
 306          $availrec->grademin = null;
 307          $this->assertEquals(
 308                  '{"op":"&","showc":[true],"c":[{"type":"grade","id":13,"max":9.90000}]}',
 309                  upgrade_availability_item(0, 0, 0, 0, 1, array($availrec), array()));
 310  
 311          // Completion (show option normal).
 312          $availrec->grademax = null;
 313          $availrec->gradeitemid = null;
 314          $availrec->sourcecmid = 666;
 315          $availrec->requiredcompletion = 1;
 316          $this->assertEquals(
 317                  '{"op":"&","showc":[true],"c":[{"type":"completion","cm":666,"e":1}]}',
 318                  upgrade_availability_item(0, 0, 0, 0, 1, array($availrec), array()));
 319          $this->assertEquals(
 320                  '{"op":"&","showc":[false],"c":[{"type":"completion","cm":666,"e":1}]}',
 321                  upgrade_availability_item(0, 0, 0, 0, 0, array($availrec), array()));
 322  
 323          // Profile conditions (custom/standard field, values/not, show option normal).
 324          $fieldrec = (object)array('userfield' => 'email', 'operator' => 'isempty',
 325                  'value' => '', 'shortname' => null);
 326          $this->assertEquals(
 327                  '{"op":"&","showc":[true],"c":[{"type":"profile","op":"isempty","sf":"email"}]}',
 328                  upgrade_availability_item(0, 0, 0, 0, 1, array(), array($fieldrec)));
 329          $fieldrec->value = '@';
 330          $fieldrec->operator = 'contains';
 331          $this->assertEquals(
 332                  '{"op":"&","showc":[true],"c":[{"type":"profile","op":"contains","sf":"email","v":"@"}]}',
 333                  upgrade_availability_item(0, 0, 0, 0, 1, array(), array($fieldrec)));
 334          $fieldrec->operator = 'isnotempty';
 335          $fieldrec->userfield = null;
 336          $fieldrec->shortname = 'frogtype';
 337          $this->assertEquals(
 338                  '{"op":"&","showc":[false],"c":[{"type":"profile","op":"isnotempty","cf":"frogtype"}]}',
 339                  upgrade_availability_item(0, 0, 0, 0, 0, array(), array($fieldrec)));
 340  
 341          // Everything at once.
 342          $this->assertEquals('{"op":"&","showc":[false,true,false,true,true,true],' .
 343                  '"c":[{"type":"grouping","id":13},' .
 344                  '{"type":"date","d":">=","t":990},' .
 345                  '{"type":"date","d":"<","t":991},' .
 346                  '{"type":"grade","id":665,"min":70.00000},' .
 347                  '{"type":"completion","cm":42,"e":2},' .
 348                  '{"type":"profile","op":"isempty","sf":"email"}]}',
 349                  upgrade_availability_item(1, 13, 990, 991, 1, array(
 350                      (object)array('sourcecmid' => null, 'gradeitemid' => 665, 'grademin' => 70),
 351                      (object)array('sourcecmid' => 42, 'gradeitemid' => null, 'requiredcompletion' => 2)
 352                  ), array(
 353                      (object)array('userfield' => 'email', 'shortname' => null, 'operator' => 'isempty'),
 354                  )));
 355      }
 356  }


Generated: Fri Nov 28 20:29:05 2014 Cross-referenced by PHPXref 0.7.1