Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 4.2.x will end 22 April 2024 (12 months).
  • Bug fixes for security issues in 4.2.x will end 7 October 2024 (18 months).
  • PHP version: minimum PHP 8.0.0 Note: minimum PHP version has increased since Moodle 4.1. PHP 8.1.x is supported too.
   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  namespace format_topics\courseformat;
  18  
  19  use core_courseformat\stateupdates;
  20  use moodle_exception;
  21  use stdClass;
  22  
  23  /**
  24   * Topics course format related unit tests.
  25   *
  26   * @package    format_topics
  27   * @copyright  2022 Ferran Recio <ferran@moodle.com>
  28   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  29   */
  30  class stateactions_test extends \advanced_testcase {
  31  
  32      /**
  33       * Enrol a user into a course and login as this user.
  34       *
  35       * @param stdClass $course the course object
  36       * @param string $rolename the rolename
  37       */
  38      private function enrol_user(stdClass $course, string $rolename): void {
  39          // Create and enrol user using given role.
  40          if ($rolename == 'admin') {
  41              $this->setAdminUser();
  42          } else {
  43              $user = $this->getDataGenerator()->create_user();
  44              if ($rolename != 'unenroled') {
  45                  $this->getDataGenerator()->enrol_user($user->id, $course->id, $rolename);
  46              }
  47              $this->setUser($user);
  48          }
  49      }
  50  
  51      /**
  52       * Tests for section_highlight method.
  53       *
  54       * @dataProvider basic_role_provider
  55       * @covers ::section_highlight
  56       * @param string $rolename The role of the user that will execute the method.
  57       * @param bool $expectedexception If this call will raise an exception.
  58       */
  59      public function test_section_highlight(string $rolename, bool $expectedexception = false): void {
  60          global $DB;
  61          $this->resetAfterTest(true);
  62  
  63          $generator = $this->getDataGenerator();
  64          $course = $generator->create_course(
  65              ['numsections' => 4, 'format' => 'topics'],
  66              ['createsections' => true]
  67          );
  68  
  69          $this->enrol_user($course, $rolename);
  70  
  71          $sectionrecords = $DB->get_records('course_sections', ['course' => $course->id], 'section');
  72          $sectionids = [];
  73          foreach ($sectionrecords as $section) {
  74              $sectionids[] = $section->id;
  75          }
  76  
  77          // Initialise stateupdates.
  78          $courseformat = course_get_format($course->id);
  79          $updates = new stateupdates($courseformat);
  80  
  81          // All state actions accepts batch editing (an array of sections in this case). However,
  82          // only one course section can be marked as highlighted. This means that if we send more
  83          // than one section id only the first one will be highlighted and the rest will be ignored.
  84          $methodparam = [
  85              $sectionids[1],
  86              $sectionids[2],
  87              $sectionids[3],
  88          ];
  89  
  90          // Actions have an array of ids as param but only the first one will be highlighted.
  91          $highlightid = reset($methodparam);
  92          $highlight = $sectionrecords[$highlightid];
  93  
  94          if ($expectedexception) {
  95              $this->expectException(moodle_exception::class);
  96          }
  97  
  98          // Execute given method.
  99          $actions = new stateactions();
 100          $actions->section_highlight(
 101              $updates,
 102              $course,
 103              $methodparam
 104          );
 105  
 106          // Check state returned after executing given action.
 107          $updatelist = $updates->jsonSerialize();
 108          $this->assertCount(1, $updatelist);
 109          $update = reset($updatelist);
 110          $this->assertEquals('section', $update->name);
 111          $this->assertEquals('put', $update->action);
 112          $this->assertEquals($highlightid, $update->fields->id);
 113          $this->assertEquals(1, $update->fields->current);
 114  
 115          // Check DB sections.
 116          $this->assertEquals($highlight->section, $DB->get_field("course", "marker", ['id' => $course->id]));
 117      }
 118  
 119      /**
 120       * Tests for section_unhighlight method.
 121       *
 122       * @dataProvider basic_role_provider
 123       * @covers ::section_unhighlight
 124       * @param string $rolename The role of the user that will execute the method.
 125       * @param bool $expectedexception If this call will raise an exception.
 126       */
 127      public function test_section_unhighlight(string $rolename, bool $expectedexception = false): void {
 128          global $DB;
 129          $this->resetAfterTest(true);
 130  
 131          $generator = $this->getDataGenerator();
 132          $course = $generator->create_course(
 133              ['numsections' => 4, 'format' => 'topics'],
 134              ['createsections' => true]
 135          );
 136  
 137          // Highlight section 1.
 138          course_set_marker($course->id, 1);
 139  
 140          $this->enrol_user($course, $rolename);
 141  
 142          $sectionrecords = $DB->get_records('course_sections', ['course' => $course->id], 'section');
 143          $sectionids = [];
 144          foreach ($sectionrecords as $section) {
 145              $sectionids[] = $section->id;
 146          }
 147  
 148          // Initialise stateupdates.
 149          $courseformat = course_get_format($course->id);
 150          $updates = new stateupdates($courseformat);
 151  
 152          // The section_unhighlight accepts extra sections to refresh the state data.
 153          $methodparam = [
 154              $sectionids[3],
 155              $sectionids[4],
 156          ];
 157  
 158          if ($expectedexception) {
 159              $this->expectException(moodle_exception::class);
 160          }
 161  
 162          // Execute given method.
 163          $actions = new stateactions();
 164          $actions->section_unhighlight(
 165              $updates,
 166              $course,
 167              $methodparam
 168          );
 169  
 170          // The Unhilight mutation always return the previous highlighted
 171          // section (1) and all the extra sections passed (3, and 4) to ensure
 172          // all of them are updated.
 173          $returnedsectionnumbers = [1, 3, 4];
 174  
 175          // Check state returned after executing given action.
 176          $updatelist = $updates->jsonSerialize();
 177          $this->assertCount(3, $updatelist);
 178          foreach ($updatelist as $update) {
 179              $this->assertEquals('section', $update->name);
 180              $this->assertEquals('put', $update->action);
 181              $this->assertContains($update->fields->number, $returnedsectionnumbers);
 182              $this->assertEquals(0, $update->fields->current);
 183          }
 184  
 185          // Check DB sections.
 186          $this->assertEquals(0, $DB->get_field("course", "marker", ['id' => $course->id]));
 187      }
 188  
 189      /**
 190       * Data provider for basic role tests.
 191       *
 192       * @return array the testing scenarios
 193       */
 194      public function basic_role_provider(): array {
 195          return [
 196              'admin' => [
 197                  'role' => 'admin',
 198                  'expectedexception' => false,
 199              ],
 200              'editingteacher' => [
 201                  'role' => 'editingteacher',
 202                  'expectedexception' => false,
 203              ],
 204              'teacher' => [
 205                  'role' => 'teacher',
 206                  'expectedexception' => true,
 207              ],
 208              'student' => [
 209                  'role' => 'student',
 210                  'expectedexception' => true,
 211              ],
 212              'guest' => [
 213                  'role' => 'guest',
 214                  'expectedexception' => true,
 215              ],
 216              'unenroled' => [
 217                  'role' => 'unenroled',
 218                  'expectedexception' => true,
 219              ],
 220          ];
 221      }
 222  }