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.

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

   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 core;
  18  
  19  defined('MOODLE_INTERNAL') || die();
  20  
  21  global $CFG;
  22  require_once($CFG->dirroot . '/lib/myprofilelib.php');
  23  
  24  /**
  25   * Tests for myprofilelib apis.
  26   *
  27   * @package    core
  28   * @copyright  2015 onwards Ankit agarwal <ankit.agrr@gmail.com>
  29   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later.
  30   */
  31  class myprofilelib_test extends \advanced_testcase {
  32  
  33      /**
  34       * @var stdClass The user.
  35       */
  36      private $user;
  37  
  38      /**
  39       * @var stdClass The course.
  40       */
  41      private $course;
  42  
  43      /**
  44       * @var \core_user\output\myprofile\tree The navigation tree.
  45       */
  46      private $tree;
  47      public function setUp(): void {
  48          // Set the $PAGE->url value so core_myprofile_navigation() doesn't complain.
  49          global $PAGE;
  50          $PAGE->set_url('/test');
  51  
  52          $this->user = $this->getDataGenerator()->create_user();
  53          $this->course = $this->getDataGenerator()->create_course();
  54          $this->tree = new \core_user\output\myprofile\tree();
  55          $this->resetAfterTest();
  56      }
  57  
  58      /**
  59       * Tests the core_myprofile_navigation() function as an admin viewing a user's course profile.
  60       */
  61      public function test_core_myprofile_navigation_as_admin() {
  62          $this->setAdminUser();
  63          $iscurrentuser = false;
  64  
  65          // Test tree as admin user.
  66          core_myprofile_navigation($this->tree, $this->user, $iscurrentuser, $this->course);
  67          $reflector = new \ReflectionObject($this->tree);
  68          $categories = $reflector->getProperty('categories');
  69          $categories->setAccessible(true);
  70          $cats = $categories->getValue($this->tree);
  71          $this->assertArrayHasKey('contact', $cats);
  72          $this->assertArrayHasKey('coursedetails', $cats);
  73          $this->assertArrayHasKey('miscellaneous', $cats);
  74          $this->assertArrayHasKey('reports', $cats);
  75          $this->assertArrayHasKey('administration', $cats);
  76          $this->assertArrayHasKey('loginactivity', $cats);
  77  
  78          $nodes = $reflector->getProperty('nodes');
  79          $nodes->setAccessible(true);
  80          $this->assertArrayHasKey('fullprofile', $nodes->getValue($this->tree));
  81      }
  82  
  83      /**
  84       * Tests the core_myprofile_navigation() function as a user without permission to view the full
  85       * profile of another another user.
  86       */
  87      public function test_core_myprofile_navigation_course_without_permission() {
  88          // User without permission.
  89          $this->setUser($this->getDataGenerator()->create_user());
  90          $iscurrentuser = false;
  91  
  92          core_myprofile_navigation($this->tree, $this->user, $iscurrentuser, $this->course);
  93          $reflector = new \ReflectionObject($this->tree);
  94          $nodes = $reflector->getProperty('nodes');
  95          $nodes->setAccessible(true);
  96          $this->assertArrayNotHasKey('fullprofile', $nodes->getValue($this->tree));
  97      }
  98  
  99      /**
 100       * Tests the core_myprofile_navigation() function as the currently logged in user.
 101       */
 102      public function test_core_myprofile_navigation_profile_link_as_current_user() {
 103          $this->setUser($this->user);
 104          $iscurrentuser = true;
 105  
 106          core_myprofile_navigation($this->tree, $this->user, $iscurrentuser, $this->course);
 107          $reflector = new \ReflectionObject($this->tree);
 108          $nodes = $reflector->getProperty('nodes');
 109          $nodes->setAccessible(true);
 110          $this->assertArrayHasKey('editprofile', $nodes->getValue($this->tree));
 111      }
 112  
 113      /**
 114       * Tests the core_myprofile_navigation() function as the admin viewing another user.
 115       */
 116      public function test_core_myprofile_navigation_profile_link_as_admin() {
 117          $this->setAdminUser();
 118          $iscurrentuser = false;
 119  
 120          core_myprofile_navigation($this->tree, $this->user, $iscurrentuser, $this->course);
 121          $reflector = new \ReflectionObject($this->tree);
 122          $nodes = $reflector->getProperty('nodes');
 123          $nodes->setAccessible(true);
 124          $this->assertArrayHasKey('editprofile', $nodes->getValue($this->tree));
 125      }
 126  
 127      /**
 128       * Tests the core_myprofile_navigation() function when viewing the preference page as an admin.
 129       */
 130      public function test_core_myprofile_navigation_preference_as_admin() {
 131          $this->setAdminUser();
 132          $iscurrentuser = false;
 133  
 134          core_myprofile_navigation($this->tree, $this->user, $iscurrentuser, $this->course);
 135          $reflector = new \ReflectionObject($this->tree);
 136          $nodes = $reflector->getProperty('nodes');
 137          $nodes->setAccessible(true);
 138          $this->assertArrayHasKey('preferences', $nodes->getValue($this->tree));
 139          $this->assertArrayHasKey('loginas', $nodes->getValue($this->tree));
 140      }
 141  
 142      /**
 143       * Tests the core_myprofile_navigation() function when viewing the preference
 144       * page as another user without the ability to use the 'loginas' functionality.
 145       */
 146      public function test_core_myprofile_navigation_preference_without_permission() {
 147          // Login as link for a user who doesn't have the capability to login as.
 148          $this->setUser($this->getDataGenerator()->create_user());
 149          $iscurrentuser = false;
 150  
 151          core_myprofile_navigation($this->tree, $this->user, $iscurrentuser, $this->course);
 152          $reflector = new \ReflectionObject($this->tree);
 153          $nodes = $reflector->getProperty('nodes');
 154          $nodes->setAccessible(true);
 155          $this->assertArrayNotHasKey('loginas', $nodes->getValue($this->tree));
 156      }
 157  
 158      /**
 159       * Tests the core_myprofile_navigation() function as an admin viewing another user's contact details.
 160       */
 161      public function test_core_myprofile_navigation_contact_fields_as_admin() {
 162          global $CFG;
 163  
 164          // User contact fields.
 165          set_config("hiddenuserfields", "country,city");
 166          set_config("showuseridentity", "email,address,phone1,phone2,institution,department,idnumber");
 167          $hiddenfields = explode(',', $CFG->hiddenuserfields);
 168          $identityfields = explode(',', $CFG->showuseridentity);
 169          $this->setAdminUser();
 170          $iscurrentuser = false;
 171  
 172          // Make sure fields are not empty.
 173          $fields = array(
 174              'country' => 'AU',
 175              'city' => 'Silent hill',
 176              'email' => 'Rulelikeaboss@example.com',
 177              'address' => 'Didn\'t I mention silent hill already ?',
 178              'phone1' => '123',
 179              'phone2' => '234',
 180              'institution' => 'strange land',
 181              'department' => 'video game/movie',
 182              'idnumber' => 'SLHL'
 183          );
 184          foreach ($fields as $field => $value) {
 185              $this->user->$field = $value;
 186          }
 187  
 188          // User with proper permissions.
 189          core_myprofile_navigation($this->tree, $this->user, $iscurrentuser, null);
 190          $reflector = new \ReflectionObject($this->tree);
 191          $nodes = $reflector->getProperty('nodes');
 192          $nodes->setAccessible(true);
 193          foreach ($hiddenfields as $field) {
 194              $this->assertArrayHasKey($field, $nodes->getValue($this->tree));
 195          }
 196          foreach ($identityfields as $field) {
 197              $this->assertArrayHasKey($field, $nodes->getValue($this->tree));
 198          }
 199      }
 200  
 201      /**
 202       * Tests the core_myprofile_navigation() function as a user viewing another user's profile
 203       * ensuring that the contact details are not shown.
 204       */
 205      public function test_core_myprofile_navigation_contact_field_without_permission() {
 206          global $CFG;
 207  
 208          $iscurrentuser = false;
 209          $hiddenfields = explode(',', $CFG->hiddenuserfields);
 210          $identityfields = explode(',', $CFG->showuseridentity);
 211  
 212          // User without permission.
 213          $this->setUser($this->getDataGenerator()->create_user());
 214          core_myprofile_navigation($this->tree, $this->user, $iscurrentuser, null);
 215          $reflector = new \ReflectionObject($this->tree);
 216          $nodes = $reflector->getProperty('nodes');
 217          $nodes->setAccessible(true);
 218          foreach ($hiddenfields as $field) {
 219              $this->assertArrayNotHasKey($field, $nodes->getValue($this->tree));
 220          }
 221          foreach ($identityfields as $field) {
 222              $this->assertArrayNotHasKey($field, $nodes->getValue($this->tree));
 223          }
 224      }
 225  
 226      /**
 227       * Data provider for {@see test_core_myprofile_navigation_contact_timezone}
 228       *
 229       * @return array[]
 230       */
 231      public function core_myprofile_navigation_contact_timezone_provider(): array {
 232          return [
 233              'Hidden field' => ['timezone', '99', '99', null],
 234              'Forced timezone' => ['', 'Europe/London', 'Pacific/Tahiti', 'Europe/London'],
 235              'User timezone (default)' => ['', '99', '99', 'Australia/Perth'],
 236              'User timezone (selected)' => ['', '99', 'Pacific/Tahiti', 'Pacific/Tahiti'],
 237          ];
 238      }
 239  
 240      /**
 241       * Test timezone node added to user profile navigation
 242       *
 243       * @param string $hiddenuserfields
 244       * @param string $forcetimezone Timezone identifier or '99' (User can choose their own)
 245       * @param string $usertimezone Timezone identifier or '99' (Use server default)
 246       * @param string|null $expectresult
 247       * @return bool
 248       *
 249       * @dataProvider core_myprofile_navigation_contact_timezone_provider
 250       */
 251      public function test_core_myprofile_navigation_contact_timezone(string $hiddenuserfields, string $forcetimezone,
 252              string $usertimezone, ?string $expectresult = null): void {
 253  
 254          set_config('hiddenuserfields', $hiddenuserfields);
 255          set_config('forcetimezone', $forcetimezone);
 256  
 257          // Set the timezone of our test user, and load their navigation tree.
 258          $this->user->timezone = $usertimezone;
 259          $this->setUser($this->user);
 260  
 261          core_myprofile_navigation($this->tree, $this->user, true, null);
 262  
 263          $reflector = new \ReflectionObject($this->tree);
 264          $nodes = $reflector->getProperty('nodes');
 265          $nodes->setAccessible(true);
 266  
 267          /** @var \core_user\output\myprofile\node[] $tree */
 268          $tree = $nodes->getValue($this->tree);
 269          if ($expectresult !== null) {
 270              $this->assertArrayHasKey('timezone', $tree);
 271              $this->assertEquals($expectresult, $tree['timezone']->content);
 272          } else {
 273              $this->assertArrayNotHasKey('timezone', $tree);
 274          }
 275      }
 276  
 277      /**
 278       * Tests the core_myprofile_navigation() function as an admin viewing another user's
 279       * profile ensuring the login activity links are shown.
 280       */
 281      public function test_core_myprofile_navigation_login_activity() {
 282          // First access, last access, last ip.
 283          $this->setAdminUser();
 284          $iscurrentuser = false;
 285  
 286          core_myprofile_navigation($this->tree, $this->user, $iscurrentuser, null);
 287          $reflector = new \ReflectionObject($this->tree);
 288          $nodes = $reflector->getProperty('nodes');
 289          $nodes->setAccessible(true);
 290          $this->assertArrayHasKey('firstaccess', $nodes->getValue($this->tree));
 291          $this->assertArrayHasKey('lastaccess', $nodes->getValue($this->tree));
 292          $this->assertArrayHasKey('lastip', $nodes->getValue($this->tree));
 293      }
 294  
 295      /**
 296       * Tests the core_myprofile_navigation() function as a user viewing another user's profile
 297       * ensuring the login activity links are not shown.
 298       */
 299      public function test_core_myprofile_navigationn_login_activity_without_permission() {
 300          // User without permission.
 301          set_config("hiddenuserfields", "firstaccess,lastaccess,lastip");
 302          $this->setUser($this->getDataGenerator()->create_user());
 303          $iscurrentuser = false;
 304  
 305          core_myprofile_navigation($this->tree, $this->user, $iscurrentuser, null);
 306          $reflector = new \ReflectionObject($this->tree);
 307          $nodes = $reflector->getProperty('nodes');
 308          $nodes->setAccessible(true);
 309          $this->assertArrayNotHasKey('firstaccess', $nodes->getValue($this->tree));
 310          $this->assertArrayNotHasKey('lastaccess', $nodes->getValue($this->tree));
 311          $this->assertArrayNotHasKey('lastip', $nodes->getValue($this->tree));
 312      }
 313  }