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.

Differences Between: [Versions 310 and 401] [Versions 401 and 402] [Versions 401 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  namespace tool_uploaduser;
  18  
  19  /**
  20   * Tests for CLI tool_uploaduser.
  21   *
  22   * @package    tool_uploaduser
  23   * @copyright  2020 Marina Glancy
  24   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  25   */
  26  class cli_test extends \advanced_testcase {
  27  
  28      /**
  29       * Generate cli_helper and mock $_SERVER['argv']
  30       *
  31       * @param array $mockargv
  32       * @return \tool_uploaduser\cli_helper
  33       */
  34      protected function construct_helper(array $mockargv = []) {
  35          if (array_key_exists('argv', $_SERVER)) {
  36              $oldservervars = $_SERVER['argv'];
  37          }
  38          $_SERVER['argv'] = array_merge([''], $mockargv);
  39          $clihelper = new cli_helper(\tool_uploaduser\local\text_progress_tracker::class);
  40          if (isset($oldservervars)) {
  41              $_SERVER['argv'] = $oldservervars;
  42          } else {
  43              unset($_SERVER['argv']);
  44          }
  45          return $clihelper;
  46      }
  47  
  48      /**
  49       * Tests simple upload with course enrolment and group allocation
  50       */
  51      public function test_upload_with_course_enrolment() {
  52          global $CFG;
  53          $this->resetAfterTest();
  54          set_config('passwordpolicy', 0);
  55          $this->setAdminUser();
  56  
  57          $course = $this->getDataGenerator()->create_course(['fullname' => 'Maths', 'shortname' => 'math102']);
  58          $g1 = $this->getDataGenerator()->create_group(['courseid' => $course->id, 'name' => 'Section 1', 'idnumber' => 'S1']);
  59          $g2 = $this->getDataGenerator()->create_group(['courseid' => $course->id, 'name' => 'Section 3', 'idnumber' => 'S3']);
  60  
  61          $filepath = $CFG->dirroot.'/lib/tests/fixtures/upload_users.csv';
  62  
  63          $clihelper = $this->construct_helper(["--file=$filepath"]);
  64          ob_start();
  65          $clihelper->process();
  66          $output = ob_get_contents();
  67          ob_end_clean();
  68  
  69          // CLI output suggests that 2 users were created.
  70          $stats = $clihelper->get_stats();
  71          $this->assertEquals(2, preg_match_all('/New user/', $output));
  72          $this->assertEquals('Users created: 2', $stats[0]);
  73  
  74          // Tom Jones and Trent Reznor are enrolled into the course, first one to group $g1 and second to group $g2.
  75          $enrols = array_values(enrol_get_course_users($course->id));
  76          $this->assertEqualsCanonicalizing(['reznor', 'jonest'], [$enrols[0]->username, $enrols[1]->username]);
  77          $g1members = groups_get_groups_members($g1->id);
  78          $this->assertEquals(1, count($g1members));
  79          $this->assertEquals('Jones', $g1members[key($g1members)]->lastname);
  80          $g2members = groups_get_groups_members($g2->id);
  81          $this->assertEquals(1, count($g2members));
  82          $this->assertEquals('Reznor', $g2members[key($g2members)]->lastname);
  83      }
  84  
  85      /**
  86       * Test applying defaults during the user upload
  87       */
  88      public function test_upload_with_applying_defaults() {
  89          global $CFG;
  90          $this->resetAfterTest();
  91          set_config('passwordpolicy', 0);
  92          $this->setAdminUser();
  93  
  94          $course = $this->getDataGenerator()->create_course(['fullname' => 'Maths', 'shortname' => 'math102']);
  95          $g1 = $this->getDataGenerator()->create_group(['courseid' => $course->id, 'name' => 'Section 1', 'idnumber' => 'S1']);
  96          $g2 = $this->getDataGenerator()->create_group(['courseid' => $course->id, 'name' => 'Section 3', 'idnumber' => 'S3']);
  97  
  98          $filepath = $CFG->dirroot.'/lib/tests/fixtures/upload_users.csv';
  99  
 100          $clihelper = $this->construct_helper(["--file=$filepath", '--city=Brighton', '--department=Purchasing']);
 101          ob_start();
 102          $clihelper->process();
 103          $output = ob_get_contents();
 104          ob_end_clean();
 105  
 106          // CLI output suggests that 2 users were created.
 107          $stats = $clihelper->get_stats();
 108          $this->assertEquals(2, preg_match_all('/New user/', $output));
 109          $this->assertEquals('Users created: 2', $stats[0]);
 110  
 111          // Users have default values applied.
 112          $user1 = \core_user::get_user_by_username('jonest');
 113          $this->assertEquals('Brighton', $user1->city);
 114          $this->assertEquals('Purchasing', $user1->department);
 115      }
 116  
 117      /**
 118       * User upload with user profile fields
 119       */
 120      public function test_upload_with_profile_fields() {
 121          global $CFG;
 122          $this->resetAfterTest();
 123          set_config('passwordpolicy', 0);
 124          $this->setAdminUser();
 125  
 126          $this->field1 = $this->getDataGenerator()->create_custom_profile_field([
 127              'shortname' => 'superfield', 'name' => 'Super field',
 128              'datatype' => 'text', 'signup' => 1, 'visible' => 1, 'required' => 1, 'sortorder' => 1]);
 129  
 130          $filepath = $CFG->dirroot.'/lib/tests/fixtures/upload_users_profile.csv';
 131  
 132          $clihelper = $this->construct_helper(["--file=$filepath"]);
 133          ob_start();
 134          $clihelper->process();
 135          $output = ob_get_contents();
 136          ob_end_clean();
 137  
 138          // CLI output suggests that 2 users were created.
 139          $stats = $clihelper->get_stats();
 140          $this->assertEquals(2, preg_match_all('/New user/', $output));
 141          $this->assertEquals('Users created: 2', $stats[0]);
 142  
 143          // Created users have data in the profile fields.
 144          $user1 = \core_user::get_user_by_username('reznort');
 145          $profilefields1 = profile_user_record($user1->id);
 146          $this->assertObjectHasAttribute('superfield', $profilefields1);
 147          $this->assertEquals('Loves cats', $profilefields1->superfield);
 148      }
 149  
 150      /**
 151       * Testing that help for CLI does not throw errors
 152       */
 153      public function test_cli_help() {
 154          $this->resetAfterTest();
 155          $this->setAdminUser();
 156          $clihelper = $this->construct_helper(["--help"]);
 157          ob_start();
 158          $clihelper->print_help();
 159          $output = ob_get_contents();
 160          ob_end_clean();
 161  
 162          // Basically a test that everything can be parsed and displayed without errors. Check that some options are present.
 163          $this->assertEquals(1, preg_match('/--delimiter_name=VALUE/', $output));
 164          $this->assertEquals(1, preg_match('/--uutype=VALUE/', $output));
 165          $this->assertEquals(1, preg_match('/--auth=VALUE/', $output));
 166      }
 167  
 168      /**
 169       * Testing skipped user when one exists
 170       */
 171      public function test_create_when_user_exists() {
 172          global $CFG;
 173          $this->resetAfterTest();
 174          set_config('passwordpolicy', 0);
 175          $this->setAdminUser();
 176  
 177          $course = $this->getDataGenerator()->create_course(['fullname' => 'Maths', 'shortname' => 'math102']);
 178          $g1 = $this->getDataGenerator()->create_group(['courseid' => $course->id, 'name' => 'Section 1', 'idnumber' => 'S1']);
 179          $g2 = $this->getDataGenerator()->create_group(['courseid' => $course->id, 'name' => 'Section 3', 'idnumber' => 'S3']);
 180  
 181          // Create a user with username jonest.
 182          $user1 = $this->getDataGenerator()->create_user(['username' => 'jonest', 'email' => 'jonest@someplace.edu']);
 183  
 184          $filepath = $CFG->dirroot.'/lib/tests/fixtures/upload_users.csv';
 185  
 186          $clihelper = $this->construct_helper(["--file=$filepath"]);
 187          ob_start();
 188          $clihelper->process();
 189          $output = ob_get_contents();
 190          ob_end_clean();
 191  
 192          // CLI output suggests that 1 user was created and 1 skipped.
 193          $stats = $clihelper->get_stats();
 194          $this->assertEquals(1, preg_match_all('/New user/', $output));
 195          $this->assertEquals('Users created: 1', $stats[0]);
 196          $this->assertEquals('Users skipped: 1', $stats[1]);
 197  
 198          // Trent Reznor is enrolled into the course, Tom Jones is not!
 199          $enrols = array_values(enrol_get_course_users($course->id));
 200          $this->assertEqualsCanonicalizing(['reznor'], [$enrols[0]->username]);
 201      }
 202  
 203      /**
 204       * Testing update mode - do not update user records but allow enrolments
 205       */
 206      public function test_enrolments_when_user_exists() {
 207          global $CFG;
 208          require_once($CFG->dirroot.'/'.$CFG->admin.'/tool/uploaduser/locallib.php');
 209  
 210          $this->resetAfterTest();
 211          set_config('passwordpolicy', 0);
 212          $this->setAdminUser();
 213  
 214          $course = $this->getDataGenerator()->create_course(['fullname' => 'Maths', 'shortname' => 'math102']);
 215          $g1 = $this->getDataGenerator()->create_group(['courseid' => $course->id, 'name' => 'Section 1', 'idnumber' => 'S1']);
 216          $g2 = $this->getDataGenerator()->create_group(['courseid' => $course->id, 'name' => 'Section 3', 'idnumber' => 'S3']);
 217  
 218          // Create a user with username jonest.
 219          $this->getDataGenerator()->create_user(['username' => 'jonest', 'email' => 'jonest@someplace.edu',
 220              'firstname' => 'OLDNAME']);
 221  
 222          $filepath = $CFG->dirroot.'/lib/tests/fixtures/upload_users.csv';
 223  
 224          $clihelper = $this->construct_helper(["--file=$filepath", '--uutype='.UU_USER_UPDATE]);
 225          ob_start();
 226          $clihelper->process();
 227          $output = ob_get_contents();
 228          ob_end_clean();
 229  
 230          // CLI output suggests that 1 user was created and 1 skipped.
 231          $stats = $clihelper->get_stats();
 232          $this->assertEquals(0, preg_match_all('/New user/', $output));
 233          $this->assertEquals('Users updated: 0', $stats[0]);
 234          $this->assertEquals('Users skipped: 1', $stats[1]);
 235  
 236          // Tom Jones is enrolled into the course.
 237          $enrols = array_values(enrol_get_course_users($course->id));
 238          $this->assertEqualsCanonicalizing(['jonest'], [$enrols[0]->username]);
 239          // User reznor is not created.
 240          $this->assertFalse(\core_user::get_user_by_username('reznor'));
 241          // User jonest is not updated.
 242          $this->assertEquals('OLDNAME', \core_user::get_user_by_username('jonest')->firstname);
 243      }
 244  
 245      /**
 246       * Testing update mode - update user records and perform enrolments.
 247       */
 248      public function test_udpate_user() {
 249          global $CFG;
 250          require_once($CFG->dirroot.'/'.$CFG->admin.'/tool/uploaduser/locallib.php');
 251  
 252          $this->resetAfterTest();
 253          set_config('passwordpolicy', 0);
 254          $this->setAdminUser();
 255  
 256          $course = $this->getDataGenerator()->create_course(['fullname' => 'Maths', 'shortname' => 'math102']);
 257          $g1 = $this->getDataGenerator()->create_group(['courseid' => $course->id, 'name' => 'Section 1', 'idnumber' => 'S1']);
 258          $g2 = $this->getDataGenerator()->create_group(['courseid' => $course->id, 'name' => 'Section 3', 'idnumber' => 'S3']);
 259  
 260          // Create a user with username jonest.
 261          $this->getDataGenerator()->create_user(['username' => 'jonest',
 262              'email' => 'jonest@someplace.edu', 'firstname' => 'OLDNAME']);
 263  
 264          $filepath = $CFG->dirroot.'/lib/tests/fixtures/upload_users.csv';
 265  
 266          $clihelper = $this->construct_helper(["--file=$filepath", '--uutype='.UU_USER_UPDATE,
 267              '--uuupdatetype='.UU_UPDATE_FILEOVERRIDE]);
 268          ob_start();
 269          $clihelper->process();
 270          $output = ob_get_contents();
 271          ob_end_clean();
 272  
 273          // CLI output suggests that 1 user was created and 1 skipped.
 274          $stats = $clihelper->get_stats();
 275          $this->assertEquals(0, preg_match_all('/New user/', $output));
 276          $this->assertEquals('Users updated: 1', $stats[0]);
 277          $this->assertEquals('Users skipped: 1', $stats[1]);
 278  
 279          // Tom Jones is enrolled into the course.
 280          $enrols = array_values(enrol_get_course_users($course->id));
 281          $this->assertEqualsCanonicalizing(['jonest'], [$enrols[0]->username]);
 282          // User reznor is not created.
 283          $this->assertFalse(\core_user::get_user_by_username('reznor'));
 284          // User jonest is updated, new first name is Tom.
 285          $this->assertEquals('Tom', \core_user::get_user_by_username('jonest')->firstname);
 286      }
 287  }