Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 4.1.x will end 13 November 2023 (12 months).
  • Bug fixes for security issues in 4.1.x will end 10 November 2025 (36 months).
  • PHP version: minimum PHP 7.4.0 Note: minimum PHP version has increased since Moodle 4.0. PHP 8.0.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 tool_uploaduser;
  18  
  19  use advanced_testcase;
  20  use context_system;
  21  use context_course;
  22  use context_coursecat;
  23  use stdClass;
  24  use tool_uploaduser\cli_helper;
  25  use tool_uploaduser\local\text_progress_tracker;
  26  
  27  /**
  28   * Class upload_users_test
  29   *
  30   * @package    tool_uploaduser
  31   * @copyright  2020 Marina Glancy
  32   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  33   */
  34  class upload_users_test extends advanced_testcase {
  35  
  36      /**
  37       * Load required test libraries
  38       */
  39      public static function setUpBeforeClass(): void {
  40          global $CFG;
  41  
  42          require_once("{$CFG->dirroot}/{$CFG->admin}/tool/uploaduser/locallib.php");
  43      }
  44  
  45      /**
  46       * Test upload users, enrol and role assignation
  47       * @covers \tool_uploadusers::process
  48       */
  49      public function test_user_can_upload_with_course_enrolment(): void {
  50  
  51          $this->resetAfterTest();
  52          set_config('passwordpolicy', 0);
  53          $this->setAdminUser();
  54  
  55          // Create category and course.
  56          $coursecat = $this->getDataGenerator()->create_category();
  57          $coursecatcontext = context_coursecat::instance($coursecat->id);
  58          $course = $this->getDataGenerator()->create_course(['shortname' => 'course01', 'category' => $coursecat->id]);
  59          $coursecontext = context_course::instance($course->id);
  60  
  61          // Create user.
  62          $user = $this->getDataGenerator()->create_user();
  63  
  64          // Create role with capability to upload CSV files, and assign this role to user.
  65          $uploadroleid = create_role('upload role', 'uploadrole', '');
  66          set_role_contextlevels($uploadroleid, [CONTEXT_SYSTEM]);
  67          $systemcontext = context_system::instance();
  68          assign_capability('moodle/site:uploadusers', CAP_ALLOW, $uploadroleid, $systemcontext->id);
  69          $this->getDataGenerator()->role_assign($uploadroleid, $user->id, $systemcontext->id);
  70  
  71          // Create role with some of allowed capabilities to enrol users, and assign this role to user.
  72          $enrolroleid = create_role('enrol role', 'enrolrole', '');
  73          set_role_contextlevels($enrolroleid, [CONTEXT_COURSECAT]);
  74          assign_capability('enrol/manual:enrol', CAP_ALLOW, $enrolroleid, $coursecatcontext->id);
  75          assign_capability('moodle/course:enrolreview', CAP_ALLOW, $enrolroleid, $coursecatcontext->id);
  76          assign_capability('moodle/role:assign', CAP_ALLOW, $enrolroleid, $coursecatcontext->id);
  77          $this->getDataGenerator()->role_assign($enrolroleid, $user->id, $coursecatcontext->id);
  78  
  79          // User makes assignments.
  80          $studentarch = get_archetype_roles('student');
  81          $studentrole = array_shift($studentarch);
  82          core_role_set_assign_allowed($enrolroleid, $studentrole->id);
  83  
  84          // Flush accesslib.
  85          accesslib_clear_all_caches_for_unit_testing();
  86  
  87          // Process CSV file as user.
  88          $csv = <<<EOF
  89  username,firstname,lastname,email,course1,role1
  90  student1,Student,One,s1@example.com,{$course->shortname},{$studentrole->shortname}
  91  student2,Student,Two,s2@example.com,{$course->shortname},teacher
  92  EOF;
  93          $this->setUser($user);
  94          $output = $this->process_csv_upload($csv, ['--uutype=' . UU_USER_ADDNEW]);
  95  
  96          $this->assertStringContainsString('Enrolled in "course01" as "student"', $output);
  97          $this->assertStringContainsString('Unknown role "teacher"', $output);
  98  
  99          // Check user creation, enrolment and role assignation.
 100          $this->assertEquals(1, count_enrolled_users($coursecontext));
 101  
 102          $usersasstudent = get_role_users($studentrole->id, $coursecontext);
 103          $this->assertCount(1, $usersasstudent);
 104          $this->assertEquals('student1', reset($usersasstudent)->username);
 105      }
 106  
 107      /**
 108       * Test upload users, enrol and assign default role from manual enrol plugin.
 109       * @covers \tool_uploadusers::process
 110       */
 111      public function test_user_can_upload_with_course_enrolment_default_role(): void {
 112  
 113          $this->resetAfterTest();
 114          set_config('passwordpolicy', 0);
 115          $this->setAdminUser();
 116  
 117          // Create category and courses.
 118          $coursecat = $this->getDataGenerator()->create_category();
 119          $coursecatcontext = context_coursecat::instance($coursecat->id);
 120          $course1 = $this->getDataGenerator()->create_course(['shortname' => 'course01', 'category' => $coursecat->id]);
 121          $course1context = context_course::instance($course1->id);
 122          // Change the default role to 'teacher'.
 123          set_config('roleid', 4, 'enrol_manual');
 124          $course2 = $this->getDataGenerator()->create_course(['shortname' => 'course02', 'category' => $coursecat->id]);
 125          $course2context = context_course::instance($course2->id);
 126  
 127          // Create user.
 128          $user = $this->getDataGenerator()->create_user();
 129  
 130          // Create role with capability to upload CSV files, and assign this role to user.
 131          $uploadroleid = create_role('upload role', 'uploadrole', '');
 132          set_role_contextlevels($uploadroleid, [CONTEXT_SYSTEM]);
 133          $systemcontext = context_system::instance();
 134          assign_capability('moodle/site:uploadusers', CAP_ALLOW, $uploadroleid, $systemcontext->id);
 135          $this->getDataGenerator()->role_assign($uploadroleid, $user->id, $systemcontext->id);
 136  
 137          // Create role with some of allowed capabilities to enrol users, and assign this role to user.
 138          $enrolroleid = create_role('enrol role', 'enrolrole', '');
 139          set_role_contextlevels($enrolroleid, [CONTEXT_COURSECAT]);
 140          assign_capability('enrol/manual:enrol', CAP_ALLOW, $enrolroleid, $coursecatcontext->id);
 141          assign_capability('moodle/course:enrolreview', CAP_ALLOW, $enrolroleid, $coursecatcontext->id);
 142          assign_capability('moodle/role:assign', CAP_ALLOW, $enrolroleid, $coursecatcontext->id);
 143          $this->getDataGenerator()->role_assign($enrolroleid, $user->id, $coursecatcontext->id);
 144  
 145          // User makes assignments.
 146          $studentarch = get_archetype_roles('student');
 147          $studentrole = array_shift($studentarch);
 148          core_role_set_assign_allowed($enrolroleid, $studentrole->id);
 149  
 150          // Flush accesslib.
 151          accesslib_clear_all_caches_for_unit_testing();
 152  
 153          // Process CSV file (no roles specified) as user.
 154          $csv = <<<EOF
 155  username,firstname,lastname,email,course1,role1
 156  student1,Student,One,s1@example.com,{$course1->shortname},
 157  student2,Student,Two,s2@example.com,{$course2->shortname},
 158  EOF;
 159          $this->setUser($user);
 160          $output = $this->process_csv_upload($csv, ['--uutype=' . UU_USER_ADDNEW]);
 161  
 162          $this->assertStringContainsString('Enrolled in "course01" as "student"', $output);
 163          // This $user cannot assign teacher role.
 164          $this->assertStringContainsString('Unknown role "teacher"', $output);
 165  
 166          // Check user creation, enrolment and role assignation.
 167          $this->assertEquals(1, count_enrolled_users($course1context));
 168          // This $user cannot enrol anyone as teacher.
 169          $this->assertEquals(0, count_enrolled_users($course2context));
 170  
 171          // Test user is enrolled as default-manual-enrol-plugin role.
 172          $manualenrolinstance = new stdClass;
 173          $enrolinstances = enrol_get_instances($course1->id, true);
 174          foreach ($enrolinstances as $courseenrolinstance) {
 175              if ($courseenrolinstance->enrol === 'manual') {
 176                  $manualenrolinstance = $courseenrolinstance;
 177                  break;
 178              }
 179          }
 180          $defaulroleidexpected = $manualenrolinstance->roleid ?? 0;
 181          // The default role of course01 is student, id 5.
 182          $this->assertEquals(5, $defaulroleidexpected);
 183  
 184          $usersasdefaultrole = get_role_users($defaulroleidexpected, $course1context);
 185          $this->assertCount(1, $usersasdefaultrole);
 186          $this->assertEquals('student1', reset($usersasdefaultrole)->username);
 187      }
 188  
 189      /**
 190       * Generate cli_helper and mock $_SERVER['argv']
 191       *
 192       * @param string $filecontent
 193       * @param array $mockargv
 194       * @return string
 195       */
 196      protected function process_csv_upload(string $filecontent, array $mockargv = []): string {
 197          $filepath = make_request_directory() . '/upload.csv';
 198          file_put_contents($filepath, $filecontent);
 199          $mockargv[] = "--file={$filepath}";
 200  
 201          if (array_key_exists('argv', $_SERVER)) {
 202              $oldservervars = $_SERVER['argv'];
 203          }
 204  
 205          $_SERVER['argv'] = array_merge([''], $mockargv);
 206          $clihelper = new cli_helper(text_progress_tracker::class);
 207  
 208          if (isset($oldservervars)) {
 209              $_SERVER['argv'] = $oldservervars;
 210          } else {
 211              unset($_SERVER['argv']);
 212          }
 213  
 214          ob_start();
 215          $clihelper->process();
 216          $output = ob_get_contents();
 217          ob_end_clean();
 218  
 219          return $output;
 220      }
 221  }