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 enrol_lti\local\ltiadvantage\service;
  18  
  19  use enrol_lti\helper;
  20  use enrol_lti\local\ltiadvantage\repository\application_registration_repository;
  21  use enrol_lti\local\ltiadvantage\repository\context_repository;
  22  use enrol_lti\local\ltiadvantage\repository\deployment_repository;
  23  use enrol_lti\local\ltiadvantage\repository\resource_link_repository;
  24  use enrol_lti\local\ltiadvantage\repository\user_repository;
  25  
  26  defined('MOODLE_INTERNAL') || die();
  27  
  28  require_once (__DIR__ . '/../lti_advantage_testcase.php');
  29  
  30  /**
  31   * Tests for the application_registration_service.
  32   *
  33   * @package enrol_lti
  34   * @copyright 2021 Jake Dallimore <jrhdallimore@gmail.com>
  35   * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  36   * @coversDefaultClass \enrol_lti\local\ltiadvantage\service\application_registration_service
  37   */
  38  class application_registration_service_test extends \lti_advantage_testcase {
  39      /**
  40       * Helper to get an application_registration_service instance.
  41       * @return application_registration_service
  42       */
  43      protected function get_application_registration_service(): application_registration_service {
  44          return new application_registration_service(
  45              new application_registration_repository(),
  46              new deployment_repository(),
  47              new resource_link_repository(),
  48              new context_repository(),
  49              new user_repository()
  50          );
  51      }
  52  
  53      /**
  54       * Test the use case "As an admin, I can register an application as an LTI consumer (platform)".
  55       *
  56       * @covers ::create_draft_application_registration
  57       */
  58      public function test_create_draft_application() {
  59          $this->resetAfterTest();
  60          $service = $this->get_application_registration_service();
  61  
  62          // Create a draft, passing the required name.
  63          $draftreg = $service->create_draft_application_registration((object) ['name' => 'My test platform']);
  64          $this->assertEquals('My test platform', $draftreg->get_name());
  65          $this->assertNull($draftreg->get_authenticationrequesturl());
  66          $this->assertNull($draftreg->get_jwksurl());
  67          $this->assertNull($draftreg->get_accesstokenurl());
  68          $this->assertNull($draftreg->get_platformid());
  69          $this->assertNull($draftreg->get_clientid());
  70          $this->assertFalse($draftreg->is_complete());
  71  
  72          // Try to create a draft omitting name.
  73          $this->expectException(\coding_exception::class);
  74          $service->create_draft_application_registration((object) []);
  75      }
  76  
  77      /**
  78       * Test the update_application_registration method.
  79       *
  80       * @covers ::update_application_registration
  81       */
  82      public function test_update_application_registration() {
  83          $this->resetAfterTest();
  84  
  85          // Create a registration in the draft state.
  86          $service = $this->get_application_registration_service();
  87          $draftreg = $service->create_draft_application_registration((object) ['name' => 'My test platform']);
  88  
  89          // Update the draft.
  90          $updatedto = (object) [
  91              'id' => $draftreg->get_id(),
  92              'name' => 'My test platform name edit 1',
  93              'platformid' => 'https://lms.example.org',
  94              'clientid' => '123',
  95              'authenticationrequesturl' => 'https://lms.example.org/authrequesturl',
  96              'jwksurl' => 'https://lms.example.org/jwksurl',
  97              'accesstokenurl' => 'https://lms.example.org/accesstokenurl'
  98          ];
  99          $reg = $service->update_application_registration($updatedto);
 100  
 101          // Verify details saved and complete status.
 102          $this->assertEquals($updatedto->id, $reg->get_id());
 103          $this->assertEquals($updatedto->name, $reg->get_name());
 104          $this->assertEquals(new \moodle_url($updatedto->platformid), $reg->get_platformid());
 105          $this->assertEquals($updatedto->clientid, $reg->get_clientid());
 106          $this->assertEquals(new \moodle_url($updatedto->authenticationrequesturl), $reg->get_authenticationrequesturl());
 107          $this->assertEquals(new \moodle_url($updatedto->jwksurl), $reg->get_jwksurl());
 108          $this->assertEquals(new \moodle_url($updatedto->accesstokenurl), $reg->get_accesstokenurl());
 109          $this->assertTrue($reg->is_complete());
 110  
 111          // Update again.
 112          $updatedto = (object) [
 113              'id' => $draftreg->get_id(),
 114              'name' => 'My test platform name edit 2',
 115              'platformid' => 'https://different.example.org',
 116              'clientid' => 'abcd1234',
 117              'authenticationrequesturl' => 'https://lms.example.org/authrequesturl2',
 118              'jwksurl' => 'https://lms.example.org/jwksurl2',
 119              'accesstokenurl' => 'https://lms.example.org/accesstokenurl2'
 120          ];
 121          $reg = $service->update_application_registration($updatedto);
 122  
 123          // Verify again.
 124          $this->assertEquals($updatedto->id, $reg->get_id());
 125          $this->assertEquals($updatedto->name, $reg->get_name());
 126          $this->assertEquals(new \moodle_url($updatedto->platformid), $reg->get_platformid());
 127          $this->assertEquals($updatedto->clientid, $reg->get_clientid());
 128          $this->assertEquals(new \moodle_url($updatedto->authenticationrequesturl), $reg->get_authenticationrequesturl());
 129          $this->assertEquals(new \moodle_url($updatedto->jwksurl), $reg->get_jwksurl());
 130          $this->assertEquals(new \moodle_url($updatedto->accesstokenurl), $reg->get_accesstokenurl());
 131          $this->assertTrue($reg->is_complete());
 132  
 133          // Update missing id.
 134          unset($updatedto->id);
 135          $this->expectException(\coding_exception::class);
 136          $service->update_application_registration($updatedto);
 137      }
 138  
 139      /**
 140       * Test that removing an application registration also removes all associated data.
 141       *
 142       * @covers ::delete_application_registration
 143       */
 144      public function test_delete_application_registration() {
 145          $this->resetAfterTest();
 146          // Setup.
 147          $registrationrepo = new application_registration_repository();
 148          $deploymentrepo = new deployment_repository();
 149          $contextrepo = new context_repository();
 150          $resourcelinkrepo = new resource_link_repository();
 151          $userrepo = new user_repository();
 152          [$course, $resource] = $this->create_test_environment();
 153  
 154          // Launch the tool for a user.
 155          $mocklaunch = $this->get_mock_launch($resource, $this->get_mock_launch_users_with_ids(['1'])[0]);
 156          $instructoruser = $this->getDataGenerator()->create_user();
 157          $launchservice = $this->get_tool_launch_service();
 158          $launchservice->user_launches_tool($instructoruser, $mocklaunch);
 159  
 160          // Check all the expected data exists for the deployment after setup.
 161          $registrations = $registrationrepo->find_all();
 162          $this->assertCount(1, $registrations);
 163          $registration = array_pop($registrations);
 164  
 165          $deployments = $deploymentrepo->find_all_by_registration($registration->get_id());
 166          $this->assertCount(1, $deployments);
 167          $deployment = array_pop($deployments);
 168  
 169          $resourcelinks = $resourcelinkrepo->find_by_resource($resource->id);
 170          $this->assertCount(1, $resourcelinks);
 171          $resourcelink = array_pop($resourcelinks);
 172  
 173          $context = $contextrepo->find($resourcelink->get_contextid());
 174          $this->assertNotNull($context);
 175  
 176          $users = $userrepo->find_by_resource($resource->id);
 177          $this->assertCount(1, $users);
 178          $user = array_pop($users);
 179  
 180          $enrolledusers = get_enrolled_users(\context_course::instance($course->id));
 181          $this->assertCount(1, $enrolledusers);
 182  
 183          // Now delete the application_registration using the service.
 184          $service = $this->get_application_registration_service();
 185          $service->delete_application_registration($registration->get_id());
 186  
 187          // Verify that the context, resourcelink, user, deployment and registration instances are all deleted.
 188          $this->assertFalse($registrationrepo->exists($registration->get_id()));
 189          $this->assertFalse($deploymentrepo->exists($deployment->get_id()));
 190          $this->assertFalse($contextrepo->exists($context->get_id()));
 191          $this->assertFalse($resourcelinkrepo->exists($resourcelink->get_id()));
 192          $this->assertFalse($userrepo->exists($user->get_id()));
 193  
 194          // Verify that all users are unenrolled.
 195          $enrolledusers = get_enrolled_users(\context_course::instance($course->id));
 196          $this->assertCount(0, $enrolledusers);
 197  
 198          // Verify the tool record stays in place (I.e. the published resource is still available).
 199          $this->assertNotEmpty(helper::get_lti_tool($resource->id));
 200      }
 201  }