Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 3.10.x will end 8 November 2021 (12 months).
  • Bug fixes for security issues in 3.10.x will end 9 May 2022 (18 months).
  • PHP version: minimum PHP 7.2.0 Note: minimum PHP version has increased since Moodle 3.8. PHP 7.3.x and 7.4.x are supported too.

Differences Between: [Versions 310 and 311] [Versions 310 and 400] [Versions 310 and 401] [Versions 310 and 402] [Versions 310 and 403]

   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   * format_weeks related unit tests
  19   *
  20   * @package    format_weeks
  21   * @copyright  2015 Marina Glancy
  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 . '/course/lib.php');
  29  
  30  /**
  31   * format_weeks related unit tests
  32   *
  33   * @package    format_weeks
  34   * @copyright  2015 Marina Glancy
  35   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  36   */
  37  class format_weeks_testcase extends advanced_testcase {
  38  
  39      /**
  40       * Tests for format_weeks::get_section_name method with default section names.
  41       */
  42      public function test_get_section_name() {
  43          global $DB;
  44          $this->resetAfterTest(true);
  45  
  46          // Generate a course with 5 sections.
  47          $generator = $this->getDataGenerator();
  48          $numsections = 5;
  49          $course = $generator->create_course(array('numsections' => $numsections, 'format' => 'weeks'),
  50              array('createsections' => true));
  51  
  52          // Get section names for course.
  53          $coursesections = $DB->get_records('course_sections', array('course' => $course->id));
  54  
  55          // Test get_section_name with default section names.
  56          $courseformat = course_get_format($course);
  57          foreach ($coursesections as $section) {
  58              // Assert that with unmodified section names, get_section_name returns the same result as get_default_section_name.
  59              $this->assertEquals($courseformat->get_default_section_name($section), $courseformat->get_section_name($section));
  60          }
  61      }
  62  
  63      /**
  64       * Tests for format_weeks::get_section_name method with modified section names.
  65       */
  66      public function test_get_section_name_customised() {
  67          global $DB;
  68          $this->resetAfterTest(true);
  69  
  70          // Generate a course with 5 sections.
  71          $generator = $this->getDataGenerator();
  72          $numsections = 5;
  73          $course = $generator->create_course(array('numsections' => $numsections, 'format' => 'weeks'),
  74              array('createsections' => true));
  75  
  76          // Get section names for course.
  77          $coursesections = $DB->get_records('course_sections', array('course' => $course->id));
  78  
  79          // Modify section names.
  80          $customname = "Custom Section";
  81          foreach ($coursesections as $section) {
  82              $section->name = "$customname $section->section";
  83              $DB->update_record('course_sections', $section);
  84          }
  85  
  86          // Requery updated section names then test get_section_name.
  87          $coursesections = $DB->get_records('course_sections', array('course' => $course->id));
  88          $courseformat = course_get_format($course);
  89          foreach ($coursesections as $section) {
  90              // Assert that with modified section names, get_section_name returns the modified section name.
  91              $this->assertEquals($section->name, $courseformat->get_section_name($section));
  92          }
  93      }
  94  
  95      /**
  96       * Tests for format_weeks::get_default_section_name.
  97       */
  98      public function test_get_default_section_name() {
  99          global $DB;
 100          $this->resetAfterTest(true);
 101  
 102          // Generate a course with 5 sections.
 103          $generator = $this->getDataGenerator();
 104          $numsections = 5;
 105          $course = $generator->create_course(array('numsections' => $numsections, 'format' => 'weeks'),
 106              array('createsections' => true));
 107  
 108          // Get section names for course.
 109          $coursesections = $DB->get_records('course_sections', array('course' => $course->id));
 110  
 111          // Test get_default_section_name with default section names.
 112          $courseformat = course_get_format($course);
 113          foreach ($coursesections as $section) {
 114              if ($section->section == 0) {
 115                  $sectionname = get_string('section0name', 'format_weeks');
 116                  $this->assertEquals($sectionname, $courseformat->get_default_section_name($section));
 117              } else {
 118                  $dates = $courseformat->get_section_dates($section);
 119                  $dates->end = ($dates->end - 86400);
 120                  $dateformat = get_string('strftimedateshort');
 121                  $weekday = userdate($dates->start, $dateformat);
 122                  $endweekday = userdate($dates->end, $dateformat);
 123                  $sectionname = $weekday.' - '.$endweekday;
 124  
 125                  $this->assertEquals($sectionname, $courseformat->get_default_section_name($section));
 126              }
 127          }
 128      }
 129  
 130      /**
 131       * Test web service updating section name
 132       */
 133      public function test_update_inplace_editable() {
 134          global $CFG, $DB, $PAGE;
 135          require_once($CFG->dirroot . '/lib/external/externallib.php');
 136  
 137          $this->resetAfterTest();
 138          $user = $this->getDataGenerator()->create_user();
 139          $this->setUser($user);
 140          $course = $this->getDataGenerator()->create_course(array('numsections' => 5, 'format' => 'weeks'),
 141              array('createsections' => true));
 142          $section = $DB->get_record('course_sections', array('course' => $course->id, 'section' => 2));
 143  
 144          // Call webservice without necessary permissions.
 145          try {
 146              core_external::update_inplace_editable('format_weeks', 'sectionname', $section->id, 'New section name');
 147              $this->fail('Exception expected');
 148          } catch (moodle_exception $e) {
 149              $this->assertEquals('Course or activity not accessible. (Not enrolled)',
 150                      $e->getMessage());
 151          }
 152  
 153          // Change to teacher and make sure that section name can be updated using web service update_inplace_editable().
 154          $teacherrole = $DB->get_record('role', array('shortname' => 'editingteacher'));
 155          $this->getDataGenerator()->enrol_user($user->id, $course->id, $teacherrole->id);
 156  
 157          $res = core_external::update_inplace_editable('format_weeks', 'sectionname', $section->id, 'New section name');
 158          $res = external_api::clean_returnvalue(core_external::update_inplace_editable_returns(), $res);
 159          $this->assertEquals('New section name', $res['value']);
 160          $this->assertEquals('New section name', $DB->get_field('course_sections', 'name', array('id' => $section->id)));
 161      }
 162  
 163      /**
 164       * Test callback updating section name
 165       */
 166      public function test_inplace_editable() {
 167          global $CFG, $DB, $PAGE;
 168  
 169          $this->resetAfterTest();
 170          $user = $this->getDataGenerator()->create_user();
 171          $course = $this->getDataGenerator()->create_course(array('numsections' => 5, 'format' => 'weeks'),
 172              array('createsections' => true));
 173          $teacherrole = $DB->get_record('role', array('shortname' => 'editingteacher'));
 174          $this->getDataGenerator()->enrol_user($user->id, $course->id, $teacherrole->id);
 175          $this->setUser($user);
 176  
 177          $section = $DB->get_record('course_sections', array('course' => $course->id, 'section' => 2));
 178  
 179          // Call callback format_weeks_inplace_editable() directly.
 180          $tmpl = component_callback('format_weeks', 'inplace_editable', array('sectionname', $section->id, 'Rename me again'));
 181          $this->assertInstanceOf('core\output\inplace_editable', $tmpl);
 182          $res = $tmpl->export_for_template($PAGE->get_renderer('core'));
 183          $this->assertEquals('Rename me again', $res['value']);
 184          $this->assertEquals('Rename me again', $DB->get_field('course_sections', 'name', array('id' => $section->id)));
 185  
 186          // Try updating using callback from mismatching course format.
 187          try {
 188              $tmpl = component_callback('format_topics', 'inplace_editable', array('sectionname', $section->id, 'New name'));
 189              $this->fail('Exception expected');
 190          } catch (moodle_exception $e) {
 191              $this->assertEquals(1, preg_match('/^Can\'t find data record in database/', $e->getMessage()));
 192          }
 193      }
 194  
 195      /**
 196       * Test get_default_course_enddate.
 197       *
 198       * @return void
 199       */
 200      public function test_default_course_enddate() {
 201          global $CFG, $DB, $PAGE;
 202  
 203          $this->resetAfterTest(true);
 204  
 205          require_once($CFG->dirroot . '/course/tests/fixtures/testable_course_edit_form.php');
 206  
 207          $this->setTimezone('UTC');
 208  
 209          $params = array('format' => 'weeks', 'numsections' => 5, 'startdate' => 1445644800);
 210          $course = $this->getDataGenerator()->create_course($params);
 211          $category = $DB->get_record('course_categories', array('id' => $course->category));
 212  
 213          $args = [
 214              'course' => $course,
 215              'category' => $category,
 216              'editoroptions' => [
 217                  'context' => context_course::instance($course->id),
 218                  'subdirs' => 0
 219              ],
 220              'returnto' => new moodle_url('/'),
 221              'returnurl' => new moodle_url('/'),
 222          ];
 223  
 224          $PAGE->set_course($course);
 225          $courseform = new testable_course_edit_form(null, $args);
 226          $courseform->definition_after_data();
 227  
 228          // format_weeks::get_section_dates is adding 2h to avoid DST problems, we need to replicate it here.
 229          $enddate = $params['startdate'] + (WEEKSECS * $params['numsections']) + 7200;
 230  
 231          $weeksformat = course_get_format($course->id);
 232          $this->assertEquals($enddate, $weeksformat->get_default_course_enddate($courseform->get_quick_form()));
 233      }
 234  
 235      /**
 236       * Test for get_view_url() to ensure that the url is only given for the correct cases
 237       */
 238      public function test_get_view_url() {
 239          global $CFG;
 240          $this->resetAfterTest();
 241  
 242          $linkcoursesections = $CFG->linkcoursesections;
 243  
 244          // Generate a course with two sections (0 and 1) and two modules.
 245          $generator = $this->getDataGenerator();
 246          $course1 = $generator->create_course(array('format' => 'weeks'));
 247          course_create_sections_if_missing($course1, array(0, 1));
 248  
 249          $data = (object)['id' => $course1->id];
 250          $format = course_get_format($course1);
 251          $format->update_course_format_options($data);
 252  
 253          // In page.
 254          $CFG->linkcoursesections = 0;
 255          $this->assertNotEmpty($format->get_view_url(null));
 256          $this->assertNotEmpty($format->get_view_url(0));
 257          $this->assertNotEmpty($format->get_view_url(1));
 258          $CFG->linkcoursesections = 1;
 259          $this->assertNotEmpty($format->get_view_url(null));
 260          $this->assertNotEmpty($format->get_view_url(0));
 261          $this->assertNotEmpty($format->get_view_url(1));
 262  
 263          // Navigation.
 264          $CFG->linkcoursesections = 0;
 265          $this->assertNull($format->get_view_url(1, ['navigation' => 1]));
 266          $this->assertNull($format->get_view_url(0, ['navigation' => 1]));
 267          $CFG->linkcoursesections = 1;
 268          $this->assertNotEmpty($format->get_view_url(1, ['navigation' => 1]));
 269          $this->assertNotEmpty($format->get_view_url(0, ['navigation' => 1]));
 270      }
 271  
 272  }