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.

Differences Between: [Versions 310 and 403] [Versions 39 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 enrol_lti;
  18  
  19  use enrol_lti\data_connector;
  20  use IMSGlobal\LTI\ToolProvider\ConsumerNonce;
  21  use IMSGlobal\LTI\ToolProvider\Context;
  22  use IMSGlobal\LTI\ToolProvider\ResourceLink;
  23  use IMSGlobal\LTI\ToolProvider\ResourceLinkShare;
  24  use IMSGlobal\LTI\ToolProvider\ResourceLinkShareKey;
  25  use IMSGlobal\LTI\ToolProvider\ToolConsumer;
  26  use IMSGlobal\LTI\ToolProvider\ToolProvider;
  27  use IMSGlobal\LTI\ToolProvider\ToolProxy;
  28  use IMSGlobal\LTI\ToolProvider\User;
  29  
  30  /**
  31   * Test the data_connector class.
  32   *
  33   * @package enrol_lti
  34   * @copyright 2016 Jun Pataleta <jun@moodle.com>
  35   * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  36   */
  37  class data_connector_test extends \advanced_testcase {
  38  
  39      /**
  40       * Test set up.
  41       *
  42       * This is executed before running any test in this file.
  43       */
  44      public function setUp(): void {
  45          $this->resetAfterTest();
  46  
  47          // Set this user as the admin.
  48          $this->setAdminUser();
  49      }
  50  
  51      /**
  52       * Test for data_connector::loadToolConsumer().
  53       */
  54      public function test_load_consumer() {
  55          $consumer = new ToolConsumer();
  56          $dc = new data_connector();
  57  
  58          // Consumer has not been saved to the database, so this should return false.
  59          $this->assertFalse($dc->loadToolConsumer($consumer));
  60  
  61          // Save a consumer into the DB.
  62          $time = time();
  63          $data = [
  64              'name' => 'TestName',
  65              'secret' => 'TestSecret',
  66              'ltiversion' => ToolProvider::LTI_VERSION1,
  67              'consumername' => 'TestConsumerName',
  68              'consumerversion' => 'TestConsumerVersion',
  69              'consumerguid' => 'TestConsumerGuid',
  70              'profile' => json_decode('{TestProfile}'),
  71              'toolproxy' => 'TestProxy',
  72              'settings' => ['setting1' => 'TestSetting 1', 'setting2' => 'TestSetting 2'],
  73              'protected' => 1,
  74              'enabled' => 0,
  75              'enablefrom' => $time,
  76              'enableuntil' => $time + 1,
  77              'lastaccess' => strtotime(date('Y-m-d')),
  78          ];
  79          $consumer->name = $data['name'];
  80          $consumer->setKey('TestKey');
  81          $consumer->secret = $data['secret'];
  82          $consumer->ltiVersion = $data['ltiversion'];
  83          $consumer->consumerName = $data['consumername'];
  84          $consumer->consumerVersion = $data['consumerversion'];
  85          $consumer->consumerGuid = $data['consumerguid'];
  86          $consumer->profile = $data['profile'];
  87          $consumer->toolProxy = $data['toolproxy'];
  88          $consumer->setSettings($data['settings']);
  89          $consumer->protected = true;
  90          $consumer->enabled = false;
  91          $consumer->enableFrom = $data['enablefrom'];
  92          $consumer->enableUntil = $data['enableuntil'];
  93          $consumer->lastAccess = $data['lastaccess'];
  94  
  95          $dc->saveToolConsumer($consumer);
  96          $this->assertTrue($dc->loadToolConsumer($consumer));
  97          $this->assertEquals($consumer->name, 'TestName');
  98          $this->assertEquals($consumer->getKey(), 'TestKey');
  99          $this->assertEquals($consumer->secret, 'TestSecret');
 100          $this->assertEquals($consumer->ltiVersion, $data['ltiversion']);
 101          $this->assertEquals($consumer->consumerName, $data['consumername']);
 102          $this->assertEquals($consumer->consumerVersion, $data['consumerversion']);
 103          $this->assertEquals($consumer->consumerGuid, $data['consumerguid']);
 104          $this->assertEquals($consumer->profile, $data['profile']);
 105          $this->assertEquals($consumer->toolProxy, $data['toolproxy']);
 106          $this->assertEquals($consumer->getSettings(), $data['settings']);
 107          $this->assertTrue($consumer->protected);
 108          $this->assertFalse($consumer->enabled);
 109          $this->assertEquals($consumer->enableFrom, $data['enablefrom']);
 110          $this->assertEquals($consumer->enableUntil, $data['enableuntil']);
 111          $this->assertEquals($consumer->lastAccess, $data['lastaccess']);
 112      }
 113  
 114      /**
 115       * Test for data_connector::saveToolConsumer().
 116       */
 117      public function test_save_consumer() {
 118          $dc = new data_connector();
 119  
 120          $time = time();
 121          $data = [
 122              'name' => 'TestName',
 123              'secret' => 'TestSecret',
 124              'ltiversion' => ToolProvider::LTI_VERSION1,
 125              'consumername' => 'TestConsumerName',
 126              'consumerversion' => 'TestConsumerVersion',
 127              'consumerguid' => 'TestConsumerGuid',
 128              'profile' => json_decode('{TestProfile}'),
 129              'toolproxy' => 'TestProxy',
 130              'settings' => ['setting1' => 'TestSetting 1', 'setting2' => 'TestSetting 2'],
 131              'protected' => 1,
 132              'enabled' => 0,
 133              'enablefrom' => $time,
 134              'enableuntil' => $time + 1,
 135              'lastaccess' => strtotime(date('Y-m-d')),
 136          ];
 137          $consumer = new ToolConsumer();
 138          $consumer->name = $data['name'];
 139          $consumer->setKey('TestKey');
 140          $consumer->secret = $data['secret'];
 141          $consumer->ltiVersion = $data['ltiversion'];
 142          $consumer->consumerName = $data['consumername'];
 143          $consumer->consumerVersion = $data['consumerversion'];
 144          $consumer->consumerGuid = $data['consumerguid'];
 145          $consumer->profile = $data['profile'];
 146          $consumer->toolProxy = $data['toolproxy'];
 147          $consumer->setSettings($data['settings']);
 148          $consumer->protected = true;
 149          $consumer->enabled = false;
 150          $consumer->enableFrom = $data['enablefrom'];
 151          $consumer->enableUntil = $data['enableuntil'];
 152          $consumer->lastAccess = $data['lastaccess'];
 153  
 154          // Save new consumer into the DB.
 155          $this->assertTrue($dc->saveToolConsumer($consumer));
 156          // Check saved values.
 157          $this->assertEquals($consumer->name, $data['name']);
 158          $this->assertEquals($consumer->getKey(), 'TestKey');
 159          $this->assertEquals($consumer->secret, $data['secret']);
 160          $this->assertEquals($consumer->ltiVersion, $data['ltiversion']);
 161          $this->assertEquals($consumer->consumerName, $data['consumername']);
 162          $this->assertEquals($consumer->consumerVersion, $data['consumerversion']);
 163          $this->assertEquals($consumer->consumerGuid, $data['consumerguid']);
 164          $this->assertEquals($consumer->profile, $data['profile']);
 165          $this->assertEquals($consumer->toolProxy, $data['toolproxy']);
 166          $this->assertEquals($consumer->getSettings(), $data['settings']);
 167          $this->assertTrue($consumer->protected);
 168          $this->assertFalse($consumer->enabled);
 169          $this->assertEquals($consumer->enableFrom, $data['enablefrom']);
 170          $this->assertEquals($consumer->enableUntil, $data['enableuntil']);
 171          $this->assertEquals($consumer->lastAccess, $data['lastaccess']);
 172  
 173          // Edit values.
 174          $edit = 'EDIT';
 175          $consumer->name = $data['name'] . $edit;
 176          $consumer->setKey('TestKey' . $edit);
 177          $consumer->secret = $data['secret'] . $edit;
 178          $consumer->ltiVersion = ToolProvider::LTI_VERSION2;
 179          $consumer->consumerName = $data['consumername'] . $edit;
 180          $consumer->consumerVersion = $data['consumerversion'] . $edit;
 181          $consumer->consumerGuid = $data['consumerguid'] . $edit;
 182          $editprofile = json_decode('{TestProfile}');
 183          $consumer->profile = $editprofile;
 184          $consumer->toolProxy = $data['toolproxy'] . $edit;
 185          $editsettings = ['setting1' => 'TestSetting 1'  . $edit, 'setting2' => 'TestSetting 2' . $edit];
 186          $consumer->setSettings($editsettings);
 187          $consumer->protected = null;
 188          $consumer->enabled = null;
 189          $consumer->enableFrom = $data['enablefrom'] + 100;
 190          $consumer->enableUntil = $data['enableuntil'] + 100;
 191  
 192          // Save edited values.
 193          $this->assertTrue($dc->saveToolConsumer($consumer));
 194          // Check edited values.
 195          $this->assertEquals($consumer->name, $data['name'] . $edit);
 196          $this->assertEquals($consumer->getKey(), 'TestKey' . $edit);
 197          $this->assertEquals($consumer->secret, $data['secret'] . $edit);
 198          $this->assertEquals($consumer->ltiVersion, ToolProvider::LTI_VERSION2);
 199          $this->assertEquals($consumer->consumerName, $data['consumername'] . $edit);
 200          $this->assertEquals($consumer->consumerVersion, $data['consumerversion'] . $edit);
 201          $this->assertEquals($consumer->consumerGuid, $data['consumerguid'] . $edit);
 202          $this->assertEquals($consumer->profile, $editprofile);
 203          $this->assertEquals($consumer->toolProxy, $data['toolproxy'] . $edit);
 204          $this->assertEquals($consumer->getSettings(), $editsettings);
 205          $this->assertNull($consumer->protected);
 206          $this->assertNull($consumer->enabled);
 207          $this->assertEquals($consumer->enableFrom, $data['enablefrom'] + 100);
 208          $this->assertEquals($consumer->enableUntil, $data['enableuntil'] + 100);
 209      }
 210  
 211      /**
 212       * Test for data_connector::deleteToolConsumer().
 213       */
 214      public function test_delete_tool_consumer() {
 215          $dc = new data_connector();
 216          $data = [
 217              'name' => 'TestName',
 218              'secret' => 'TestSecret',
 219              'ltiversion' => ToolProvider::LTI_VERSION1,
 220          ];
 221          $consumer = new ToolConsumer(null, $dc);
 222          $consumer->name = $data['name'];
 223          $consumer->setKey('TestKey');
 224          $consumer->secret = $data['secret'];
 225          $consumer->save();
 226  
 227          $nonce = new ConsumerNonce($consumer, 'testnonce');
 228          $nonce->save();
 229  
 230          $context = Context::fromConsumer($consumer, 'testlticontext');
 231          $context->save();
 232  
 233          $resourcelink = ResourceLink::fromConsumer($consumer, 'testresourcelinkid');
 234          $resourcelink->setContextId($context->getRecordId());
 235          $resourcelink->save();
 236          $this->assertEquals($consumer->getRecordId(), $resourcelink->getConsumer()->getRecordId());
 237  
 238          $resourcelinkchild = ResourceLink::fromConsumer($consumer, 'testresourcelinkchildid');
 239          $resourcelinkchild->primaryResourceLinkId = $resourcelink->getRecordId();
 240          $resourcelinkchild->shareApproved = true;
 241          $resourcelinkchild->setContextId($context->getRecordId());
 242          $resourcelinkchild->save();
 243          $this->assertEquals($consumer->getRecordId(), $resourcelinkchild->getConsumer()->getRecordId());
 244          $this->assertEquals($resourcelink->getRecordId(), $resourcelinkchild->primaryResourceLinkId);
 245          $this->assertTrue($resourcelinkchild->shareApproved);
 246  
 247          $resourcelinkchild2 = clone $resourcelink;
 248          $resourcelinkchild2->setRecordId(null);
 249          $resourcelinkchild2->setConsumerId(null);
 250          $resourcelinkchild2->setContextId(0);
 251          $resourcelinkchild2->primaryResourceLinkId = $resourcelink->getRecordId();
 252          $resourcelinkchild2->shareApproved = true;
 253          $resourcelinkchild2->save();
 254          $this->assertNull($resourcelinkchild2->getConsumer()->getRecordId());
 255          $this->assertEquals(0, $resourcelinkchild2->getContextId());
 256          $this->assertNotEquals($resourcelink->getRecordId(), $resourcelinkchild2->getRecordId());
 257  
 258          $resourcelinksharekey = new ResourceLinkShareKey($resourcelink);
 259          $resourcelinksharekey->save();
 260  
 261          $user = User::fromResourceLink($resourcelink, '');
 262          $user->ltiResultSourcedId = 'testLtiResultSourcedId';
 263          $dc->saveUser($user);
 264  
 265          // Confirm that tool consumer deletion processing ends successfully.
 266          $this->assertTrue($dc->deleteToolConsumer($consumer));
 267  
 268          // Consumer object should have been initialised.
 269          foreach ($consumer as $key => $value) {
 270              $this->assertTrue(empty($value));
 271          }
 272  
 273          // Nonce record should have been deleted.
 274          $this->assertFalse($dc->loadConsumerNonce($nonce));
 275          // Share key record record should have been deleted.
 276          $this->assertFalse($dc->loadResourceLinkShareKey($resourcelinksharekey));
 277          // Resource record link should have been deleted.
 278          $this->assertFalse($dc->loadResourceLink($resourcelink));
 279          // Consumer record should have been deleted.
 280          $this->assertFalse($dc->loadToolConsumer($consumer));
 281          // Resource links for contexts in this consumer should have been deleted. Even child ones.
 282          $this->assertFalse($dc->loadResourceLink($resourcelinkchild));
 283  
 284          // Child resource link primaryResourceLinkId and shareApproved attributes should have been set to null.
 285          $this->assertTrue($dc->loadResourceLink($resourcelinkchild2));
 286          $this->assertNull($resourcelinkchild2->primaryResourceLinkId);
 287          $this->assertNull($resourcelinkchild2->shareApproved);
 288      }
 289  
 290      /**
 291       * Test for data_connector::getToolConsumers().
 292       */
 293      public function test_get_tool_consumers() {
 294          $dc = new data_connector();
 295  
 296          $consumers = $dc->getToolConsumers();
 297          // Does not return null.
 298          $this->assertNotNull($consumers);
 299          // But returns empty array when no consumers found.
 300          $this->assertEmpty($consumers);
 301  
 302          $data = [
 303              'name' => 'TestName',
 304              'secret' => 'TestSecret',
 305              'ltiversion' => ToolProvider::LTI_VERSION1,
 306          ];
 307          $count = 3;
 308          for ($i = 0; $i < $count; $i++) {
 309              $consumer = new ToolConsumer(null, $dc);
 310              $consumer->name = $data['name'] . $i;
 311              $consumer->setKey('TestKey' . $i);
 312              $consumer->secret = $data['secret'] . $i;
 313              $consumer->ltiVersion = $data['ltiversion'];
 314              $consumer->save();
 315          }
 316  
 317          $consumers = $dc->getToolConsumers();
 318  
 319          $this->assertNotEmpty($consumers);
 320          $this->assertCount($count, $consumers);
 321  
 322          // Check values.
 323          foreach ($consumers as $index => $record) {
 324              $this->assertEquals($data['name'] . $index, $record->name);
 325              $this->assertEquals('TestKey' . $index, $record->getKey());
 326              $this->assertEquals($data['secret'] . $index, $record->secret);
 327              $record->ltiVersion = $data['ltiversion'];
 328          }
 329      }
 330  
 331      /**
 332       * Test for data_connector::loadToolProxy().
 333       */
 334      public function test_get_tool_proxy() {
 335          $dc = new data_connector();
 336          $toolproxy = new ToolProxy($dc);
 337          $this->assertFalse($dc->loadToolProxy($toolproxy));
 338      }
 339  
 340      /**
 341       * Test for data_connector::saveToolProxy().
 342       */
 343      public function test_save_tool_proxy() {
 344          $dc = new data_connector();
 345          $toolproxy = new ToolProxy($dc);
 346          $this->assertFalse($dc->saveToolProxy($toolproxy));
 347      }
 348  
 349      /**
 350       * Test for data_connector::deleteToolProxy().
 351       */
 352      public function test_delete_tool_proxy() {
 353          $dc = new data_connector();
 354          $toolproxy = new ToolProxy($dc);
 355          $this->assertFalse($dc->deleteToolProxy($toolproxy));
 356      }
 357  
 358      /**
 359       * Test for data_connector::loadContext().
 360       */
 361      public function test_load_context() {
 362          $dc = new data_connector();
 363          $consumer = new ToolConsumer(null, $dc);
 364          $consumer->name = 'testconsumername';
 365          $consumer->setKey('TestKey');
 366          $consumer->secret = 'testsecret';
 367          $consumer->save();
 368  
 369          $title = 'testcontexttitle';
 370          $settings = ['a', 'b', 'c'];
 371          $lticontextid = 'testlticontextid';
 372          $context = Context::fromConsumer($consumer, $lticontextid);
 373          $context->title = $title;
 374          $context->settings = $settings;
 375  
 376          // Load an unsaved context.
 377          $this->assertFalse($dc->loadContext($context));
 378  
 379          // Save the context.
 380          $dc->saveContext($context);
 381          $created = $context->created;
 382          $updated = $context->updated;
 383  
 384          // Load saved context.
 385          $this->assertTrue($dc->loadContext($context));
 386          $this->assertEquals($consumer, $context->getConsumer());
 387          $this->assertEquals($title, $context->title);
 388          $this->assertEquals($settings, $context->getSettings());
 389          $this->assertEquals($lticontextid, $context->ltiContextId);
 390          $this->assertEquals($created, $context->created);
 391          $this->assertEquals($updated, $context->updated);
 392      }
 393  
 394      /**
 395       * Test for data_connector::saveContext().
 396       */
 397      public function test_save_context() {
 398          $dc = new data_connector();
 399          $consumer = new ToolConsumer(null, $dc);
 400          $consumer->name = 'testconsumername';
 401          $consumer->setKey('TestKey');
 402          $consumer->secret = 'testsecret';
 403          $consumer->save();
 404  
 405          $title = 'testcontexttitle';
 406          $settings = ['a', 'b', 'c'];
 407          $lticontextid = 'testlticontextid';
 408          $context = Context::fromConsumer($consumer, $lticontextid);
 409          $context->title = $title;
 410          $context->settings = $settings;
 411  
 412          // Save the context.
 413          $this->assertTrue($dc->saveContext($context));
 414          $id = $context->getRecordId();
 415          $created = $context->created;
 416          $updated = $context->updated;
 417  
 418          // Check saved values.
 419          $this->assertNotNull($id);
 420          $this->assertNotEmpty($created);
 421          $this->assertNotEmpty($updated);
 422          $this->assertEquals($consumer, $context->getConsumer());
 423          $this->assertEquals($title, $context->title);
 424          $this->assertEquals($settings, $context->getSettings());
 425          $this->assertEquals($lticontextid, $context->ltiContextId);
 426  
 427          // Edit the context details.
 428          $newsettings = array_merge($settings, ['d', 'e']);
 429          $context->title = $title . 'edited';
 430          $context->settings = $newsettings;
 431          $context->ltiContextId = $lticontextid . 'edited';
 432  
 433          // Confirm that edited context is saved successfully.
 434          $this->assertTrue($dc->saveContext($context));
 435  
 436          // Check edited values.
 437          $this->assertEquals($title . 'edited', $context->title);
 438          $this->assertEquals($newsettings, $context->getSettings());
 439          $this->assertEquals($lticontextid . 'edited', $context->ltiContextId);
 440          // Created time stamp should not change.
 441          $this->assertEquals($created, $context->created);
 442          // Updated time stamp should have been changed.
 443          $this->assertGreaterThanOrEqual($updated, $context->updated);
 444      }
 445  
 446      /**
 447       * Test for data_connector::deleteContext().
 448       */
 449      public function test_delete_context() {
 450          $dc = new data_connector();
 451          $consumer = new ToolConsumer(null, $dc);
 452          $consumer->name = 'testconsumername';
 453          $consumer->setKey('TestKey');
 454          $consumer->secret = 'testsecret';
 455          $consumer->save();
 456  
 457          $title = 'testcontexttitle';
 458          $settings = ['a', 'b', 'c'];
 459          $lticontextid = 'testlticontextid';
 460          $context = Context::fromConsumer($consumer, $lticontextid);
 461          $context->title = $title;
 462          $context->settings = $settings;
 463  
 464          // Save the context.
 465          $this->assertTrue($dc->saveContext($context));
 466  
 467          $resourcelink = ResourceLink::fromConsumer($consumer, 'testresourcelinkid');
 468          $resourcelink->setContextId($context->getRecordId());
 469          $resourcelink->save();
 470          $this->assertEquals($consumer->getRecordId(), $resourcelink->getConsumer()->getRecordId());
 471  
 472          $resourcelinkchild = ResourceLink::fromConsumer($consumer, 'testresourcelinkchildid');
 473          $resourcelinkchild->primaryResourceLinkId = $resourcelink->getRecordId();
 474          $resourcelinkchild->shareApproved = true;
 475          $resourcelinkchild->setContextId($context->getRecordId());
 476          $resourcelinkchild->save();
 477          $this->assertEquals($consumer->getRecordId(), $resourcelinkchild->getConsumer()->getRecordId());
 478          $this->assertEquals($resourcelink->getRecordId(), $resourcelinkchild->primaryResourceLinkId);
 479          $this->assertTrue($resourcelinkchild->shareApproved);
 480  
 481          $resourcelinkchild2 = clone $resourcelink;
 482          $resourcelinkchild2->setRecordId(null);
 483          $resourcelinkchild2->setConsumerId(null);
 484          $resourcelinkchild2->setContextId(0);
 485          $resourcelinkchild2->primaryResourceLinkId = $resourcelink->getRecordId();
 486          $resourcelinkchild2->shareApproved = true;
 487          $resourcelinkchild2->save();
 488          $this->assertNull($resourcelinkchild2->getConsumer()->getRecordId());
 489          $this->assertEquals(0, $resourcelinkchild2->getContextId());
 490          $this->assertNotEquals($resourcelink->getRecordId(), $resourcelinkchild2->getRecordId());
 491  
 492          $resourcelinksharekey = new ResourceLinkShareKey($resourcelink);
 493          $resourcelinksharekey->save();
 494  
 495          $user = User::fromResourceLink($resourcelink, '');
 496          $user->ltiResultSourcedId = 'testLtiResultSourcedId';
 497          $dc->saveUser($user);
 498  
 499          $this->assertTrue($dc->deleteContext($context));
 500  
 501          // Context properties should have been reset.
 502          $this->assertEmpty($context->title);
 503          $this->assertEmpty($context->settings);
 504          $this->assertNull($context->created);
 505          $this->assertNull($context->updated);
 506  
 507          // Context record should have already been deleted from the DB.
 508          $this->assertFalse($dc->loadContext($context));
 509  
 510          // Share key record record should have been deleted.
 511          $this->assertFalse($dc->loadResourceLinkShareKey($resourcelinksharekey));
 512          // Resource record link should have been deleted.
 513          $this->assertFalse($dc->loadResourceLink($resourcelink));
 514          // Resource links for contexts in this consumer should have been deleted. Even child ones.
 515          $this->assertFalse($dc->loadResourceLink($resourcelinkchild));
 516  
 517          // Child resource link primaryResourceLinkId and shareApproved attributes should have been set to null.
 518          $this->assertTrue($dc->loadResourceLink($resourcelinkchild2));
 519          $this->assertNull($resourcelinkchild2->primaryResourceLinkId);
 520          $this->assertNull($resourcelinkchild2->shareApproved);
 521      }
 522  
 523      /**
 524       * Test for data_connector::loadResourceLink().
 525       */
 526      public function test_load_resource_link() {
 527          $dc = new data_connector();
 528  
 529          // Consumer for the resource link.
 530          $consumer = new ToolConsumer(null, $dc);
 531          $consumer->name = 'testconsumername';
 532          $consumer->setKey('TestKey');
 533          $consumer->secret = 'testsecret';
 534          $consumer->save();
 535  
 536          // Context for the resource link.
 537          $title = 'testcontexttitle';
 538          $settings = ['a', 'b', 'c'];
 539          $lticontextid = 'testlticontextid';
 540          $context = Context::fromConsumer($consumer, $lticontextid);
 541          $context->title = $title;
 542          $context->settings = $settings;
 543          // Save the context.
 544          $context->save();
 545  
 546          $ltiresourcelinkid = 'testltiresourcelinkid';
 547          $resourcelink = ResourceLink::fromConsumer($consumer, $ltiresourcelinkid);
 548          $resourcelink->setContextId($context->getRecordId());
 549          $resourcelink->setSettings($settings);
 550          $resourcelink->shareApproved = true;
 551          $resourcelink->primaryResourceLinkId = 999;
 552  
 553          // Try to load an unsaved resource link.
 554          $this->assertFalse($dc->loadResourceLink($resourcelink));
 555  
 556          // Save the resource link.
 557          $resourcelink->save();
 558  
 559          // Load saved resource link.
 560          $this->assertTrue($dc->loadResourceLink($resourcelink));
 561          $this->assertNotEmpty($resourcelink->getRecordId());
 562          $this->assertEquals($settings, $resourcelink->getSettings());
 563          $this->assertTrue($resourcelink->shareApproved);
 564          $this->assertEquals(999, $resourcelink->primaryResourceLinkId);
 565          $this->assertNotEmpty($resourcelink->created);
 566          $this->assertNotEmpty($resourcelink->updated);
 567  
 568          // Create another resource link instance similar to the first one.
 569          $resourcelink2 = ResourceLink::fromConsumer($consumer, $ltiresourcelinkid);
 570          $resourcelink2->setContextId($context->getRecordId());
 571  
 572          // This should load the previous resource link.
 573          $this->assertTrue($dc->loadResourceLink($resourcelink2));
 574          $this->assertEquals($resourcelink, $resourcelink2);
 575  
 576          $resourcelink2->ltiResourceLinkId = $ltiresourcelinkid . '2';
 577          $resourcelink2->save();
 578          $dc->loadResourceLink($resourcelink2);
 579          $this->assertNotEquals($resourcelink, $resourcelink2);
 580      }
 581  
 582      /**
 583       * Test for data_connector::saveResourceLink().
 584       */
 585      public function test_save_resource_link() {
 586          $dc = new data_connector();
 587  
 588          // Consumer for the resource link.
 589          $consumer = new ToolConsumer(null, $dc);
 590          $consumer->name = 'testconsumername';
 591          $consumer->setKey('TestKey');
 592          $consumer->secret = 'testsecret';
 593          $consumer->save();
 594  
 595          // Context for the resource link.
 596          $title = 'testcontexttitle';
 597          $settings = ['a', 'b', 'c'];
 598          $lticontextid = 'testlticontextid';
 599          $context = Context::fromConsumer($consumer, $lticontextid);
 600          $context->title = $title;
 601          $context->settings = $settings;
 602          // Save the context.
 603          $context->save();
 604  
 605          $ltiresourcelinkid = 'testltiresourcelinkid';
 606          $resourcelink = ResourceLink::fromConsumer($consumer, $ltiresourcelinkid);
 607          $resourcelink->setContextId($context->getRecordId());
 608          $resourcelink->setSettings($settings);
 609          $resourcelink->shareApproved = true;
 610          $resourcelink->primaryResourceLinkId = 999;
 611  
 612          // Try to load an unsaved resource link.
 613          $this->assertFalse($dc->loadResourceLink($resourcelink));
 614  
 615          // Save the resource link.
 616          $this->assertTrue($resourcelink->save());
 617  
 618          // Check values.
 619          $resoucelinkid = $resourcelink->getRecordId();
 620          $created = $resourcelink->created;
 621          $updated = $resourcelink->updated;
 622          $this->assertNotEmpty($resoucelinkid);
 623          $this->assertEquals($settings, $resourcelink->getSettings());
 624          $this->assertTrue($resourcelink->shareApproved);
 625          $this->assertEquals(999, $resourcelink->primaryResourceLinkId);
 626          $this->assertNotEmpty($created);
 627          $this->assertNotEmpty($updated);
 628  
 629          // Update values.
 630          $newsettings = array_merge($settings, ['d', 'e']);
 631          $resourcelink->setSettings($newsettings);
 632          $resourcelink->shareApproved = false;
 633          $resourcelink->primaryResourceLinkId = 1000;
 634          $resourcelink->ltiResourceLinkId = $ltiresourcelinkid . 'edited';
 635  
 636          // Save modified resource link.
 637          $this->assertTrue($resourcelink->save());
 638  
 639          // Check edited values.
 640          $this->assertEquals($resoucelinkid, $resourcelink->getRecordId());
 641          $this->assertEquals($newsettings, $resourcelink->getSettings());
 642          $this->assertFalse($resourcelink->shareApproved);
 643          $this->assertEquals(1000, $resourcelink->primaryResourceLinkId);
 644          $this->assertEquals($created, $resourcelink->created);
 645          $this->assertGreaterThanOrEqual($updated, $resourcelink->updated);
 646      }
 647  
 648      /**
 649       * Test for data_connector::deleteResourceLink().
 650       */
 651      public function test_delete_resource_link() {
 652          $dc = new data_connector();
 653          $consumer = new ToolConsumer(null, $dc);
 654          $consumer->name = 'testconsumername';
 655          $consumer->setKey('TestKey');
 656          $consumer->secret = 'testsecret';
 657          $consumer->save();
 658  
 659          $title = 'testcontexttitle';
 660          $settings = ['a', 'b', 'c'];
 661          $lticontextid = 'testlticontextid';
 662          $context = Context::fromConsumer($consumer, $lticontextid);
 663          $context->title = $title;
 664          $context->settings = $settings;
 665  
 666          // Save the context.
 667          $this->assertTrue($dc->saveContext($context));
 668  
 669          $resourcelink = ResourceLink::fromConsumer($consumer, 'testresourcelinkid');
 670          $resourcelink->setContextId($context->getRecordId());
 671          $resourcelink->save();
 672  
 673          $resourcelinkchild = ResourceLink::fromConsumer($consumer, 'testresourcelinkchildid');
 674          $resourcelinkchild->primaryResourceLinkId = $resourcelink->getRecordId();
 675          $resourcelinkchild->shareApproved = true;
 676          $resourcelinkchild->setContextId($context->getRecordId());
 677          $resourcelinkchild->save();
 678  
 679          $resourcelinksharekey = new ResourceLinkShareKey($resourcelink);
 680          $resourcelinksharekey->save();
 681  
 682          $user = User::fromResourceLink($resourcelink, '');
 683          $user->ltiResultSourcedId = 'testLtiResultSourcedId';
 684          $dc->saveUser($user);
 685  
 686          $this->assertTrue($dc->deleteResourceLink($resourcelink));
 687  
 688          // Resource link properties should have been reset.
 689          $this->assertEmpty($resourcelink->title);
 690          $this->assertEmpty($resourcelink->getSettings());
 691          $this->assertNull($resourcelink->groupSets);
 692          $this->assertNull($resourcelink->groups);
 693          $this->assertNull($resourcelink->primaryResourceLinkId);
 694          $this->assertNull($resourcelink->shareApproved);
 695          $this->assertNull($resourcelink->created);
 696          $this->assertNull($resourcelink->updated);
 697  
 698          // Share key record record should have been deleted.
 699          $this->assertFalse($dc->loadResourceLinkShareKey($resourcelinksharekey));
 700          // Resource link record should have been deleted.
 701          $this->assertFalse($dc->loadResourceLink($resourcelink));
 702          // Child resource link should still exist and its primaryResourceLinkId attribute should have been set to null.
 703          $this->assertTrue($dc->loadResourceLink($resourcelinkchild));
 704          $this->assertNull($resourcelinkchild->primaryResourceLinkId);
 705      }
 706  
 707      /**
 708       * Test for data_connector::getUserResultSourcedIDsResourceLink().
 709       */
 710      public function test_get_user_result_sourced_ids_resource_link() {
 711          $dc = new data_connector();
 712          $consumer = new ToolConsumer(null, $dc);
 713          $consumer->name = 'testconsumername';
 714          $consumer->setKey('TestKey');
 715          $consumer->secret = 'testsecret';
 716          $consumer->idScope = ToolProvider::ID_SCOPE_GLOBAL;
 717          $consumer->save();
 718  
 719          $title = 'testcontexttitle';
 720          $settings = ['a', 'b', 'c'];
 721          $lticontextid = 'testlticontextid';
 722          $context = Context::fromConsumer($consumer, $lticontextid);
 723          $context->title = $title;
 724          $context->settings = $settings;
 725          $context->save();
 726  
 727          $resourcelink = ResourceLink::fromConsumer($consumer, 'testresourcelinkid');
 728          $resourcelink->setContextId($context->getRecordId());
 729          $resourcelink->save();
 730  
 731          $resourcelinkchild = ResourceLink::fromConsumer($consumer, 'testresourcelinkchildid');
 732          $resourcelinkchild->primaryResourceLinkId = $resourcelink->getRecordId();
 733          $resourcelinkchild->shareApproved = true;
 734          $resourcelinkchild->setContextId($context->getRecordId());
 735          $resourcelinkchild->save();
 736  
 737          $user = User::fromResourceLink($resourcelink, '');
 738          $user->ltiResultSourcedId = 'testLtiResultSourcedId';
 739          $user->ltiUserId = 'user1';
 740          $dc->saveUser($user);
 741  
 742          $user2 = User::fromResourceLink($resourcelinkchild, '');
 743          $user2->ltiResultSourcedId = 'testLtiResultSourcedId2';
 744          $user->ltiUserId = 'user2';
 745          $dc->saveUser($user2);
 746  
 747          $users = $dc->getUserResultSourcedIDsResourceLink($resourcelink, false, null);
 748          $this->assertNotEmpty($users);
 749          $this->assertCount(2, $users);
 750  
 751          $users = $dc->getUserResultSourcedIDsResourceLink($resourcelink, true, null);
 752          $this->assertNotEmpty($users);
 753          $this->assertCount(1, $users);
 754  
 755          $users = $dc->getUserResultSourcedIDsResourceLink($resourcelink, false, ToolProvider::ID_SCOPE_GLOBAL);
 756          $this->assertNotEmpty($users);
 757          $this->assertCount(2, $users);
 758  
 759          $users = $dc->getUserResultSourcedIDsResourceLink($resourcelink, true, ToolProvider::ID_SCOPE_GLOBAL);
 760          $this->assertNotEmpty($users);
 761          $this->assertCount(1, $users);
 762      }
 763  
 764      /**
 765       * Test for data_connector::getSharesResourceLink().
 766       */
 767      public function test_get_shares_resource_link() {
 768          $dc = new data_connector();
 769          $consumer = new ToolConsumer(null, $dc);
 770          $consumer->name = 'testconsumername';
 771          $consumer->setKey('TestKey');
 772          $consumer->secret = 'testsecret';
 773          $consumer->idScope = ToolProvider::ID_SCOPE_GLOBAL;
 774          $consumer->save();
 775  
 776          $title = 'testcontexttitle';
 777          $settings = ['a', 'b', 'c'];
 778          $lticontextid = 'testlticontextid';
 779          $context = Context::fromConsumer($consumer, $lticontextid);
 780          $context->title = $title;
 781          $context->settings = $settings;
 782          $context->save();
 783  
 784          $resourcelink = ResourceLink::fromConsumer($consumer, 'testresourcelinkid');
 785          $resourcelink->setContextId($context->getRecordId());
 786          $resourcelink->save();
 787          $shares = $dc->getSharesResourceLink($resourcelink);
 788          $this->assertEmpty($shares);
 789  
 790          $resourcelinkchild = ResourceLink::fromConsumer($consumer, 'testresourcelinkchildid');
 791          $resourcelinkchild->primaryResourceLinkId = $resourcelink->getRecordId();
 792          $resourcelinkchild->shareApproved = true;
 793          $resourcelinkchild->save();
 794  
 795          $resourcelinkchild2 = ResourceLink::fromConsumer($consumer, 'testresourcelinkchildid2');
 796          $resourcelinkchild2->primaryResourceLinkId = $resourcelink->getRecordId();
 797          $resourcelinkchild2->shareApproved = false;
 798          $resourcelinkchild2->save();
 799  
 800          $shares = $dc->getSharesResourceLink($resourcelink);
 801          $this->assertCount(2, $shares);
 802          $shareids = [$resourcelinkchild->getRecordId(), $resourcelinkchild2->getRecordId()];
 803          foreach ($shares as $share) {
 804              $this->assertTrue($share instanceof ResourceLinkShare);
 805              $this->assertTrue(in_array($share->resourceLinkId, $shareids));
 806              if ($share->resourceLinkId == $shareids[0]) {
 807                  $this->assertTrue($share->approved);
 808              } else {
 809                  $this->assertFalse($share->approved);
 810              }
 811          }
 812      }
 813  
 814      /**
 815       * Test for data_connector::loadConsumerNonce().
 816       */
 817      public function test_load_consumer_nonce() {
 818          $dc = new data_connector();
 819  
 820          $consumer = new ToolConsumer(null, $dc);
 821          $consumer->name = 'TestName';
 822          $consumer->setKey('TestKey');
 823          $consumer->secret = 'TestSecret';
 824          $consumer->save();
 825  
 826          $nonce = new ConsumerNonce($consumer, 'testnonce');
 827          // Should still not be available since it has not been saved yet.
 828          $this->assertFalse($dc->loadConsumerNonce($nonce));
 829          // Save the nonce.
 830          $nonce->save();
 831          // Should now be available.
 832          $this->assertTrue($dc->loadConsumerNonce($nonce));
 833      }
 834  
 835      /**
 836       * Test for data_connector::loadConsumerNonce() for a nonce that has expired.
 837       */
 838      public function test_load_consumer_nonce_expired() {
 839          $dc = new data_connector();
 840  
 841          $consumer = new ToolConsumer(null, $dc);
 842          $consumer->name = 'TestName';
 843          $consumer->setKey('TestKey');
 844          $consumer->secret = 'TestSecret';
 845          $consumer->save();
 846  
 847          $nonce = new ConsumerNonce($consumer, 'testnonce');
 848          $nonce->expires = time() - 100;
 849          // Save the nonce.
 850          $nonce->save();
 851          // Expired nonce should have been deleted.
 852          $this->assertFalse($dc->loadConsumerNonce($nonce));
 853      }
 854  
 855      /**
 856       * Test for data_connector::saveConsumerNonce().
 857       */
 858      public function test_save_consumer_nonce() {
 859          $dc = new data_connector();
 860  
 861          $consumer = new ToolConsumer(null, $dc);
 862          $consumer->name = 'TestName';
 863          $consumer->setKey('TestKey');
 864          $consumer->secret = 'TestSecret';
 865          $consumer->save();
 866  
 867          $nonce = new ConsumerNonce($consumer, 'testnonce');
 868  
 869          // Save the nonce.
 870          $this->assertTrue($dc->saveConsumerNonce($nonce));
 871      }
 872  
 873      /**
 874       * Test for data_connector::loadResourceLinkShareKey().
 875       */
 876      public function test_load_resource_link_share_key() {
 877          $dc = new data_connector();
 878  
 879          $consumer = new ToolConsumer(null, $dc);
 880          $consumer->name = 'TestName';
 881          $consumer->setKey('TestKey');
 882          $consumer->secret = 'TestSecret';
 883          $consumer->save();
 884  
 885          $resourcelink = ResourceLink::fromConsumer($consumer, 'testresourcelinkid');
 886          $resourcelink->save();
 887  
 888          $sharekey = new ResourceLinkShareKey($resourcelink);
 889          // Should still not be available since it has not been saved yet.
 890          $this->assertFalse($dc->loadResourceLinkShareKey($sharekey));
 891          // Save the share key.
 892          $sharekey->save();
 893          // Should now be available.
 894          $this->assertTrue($dc->loadResourceLinkShareKey($sharekey));
 895  
 896          // Check values.
 897          $this->assertEquals(strlen($sharekey->getId()), $sharekey->length);
 898          $this->assertEquals(ResourceLinkShareKey::DEFAULT_SHARE_KEY_LIFE, $sharekey->life);
 899          $this->assertNotNull($sharekey->expires);
 900          $this->assertFalse($sharekey->autoApprove);
 901      }
 902  
 903      /**
 904       * Test for data_connector::loadResourceLinkShareKey() with an expired share key.
 905       */
 906      public function test_load_resource_link_share_key_expired() {
 907          $dc = new data_connector();
 908  
 909          $consumer = new ToolConsumer(null, $dc);
 910          $consumer->name = 'TestName';
 911          $consumer->setKey('TestKey');
 912          $consumer->secret = 'TestSecret';
 913          $consumer->save();
 914  
 915          $resourcelink = ResourceLink::fromConsumer($consumer, 'testresourcelinkid');
 916          $resourcelink->save();
 917  
 918          $sharekey = new ResourceLinkShareKey($resourcelink, 'testsharelinkid');
 919          $sharekey->expires = time() - 100;
 920          // ResourceLinkShareKey::save() adds a default expires time and cannot be modified.
 921          $dc->saveResourceLinkShareKey($sharekey);
 922  
 923          // Expired shared key should have been deleted.
 924          $this->assertFalse($dc->loadResourceLinkShareKey($sharekey));
 925      }
 926  
 927      /**
 928       * Test for data_connector::saveResourceLinkShareKey().
 929       */
 930      public function test_save_resource_link_share_key() {
 931          $dc = new data_connector();
 932  
 933          $consumer = new ToolConsumer(null, $dc);
 934          $consumer->name = 'TestName';
 935          $consumer->setKey('TestKey');
 936          $consumer->secret = 'TestSecret';
 937          $consumer->save();
 938  
 939          $resourcelink = ResourceLink::fromConsumer($consumer, 'testresourcelinkid');
 940          $resourcelink->save();
 941  
 942          $expires = time() - 100;
 943          $sharekey = new ResourceLinkShareKey($resourcelink, 'testsharelinkid');
 944          $sharekey->expires = $expires;
 945          $sharekey->life = ResourceLinkShareKey::DEFAULT_SHARE_KEY_LIFE;
 946  
 947          $this->assertTrue($dc->saveResourceLinkShareKey($sharekey));
 948  
 949          // Check values.
 950          $this->assertEquals(strlen($sharekey->getId()), $sharekey->length);
 951          $this->assertEquals(ResourceLinkShareKey::DEFAULT_SHARE_KEY_LIFE, $sharekey->life);
 952          $this->assertEquals($expires, $sharekey->expires);
 953          $this->assertFalse($sharekey->autoApprove);
 954      }
 955  
 956      /**
 957       * Test for data_connector::deleteResourceLinkShareKey().
 958       */
 959      public function test_delete_resource_link_share_key() {
 960          $dc = new data_connector();
 961  
 962          $consumer = new ToolConsumer(null, $dc);
 963          $consumer->name = 'TestName';
 964          $consumer->setKey('TestKey');
 965          $consumer->secret = 'TestSecret';
 966          $consumer->save();
 967  
 968          $resourcelink = ResourceLink::fromConsumer($consumer, 'testresourcelinkid');
 969          $resourcelink->save();
 970  
 971          $sharekey = new ResourceLinkShareKey($resourcelink, 'testsharelinkid');
 972          $sharekey->save();
 973  
 974          $this->assertTrue($dc->deleteResourceLinkShareKey($sharekey));
 975  
 976          $controlsharekey = new ResourceLinkShareKey($resourcelink, 'testsharelinkid');
 977          $controlsharekey->initialise();
 978          $this->assertEquals($controlsharekey, $sharekey);
 979  
 980          // This should no longer be in the DB.
 981          $this->assertFalse($dc->loadResourceLinkShareKey($sharekey));
 982      }
 983  
 984      /**
 985       * Test for data_connector::loadUser().
 986       */
 987      public function test_load_user() {
 988          $dc = new data_connector();
 989          $consumer = new ToolConsumer(null, $dc);
 990          $consumer->name = 'TestName';
 991          $consumer->setKey('TestKey');
 992          $consumer->secret = 'TestSecret';
 993          $consumer->save();
 994  
 995          $resourcelink = ResourceLink::fromConsumer($consumer, 'testresourcelinkid');
 996          $resourcelink->save();
 997  
 998          $user = User::fromResourceLink($resourcelink, '');
 999          $user->ltiResultSourcedId = 'testLtiResultSourcedId';
1000  
1001          // Should still not be available since it has not been saved yet.
1002          $this->assertFalse($dc->loadUser($user));
1003  
1004          // Save the user.
1005          $user->save();
1006  
1007          // Should now be available.
1008          $this->assertTrue($dc->loadUser($user));
1009  
1010          // Check loaded values.
1011          $created = $user->created;
1012          $updated = $user->updated;
1013          $this->assertNotNull($created);
1014          $this->assertNotNull($updated);
1015          $this->assertEquals('testLtiResultSourcedId', $user->ltiResultSourcedId);
1016          $this->assertEquals($resourcelink, $user->getResourceLink());
1017      }
1018  
1019      /**
1020       * Test for data_connector::saveUser().
1021       */
1022      public function test_save_user() {
1023          $dc = new data_connector();
1024          $consumer = new ToolConsumer(null, $dc);
1025          $consumer->name = 'TestName';
1026          $consumer->setKey('TestKey');
1027          $consumer->secret = 'TestSecret';
1028          $consumer->save();
1029  
1030          $resourcelink = ResourceLink::fromConsumer($consumer, 'testresourcelinkid');
1031          $resourcelink->save();
1032  
1033          $user = User::fromResourceLink($resourcelink, '');
1034          $user->ltiResultSourcedId = 'testLtiResultSourcedId';
1035          // Save user.
1036          $this->assertTrue($dc->saveUser($user));
1037  
1038          // Check loaded values.
1039          $created = $user->created;
1040          $updated = $user->updated;
1041          $this->assertNotNull($created);
1042          $this->assertNotNull($updated);
1043          $this->assertEquals('testLtiResultSourcedId', $user->ltiResultSourcedId);
1044          $this->assertEquals($resourcelink, $user->getResourceLink());
1045  
1046          // Update user.
1047          $user->ltiResultSourcedId = 'testLtiResultSourcedId2';
1048  
1049          // Save updated values.
1050          $this->assertTrue($dc->saveUser($user));
1051  
1052          // Check updated values.
1053          $this->assertEquals($created, $user->created);
1054          $this->assertGreaterThanOrEqual($updated, $user->updated);
1055          $this->assertEquals('testLtiResultSourcedId2', $user->ltiResultSourcedId);
1056      }
1057  
1058      /**
1059       * Test for data_connector::deleteUser().
1060       */
1061      public function test_delete_user() {
1062          $dc = new data_connector();
1063          $consumer = new ToolConsumer(null, $dc);
1064          $consumer->name = 'TestName';
1065          $consumer->setKey('TestKey');
1066          $consumer->secret = 'TestSecret';
1067          $consumer->save();
1068  
1069          $resourcelink = ResourceLink::fromConsumer($consumer, 'testresourcelinkid');
1070          $resourcelink->save();
1071  
1072          $user = User::fromResourceLink($resourcelink, '');
1073          $user->ltiResultSourcedId = 'testLtiResultSourcedId';
1074          $user->firstname = 'First';
1075          $user->lastname = 'Last';
1076          $user->fullname = 'Full name';
1077          $user->email = 'test@email.com';
1078          $user->roles = ['a', 'b'];
1079          $user->groups = ['1', '2'];
1080          $user->save();
1081  
1082          // Delete user.
1083          $this->assertTrue($dc->deleteUser($user));
1084  
1085          // User record should have been deleted from the DB.
1086          $this->assertFalse($dc->loadUser($user));
1087  
1088          // User object should have been initialised().
1089          $this->assertEmpty($user->firstname);
1090          $this->assertEmpty($user->lastname);
1091          $this->assertEmpty($user->fullname);
1092          $this->assertEmpty($user->email);
1093          $this->assertEmpty($user->roles);
1094          $this->assertEmpty($user->groups);
1095          $this->assertNull($user->ltiResultSourcedId);
1096          $this->assertNull($user->created);
1097          $this->assertNull($user->updated);
1098      }
1099  
1100      /**
1101       * Test for data_connector::get_contexts_from_consumer().
1102       */
1103      public function test_get_contexts_from_consumer() {
1104          $dc = new data_connector();
1105          $consumer = new ToolConsumer(null, $dc);
1106          $consumer->name = 'testconsumername';
1107          $consumer->setKey('TestKey');
1108          $consumer->secret = 'testsecret';
1109          $consumer->save();
1110  
1111          $settings = ['a', 'b', 'c'];
1112          $lticontextid = 'testlticontextid';
1113          $context = Context::fromConsumer($consumer, $lticontextid);
1114          $context->settings = $settings;
1115          $context->save();
1116          $dc->loadContext($context);
1117  
1118          $consumer2 = new ToolConsumer(null, $dc);
1119          $consumer2->name = 'testconsumername2';
1120          $consumer2->setKey('TestKey2');
1121          $consumer2->secret = 'testsecret2';
1122          $consumer2->save();
1123  
1124          $context2 = Context::fromConsumer($consumer2, $lticontextid . '2');
1125          $context2->settings = $settings;
1126          $consumer2->save();
1127  
1128          $contexts = $dc->get_contexts_from_consumer($consumer);
1129          $this->assertCount(1, $contexts);
1130          $this->assertEquals($context, $contexts[0]);
1131      }
1132  
1133      /**
1134       * Test for data_connector::get_consumers_mapped_to_tool().
1135       */
1136      public function test_get_consumers_mapped_to_tool() {
1137          $generator = $this->getDataGenerator();
1138          // Create two tools belonging to the same course.
1139          $course1 = $generator->create_course();
1140          $data = new \stdClass();
1141          $data->courseid = $course1->id;
1142          $tool = $generator->create_lti_tool($data);
1143          $tool2 = $generator->create_lti_tool($data);
1144  
1145          $dc = new data_connector();
1146          $consumer = new ToolConsumer('key1', $dc);
1147          $consumer->name = 'testconsumername';
1148          $consumer->secret = 'testsecret';
1149          $consumer->save();
1150  
1151          $tp = new \enrol_lti\tool_provider($tool->id);
1152          $tp->consumer = $consumer;
1153          $tp->map_tool_to_consumer();
1154  
1155          $consumer2 = new ToolConsumer('key2', $dc);
1156          $consumer2->name = 'testconsumername2';
1157          $consumer2->secret = 'testsecret2';
1158          $consumer2->save();
1159  
1160          $tp2 = new \enrol_lti\tool_provider($tool2->id);
1161          $tp2->consumer = $consumer2;
1162          $tp2->map_tool_to_consumer();
1163  
1164          $consumers = $dc->get_consumers_mapped_to_tool($tool->id);
1165          $this->assertCount(1, $consumers);
1166          $this->assertEquals($consumer, $consumers[0]);
1167  
1168          $consumers2 = $dc->get_consumers_mapped_to_tool($tool2->id);
1169          $this->assertCount(1, $consumers2);
1170          $this->assertEquals($consumer2, $consumers2[0]);
1171      }
1172  
1173      /**
1174       * Test for data_connector::get_resourcelink_from_consumer()
1175       */
1176      public function test_get_resourcelink_from_consumer() {
1177          $dc = new data_connector();
1178  
1179          $consumer = new ToolConsumer(null, $dc);
1180          $consumer->name = 'TestName';
1181          $consumer->setKey('TestKey');
1182          $consumer->secret = 'TestSecret';
1183          $consumer->save();
1184  
1185          // No ResourceLink associated with the ToolConsumer yet.
1186          $this->assertNull($dc->get_resourcelink_from_consumer($consumer));
1187  
1188          // Create and save ResourceLink from ToolConsumer.
1189          $resourcelink = ResourceLink::fromConsumer($consumer, 'testresourcelinkid');
1190          $resourcelink->save();
1191          $dc->loadResourceLink($resourcelink);
1192  
1193          // Assert that the resource link and the one fetched by get_resourcelink_from_consumer() are the same.
1194          $this->assertEquals($resourcelink, $dc->get_resourcelink_from_consumer($consumer));
1195      }
1196  
1197      /**
1198       * Test for data_connector::get_resourcelink_from_context()
1199       */
1200      public function test_get_resourcelink_from_context() {
1201          $dc = new data_connector();
1202  
1203          $consumer = new ToolConsumer(null, $dc);
1204          $consumer->name = 'TestName';
1205          $consumer->setKey('TestKey');
1206          $consumer->secret = 'TestSecret';
1207          $consumer->save();
1208  
1209          $settings = ['a', 'b', 'c'];
1210          $lticontextid = 'testlticontextid';
1211          $context = Context::fromConsumer($consumer, $lticontextid);
1212          $context->settings = $settings;
1213          $context->save();
1214  
1215          // No ResourceLink associated with the Context yet.
1216          $this->assertNull($dc->get_resourcelink_from_context($context));
1217  
1218          // Create and save ResourceLink from the Context.
1219          $resourcelink = ResourceLink::fromContext($context, 'testresourcelinkid');
1220          $resourcelink->save();
1221          $dc->loadResourceLink($resourcelink);
1222  
1223          // Assert that the resource link and the one fetched by get_resourcelink_from_context() are the same.
1224          $this->assertEquals($resourcelink, $dc->get_resourcelink_from_context($context));
1225      }
1226  }