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  // This file is part of BasicLTI4Moodle
  18  //
  19  // BasicLTI4Moodle is an IMS BasicLTI (Basic Learning Tools for Interoperability)
  20  // consumer for Moodle 1.9 and Moodle 2.0. BasicLTI is a IMS Standard that allows web
  21  // based learning tools to be easily integrated in LMS as native ones. The IMS BasicLTI
  22  // specification is part of the IMS standard Common Cartridge 1.1 Sakai and other main LMS
  23  // are already supporting or going to support BasicLTI. This project Implements the consumer
  24  // for Moodle. Moodle is a Free Open source Learning Management System by Martin Dougiamas.
  25  // BasicLTI4Moodle is a project iniciated and leaded by Ludo(Marc Alier) and Jordi Piguillem
  26  // at the GESSI research group at UPC.
  27  // SimpleLTI consumer for Moodle is an implementation of the early specification of LTI
  28  // by Charles Severance (Dr Chuck) htp://dr-chuck.com , developed by Jordi Piguillem in a
  29  // Google Summer of Code 2008 project co-mentored by Charles Severance and Marc Alier.
  30  //
  31  // BasicLTI4Moodle is copyright 2009 by Marc Alier Forment, Jordi Piguillem and Nikolas Galanis
  32  // of the Universitat Politecnica de Catalunya http://www.upc.edu
  33  // Contact info: Marc Alier Forment granludo @ gmail.com or marc.alier @ upc.edu.
  34  
  35  namespace mod_lti\local;
  36  
  37  use mod_lti_testcase;
  38  
  39  defined('MOODLE_INTERNAL') || die();
  40  
  41  global $CFG;
  42  require_once($CFG->dirroot . '/mod/lti/locallib.php');
  43  require_once($CFG->dirroot . '/mod/lti/tests/mod_lti_testcase.php');
  44  
  45  /**
  46   * Types helper tests.
  47   *
  48   * @package    mod_lti
  49   * @copyright  2023 Jake Dallimore <jrhdallimore@gmail.com>
  50   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  51   * @coversDefaultClass \mod_lti\local\types_helper
  52   */
  53  class types_helper_test extends mod_lti_testcase {
  54  
  55      /**
  56       * Test fetching tool types for a given course and user.
  57       *
  58       * @covers ::get_lti_types_by_course
  59       * @return void.
  60       */
  61      public function test_get_lti_types_by_course(): void {
  62          $this->resetAfterTest();
  63  
  64          global $DB;
  65          $coursecat1 = $this->getDataGenerator()->create_category();
  66          $coursecat2 = $this->getDataGenerator()->create_category();
  67          $course = $this->getDataGenerator()->create_course(['category' => $coursecat1->id]);
  68          $course2 = $this->getDataGenerator()->create_course(['category' => $coursecat2->id]);
  69          $teacher = $this->getDataGenerator()->create_and_enrol($course, 'editingteacher');
  70          $teacher2 = $this->getDataGenerator()->create_and_enrol($course2, 'editingteacher');
  71  
  72          $this->setUser($teacher);
  73  
  74          // Create the following tool types for testing:
  75          // - Site tool configured as "Do not show" (LTI_COURSEVISIBLE_NO).
  76          // - Site tool configured as "Show as a preconfigured tool only" (LTI_COURSEVISIBLE_PRECONFIGURED).
  77          // - Site tool configured as "Show as a preconfigured tool and in the activity chooser" (LTI_COURSEVISIBLE_ACTIVITYCHOOSER).
  78          // - Course tool which, by default, is configured as LTI_COURSEVISIBLE_ACTIVITYCHOOSER).
  79          // - Site tool configured to "Show as a preconfigured tool and in the activity chooser" but restricted to a category.
  80  
  81          /** @var \mod_lti_generator $ltigenerator */
  82          $ltigenerator = $this->getDataGenerator()->get_plugin_generator('mod_lti');
  83          $ltigenerator->create_tool_types([
  84              'name' => 'site tool do not show',
  85              'baseurl' => 'http://example.com/tool/1',
  86              'coursevisible' => LTI_COURSEVISIBLE_NO,
  87              'state' => LTI_TOOL_STATE_CONFIGURED
  88          ]);
  89          $ltigenerator->create_tool_types([
  90              'name' => 'site tool preconfigured only',
  91              'baseurl' => 'http://example.com/tool/2',
  92              'coursevisible' => LTI_COURSEVISIBLE_PRECONFIGURED,
  93              'state' => LTI_TOOL_STATE_CONFIGURED
  94          ]);
  95          $ltigenerator->create_tool_types([
  96              'name' => 'site tool preconfigured and activity chooser',
  97              'baseurl' => 'http://example.com/tool/3',
  98              'coursevisible' => LTI_COURSEVISIBLE_ACTIVITYCHOOSER,
  99              'state' => LTI_TOOL_STATE_CONFIGURED
 100          ]);
 101          $ltigenerator->create_course_tool_types([
 102              'name' => 'course tool preconfigured and activity chooser',
 103              'baseurl' => 'http://example.com/tool/4',
 104              'course' => $course->id
 105          ]);
 106          $ltigenerator->create_tool_types([
 107              'name' => 'site tool preconfigured and activity chooser, restricted to category 2',
 108              'baseurl' => 'http://example.com/tool/5',
 109              'coursevisible' => LTI_COURSEVISIBLE_ACTIVITYCHOOSER,
 110              'state' => LTI_TOOL_STATE_CONFIGURED,
 111              'lti_coursecategories' => $coursecat2->id
 112          ]);
 113  
 114          // Request using the default 'coursevisible' param will include all tools except the one configured as "Do not show" and
 115          // the tool restricted to category 2.
 116          $coursetooltypes = types_helper::get_lti_types_by_course($course->id, $teacher->id);
 117          $this->assertCount(3, $coursetooltypes);
 118          $expected = [
 119              'http://example.com/tool/2',
 120              'http://example.com/tool/3',
 121              'http://example.com/tool/4',
 122          ];
 123          sort($expected);
 124          $actual = array_column($coursetooltypes, 'baseurl');
 125          sort($actual);
 126          $this->assertEquals($expected, $actual);
 127  
 128          // Request for only those tools configured to show in the activity chooser for the teacher.
 129          $coursetooltypes = types_helper::get_lti_types_by_course($course->id, $teacher->id,
 130              [LTI_COURSEVISIBLE_ACTIVITYCHOOSER]);
 131          $this->assertCount(2, $coursetooltypes);
 132          $expected = [
 133              'http://example.com/tool/3',
 134              'http://example.com/tool/4',
 135          ];
 136          sort($expected);
 137          $actual = array_column($coursetooltypes, 'baseurl');
 138          sort($actual);
 139          $this->assertEquals($expected, $actual);
 140  
 141          // Request for only those tools configured to show as a preconfigured tool for the teacher.
 142          $coursetooltypes = types_helper::get_lti_types_by_course($course->id, $teacher->id,
 143              [LTI_COURSEVISIBLE_PRECONFIGURED]);
 144          $this->assertCount(1, $coursetooltypes);
 145          $expected = [
 146              'http://example.com/tool/2',
 147          ];
 148          $actual = array_column($coursetooltypes, 'baseurl');
 149          $this->assertEquals($expected, $actual);
 150  
 151          // Request for teacher2 in course2 (course category 2).
 152          $coursetooltypes = types_helper::get_lti_types_by_course($course2->id, $teacher2->id);
 153          $this->assertCount(3, $coursetooltypes);
 154          $expected = [
 155              'http://example.com/tool/2',
 156              'http://example.com/tool/3',
 157              'http://example.com/tool/5',
 158          ];
 159          sort($expected);
 160          $actual = array_column($coursetooltypes, 'baseurl');
 161          sort($actual);
 162          $this->assertEquals($expected, $actual);
 163  
 164          // Request for a teacher who cannot use preconfigured tools in the course.
 165          $teacherrole = $DB->get_record('role', array('shortname' => 'editingteacher'));
 166          assign_capability('mod/lti:addpreconfiguredinstance', CAP_PROHIBIT, $teacherrole->id,
 167              \core\context\course::instance($course->id));
 168          $coursetooltypes = types_helper::get_lti_types_by_course($course->id, $teacher->id);
 169          $this->assertCount(0, $coursetooltypes);
 170      }
 171  
 172      /**
 173       * Test fetching tool types for a given course and user.
 174       *
 175       * @covers ::override_type_showinactivitychooser
 176       * @return void.
 177       */
 178      public function test_override_type_showinactivitychooser(): void {
 179          $this->resetAfterTest();
 180  
 181          global $DB;
 182          $coursecat1 = $this->getDataGenerator()->create_category();
 183          $coursecat2 = $this->getDataGenerator()->create_category();
 184          $course = $this->getDataGenerator()->create_course(['category' => $coursecat1->id]);
 185          $course2 = $this->getDataGenerator()->create_course(['category' => $coursecat2->id]);
 186          $teacher = $this->getDataGenerator()->create_and_enrol($course, 'editingteacher');
 187          $teacher2 = $this->getDataGenerator()->create_and_enrol($course2, 'editingteacher');
 188          $context =  \core\context\course::instance($course->id);
 189  
 190          $this->setUser($teacher);
 191  
 192          /*
 193              Create the following tool types for testing:
 194              | tooltype | coursevisible                     | restrictedtocategory |
 195              | site     | LTI_COURSEVISIBLE_NO              |                      |
 196              | site     | LTI_COURSEVISIBLE_PRECONFIGURED   |                      |
 197              | site     | LTI_COURSEVISIBLE_ACTIVITYCHOOSER | yes                  |
 198              | site     | LTI_COURSEVISIBLE_ACTIVITYCHOOSER | yes                  |
 199              | course   | LTI_COURSEVISIBLE_ACTIVITYCHOOSER |                      |
 200          */
 201  
 202          /** @var \mod_lti_generator $ltigenerator */
 203          $ltigenerator = $this->getDataGenerator()->get_plugin_generator('mod_lti');
 204          $tool1id = $ltigenerator->create_tool_types([
 205              'name' => 'site tool do not show',
 206              'baseurl' => 'http://example.com/tool/1',
 207              'coursevisible' => LTI_COURSEVISIBLE_NO,
 208              'state' => LTI_TOOL_STATE_CONFIGURED
 209          ]);
 210          $tool2id = $ltigenerator->create_tool_types([
 211              'name' => 'site tool preconfigured only',
 212              'baseurl' => 'http://example.com/tool/2',
 213              'coursevisible' => LTI_COURSEVISIBLE_PRECONFIGURED,
 214              'state' => LTI_TOOL_STATE_CONFIGURED
 215          ]);
 216          $tool3id = $ltigenerator->create_course_tool_types([
 217              'name' => 'course tool preconfigured and activity chooser',
 218              'baseurl' => 'http://example.com/tool/3',
 219              'course' => $course->id
 220          ]);
 221          $tool4id = $ltigenerator->create_tool_types([
 222              'name' => 'site tool preconfigured and activity chooser, restricted to category 2',
 223              'baseurl' => 'http://example.com/tool/4',
 224              'coursevisible' => LTI_COURSEVISIBLE_ACTIVITYCHOOSER,
 225              'state' => LTI_TOOL_STATE_CONFIGURED,
 226              'lti_coursecategories' => $coursecat2->id
 227          ]);
 228          $tool5id = $ltigenerator->create_tool_types([
 229              'name' => 'site tool preconfigured and activity chooser, restricted to category 1',
 230              'baseurl' => 'http://example.com/tool/5',
 231              'coursevisible' => LTI_COURSEVISIBLE_ACTIVITYCHOOSER,
 232              'state' => LTI_TOOL_STATE_CONFIGURED,
 233              'lti_coursecategories' => $coursecat1->id
 234          ]);
 235  
 236          // LTI_COURSEVISIBLE_NO can't be updated.
 237          $result = types_helper::override_type_showinactivitychooser($tool1id, $course->id, $context, true);
 238          $this->assertFalse($result);
 239  
 240          // Tool not exist.
 241          $result = types_helper::override_type_showinactivitychooser($tool5id + 1, $course->id, $context, false);
 242          $this->assertFalse($result);
 243  
 244          $result = types_helper::override_type_showinactivitychooser($tool2id, $course->id, $context, true);
 245          $this->assertTrue($result);
 246          $coursevisibleoverriden = $DB->get_field('lti_coursevisible', 'coursevisible',
 247              ['typeid' => $tool2id, 'courseid' => $course->id]);
 248          $this->assertEquals(LTI_COURSEVISIBLE_ACTIVITYCHOOSER, $coursevisibleoverriden);
 249  
 250          $result = types_helper::override_type_showinactivitychooser($tool3id, $course->id, $context, false);
 251          $this->assertTrue($result);
 252          $coursevisible = $DB->get_field('lti_types', 'coursevisible', ['id' => $tool3id]);
 253          $this->assertEquals(LTI_COURSEVISIBLE_PRECONFIGURED, $coursevisible);
 254  
 255          // Restricted category no allowed.
 256          $this->expectException('moodle_exception');
 257          $this->expectExceptionMessage('You are not allowed to change this setting for this tool.');
 258          types_helper::override_type_showinactivitychooser($tool4id, $course->id, $context, false);
 259  
 260          // Restricted category allowed.
 261          $result = types_helper::override_type_showinactivitychooser($tool5id, $course->id, $context, false);
 262          $this->assertTrue($result);
 263          $coursevisibleoverriden = $DB->get_field('lti_coursevisible', 'coursevisible',
 264              ['typeid' => $tool5id, 'courseid' => $course->id]);
 265          $this->assertEquals(LTI_COURSEVISIBLE_PRECONFIGURED, $coursevisibleoverriden);
 266  
 267          $this->setUser($teacher2);
 268          $this->expectException(\required_capability_exception::class);
 269          types_helper::override_type_showinactivitychooser($tool5id, $course->id, $context, false);
 270      }
 271  
 272  }