Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 4.3.x will end 7 October 2024 (12 months).
  • Bug fixes for security issues in 4.3.x will end 21 April 2025 (18 months).
  • PHP version: minimum PHP 8.0.0 Note: minimum PHP version has increased since Moodle 4.1. PHP 8.2.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 core_badges\external;
  18  
  19  use externallib_advanced_testcase;
  20  
  21  defined('MOODLE_INTERNAL') || die();
  22  
  23  global $CFG;
  24  
  25  require_once($CFG->dirroot . '/webservice/tests/helpers.php');
  26  require_once($CFG->libdir . '/badgeslib.php');
  27  
  28  /**
  29   * Tests for external function get_user_badge_by_hash.
  30   *
  31   * @package    core_badges
  32   * @category   external
  33   * @copyright  2023 Rodrigo Mady <rodrigo.mady@moodle.com>
  34   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  35   * @since      Moodle 4.3
  36   * @coversDefaultClass \core_badges\external\get_user_badge_by_hash
  37   */
  38  class get_user_badge_by_hash_test extends externallib_advanced_testcase {
  39  
  40      /**
  41       * Prepare the test.
  42       *
  43       * @return array
  44       */
  45      private function prepare_test_data(): array {
  46          global $DB;
  47          $this->resetAfterTest();
  48          $this->setAdminUser();
  49  
  50          // Setup test data.
  51          $course = $this->getDataGenerator()->create_course();
  52  
  53          // Create users and enrolments.
  54          $student1 = $this->getDataGenerator()->create_and_enrol($course);
  55          $student2 = $this->getDataGenerator()->create_and_enrol($course);
  56          $teacher  = $this->getDataGenerator()->create_and_enrol($course, 'editingteacher');
  57  
  58          // Mock up a site badge.
  59          $now = time();
  60          $badge = new \stdClass();
  61          $badge->id = null;
  62          $badge->name = "Test badge site";
  63          $badge->description  = "Testing badges site";
  64          $badge->timecreated  = $now;
  65          $badge->timemodified = $now;
  66          $badge->usercreated  = (int) $teacher->id;
  67          $badge->usermodified = (int) $teacher->id;
  68          $badge->expiredate    = null;
  69          $badge->expireperiod  = null;
  70          $badge->type = BADGE_TYPE_SITE;
  71          $badge->courseid = null;
  72          $badge->messagesubject = "Test message subject for badge";
  73          $badge->message = "Test message body for badge";
  74          $badge->attachment = 1;
  75          $badge->notification = 0;
  76          $badge->status = BADGE_STATUS_ACTIVE;
  77          $badge->version = '1';
  78          $badge->language = 'en';
  79          $badge->imageauthorname = 'Image author';
  80          $badge->imageauthoremail = 'imageauthor@example.com';
  81          $badge->imageauthorurl = 'http://image-author-url.domain.co.nz';
  82          $badge->imagecaption = 'Caption';
  83  
  84          $badgeid   = $DB->insert_record('badge', $badge, true);
  85          $badge->id = $badgeid;
  86          $sitebadge = new \badge($badgeid);
  87          $sitebadge->issue($student1->id, true);
  88          $siteissuedbadge = $DB->get_record('badge_issued', [ 'badgeid' => $badge->id ]);
  89  
  90          $badge->issuername = $sitebadge->issuername;
  91          $badge->issuercontact = $sitebadge->issuercontact;
  92          $badge->issuerurl  = $sitebadge->issuerurl;
  93          $badge->nextcron   = $sitebadge->nextcron;
  94          $badge->issuedid   = (int) $siteissuedbadge->id;
  95          $badge->uniquehash = $siteissuedbadge->uniquehash;
  96          $badge->dateissued = (int) $siteissuedbadge->dateissued;
  97          $badge->dateexpire = $siteissuedbadge->dateexpire;
  98          $badge->visible    = (int) $siteissuedbadge->visible;
  99          $badge->email      = $student1->email;
 100          $context           = \context_system::instance();
 101          $badge->badgeurl   = \moodle_url::make_webservice_pluginfile_url($context->id, 'badges', 'badgeimage', $badge->id, '/',
 102                                                                              'f3')->out(false);
 103          $badge->status = BADGE_STATUS_ACTIVE_LOCKED;
 104  
 105          // Add an endorsement for the badge.
 106          $endorsement              = new \stdClass();
 107          $endorsement->badgeid     = $badgeid;
 108          $endorsement->issuername  = 'Issuer name';
 109          $endorsement->issuerurl   = 'http://endorsement-issuer-url.domain.co.nz';
 110          $endorsement->issueremail = 'endorsementissuer@example.com';
 111          $endorsement->claimid     = 'http://claim-url.domain.co.nz';
 112          $endorsement->claimcomment = 'Claim comment';
 113          $endorsement->dateissued  = $now;
 114          $endorsement->id          = $sitebadge->save_endorsement($endorsement);
 115          $badge->endorsement       = (array) $endorsement;
 116  
 117          // Add 2 alignments.
 118          $alignment          = new \stdClass();
 119          $alignment->badgeid = $badgeid;
 120          $alignment->id      = $sitebadge->save_alignment($alignment);
 121          $badge->alignment[] = (array) $alignment;
 122  
 123          $alignment->id        = $sitebadge->save_alignment($alignment);
 124          $badge->alignment[]   = (array) $alignment;
 125          $badge->relatedbadges = [];
 126          $usersitebadge[]      = (array) $badge;
 127  
 128          // Now a course badge.
 129          $badge->id          = null;
 130          $badge->name        = "Test badge course";
 131          $badge->description = "Testing badges course";
 132          $badge->type        = BADGE_TYPE_COURSE;
 133          $badge->courseid    = (int) $course->id;
 134  
 135          $badge->id     = $DB->insert_record('badge', $badge, true);
 136          $coursebadge   = new \badge($badge->id );
 137          $coursebadge->issue($student1->id, true);
 138          $courseissuedbadge = $DB->get_record('badge_issued', [ 'badgeid' => $badge->id ]);
 139  
 140          $badge->issuername = $coursebadge->issuername;
 141          $badge->issuercontact = $coursebadge->issuercontact;
 142          $badge->issuerurl  = $coursebadge->issuerurl;
 143          $badge->nextcron   = $coursebadge->nextcron;
 144          $badge->issuedid   = (int) $courseissuedbadge->id;
 145          $badge->uniquehash = $courseissuedbadge->uniquehash;
 146          $badge->dateissued = (int) $courseissuedbadge->dateissued;
 147          $badge->dateexpire = $courseissuedbadge->dateexpire;
 148          $badge->visible    = (int) $courseissuedbadge->visible;
 149          $badge->email      = $student1->email;
 150          $context           = \context_course::instance($badge->courseid);
 151          $badge->badgeurl   = \moodle_url::make_webservice_pluginfile_url($context->id, 'badges', 'badgeimage', $badge->id , '/',
 152                                                                              'f3')->out(false);
 153  
 154          unset($badge->endorsement);
 155          $badge->alignment    = [];
 156          $usercoursebadge[] = (array) $badge;
 157          // Make the site badge a related badge.
 158          $sitebadge->add_related_badges([$badge->id]);
 159          $usersitebadge[0]['relatedbadges'][0] = [
 160              'id'   => (int) $coursebadge->id,
 161              'name' => $coursebadge->name
 162          ];
 163          $usercoursebadge[0]['relatedbadges'][0] = [
 164              'id'   => (int) $sitebadge->id,
 165              'name' => $sitebadge->name
 166          ];
 167          return [
 168              'coursebadge' => $usercoursebadge,
 169              'sitebadge'   => $usersitebadge,
 170              'student1'    => $student1,
 171              'student2'    => $student2
 172          ];
 173      }
 174  
 175      /**
 176       * Test get user badge by hash.
 177       * These are a basic tests since the badges_get_my_user_badges used by the external function already has unit tests.
 178       * @covers ::execute
 179       */
 180      public function test_get_user_badge_by_hash() {
 181          $data = $this->prepare_test_data();
 182          $this->setUser($data['student1']);
 183  
 184          // Site badge.
 185          $result = get_user_badge_by_hash::execute($data['sitebadge'][0]['uniquehash']);
 186          $result = \core_external\external_api::clean_returnvalue(get_user_badge_by_hash::execute_returns(), $result);
 187          $this->assertEquals($data['sitebadge'][0]['uniquehash'], $result['badge'][0]['uniquehash']);
 188          $this->assertEmpty($result['warnings']);
 189  
 190          // Course badge.
 191          $result = get_user_badge_by_hash::execute($data['coursebadge'][0]['uniquehash']);
 192          $result = \core_external\external_api::clean_returnvalue(get_user_badge_by_hash::execute_returns(), $result);
 193          $this->assertEquals($data['coursebadge'][0]['uniquehash'], $result['badge'][0]['uniquehash']);
 194          $this->assertEmpty($result['warnings']);
 195  
 196          // Wrong hash.
 197          $result = get_user_badge_by_hash::execute('1234');
 198          $result = \core_external\external_api::clean_returnvalue(get_user_badge_by_hash::execute_returns(), $result);
 199          $this->assertEmpty($result['badge']);
 200          $this->assertNotEmpty($result['warnings']);
 201          $this->assertEquals('badgeawardnotfound', $result['warnings'][0]['warningcode']);
 202      }
 203  
 204      /**
 205       * Test get user badge by hash with restrictions.
 206       * @covers ::execute
 207       */
 208      public function test_get_user_badge_by_hash_with_restrictions() {
 209          $data = $this->prepare_test_data();
 210          $this->setUser($data['student2']);
 211  
 212          // Site badge.
 213          $result = get_user_badge_by_hash::execute($data['sitebadge'][0]['uniquehash']);
 214          $result = \core_external\external_api::clean_returnvalue(get_user_badge_by_hash::execute_returns(), $result);
 215          $this->assertNotEmpty($result['badge']);
 216          $this->assertEmpty($result['warnings']);
 217  
 218          // Check that we don't have permissions for view the complete information for site badges.
 219          if (isset($result['badge'][0]['type']) && $result['badge'][0]['type'] == BADGE_TYPE_SITE) {
 220              $this->assertFalse(isset($result['badge'][0]['message']));
 221  
 222              // Check that we have permissions to see all the data in alignments and related badges.
 223              foreach ($result['badge'][0]['alignment'] as $alignment) {
 224                  $this->assertTrue(isset($alignment['id']));
 225              }
 226  
 227              foreach ($result['badge'][0]['relatedbadges'] as $relatedbadge) {
 228                  $this->assertTrue(isset($relatedbadge['id']));
 229              }
 230          } else {
 231              $this->assertTrue(isset($result['badge'][0]['message']));
 232          }
 233  
 234          // Course badge.
 235          $result = get_user_badge_by_hash::execute($data['coursebadge'][0]['uniquehash']);
 236          $result = \core_external\external_api::clean_returnvalue(get_user_badge_by_hash::execute_returns(), $result);
 237          $this->assertNotEmpty($result['badge']);
 238          $this->assertEmpty($result['warnings']);
 239  
 240          // Check that we don't have permissions for view the complete information for course badges.
 241          if (isset($result['badge'][0]['type']) && $result['badge'][0]['type'] == BADGE_TYPE_COURSE) {
 242              $this->assertFalse(isset($result['badge'][0]['message']));
 243          } else {
 244              $this->assertTrue(isset($result['badge'][0]['message']));
 245          }
 246      }
 247  }