Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 3.10.x will end 8 November 2021 (12 months).
  • Bug fixes for security issues in 3.10.x will end 9 May 2022 (18 months).
  • PHP version: minimum PHP 7.2.0 Note: minimum PHP version has increased since Moodle 3.8. PHP 7.3.x and 7.4.x are supported too.

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

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