mirror of
https://github.com/moodle/moodle.git
synced 2025-04-22 17:02:03 +02:00
MDL-69542 enrol_lti: add new entity classes for storing launch data
This commit is contained in:
parent
23894ddd98
commit
7a1f433043
178
enrol/lti/classes/local/ltiadvantage/entity/ags_info.php
Normal file
178
enrol/lti/classes/local/ltiadvantage/entity/ags_info.php
Normal file
@ -0,0 +1,178 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
namespace enrol_lti\local\ltiadvantage\entity;
|
||||
|
||||
/**
|
||||
* The ags_info class, instances of which represent grade service information for a resource_link or context.
|
||||
*
|
||||
* For information about Assignment and Grade Services 2.0, see https://www.imsglobal.org/spec/lti-ags/v2p0/.
|
||||
*
|
||||
* @package enrol_lti
|
||||
* @copyright 2021 Jake Dallimore <jrhdallimore@gmail.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class ags_info {
|
||||
/** @var string Scope for lineitem management, used when a platform allows the tool to create lineitems.*/
|
||||
private const SCOPES_LINEITEM_MANAGE = 'https://purl.imsglobal.org/spec/lti-ags/scope/lineitem';
|
||||
|
||||
/** @var string Scope for lineitem reads, used when a tool only grants read access to line items.*/
|
||||
private const SCOPES_LINEITEM_READONLY = 'https://purl.imsglobal.org/spec/lti-ags/scope/lineitem.readonly';
|
||||
|
||||
/** @var string Scope for reading results.*/
|
||||
private const SCOPES_RESULT_READONLY = 'https://purl.imsglobal.org/spec/lti-ags/scope/result.readonly';
|
||||
|
||||
/** @var string Scope for posting scores.*/
|
||||
private const SCOPES_SCORES_POST = 'https://purl.imsglobal.org/spec/lti-ags/scope/score';
|
||||
|
||||
/** @var \moodle_url The service URL used to get/put lineitems*/
|
||||
private $lineitemsurl;
|
||||
|
||||
/** @var \moodle_url|null The lineitemurl, which is only present when a single lineitem is supported.*/
|
||||
private $lineitemurl;
|
||||
|
||||
/** @var array The array of supported lineitem-related scopes for this service instance.*/
|
||||
private $lineitemscopes = [];
|
||||
|
||||
/** @var string|null The supported result scope for this service instance.*/
|
||||
private $resultscope = null;
|
||||
|
||||
/** @var string|null The supported score scope for this service instance.*/
|
||||
private $scorescope = null;
|
||||
|
||||
/**
|
||||
* The ags_info constructor.
|
||||
*
|
||||
* @param \moodle_url $lineitemsurl The service URL used to get/put lineitems.
|
||||
* @param \moodle_url|null $lineitemurl The lineitemurl, which is only present when a single lineitem is supported.
|
||||
* @param array $scopes The array of supported scopes for this service instance.
|
||||
*/
|
||||
private function __construct(\moodle_url $lineitemsurl, ?\moodle_url $lineitemurl, array $scopes) {
|
||||
$this->lineitemsurl = $lineitemsurl;
|
||||
$this->lineitemurl = $lineitemurl;
|
||||
$this->validate_scopes($scopes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method to create a new ags_info instance.
|
||||
*
|
||||
* @param \moodle_url $lineitemsurl The service URL used to get/put lineitems.
|
||||
* @param \moodle_url|null $lineitemurl The lineitemurl, which is only present when a single lineitem is supported.
|
||||
* @param array $scopes The array of supported scopes for this service instance.
|
||||
* @return ags_info the object instance.
|
||||
*/
|
||||
public static function create(\moodle_url $lineitemsurl, ?\moodle_url $lineitemurl = null,
|
||||
array $scopes = []): ags_info {
|
||||
return new self($lineitemsurl, $lineitemurl, $scopes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the supplied scopes for validity and set instance vars if appropriate.
|
||||
*
|
||||
* @param array $scopes the array of string scopes to check.
|
||||
* @throws \coding_exception if any of the scopes is invalid.
|
||||
*/
|
||||
private function validate_scopes(array $scopes): void {
|
||||
$validscopes = [
|
||||
self::SCOPES_LINEITEM_READONLY,
|
||||
self::SCOPES_LINEITEM_MANAGE,
|
||||
self::SCOPES_RESULT_READONLY,
|
||||
self::SCOPES_SCORES_POST
|
||||
];
|
||||
foreach ($scopes as $scope) {
|
||||
if (!is_string($scope)) {
|
||||
throw new \coding_exception('Scope must be a string value');
|
||||
}
|
||||
$key = array_search($scope, $validscopes);
|
||||
if ($key === false) {
|
||||
throw new \coding_exception("Scope '{$scope}' is invalid.");
|
||||
}
|
||||
if ($key == 0) {
|
||||
$this->lineitemscopes[] = self::SCOPES_LINEITEM_READONLY;
|
||||
} else if ($key == 1) {
|
||||
$this->lineitemscopes[] = self::SCOPES_LINEITEM_MANAGE;
|
||||
} else if ($key == 2) {
|
||||
$this->resultscope = self::SCOPES_RESULT_READONLY;
|
||||
} else if ($key == 3) {
|
||||
$this->scorescope = self::SCOPES_SCORES_POST;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the url for querying line items.
|
||||
*
|
||||
* @return \moodle_url the url.
|
||||
*/
|
||||
public function get_lineitemsurl(): \moodle_url {
|
||||
return $this->lineitemsurl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the single line item url, in cases where only one line item exists.
|
||||
*
|
||||
* @return \moodle_url|null the url, or null if not present.
|
||||
*/
|
||||
public function get_lineitemurl(): ?\moodle_url {
|
||||
return $this->lineitemurl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the authorization scope for lineitems.
|
||||
*
|
||||
* @return array|null the scopes, if present, else null.
|
||||
*/
|
||||
public function get_lineitemscope(): ?array {
|
||||
return !empty($this->lineitemscopes) ? $this->lineitemscopes : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the authorization scope for results.
|
||||
*
|
||||
* @return string|null the scope, if present, else null.
|
||||
*/
|
||||
public function get_resultscope(): ?string {
|
||||
return $this->resultscope;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the authorization scope for scores.
|
||||
*
|
||||
* @return string|null the scope, if present, else null.
|
||||
*/
|
||||
public function get_scorescope(): ?string {
|
||||
return $this->scorescope;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all supported scopes for this service.
|
||||
*
|
||||
* @return string[] the array of supported scopes.
|
||||
*/
|
||||
public function get_scopes(): array {
|
||||
$scopes = [];
|
||||
foreach ($this->lineitemscopes as $lineitemscope) {
|
||||
$scopes[] = $lineitemscope;
|
||||
}
|
||||
if (!empty($this->resultscope)) {
|
||||
$scopes[] = $this->resultscope;
|
||||
}
|
||||
if (!empty($this->scorescope)) {
|
||||
$scopes[] = $this->scorescope;
|
||||
}
|
||||
return $scopes;
|
||||
}
|
||||
}
|
@ -0,0 +1,186 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
namespace enrol_lti\local\ltiadvantage\entity;
|
||||
|
||||
/**
|
||||
* Class application_registration.
|
||||
*
|
||||
* This class represents an LTI Advantage Application Registration.
|
||||
* Each registered application may contain one or more deployments of the Moodle tool.
|
||||
* This registration provides the security contract for all tool deployments belonging to the registration.
|
||||
*
|
||||
* @package enrol_lti
|
||||
* @copyright 2021 Jake Dallimore <jrhdallimore@gmail.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class application_registration {
|
||||
|
||||
/** @var int|null the if of this registration instance, or null if it hasn't been stored yet. */
|
||||
private $id;
|
||||
|
||||
/** @var string the name of the application being registered. */
|
||||
private $name;
|
||||
|
||||
/** @var \moodle_url the issuer identifying the platform, as provided by the platform. */
|
||||
private $platformid;
|
||||
|
||||
/** @var string the client id as provided by the platform. */
|
||||
private $clientid;
|
||||
|
||||
/** @var \moodle_url the authentication request URL, as provided by the platform. */
|
||||
private $authenticationrequesturl;
|
||||
|
||||
/** @var \moodle_url the certificate URL, as provided by the platform. */
|
||||
private $jwksurl;
|
||||
|
||||
/** @var \moodle_url the access token URL, as provided by the platform. */
|
||||
private $accesstokenurl;
|
||||
|
||||
/**
|
||||
* The application_registration constructor.
|
||||
*
|
||||
* @param string $name the descriptor for this application registration.
|
||||
* @param \moodle_url $platformid the URL of application
|
||||
* @param string $clientid unique id for the client on the application
|
||||
* @param \moodle_url $authenticationrequesturl URL to send OIDC Auth requests to.
|
||||
* @param \moodle_url $jwksurl URL to use to get public keys from the application.
|
||||
* @param \moodle_url $accesstokenurl URL to use to get an access token from the application, used in service calls.
|
||||
* @param int|null $id the id of the object instance, if being created from an existing store item.
|
||||
*/
|
||||
private function __construct(string $name, \moodle_url $platformid, string $clientid,
|
||||
\moodle_url $authenticationrequesturl, \moodle_url $jwksurl, \moodle_url $accesstokenurl, int $id = null) {
|
||||
|
||||
if (empty($name)) {
|
||||
throw new \coding_exception("Invalid 'name' arg. Cannot be an empty string.");
|
||||
}
|
||||
if (empty($clientid)) {
|
||||
throw new \coding_exception("Invalid 'clientid' arg. Cannot be an empty string.");
|
||||
}
|
||||
$this->name = $name;
|
||||
$this->platformid = $platformid;
|
||||
$this->clientid = $clientid;
|
||||
$this->authenticationrequesturl = $authenticationrequesturl;
|
||||
$this->jwksurl = $jwksurl;
|
||||
$this->accesstokenurl = $accesstokenurl;
|
||||
$this->id = $id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method to create a new instance of an application repository
|
||||
*
|
||||
* @param string $name the descriptor for this application registration.
|
||||
* @param \moodle_url $platformid the URL of application
|
||||
* @param string $clientid unique id for the client on the application
|
||||
* @param \moodle_url $authenticationrequesturl URL to send OIDC Auth requests to.
|
||||
* @param \moodle_url $jwksurl URL to use to get public keys from the application.
|
||||
* @param \moodle_url $accesstokenurl URL to use to get an access token from the application, used in service calls.
|
||||
* @param int|null $id the id of the object instance, if being created from an existing store item.
|
||||
* @return application_registration the application_registration instance.
|
||||
*/
|
||||
public static function create(string $name, \moodle_url $platformid, string $clientid,
|
||||
\moodle_url $authenticationrequesturl, \moodle_url $jwksurl, \moodle_url $accesstokenurl,
|
||||
int $id = null): application_registration {
|
||||
|
||||
return new self($name, $platformid, $clientid, $authenticationrequesturl, $jwksurl, $accesstokenurl, $id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the integer id of this object instance.
|
||||
*
|
||||
* Will return null if the instance has not yet been stored.
|
||||
*
|
||||
* @return null|int the id, if set, otherwise null.
|
||||
*/
|
||||
public function get_id(): ?int {
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name of the application being registered.
|
||||
*
|
||||
* @return string the name.
|
||||
*/
|
||||
public function get_name(): string {
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the platform id.
|
||||
*
|
||||
* @return \moodle_url the platformid/issuer URL.
|
||||
*/
|
||||
public function get_platformid(): \moodle_url {
|
||||
return $this->platformid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the client id.
|
||||
*
|
||||
* @return string the client id.
|
||||
*/
|
||||
public function get_clientid(): string {
|
||||
return $this->clientid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the authentication request URL.
|
||||
*
|
||||
* @return \moodle_url the authentication request URL.
|
||||
*/
|
||||
public function get_authenticationrequesturl(): \moodle_url {
|
||||
return $this->authenticationrequesturl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the JWKS URL.
|
||||
*
|
||||
* @return \moodle_url the JWKS URL.
|
||||
*/
|
||||
public function get_jwksurl(): \moodle_url {
|
||||
return $this->jwksurl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the access token URL.
|
||||
*
|
||||
* @return \moodle_url the access token URL.
|
||||
*/
|
||||
public function get_accesstokenurl(): \moodle_url {
|
||||
return $this->accesstokenurl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a tool deployment to this registration.
|
||||
*
|
||||
* @param string $name human readable name for the deployment.
|
||||
* @param string $deploymentid the unique id of the tool deployment in the platform.
|
||||
* @return deployment the new deployment.
|
||||
* @throws \coding_exception if trying to add a deployment to an instance without an id assigned.
|
||||
*/
|
||||
public function add_tool_deployment(string $name, string $deploymentid): deployment {
|
||||
|
||||
if (empty($this->get_id())) {
|
||||
throw new \coding_exception("Can't add deployment to a resource_link that hasn't first been saved.");
|
||||
}
|
||||
|
||||
return deployment::create(
|
||||
$this->get_id(),
|
||||
$deploymentid,
|
||||
$name
|
||||
);
|
||||
}
|
||||
}
|
179
enrol/lti/classes/local/ltiadvantage/entity/context.php
Normal file
179
enrol/lti/classes/local/ltiadvantage/entity/context.php
Normal file
@ -0,0 +1,179 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
namespace enrol_lti\local\ltiadvantage\entity;
|
||||
|
||||
/**
|
||||
* Class context, instances of which represent a context in the platform.
|
||||
*
|
||||
* See: http://www.imsglobal.org/spec/lti/v1p3/#context-type-vocabulary for supported context types.
|
||||
*
|
||||
* @package enrol_lti
|
||||
* @copyright 2021 Jake Dallimore <jrhdallimore@gmail.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */
|
||||
class context {
|
||||
|
||||
// The following full contexts are per the spec:
|
||||
// http://www.imsglobal.org/spec/lti/v1p3/#context-type-vocabulary.
|
||||
/** @var string course template context */
|
||||
private const CONTEXT_TYPE_COURSE_TEMPLATE = 'http://purl.imsglobal.org/vocab/lis/v2/course#CourseTemplate';
|
||||
|
||||
/** @var string course offering context */
|
||||
private const CONTEXT_TYPE_COURSE_OFFERING = 'http://purl.imsglobal.org/vocab/lis/v2/course#CourseOffering';
|
||||
|
||||
/** @var string course section context */
|
||||
private const CONTEXT_TYPE_COURSE_SECTION = 'http://purl.imsglobal.org/vocab/lis/v2/course#CourseSection';
|
||||
|
||||
/** @var string group context */
|
||||
private const CONTEXT_TYPE_GROUP = 'http://purl.imsglobal.org/vocab/lis/v2/course#Group';
|
||||
|
||||
// The following simple names are deprecated but are still supported in 1.3 for backwards compatibility.
|
||||
// http://www.imsglobal.org/spec/lti/v1p3/#context-type-vocabulary.
|
||||
/** @var string deprecated simple course template context */
|
||||
private const LEGACY_CONTEXT_TYPE_COURSE_TEMPLATE = 'CourseTemplate';
|
||||
|
||||
/** @var string deprecated simple course offering context */
|
||||
private const LEGACY_CONTEXT_TYPE_COURSE_OFFERING = 'CourseOffering';
|
||||
|
||||
/** @var string deprecated simple course section context */
|
||||
private const LEGACY_CONTEXT_TYPE_COURSE_SECTION = 'CourseSection';
|
||||
|
||||
/** @var string deprecated simple group context */
|
||||
private const LEGACY_CONTEXT_TYPE_GROUP = 'Group';
|
||||
|
||||
/** @var int the local id of the deployment instance to which this context belongs. */
|
||||
private $deploymentid;
|
||||
|
||||
/** @var string the contextid as supplied by the platform. */
|
||||
private $contextid;
|
||||
|
||||
/** @var int|null the local id of this object instance, which can be null if the object hasn't been stored before */
|
||||
private $id;
|
||||
|
||||
/** @var string[] the array of context types */
|
||||
private $types;
|
||||
|
||||
/**
|
||||
* Private constructor.
|
||||
*
|
||||
* @param int $deploymentid the local id of the deployment instance to which this context belongs.
|
||||
* @param string $contextid the context id string, as provided by the platform during launch.
|
||||
* @param array $types an array of string context types, as provided by the platform during launch.
|
||||
* @param int|null $id local id of this object instance, nullable for new objects.
|
||||
*/
|
||||
private function __construct(int $deploymentid, string $contextid, array $types, ?int $id) {
|
||||
if (!is_null($id) && $id <= 0) {
|
||||
throw new \coding_exception('id must be a positive int');
|
||||
}
|
||||
$this->deploymentid = $deploymentid;
|
||||
$this->contextid = $contextid;
|
||||
$this->set_types($types); // Handles type validation.
|
||||
$this->id = $id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method for creating a context instance.
|
||||
*
|
||||
* @param int $deploymentid the local id of the deployment instance to which this context belongs.
|
||||
* @param string $contextid the context id string, as provided by the platform during launch.
|
||||
* @param array $types an array of string context types, as provided by the platform during launch.
|
||||
* @param int|null $id local id of this object instance, nullable for new objects.
|
||||
* @return context the context instance.
|
||||
*/
|
||||
public static function create(int $deploymentid, string $contextid, array $types, int $id = null): context {
|
||||
return new self($deploymentid, $contextid, $types, $id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether a context is valid or not, checking also deprecated but supported legacy context names.
|
||||
*
|
||||
* @param string $type context type to check.
|
||||
* @param bool $includelegacy whether to check the legacy simple context names too.
|
||||
* @return bool true if the type is valid, false otherwise.
|
||||
*/
|
||||
private function is_valid_type(string $type, bool $includelegacy = false): bool {
|
||||
// Check LTI Advantage types.
|
||||
$valid = in_array($type, [
|
||||
self::CONTEXT_TYPE_COURSE_TEMPLATE,
|
||||
self::CONTEXT_TYPE_COURSE_OFFERING,
|
||||
self::CONTEXT_TYPE_COURSE_SECTION,
|
||||
self::CONTEXT_TYPE_GROUP
|
||||
]);
|
||||
|
||||
// Check legacy short names.
|
||||
if ($includelegacy) {
|
||||
$valid = $valid || in_array($type, [
|
||||
self::LEGACY_CONTEXT_TYPE_COURSE_TEMPLATE,
|
||||
self::LEGACY_CONTEXT_TYPE_COURSE_OFFERING,
|
||||
self::LEGACY_CONTEXT_TYPE_COURSE_SECTION,
|
||||
self::LEGACY_CONTEXT_TYPE_GROUP
|
||||
]);
|
||||
}
|
||||
|
||||
return $valid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the object instance id.
|
||||
*
|
||||
* @return int|null the id, or null if the object doesn't yet have one assigned.
|
||||
*/
|
||||
public function get_id(): ?int {
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the platform contextid string.
|
||||
*
|
||||
* @return string the id of the context in the platform.
|
||||
*/
|
||||
public function get_contextid(): string {
|
||||
return $this->contextid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the id of the local deployment instance to which this context instance belongs.
|
||||
*
|
||||
* @return int the id of the local deployment instance to which this context instance belongs.
|
||||
*/
|
||||
public function get_deploymentid(): int {
|
||||
return $this->deploymentid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the context types this context instance represents.
|
||||
*
|
||||
* @return string[] the array of context types this context instance represents.
|
||||
*/
|
||||
public function get_types(): array {
|
||||
return $this->types;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the list of types this context instance represents.
|
||||
*
|
||||
* @param array $types the array of string types.
|
||||
* @throws \coding_exception if any of the supplied types are invalid.
|
||||
*/
|
||||
public function set_types(array $types): void {
|
||||
foreach ($types as $type) {
|
||||
if (!$this->is_valid_type($type, true)) {
|
||||
throw new \coding_exception("Cannot set invalid context type '{$type}'.");
|
||||
}
|
||||
}
|
||||
$this->types = $types;
|
||||
}
|
||||
}
|
178
enrol/lti/classes/local/ltiadvantage/entity/deployment.php
Normal file
178
enrol/lti/classes/local/ltiadvantage/entity/deployment.php
Normal file
@ -0,0 +1,178 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
namespace enrol_lti\local\ltiadvantage\entity;
|
||||
|
||||
/**
|
||||
* Class deployment.
|
||||
*
|
||||
* This class represents an LTI Advantage Tool Deployment (http://www.imsglobal.org/spec/lti/v1p3/#tool-deployment).
|
||||
*
|
||||
* @package enrol_lti
|
||||
* @copyright 2021 Jake Dallimore <jrhdallimore@gmail.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class deployment {
|
||||
/** @var int|null the id of this object instance, or null if it has not been saved yet. */
|
||||
private $id;
|
||||
|
||||
/** @var string the name of this deployment. */
|
||||
private $deploymentname;
|
||||
|
||||
/** @var string The platform-issued deployment id. */
|
||||
private $deploymentid;
|
||||
|
||||
/** @var int the local ID of the application registration to which this deployment belongs. */
|
||||
private $registrationid;
|
||||
|
||||
/** @var string|null the legacy consumer key, if the deployment instance is migrated from a legacy consumer. */
|
||||
private $legacyconsumerkey;
|
||||
|
||||
/**
|
||||
* The private deployment constructor.
|
||||
*
|
||||
* @param string $deploymentname the name of this deployment.
|
||||
* @param string $deploymentid the platform-issued deployment id.
|
||||
* @param int $registrationid the local ID of the application registration.
|
||||
* @param int|null $id the id of this object instance, or null if it is a new instance which has not yet been saved.
|
||||
* @param string|null $legacyconsumerkey the 1.1 consumer key associated with this deployment, used for upgrades.
|
||||
*/
|
||||
private function __construct(string $deploymentname, string $deploymentid, int $registrationid, ?int $id = null,
|
||||
?string $legacyconsumerkey = null) {
|
||||
|
||||
if (!is_null($id) && $id <= 0) {
|
||||
throw new \coding_exception('id must be a positive int');
|
||||
}
|
||||
if (empty($deploymentname)) {
|
||||
throw new \coding_exception("Invalid 'deploymentname' arg. Cannot be an empty string.");
|
||||
}
|
||||
if (empty($deploymentid)) {
|
||||
throw new \coding_exception("Invalid 'deploymentid' arg. Cannot be an empty string.");
|
||||
}
|
||||
$this->deploymentname = $deploymentname;
|
||||
$this->deploymentid = $deploymentid;
|
||||
$this->registrationid = $registrationid;
|
||||
$this->id = $id;
|
||||
$this->legacyconsumerkey = $legacyconsumerkey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method to create a new instance of a deployment.
|
||||
*
|
||||
* @param int $registrationid the local ID of the application registration.
|
||||
* @param string $deploymentid the platform-issued deployment id.
|
||||
* @param string $deploymentname the name of this deployment.
|
||||
* @param int|null $id optional local id of this object instance, omitted for new deployment objects.
|
||||
* @param string|null $legacyconsumerkey the 1.1 consumer key associated with this deployment, used for upgrades.
|
||||
* @return deployment the deployment instance.
|
||||
*/
|
||||
public static function create(int $registrationid, string $deploymentid, string $deploymentname,
|
||||
?int $id = null, ?string $legacyconsumerkey = null): deployment {
|
||||
return new self($deploymentname, $deploymentid, $registrationid, $id, $legacyconsumerkey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the object id.
|
||||
*
|
||||
* @return int|null the id.
|
||||
*/
|
||||
public function get_id(): ?int {
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the short name of this tool deployment.
|
||||
*
|
||||
* @return string the short name.
|
||||
*/
|
||||
public function get_deploymentname(): string {
|
||||
return $this->deploymentname;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the deployment id string.
|
||||
*
|
||||
* @return string deploymentid
|
||||
*/
|
||||
public function get_deploymentid(): string {
|
||||
return $this->deploymentid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the id of the application_registration.
|
||||
*
|
||||
* @return int the id of the application_registration instance to which this deployment belongs.
|
||||
*/
|
||||
public function get_registrationid(): int {
|
||||
return $this->registrationid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the legacy consumer key to which this deployment instance is mapped.
|
||||
*
|
||||
* @return string|null the legacy consumer key, if set, else null.
|
||||
*/
|
||||
public function get_legacy_consumer_key(): ?string {
|
||||
return $this->legacyconsumerkey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method to add a platform-specific context to the deployment.
|
||||
*
|
||||
* @param string $contextid the contextid, as supplied by the platform during launch.
|
||||
* @param array $types the context types the context represents, as supplied by the platform during launch.
|
||||
* @return context the context instance.
|
||||
* @throws \coding_exception if the context could not be created.
|
||||
*/
|
||||
public function add_context(string $contextid, array $types): context {
|
||||
if (!$this->get_id()) {
|
||||
throw new \coding_exception('Can\'t add context to a deployment that hasn\'t first been saved');
|
||||
}
|
||||
|
||||
return context::create($this->get_id(), $contextid, $types);
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method to create a resource link from this deployment instance.
|
||||
*
|
||||
* @param string $resourcelinkid the platform-issued string id of the resource link.
|
||||
* @param int $resourceid the local published resource to which this link points.
|
||||
* @param int|null $contextid the platform context instance in which the resource link resides, if available.
|
||||
* @return resource_link the resource_link instance.
|
||||
* @throws \coding_exception if the resource_link can't be created.
|
||||
*/
|
||||
public function add_resource_link(string $resourcelinkid, int $resourceid,
|
||||
int $contextid = null): resource_link {
|
||||
|
||||
if (!$this->get_id()) {
|
||||
throw new \coding_exception('Can\'t add resource_link to a deployment that hasn\'t first been saved');
|
||||
}
|
||||
return resource_link::create($resourcelinkid, $this->get_id(), $resourceid, $contextid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the legacy consumer key for this instance, indicating that the deployment has been migrated from a consumer.
|
||||
*
|
||||
* @param string $key the legacy consumer key.
|
||||
* @throws \coding_exception if the key is invalid.
|
||||
*/
|
||||
public function set_legacy_consumer_key(string $key): void {
|
||||
if (strlen($key) > 255) {
|
||||
throw new \coding_exception('Legacy consumer key too long. Cannot exceed 255 chars.');
|
||||
}
|
||||
$this->legacyconsumerkey = $key;
|
||||
}
|
||||
}
|
191
enrol/lti/classes/local/ltiadvantage/entity/migration_claim.php
Normal file
191
enrol/lti/classes/local/ltiadvantage/entity/migration_claim.php
Normal file
@ -0,0 +1,191 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
namespace enrol_lti\local\ltiadvantage\entity;
|
||||
|
||||
use enrol_lti\local\ltiadvantage\repository\legacy_consumer_repository;
|
||||
|
||||
/**
|
||||
* The migration_claim class, instances of which represent information passed in an 'lti1p1' migration claim.
|
||||
*
|
||||
* Provides validation and data retrieval for the claim.
|
||||
*
|
||||
* See https://www.imsglobal.org/spec/lti/v1p3/migr#lti-1-1-migration-claim
|
||||
*
|
||||
* @package enrol_lti
|
||||
* @copyright 2021 Jake Dallimore <jrhdallimore@gmail.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class migration_claim {
|
||||
|
||||
/** @var string the LTI 1.1 consumer key */
|
||||
private $consumerkey;
|
||||
|
||||
/** @var string the LTI 1.1 user identifier.
|
||||
* This is only included in the claim if it differs to the value included in the LTI 1.3 'sub' claim.
|
||||
* I.e. https://www.imsglobal.org/spec/security/v1p0#id-token
|
||||
*/
|
||||
private $userid = null;
|
||||
|
||||
/** @var string the LTI 1.1 context identifier.
|
||||
* This is only included in the claim if it differs to the 'id' property of the LTI 1.3 'context' claim.
|
||||
* I.e. https://purl.imsglobal.org/spec/lti/claim/context#id.
|
||||
*/
|
||||
private $contextid = null;
|
||||
|
||||
/** @var string the LTI 1.1 consumer instance GUID.
|
||||
* This is only included in the claim if it differs to the 'guid' property of the LTI 1.3 'tool_platform' claim.
|
||||
* I.e. https://purl.imsglobal.org/spec/lti/claim/tool_platform#guid.
|
||||
*/
|
||||
private $toolconsumerinstanceguid = null;
|
||||
|
||||
/** @var string the LTI 1.1 resource link identifier.
|
||||
* This is only included in the claim if it differs to the 'id' property of the LTI 1.3 'resource_link' claim.
|
||||
* I.e. https://purl.imsglobal.org/spec/lti/claim/resource_link#id.
|
||||
*/
|
||||
private $resourcelinkid = null;
|
||||
|
||||
/** @var legacy_consumer_repository repository instance for querying consumer secrets when verifying signature. */
|
||||
private $legacyconsumerrepo;
|
||||
|
||||
/**
|
||||
* The migration_claim constructor.
|
||||
*
|
||||
* @param array $claim the array of claim data, as received in a resource link launch.
|
||||
* @param string $deploymentid the deployment id included in the launch.
|
||||
* @param string $platform the platform included in the launch.
|
||||
* @param string $clientid the client id included in the launch.
|
||||
* @param string $exp the exp included in the launch.
|
||||
* @param string $nonce the nonce included in the launch.
|
||||
* @param legacy_consumer_repository $legacyconsumerrepo a legacy consumer repository instance.
|
||||
* @throws \coding_exception if the claim data is invalid.
|
||||
*/
|
||||
public function __construct(array $claim, string $deploymentid, string $platform, string $clientid, string $exp,
|
||||
string $nonce, legacy_consumer_repository $legacyconsumerrepo) {
|
||||
|
||||
// The oauth_consumer_key property MUST be sent.
|
||||
// See: https://www.imsglobal.org/spec/lti/v1p3/migr#oauth_consumer_key.
|
||||
if (empty($claim['oauth_consumer_key'])) {
|
||||
throw new \coding_exception("Missing 'oauth_consumer_key' property in lti1p1 migration claim.");
|
||||
}
|
||||
|
||||
// The oauth_consumer_key_sign property MAY be sent.
|
||||
// For user migration to take place, however, this is deemed a required property.
|
||||
// See: https://www.imsglobal.org/spec/lti/v1p3/migr#oauth_consumer_key_sign.
|
||||
if (empty($claim['oauth_consumer_key_sign'])) {
|
||||
throw new \coding_exception("Missing 'oauth_consumer_key_sign' property in lti1p1 migration claim.");
|
||||
}
|
||||
$this->legacyconsumerrepo = $legacyconsumerrepo;
|
||||
|
||||
if (!$this->verify_signature($claim['oauth_consumer_key'], $claim['oauth_consumer_key_sign'], $deploymentid,
|
||||
$platform, $clientid, $exp, $nonce, $legacyconsumerrepo)) {
|
||||
throw new \coding_exception("Invalid 'oauth_consumer_key_sign' signature in lti1p1 claim.");
|
||||
}
|
||||
|
||||
$this->consumerkey = $claim['oauth_consumer_key'];
|
||||
$this->userid = $claim['user_id'] ?? null;
|
||||
$this->contextid = $claim['context_id'] ?? null;
|
||||
$this->toolconsumerinstanceguid = $claim['tool_consumer_instance_guid'] ?? null;
|
||||
$this->resourcelinkid = $claim['resource_link_id'] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify the claim signature by recalculating it using the launch data and locally stored consumer secret.
|
||||
*
|
||||
* @param string $consumerkey the LTI 1.1 consumer key.
|
||||
* @param string $signature a signature of the LTI 1.1 consumer key and associated launch data.
|
||||
* @param string $deploymentid the deployment id included in the launch.
|
||||
* @param string $platform the platform included in the launch.
|
||||
* @param string $clientid the client id included in the launch.
|
||||
* @param string $exp the exp included in the launch.
|
||||
* @param string $nonce the nonce included in the launch.
|
||||
* @return bool true if the signature was verified, false otherwise.
|
||||
*/
|
||||
private function verify_signature(string $consumerkey, string $signature, string $deploymentid, string $platform,
|
||||
string $clientid, string $exp, string $nonce): bool {
|
||||
|
||||
$base = [
|
||||
$consumerkey,
|
||||
$deploymentid,
|
||||
$platform,
|
||||
$clientid,
|
||||
$exp,
|
||||
$nonce
|
||||
];
|
||||
$basestring = implode('&', $base);
|
||||
|
||||
// Legacy enrol_lti code permits tools to share a consumer key but use different secrets. This results in
|
||||
// potentially many secrets per mapped tool consumer. As such, when generating the migration claim it's
|
||||
// impossible to know which secret the platform will use to sign the consumer key. The consumer key in the
|
||||
// migration claim is thus verified by trying all known secrets for the consumer, until either a match is found
|
||||
// or no signatures match.
|
||||
$consumersecrets = $this->legacyconsumerrepo->get_consumer_secrets($consumerkey);
|
||||
foreach ($consumersecrets as $consumersecret) {
|
||||
$calculatedsignature = base64_encode(hash_hmac('sha256', $basestring, $consumersecret));
|
||||
|
||||
if ($signature === $calculatedsignature) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the consumer key stored in the claim.
|
||||
*
|
||||
* @return string the consumer key included in the claim.
|
||||
*/
|
||||
public function get_consumer_key(): string {
|
||||
return $this->consumerkey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the LTI 1.1 user id stored in the claim.
|
||||
*
|
||||
* @return string|null the user id, or null if not provided in the claim.
|
||||
*/
|
||||
public function get_user_id(): ?string {
|
||||
return $this->userid;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the LTI 1.1 context id stored in the claim.
|
||||
*
|
||||
* @return string|null the context id, or null if not provided in the claim.
|
||||
*/
|
||||
public function get_context_id(): ?string {
|
||||
return $this->contextid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the LTI 1.1 tool consumer instance GUID stored in the claim.
|
||||
*
|
||||
* @return string|null the tool consumer instance GUID, or null if not provided in the claim.
|
||||
*/
|
||||
public function get_tool_consumer_instance_guid(): ?string {
|
||||
return $this->toolconsumerinstanceguid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the LTI 1.1 resource link id stored in the claim.
|
||||
*
|
||||
* @return string|null the resource link id, or null if not provided in the claim.
|
||||
*/
|
||||
public function get_resource_link_id(): ?string {
|
||||
return $this->resourcelinkid;
|
||||
}
|
||||
}
|
131
enrol/lti/classes/local/ltiadvantage/entity/nrps_info.php
Normal file
131
enrol/lti/classes/local/ltiadvantage/entity/nrps_info.php
Normal file
@ -0,0 +1,131 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
namespace enrol_lti\local\ltiadvantage\entity;
|
||||
|
||||
/**
|
||||
* Class nrps_info, instances of which represent a names and roles provisioning service for a resource.
|
||||
*
|
||||
* For information about Names and Role Provisioning Services 2.0, see http://www.imsglobal.org/spec/lti-nrps/v2p0.
|
||||
*
|
||||
* @package enrol_lti
|
||||
* @copyright 2021 Jake Dallimore <jrhdallimore@gmail.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */
|
||||
class nrps_info {
|
||||
|
||||
/** @var \moodle_url the memberships URL for the service. */
|
||||
private $contextmembershipsurl;
|
||||
|
||||
/** @var float[] the array of supported service versions. */
|
||||
private $serviceversions;
|
||||
|
||||
// Service versions are specified by the platform during launch.
|
||||
// See http://www.imsglobal.org/spec/lti-nrps/v2p0#lti-1-3-integration.
|
||||
/** @var string version 1.0 */
|
||||
private const SERVICE_VERSION_1 = '1.0';
|
||||
|
||||
/** @var string version 2.0 */
|
||||
private const SERVICE_VERSION_2 = '2.0';
|
||||
|
||||
// Scope that must be requested as part of making a service call.
|
||||
// See: http://www.imsglobal.org/spec/lti-nrps/v2p0#lti-1-3-integration.
|
||||
/** @var string the scope to request to make service calls. */
|
||||
private $servicescope = 'https://purl.imsglobal.org/spec/lti-nrps/scope/contextmembership.readonly';
|
||||
|
||||
/**
|
||||
* The private nrps_info constructor.
|
||||
*
|
||||
* @param \moodle_url $contextmembershipsurl the memberships URL.
|
||||
* @param string[] $serviceversions the supported service versions.
|
||||
*/
|
||||
private function __construct(\moodle_url $contextmembershipsurl, array $serviceversions = [self::SERVICE_VERSION_2]) {
|
||||
$this->contextmembershipsurl = $contextmembershipsurl;
|
||||
$this->set_service_versions($serviceversions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method to create a new nrps_info instance.
|
||||
*
|
||||
* @param \moodle_url $contextmembershipsurl the memberships URL.
|
||||
* @param string[] $serviceversions the supported service versions.
|
||||
* @return nrps_info the object instance.
|
||||
*/
|
||||
public static function create(\moodle_url $contextmembershipsurl,
|
||||
array $serviceversions = [self::SERVICE_VERSION_2]): nrps_info {
|
||||
return new self($contextmembershipsurl, $serviceversions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the supplied service version is valid or not.
|
||||
*
|
||||
* @param string $serviceversion the service version to check.
|
||||
* @return bool true if valid, false otherwise.
|
||||
*/
|
||||
private function is_valid_service_version(string $serviceversion): bool {
|
||||
$validversions = [
|
||||
self::SERVICE_VERSION_1,
|
||||
self::SERVICE_VERSION_2
|
||||
];
|
||||
|
||||
return in_array($serviceversion, $validversions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to set the supported service versions for this instance.
|
||||
*
|
||||
* @param array $serviceversions the service versions to set.
|
||||
* @throws \coding_exception if any of the supplied versions are not valid.
|
||||
*/
|
||||
private function set_service_versions(array $serviceversions): void {
|
||||
if (empty($serviceversions)) {
|
||||
throw new \coding_exception('Service versions array cannot be empty');
|
||||
}
|
||||
$serviceversions = array_unique($serviceversions);
|
||||
foreach ($serviceversions as $serviceversion) {
|
||||
if (!$this->is_valid_service_version($serviceversion)) {
|
||||
throw new \coding_exception("Invalid Names and Roles service version '{$serviceversion}'");
|
||||
}
|
||||
}
|
||||
$this->serviceversions = $serviceversions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the service URL for this grade service instance.
|
||||
*
|
||||
* @return \moodle_url the service URL.
|
||||
*/
|
||||
public function get_context_memberships_url(): \moodle_url {
|
||||
return $this->contextmembershipsurl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the supported service versions for this grade service instance.
|
||||
*
|
||||
* @return string[] the array of supported service versions.
|
||||
*/
|
||||
public function get_service_versions(): array {
|
||||
return $this->serviceversions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the nrps service scope.
|
||||
*
|
||||
* @return string the service scope.
|
||||
*/
|
||||
public function get_service_scope(): string {
|
||||
return $this->servicescope;
|
||||
}
|
||||
}
|
@ -0,0 +1,69 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
namespace enrol_lti\local\ltiadvantage\entity;
|
||||
use moodle_url;
|
||||
|
||||
/**
|
||||
* Class registration_url, representing a single dynamic registration URL.
|
||||
*
|
||||
* @package enrol_lti
|
||||
* @copyright 2021 Jake Dallimore <jrhdallimore@gmail.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class registration_url extends moodle_url {
|
||||
|
||||
/** @var string the address of the registration URL. */
|
||||
protected $address;
|
||||
|
||||
/** @var string the random token used to secure this registration URL. */
|
||||
protected $token;
|
||||
|
||||
/** @var int Unix time at which this registration URL is no longer valid. */
|
||||
protected $expirytime;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param int $expirytime the unix time after which the URL is deemed invalid.
|
||||
* @param string|null $token the unique token securing requests to the URL.
|
||||
* @throws \coding_exception if the token or expiry time is invalid.
|
||||
*/
|
||||
public function __construct(int $expirytime, string $token = null) {
|
||||
global $CFG;
|
||||
if ($expirytime < 0) {
|
||||
throw new \coding_exception('Invalid registration_url expiry time. Must be greater than or equal to 0.');
|
||||
}
|
||||
$this->address = $CFG->wwwroot . '/enrol/lti/register.php';
|
||||
$this->expirytime = $expirytime;
|
||||
if (is_null($token)) {
|
||||
$bytes = random_bytes(30);
|
||||
$token = bin2hex($bytes);
|
||||
}
|
||||
$this->token = $token;
|
||||
|
||||
parent::__construct($this->address, ['token' => $this->token], null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the expiry time of this registration_url instance.
|
||||
*
|
||||
* @return int the unix time of the expiry.
|
||||
*/
|
||||
public function get_expiry_time(): int {
|
||||
return $this->expirytime;
|
||||
}
|
||||
}
|
231
enrol/lti/classes/local/ltiadvantage/entity/resource_link.php
Normal file
231
enrol/lti/classes/local/ltiadvantage/entity/resource_link.php
Normal file
@ -0,0 +1,231 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
namespace enrol_lti\local\ltiadvantage\entity;
|
||||
|
||||
/**
|
||||
* Class resource_link.
|
||||
*
|
||||
* This class represents an LTI Advantage Resource Link (http://www.imsglobal.org/spec/lti/v1p3/#resource-link).
|
||||
*
|
||||
* @package enrol_lti
|
||||
* @copyright 2021 Jake Dallimore <jrhdallimore@gmail.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class resource_link {
|
||||
|
||||
/** @var int|null the id of this object, or null if the object hasn't been stored yet. */
|
||||
private $id;
|
||||
|
||||
/** @var string resourcelinkid the id of the resource link as supplied by the platform. */
|
||||
private $resourcelinkid;
|
||||
|
||||
/** @var int $deploymentid the local id of the deployment instance to which this resource link belongs. */
|
||||
private $deploymentid;
|
||||
|
||||
/** @var int|null $contextid the id of local context object representing the platform context, or null. */
|
||||
private $contextid;
|
||||
|
||||
/** @var int The id of the local published resource this resource_link points to. */
|
||||
private $resourceid;
|
||||
|
||||
/** @var ags_info|null the grade service for this resource_link, null if not applicable/not provided. */
|
||||
private $gradeservice;
|
||||
|
||||
/** @var nrps_info|null the names and roles service for this resource_link, null if not applicable/not provided. */
|
||||
private $namesrolesservice;
|
||||
|
||||
/**
|
||||
* The private resource_link constructor.
|
||||
*
|
||||
* @param string $resourcelinkid the id of the resource link as supplied by the platform.
|
||||
* @param int $deploymentid the local id of the deployment instance to which this resource link belongs.
|
||||
* @param int $resourceid the id of the local resource to which this link refers.
|
||||
* @param int|null $contextid the id local context object representing the context within the platform.
|
||||
* @param int|null $id the local id of this resource_link object.
|
||||
* @throws \coding_exception if the instance is unable to be created.
|
||||
*/
|
||||
private function __construct(string $resourcelinkid, int $deploymentid, int $resourceid, ?int $contextid = null,
|
||||
int $id = null) {
|
||||
|
||||
if (empty($resourcelinkid)) {
|
||||
throw new \coding_exception('Error: resourcelinkid cannot be an empty string');
|
||||
}
|
||||
$this->resourcelinkid = $resourcelinkid;
|
||||
$this->deploymentid = $deploymentid;
|
||||
$this->resourceid = $resourceid;
|
||||
$this->contextid = $contextid;
|
||||
$this->id = $id;
|
||||
$this->gradeservice = null;
|
||||
$this->namesrolesservice = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method to create an instance.
|
||||
*
|
||||
* @param string $resourcelinkid the resourcelinkid, as provided by the platform.
|
||||
* @param int $deploymentid the local id of the deployment to which this resource link belongs.
|
||||
* @param int $resourceid the id of the local resource this resource_link refers to.
|
||||
* @param int|null $contextid the id of the local context object representing the platform context.
|
||||
* @param int|null $id the local id of the resource link instance.
|
||||
* @return resource_link the newly created instance.
|
||||
*/
|
||||
public static function create(string $resourcelinkid, int $deploymentid, int $resourceid, ?int $contextid = null,
|
||||
int $id = null): resource_link {
|
||||
|
||||
return new self($resourcelinkid, $deploymentid, $resourceid, $contextid, $id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the id of this object instance.
|
||||
*
|
||||
* @return null|int the id or null if the object has not yet been stored.
|
||||
*/
|
||||
public function get_id(): ?int {
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the resourcelinkid as provided by the platform.
|
||||
*
|
||||
* @return string the resourcelinkid.
|
||||
*/
|
||||
public function get_resourcelinkid(): string {
|
||||
return $this->resourcelinkid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the id of the deployment to which this resource link belongs.
|
||||
*
|
||||
* This id is the local id of the deployment instance, not the deploymentid provided by the platform.
|
||||
*
|
||||
* @return int the deployment id.
|
||||
*/
|
||||
public function get_deploymentid(): int {
|
||||
return $this->deploymentid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the local id of the published resource to which this resource link refers.
|
||||
*
|
||||
* @return int the id of the published resource.
|
||||
*/
|
||||
public function get_resourceid(): int {
|
||||
return $this->resourceid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the id of the context object holding information about where this resource link resides.
|
||||
*
|
||||
* @return int|null the id or null if not present.
|
||||
*/
|
||||
public function get_contextid(): ?int {
|
||||
return $this->contextid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Link this resource_link instance with a context.
|
||||
*
|
||||
* @param int $contextid the local id of the context instance containing information about the platform context.
|
||||
*/
|
||||
public function set_contextid(int $contextid): void {
|
||||
if ($contextid <= 0) {
|
||||
throw new \coding_exception('Context id must be a positive int');
|
||||
}
|
||||
$this->contextid = $contextid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set which local published resource this resource link refers to.
|
||||
*
|
||||
* @param int $resourceid the published resource id.
|
||||
*/
|
||||
public function set_resourceid(int $resourceid): void {
|
||||
if ($resourceid <= 0) {
|
||||
throw new \coding_exception('Resource id must be a positive int');
|
||||
}
|
||||
$this->resourceid = $resourceid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add grade service information to this resource_link instance.
|
||||
*
|
||||
* @param \moodle_url $lineitemsurl the service URL for get/put of line items.
|
||||
* @param \moodle_url|null $lineitemurl the service URL if only a single line item is present in the platform.
|
||||
* @param string[] $scopes the string array of grade service scopes which may be used by the service.
|
||||
*/
|
||||
public function add_grade_service(\moodle_url $lineitemsurl, ?\moodle_url $lineitemurl = null, array $scopes = []) {
|
||||
$this->gradeservice = ags_info::create($lineitemsurl, $lineitemurl, $scopes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the grade service attached to this resource_link instance, or null if there isn't one associated.
|
||||
*
|
||||
* @return ags_info|null the grade service object instance, or null if not found.
|
||||
*/
|
||||
public function get_grade_service(): ?ags_info {
|
||||
return $this->gradeservice;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add names and roles service information to this resource_link instance.
|
||||
*
|
||||
* @param \moodle_url $contextmembershipurl the service URL for memberships.
|
||||
* @param string[] $serviceversions the string array of supported service versions.
|
||||
*/
|
||||
public function add_names_and_roles_service(\moodle_url $contextmembershipurl, array $serviceversions): void {
|
||||
$this->namesrolesservice = nrps_info::create($contextmembershipurl, $serviceversions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the names and roles service attached to this resource_link instance, or null if there isn't one associated.
|
||||
*
|
||||
* @return nrps_info|null the names and roles service object instance, or null if not found.
|
||||
*/
|
||||
public function get_names_and_roles_service(): ?nrps_info {
|
||||
return $this->namesrolesservice;
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method to create a user from this resource_link instance.
|
||||
*
|
||||
* This is useful for associating the user with the resource link and resource I.e. the user was created when
|
||||
* launching a specific resource link.
|
||||
*
|
||||
* @param int $userid the id of the Moodle user record.
|
||||
* @param string $sourceid the id of the user on the platform.
|
||||
* @param string $lang the user's lang code.
|
||||
* @param string $city the user's city.
|
||||
* @param string $country the user's country.
|
||||
* @param string $institution the user's institution.
|
||||
* @param string $timezone the user's timezone.
|
||||
* @param int|null $maildisplay the user's maildisplay, which can be omitted to use sensible defaults.
|
||||
* @return user the user instance.
|
||||
* @throws \coding_exception if trying to add a user to an as-yet-unsaved resource_link instance.
|
||||
*/
|
||||
public function add_user(int $userid, string $sourceid, string $lang,
|
||||
string $city, string $country, string $institution, string $timezone,
|
||||
?int $maildisplay = null): user {
|
||||
|
||||
if (empty($this->get_id())) {
|
||||
throw new \coding_exception('Can\'t add user to a resource_link that hasn\'t first been saved');
|
||||
}
|
||||
|
||||
return user::create_from_resource_link($this->get_id(), $this->get_resourceid(), $userid,
|
||||
$this->get_deploymentid(), $sourceid, $lang, $timezone, $city, $country,
|
||||
$institution, $maildisplay);
|
||||
}
|
||||
}
|
420
enrol/lti/classes/local/ltiadvantage/entity/user.php
Normal file
420
enrol/lti/classes/local/ltiadvantage/entity/user.php
Normal file
@ -0,0 +1,420 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
namespace enrol_lti\local\ltiadvantage\entity;
|
||||
|
||||
/**
|
||||
* Class user, instances of which represent a specific lti user in the tool.
|
||||
*
|
||||
* A user is always associated with a resource, as lti users cannot exist without a tool-published-resource. A user will
|
||||
* always come from either:
|
||||
* - a resource link launch or
|
||||
* - a membership sync
|
||||
* Both of which required a published resource.
|
||||
*
|
||||
* Additionally, a user may be associated with a given resource_link instance, to signify that the user originated from
|
||||
* that resource_link. If a user is not associated with a resource_link, such as when creating a user during a member
|
||||
* sync, that param is nullable. This can be achieved via the factory method user::create_from_resource_link() or set
|
||||
* after instantiation via the user::set_resource_link_id() method.
|
||||
*
|
||||
* @package enrol_lti
|
||||
* @copyright 2021 Jake Dallimore <jrhdallimore@gmail.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */
|
||||
class user {
|
||||
|
||||
/** @var int the id of the published resource to which this user belongs. */
|
||||
private $resourceid;
|
||||
|
||||
/** @var int the local id of the deployment instance to which this user belongs. */
|
||||
private $deploymentid;
|
||||
|
||||
/** @var string the id of the user in the platform site. */
|
||||
private $sourceid;
|
||||
|
||||
/** @var int|null the id of this user instance, or null if not stored yet. */
|
||||
private $id;
|
||||
|
||||
/** @var int|null the id of the user in the tool site, or null if the instance hasn't been stored yet. */
|
||||
private $localid;
|
||||
|
||||
/** @var string city of the user. */
|
||||
private $city;
|
||||
|
||||
/** @var string country of the user. */
|
||||
private $country;
|
||||
|
||||
/** @var string institution of the user.*/
|
||||
private $institution;
|
||||
|
||||
/** @var string timezone of the user. */
|
||||
private $timezone;
|
||||
|
||||
/** @var int maildisplay of the user. */
|
||||
private $maildisplay;
|
||||
|
||||
/** @var string language code of the user. */
|
||||
private $lang;
|
||||
|
||||
/** @var float the user's last grade value. */
|
||||
private $lastgrade;
|
||||
|
||||
/** @var int|null the user's last access unix timestamp, or null if they have not accessed the resource yet.*/
|
||||
private $lastaccess;
|
||||
|
||||
/** @var int|null the id of the resource_link instance, or null if the user doesn't originate from one. */
|
||||
private $resourcelinkid;
|
||||
|
||||
/**
|
||||
* Private constructor.
|
||||
*
|
||||
* @param int $resourceid the id of the published resource to which this user belongs.
|
||||
* @param int $userid the id of the Moodle user to which this LTI user relates.
|
||||
* @param int $deploymentid the local id of the deployment instance to which this user belongs.
|
||||
* @param string $sourceid the id of the user in the platform site.
|
||||
* @param string $lang the user's language code.
|
||||
* @param string $city the user's city.
|
||||
* @param string $country the user's country.
|
||||
* @param string $institution the user's institution.
|
||||
* @param string $timezone the user's timezone.
|
||||
* @param int|null $maildisplay the user's maildisplay, or null to select defaults.
|
||||
* @param float|null $lastgrade the user's last grade value.
|
||||
* @param int|null $lastaccess the user's last access time, or null if they haven't accessed the resource.
|
||||
* @param int|null $resourcelinkid the id of the resource link to link to the user, or null if not applicable.
|
||||
* @param int|null $id the id of this object instance, or null if it's a not-yet-persisted object.
|
||||
* @throws \coding_exception
|
||||
*/
|
||||
private function __construct(int $resourceid, int $userid, int $deploymentid, string $sourceid,
|
||||
string $lang, string $city, string $country,
|
||||
string $institution, string $timezone, ?int $maildisplay, ?float $lastgrade, ?int $lastaccess,
|
||||
?int $resourcelinkid = null, ?int $id = null) {
|
||||
|
||||
global $CFG;
|
||||
$this->resourceid = $resourceid;
|
||||
$this->localid = $userid;
|
||||
$this->deploymentid = $deploymentid;
|
||||
if (empty($sourceid)) {
|
||||
throw new \coding_exception('Invalid sourceid value. Cannot be an empty string.');
|
||||
}
|
||||
$this->sourceid = $sourceid;
|
||||
$this->set_lang($lang);
|
||||
$this->set_city($city);
|
||||
$this->set_country($country);
|
||||
$this->set_institution($institution);
|
||||
$this->set_timezone($timezone);
|
||||
$maildisplay = $maildisplay ?? ($CFG->defaultpreference_maildisplay ?? 2);
|
||||
$this->set_maildisplay($maildisplay);
|
||||
$this->lastgrade = $lastgrade ?? 0.0;
|
||||
$this->lastaccess = $lastaccess;
|
||||
$this->resourcelinkid = $resourcelinkid;
|
||||
$this->id = $id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method for creating a user instance associated with a given resource_link instance.
|
||||
*
|
||||
* @param int $resourcelinkid the local id of the resource link instance to link to the user.
|
||||
* @param int $resourceid the id of the published resource to which this user belongs.
|
||||
* @param int $userid the id of the Moodle user to which this LTI user relates.
|
||||
* @param int $deploymentid the local id of the deployment instance to which this user belongs.
|
||||
* @param string $sourceid the id of the user in the platform site.
|
||||
* @param string $lang the user's language code.
|
||||
* @param string $timezone the user's timezone.
|
||||
* @param string $city the user's city.
|
||||
* @param string $country the user's country.
|
||||
* @param string $institution the user's institution.
|
||||
* @param int|null $maildisplay the user's maildisplay, or null to select defaults.
|
||||
* @return user the user instance.
|
||||
*/
|
||||
public static function create_from_resource_link(int $resourcelinkid, int $resourceid, int $userid,
|
||||
int $deploymentid, string $sourceid, string $lang, string $timezone,
|
||||
string $city = '', string $country = '', string $institution = '',
|
||||
?int $maildisplay = null): user {
|
||||
|
||||
return new self($resourceid, $userid, $deploymentid, $sourceid, $lang, $city,
|
||||
$country, $institution, $timezone, $maildisplay, null, null, $resourcelinkid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method for creating a user.
|
||||
*
|
||||
* @param int $resourceid the id of the published resource to which this user belongs.
|
||||
* @param int $userid the id of the Moodle user to which this LTI user relates.
|
||||
* @param int $deploymentid the local id of the deployment instance to which this user belongs.
|
||||
* @param string $sourceid the id of the user in the platform site.
|
||||
* @param string $lang the user's language code.
|
||||
* @param string $timezone the user's timezone.
|
||||
* @param string $city the user's city.
|
||||
* @param string $country the user's country.
|
||||
* @param string $institution the user's institution.
|
||||
* @param int|null $maildisplay the user's maildisplay, or null to select defaults.
|
||||
* @param float|null $lastgrade the user's last grade value.
|
||||
* @param int|null $lastaccess the user's last access time, or null if they haven't accessed the resource.
|
||||
* @param int|null $resourcelinkid the local id of the resource link instance associated with the user.
|
||||
* @param int|null $id the id of this lti user instance, or null if it's a not-yet-persisted object.
|
||||
* @return user the user instance.
|
||||
*/
|
||||
public static function create(int $resourceid, int $userid, int $deploymentid, string $sourceid,
|
||||
string $lang, string $timezone, string $city = '',
|
||||
string $country = '', string $institution = '', ?int $maildisplay = null, ?float $lastgrade = null,
|
||||
?int $lastaccess = null, ?int $resourcelinkid = null, int $id = null): user {
|
||||
|
||||
return new self($resourceid, $userid, $deploymentid, $sourceid, $lang, $city,
|
||||
$country, $institution, $timezone, $maildisplay, $lastgrade, $lastaccess, $resourcelinkid, $id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the id of this user instance.
|
||||
*
|
||||
* @return int|null the object id, or null if not yet persisted.
|
||||
*/
|
||||
public function get_id(): ?int {
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the id of the resource_link instance to which this user is associated.
|
||||
*
|
||||
* @return int|null the object id, or null if the user isn't associated with one.
|
||||
*/
|
||||
public function get_resourcelinkid(): ?int {
|
||||
return $this->resourcelinkid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Associate this user with the given resource_link instance, denoting that this user launched from the instance.
|
||||
*
|
||||
* @param int $resourcelinkid the id of the resource_link instance.
|
||||
*/
|
||||
public function set_resourcelinkid(int $resourcelinkid): void {
|
||||
if ($resourcelinkid <= 0) {
|
||||
throw new \coding_exception("Invalid resourcelinkid '$resourcelinkid' provided. Must be > 0.");
|
||||
}
|
||||
$this->resourcelinkid = $resourcelinkid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the id of the published resource to which this user is associated.
|
||||
*
|
||||
* @return int the resource id.
|
||||
*/
|
||||
public function get_resourceid(): int {
|
||||
return $this->resourceid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the id of the deployment instance to which this user belongs.
|
||||
*
|
||||
* @return int id of the deployment instance.
|
||||
*/
|
||||
public function get_deploymentid(): int {
|
||||
return $this->deploymentid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the id of the user in the platform.
|
||||
*
|
||||
* @return string the source id.
|
||||
*/
|
||||
public function get_sourceid(): string {
|
||||
return $this->sourceid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the id of the user in the tool.
|
||||
*
|
||||
* @return int|null the id, or null if the object instance hasn't yet been persisted.
|
||||
*/
|
||||
public function get_localid(): ?int {
|
||||
return $this->localid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the user's city.
|
||||
*
|
||||
* @return string the city.
|
||||
*/
|
||||
public function get_city(): string {
|
||||
return $this->city;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the user's city.
|
||||
*
|
||||
* @param string $city the city string.
|
||||
*/
|
||||
public function set_city(string $city): void {
|
||||
$this->city = $city;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the user's country code.
|
||||
*
|
||||
* @return string the country code.
|
||||
*/
|
||||
public function get_country(): string {
|
||||
return $this->country;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the user's country.
|
||||
*
|
||||
* @param string $countrycode the 2 digit country code representing the country, or '' to denote none.
|
||||
*/
|
||||
public function set_country(string $countrycode): void {
|
||||
global $CFG;
|
||||
require_once($CFG->libdir . '/moodlelib.php');
|
||||
$validcountrycodes = array_merge([''], array_keys(get_string_manager()->get_list_of_countries(true)));
|
||||
if (!in_array($countrycode, $validcountrycodes)) {
|
||||
throw new \coding_exception("Invalid country code '$countrycode'.");
|
||||
}
|
||||
$this->country = $countrycode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the instituation of the user.
|
||||
*
|
||||
* @return string the institution.
|
||||
*/
|
||||
public function get_institution(): string {
|
||||
return $this->institution;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the user's institution.
|
||||
*
|
||||
* @param string $institution the name of the institution.
|
||||
*/
|
||||
public function set_institution(string $institution): void {
|
||||
$this->institution = $institution;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the timezone of the user.
|
||||
*
|
||||
* @return string the user timezone.
|
||||
*/
|
||||
public function get_timezone(): string {
|
||||
return $this->timezone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the user's timezone, or set '99' to specify server timezone.
|
||||
*
|
||||
* @param string $timezone the timezone string, or '99' to use server timezone.
|
||||
*/
|
||||
public function set_timezone(string $timezone): void {
|
||||
if (empty($timezone)) {
|
||||
throw new \coding_exception('Invalid timezone value. Cannot be an empty string.');
|
||||
}
|
||||
$validtimezones = array_keys(\core_date::get_list_of_timezones(null, true));
|
||||
if (!in_array($timezone, $validtimezones)) {
|
||||
throw new \coding_exception("Invalid timezone '$timezone' provided.");
|
||||
}
|
||||
$this->timezone = $timezone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the maildisplay of the user.
|
||||
*
|
||||
* @return int the maildisplay.
|
||||
*/
|
||||
public function get_maildisplay(): int {
|
||||
return $this->maildisplay;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the user's mail display preference from a range of supported options.
|
||||
*
|
||||
* 0 - hide from non privileged users
|
||||
* 1 - allow everyone to see
|
||||
* 2 - allow only course participants to see
|
||||
*
|
||||
* @param int $maildisplay the maildisplay preference to set.
|
||||
*/
|
||||
public function set_maildisplay(int $maildisplay): void {
|
||||
if (!in_array($maildisplay, range(0, 2))) {
|
||||
throw new \coding_exception("Invalid maildisplay value '$maildisplay'. Must be in the range {0..2}.");
|
||||
}
|
||||
$this->maildisplay = $maildisplay;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the lang code of the user.
|
||||
*
|
||||
* @return string the user's language code.
|
||||
*/
|
||||
public function get_lang(): string {
|
||||
return $this->lang;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the user's language.
|
||||
*
|
||||
* @param string $langcode the language code representing the user's language.
|
||||
*/
|
||||
public function set_lang(string $langcode): void {
|
||||
if (empty($langcode)) {
|
||||
throw new \coding_exception('Invalid lang value. Cannot be an empty string.');
|
||||
}
|
||||
$validlangcodes = array_keys(get_string_manager()->get_list_of_translations());
|
||||
if (!in_array($langcode, $validlangcodes)) {
|
||||
throw new \coding_exception("Invalid lang '$langcode' provided.");
|
||||
}
|
||||
$this->lang = $langcode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the last grade value for this user.
|
||||
*
|
||||
* @return float the float grade.
|
||||
*/
|
||||
public function get_lastgrade(): float {
|
||||
return $this->lastgrade;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the last grade for the user.
|
||||
*
|
||||
* @param float $lastgrade the last grade the user received.
|
||||
*/
|
||||
public function set_lastgrade(float $lastgrade): void {
|
||||
global $CFG;
|
||||
require_once($CFG->libdir . '/gradelib.php');
|
||||
$this->lastgrade = grade_floatval($lastgrade);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the last access timestamp for this user.
|
||||
*
|
||||
* @return int|null the last access timestampt, or null if the user hasn't accessed the resource.
|
||||
*/
|
||||
public function get_lastaccess(): ?int {
|
||||
return $this->lastaccess;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the last access time for the user.
|
||||
*
|
||||
* @param int $time unix timestamp representing the last time the user accessed the published resource.
|
||||
* @throws \coding_exception if $time is not a positive int.
|
||||
*/
|
||||
public function set_lastaccess(int $time): void {
|
||||
if ($time < 0) {
|
||||
throw new \coding_exception('Cannot set negative access time');
|
||||
}
|
||||
$this->lastaccess = $time;
|
||||
}
|
||||
}
|
276
enrol/lti/tests/local/ltiadvantage/entity/ags_info_test.php
Normal file
276
enrol/lti/tests/local/ltiadvantage/entity/ags_info_test.php
Normal file
@ -0,0 +1,276 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
namespace enrol_lti\local\ltiadvantage\entity;
|
||||
|
||||
/**
|
||||
* Tests for ags_info.
|
||||
*
|
||||
* @package enrol_lti
|
||||
* @copyright 2021 Jake Dallimore <jrhdallimore@gmail.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @coversDefaultClass \enrol_lti\local\ltiadvantage\entity\ags_info
|
||||
*/
|
||||
class ags_info_test extends \advanced_testcase {
|
||||
|
||||
/**
|
||||
* Test creation of the object instances.
|
||||
* @dataProvider instantiation_data_provider
|
||||
* @param array $args the arguments to the creation method.
|
||||
* @param array $expectations various expectations for the test cases.
|
||||
* @covers ::create
|
||||
*/
|
||||
public function test_creation(array $args, array $expectations) {
|
||||
if (!$expectations['valid']) {
|
||||
$this->expectException($expectations['exception']);
|
||||
$this->expectExceptionMessage($expectations['exceptionmessage']);
|
||||
ags_info::create(...array_values($args));
|
||||
} else {
|
||||
$agsinfo = ags_info::create(...array_values($args));
|
||||
$this->assertEquals($args['lineitemsurl'], $agsinfo->get_lineitemsurl());
|
||||
$this->assertEquals($args['lineitemurl'], $agsinfo->get_lineitemurl());
|
||||
$this->assertEquals($args['scopes'], $agsinfo->get_scopes());
|
||||
$this->assertEquals($expectations['lineitemscope'], $agsinfo->get_lineitemscope());
|
||||
$this->assertEquals($expectations['scorescope'], $agsinfo->get_scorescope());
|
||||
$this->assertEquals($expectations['resultscope'], $agsinfo->get_resultscope());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for testing object instantiation.
|
||||
* @return array the data for testing.
|
||||
*/
|
||||
public function instantiation_data_provider(): array {
|
||||
return [
|
||||
'Both lineitems and lineitem URL provided with full list of valid scopes' => [
|
||||
'args' => [
|
||||
'lineitemsurl' => new \moodle_url('https://platform.example.org/10/lineitems'),
|
||||
'lineitemurl' => new \moodle_url('https://platform.example.org/10/lineitems/4/lineitem'),
|
||||
'scopes' => [
|
||||
'https://purl.imsglobal.org/spec/lti-ags/scope/lineitem',
|
||||
'https://purl.imsglobal.org/spec/lti-ags/scope/lineitem.readonly',
|
||||
'https://purl.imsglobal.org/spec/lti-ags/scope/result.readonly',
|
||||
'https://purl.imsglobal.org/spec/lti-ags/scope/score'
|
||||
]
|
||||
],
|
||||
'expectations' => [
|
||||
'valid' => true,
|
||||
'lineitemscope' => [
|
||||
'https://purl.imsglobal.org/spec/lti-ags/scope/lineitem',
|
||||
'https://purl.imsglobal.org/spec/lti-ags/scope/lineitem.readonly'
|
||||
],
|
||||
'resultscope' => 'https://purl.imsglobal.org/spec/lti-ags/scope/result.readonly',
|
||||
'scorescope' => 'https://purl.imsglobal.org/spec/lti-ags/scope/score'
|
||||
]
|
||||
],
|
||||
'Both lineitems and lineitem URL provided with lineitem scopes only' => [
|
||||
'args' => [
|
||||
'lineitemsurl' => new \moodle_url('https://platform.example.org/10/lineitems'),
|
||||
'lineitemurl' => new \moodle_url('https://platform.example.org/10/lineitems/4/lineitem'),
|
||||
'scopes' => [
|
||||
'https://purl.imsglobal.org/spec/lti-ags/scope/lineitem',
|
||||
'https://purl.imsglobal.org/spec/lti-ags/scope/lineitem.readonly',
|
||||
]
|
||||
],
|
||||
'expectations' => [
|
||||
'valid' => true,
|
||||
'lineitemscope' => [
|
||||
'https://purl.imsglobal.org/spec/lti-ags/scope/lineitem',
|
||||
'https://purl.imsglobal.org/spec/lti-ags/scope/lineitem.readonly',
|
||||
],
|
||||
'scorescope' => null,
|
||||
'resultscope' => null
|
||||
]
|
||||
],
|
||||
'Both lineitems and lineitem URL provided with score scope only' => [
|
||||
'args' => [
|
||||
'lineitemsurl' => new \moodle_url('https://platform.example.org/10/lineitems'),
|
||||
'lineitemurl' => new \moodle_url('https://platform.example.org/10/lineitems/4/lineitem'),
|
||||
'scopes' => [
|
||||
'https://purl.imsglobal.org/spec/lti-ags/scope/score'
|
||||
]
|
||||
],
|
||||
'expectations' => [
|
||||
'valid' => true,
|
||||
'lineitemscope' => null,
|
||||
'scorescope' => 'https://purl.imsglobal.org/spec/lti-ags/scope/score',
|
||||
'resultscope' => null
|
||||
]
|
||||
],
|
||||
'Both lineitems and lineitem URL provided with result scope only' => [
|
||||
'args' => [
|
||||
'lineitemsurl' => new \moodle_url('https://platform.example.org/10/lineitems'),
|
||||
'lineitemurl' => new \moodle_url('https://platform.example.org/10/lineitems/4/lineitem'),
|
||||
'scopes' => [
|
||||
'https://purl.imsglobal.org/spec/lti-ags/scope/result.readonly'
|
||||
]
|
||||
],
|
||||
'expectations' => [
|
||||
'valid' => true,
|
||||
'lineitemscope' => null,
|
||||
'scorescope' => null,
|
||||
'resultscope' => 'https://purl.imsglobal.org/spec/lti-ags/scope/result.readonly'
|
||||
]
|
||||
],
|
||||
'Both lineitems and lineitem URL provided with no scopes' => [
|
||||
'args' => [
|
||||
'lineitemsurl' => new \moodle_url('https://platform.example.org/10/lineitems'),
|
||||
'lineitemurl' => new \moodle_url('https://platform.example.org/10/lineitems/4/lineitem'),
|
||||
'scopes' => []
|
||||
],
|
||||
'expectations' => [
|
||||
'valid' => true,
|
||||
'lineitemscope' => null,
|
||||
'scorescope' => null,
|
||||
'resultscope' => null
|
||||
]
|
||||
],
|
||||
'Just lineitems URL, no lineitem URL, with full list of valid scopes' => [
|
||||
'args' => [
|
||||
'lineitemsurl' => new \moodle_url('https://platform.example.org/10/lineitems'),
|
||||
'lineitemurl' => null,
|
||||
'scopes' => [
|
||||
'https://purl.imsglobal.org/spec/lti-ags/scope/lineitem',
|
||||
'https://purl.imsglobal.org/spec/lti-ags/scope/lineitem.readonly',
|
||||
'https://purl.imsglobal.org/spec/lti-ags/scope/result.readonly',
|
||||
'https://purl.imsglobal.org/spec/lti-ags/scope/score'
|
||||
]
|
||||
],
|
||||
'expectations' => [
|
||||
'valid' => true,
|
||||
'lineitemscope' => [
|
||||
'https://purl.imsglobal.org/spec/lti-ags/scope/lineitem',
|
||||
'https://purl.imsglobal.org/spec/lti-ags/scope/lineitem.readonly'
|
||||
],
|
||||
'resultscope' => 'https://purl.imsglobal.org/spec/lti-ags/scope/result.readonly',
|
||||
'scorescope' => 'https://purl.imsglobal.org/spec/lti-ags/scope/score'
|
||||
]
|
||||
],
|
||||
'Just lineitems URL, no lineitem URL, with lineitems scopes only' => [
|
||||
'args' => [
|
||||
'lineitemsurl' => new \moodle_url('https://platform.example.org/10/lineitems'),
|
||||
'lineitemurl' => null,
|
||||
'scopes' => [
|
||||
'https://purl.imsglobal.org/spec/lti-ags/scope/lineitem',
|
||||
'https://purl.imsglobal.org/spec/lti-ags/scope/lineitem.readonly',
|
||||
]
|
||||
],
|
||||
'expectations' => [
|
||||
'valid' => true,
|
||||
'lineitemscope' => [
|
||||
'https://purl.imsglobal.org/spec/lti-ags/scope/lineitem',
|
||||
'https://purl.imsglobal.org/spec/lti-ags/scope/lineitem.readonly',
|
||||
],
|
||||
'scorescope' => null,
|
||||
'resultscope' => null
|
||||
]
|
||||
],
|
||||
'Just lineitems URL, no lineitem URL, with score scope only' => [
|
||||
'args' => [
|
||||
'lineitemsurl' => new \moodle_url('https://platform.example.org/10/lineitems'),
|
||||
'lineitemurl' => null,
|
||||
'scopes' => [
|
||||
'https://purl.imsglobal.org/spec/lti-ags/scope/score'
|
||||
]
|
||||
],
|
||||
'expectations' => [
|
||||
'valid' => true,
|
||||
'lineitemscope' => null,
|
||||
'scorescope' => 'https://purl.imsglobal.org/spec/lti-ags/scope/score',
|
||||
'resultscope' => null
|
||||
]
|
||||
],
|
||||
'Just lineitems URL, no lineitem URL, with result scope only' => [
|
||||
'args' => [
|
||||
'lineitemsurl' => new \moodle_url('https://platform.example.org/10/lineitems'),
|
||||
'lineitemurl' => null,
|
||||
'scopes' => [
|
||||
'https://purl.imsglobal.org/spec/lti-ags/scope/result.readonly'
|
||||
]
|
||||
],
|
||||
'expectations' => [
|
||||
'valid' => true,
|
||||
'lineitemscope' => null,
|
||||
'scorescope' => null,
|
||||
'resultscope' => 'https://purl.imsglobal.org/spec/lti-ags/scope/result.readonly'
|
||||
]
|
||||
],
|
||||
'Just lineitems URL, no lineitem URL, with no scopes' => [
|
||||
'args' => [
|
||||
'lineitemsurl' => new \moodle_url('https://platform.example.org/10/lineitems'),
|
||||
'lineitemurl' => null,
|
||||
'scopes' => []
|
||||
],
|
||||
'expectations' => [
|
||||
'valid' => true,
|
||||
'lineitemscope' => null,
|
||||
'scorescope' => null,
|
||||
'resultscope' => null
|
||||
]
|
||||
],
|
||||
'Both lineitems and lineitem URL provided with non-string scope' => [
|
||||
'args' => [
|
||||
'lineitemsurl' => new \moodle_url('https://platform.example.org/10/lineitems'),
|
||||
'lineitemurl' => new \moodle_url('https://platform.example.org/10/lineitems/4/lineitem'),
|
||||
'scopes' => [
|
||||
'https://purl.imsglobal.org/spec/lti-ags/scope/lineitem',
|
||||
'https://purl.imsglobal.org/spec/lti-ags/scope/lineitem.readonly',
|
||||
'https://purl.imsglobal.org/spec/lti-ags/scope/result.readonly',
|
||||
'https://purl.imsglobal.org/spec/lti-ags/scope/score',
|
||||
12345
|
||||
]
|
||||
],
|
||||
'expectations' => [
|
||||
'valid' => false,
|
||||
'exception' => \coding_exception::class,
|
||||
'exceptionmessage' => 'Scope must be a string value'
|
||||
]
|
||||
],
|
||||
'Both lineitems and lineitem URL provided with invalid scopes' => [
|
||||
'args' => [
|
||||
'lineitemsurl' => new \moodle_url('https://platform.example.org/10/lineitems'),
|
||||
'lineitemurl' => new \moodle_url('https://platform.example.org/10/lineitems/4/lineitem'),
|
||||
'scopes' => [
|
||||
'https://purl.imsglobal.org/spec/lti-ags/scope/lineitem',
|
||||
'https://purl.imsglobal.org/spec/lti-ags/scope/lineitem.readonly',
|
||||
'https://purl.imsglobal.org/spec/lti-ags/scope/result.readonly',
|
||||
'https://purl.imsglobal.org/spec/lti-ags/scope/score',
|
||||
'https://example.com/invalid/scope'
|
||||
]
|
||||
],
|
||||
'expectations' => [
|
||||
'valid' => false,
|
||||
'exception' => \coding_exception::class,
|
||||
'exceptionmessage' => "Scope 'https://example.com/invalid/scope' is invalid."
|
||||
]
|
||||
],
|
||||
'Both lineitems and lineitem URL provided with invalid scope types' => [
|
||||
'args' => [
|
||||
'lineitemsurl' => new \moodle_url('https://platform.example.org/10/lineitems'),
|
||||
'lineitemurl' => new \moodle_url('https://platform.example.org/10/lineitems/4/lineitem'),
|
||||
'scopes' => [
|
||||
12
|
||||
]
|
||||
],
|
||||
'expectations' => [
|
||||
'valid' => false,
|
||||
'exception' => \coding_exception::class,
|
||||
'exceptionmessage' => "Scope must be a string value"
|
||||
]
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
@ -0,0 +1,241 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
namespace enrol_lti\local\ltiadvantage\entity;
|
||||
|
||||
/**
|
||||
* Tests for application_registration.
|
||||
*
|
||||
* @package enrol_lti
|
||||
* @copyright 2021 Jake Dallimore <jrhdallimore@gmail.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @coversDefaultClass \enrol_lti\local\ltiadvantage\entity\application_registration
|
||||
*/
|
||||
class application_registration_test extends \advanced_testcase {
|
||||
|
||||
/**
|
||||
* Test the creation of an application_registration instance.
|
||||
*
|
||||
* @dataProvider creation_data_provider
|
||||
* @param array $args the arguments to the creation method.
|
||||
* @param array $expectations various expectations for the test cases.
|
||||
* @covers ::create
|
||||
*/
|
||||
public function test_creation(array $args, array $expectations) {
|
||||
if ($expectations['valid']) {
|
||||
$reg = application_registration::create(...array_values($args));
|
||||
$this->assertEquals($args['name'], $reg->get_name());
|
||||
$this->assertEquals($args['platformid'], $reg->get_platformid());
|
||||
$this->assertEquals($args['clientid'], $reg->get_clientid());
|
||||
$this->assertEquals($args['authrequesturl'], $reg->get_authenticationrequesturl());
|
||||
$this->assertEquals($args['jwksurl'], $reg->get_jwksurl());
|
||||
$this->assertEquals($args['accesstokenurl'], $reg->get_accesstokenurl());
|
||||
$expectedid = $args['id'] ?? null;
|
||||
$this->assertEquals($expectedid, $reg->get_id());
|
||||
} else {
|
||||
$this->expectException($expectations['exception']);
|
||||
$this->expectExceptionMessage($expectations['exceptionmessage']);
|
||||
application_registration::create(...array_values($args));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for testing the creation of application_registration instances.
|
||||
*
|
||||
* @return array the data for testing.
|
||||
*/
|
||||
public function creation_data_provider(): array {
|
||||
return [
|
||||
'Valid, only required args provided' => [
|
||||
'args' => [
|
||||
'name' => 'Platform X',
|
||||
'platformid' => new \moodle_url('https://lms.example.com'),
|
||||
'clientid' => 'client-id-12345',
|
||||
'authrequesturl' => new \moodle_url('https://lms.example.com/auth'),
|
||||
'jwksurl' => new \moodle_url('https://lms.example.com/jwks'),
|
||||
'accesstokenurl' => new \moodle_url('https://lms.example.com/token'),
|
||||
],
|
||||
'expectations' => [
|
||||
'valid' => true
|
||||
]
|
||||
],
|
||||
'Valid, all args provided' => [
|
||||
'args' => [
|
||||
'name' => 'Platform X',
|
||||
'platformid' => new \moodle_url('https://lms.example.com'),
|
||||
'clientid' => 'client-id-12345',
|
||||
'authrequesturl' => new \moodle_url('https://lms.example.com/auth'),
|
||||
'jwksurl' => new \moodle_url('https://lms.example.com/jwks'),
|
||||
'accesstokenurl' => new \moodle_url('https://lms.example.com/token'),
|
||||
'id' => 24
|
||||
],
|
||||
'expectations' => [
|
||||
'valid' => true
|
||||
]
|
||||
],
|
||||
'Invalid, empty name provided' => [
|
||||
'args' => [
|
||||
'name' => '',
|
||||
'platformid' => new \moodle_url('https://lms.example.com'),
|
||||
'clientid' => 'client-id-12345',
|
||||
'authrequesturl' => new \moodle_url('https://lms.example.com/auth'),
|
||||
'jwksurl' => new \moodle_url('https://lms.example.com/jwks'),
|
||||
'accesstokenurl' => new \moodle_url('https://lms.example.com/token'),
|
||||
],
|
||||
'expectations' => [
|
||||
'valid' => false,
|
||||
'exception' => \coding_exception::class,
|
||||
'exceptionmessage' => "Invalid 'name' arg. Cannot be an empty string."
|
||||
]
|
||||
],
|
||||
'Invalid, empty clientid provided' => [
|
||||
'args' => [
|
||||
'name' => 'Platform X',
|
||||
'platformid' => new \moodle_url('https://lms.example.com'),
|
||||
'clientid' => '',
|
||||
'authrequesturl' => new \moodle_url('https://lms.example.com/auth'),
|
||||
'jwksurl' => new \moodle_url('https://lms.example.com/jwks'),
|
||||
'accesstokenurl' => new \moodle_url('https://lms.example.com/token'),
|
||||
],
|
||||
'expectations' => [
|
||||
'valid' => false,
|
||||
'exception' => \coding_exception::class,
|
||||
'exceptionmessage' => "Invalid 'clientid' arg. Cannot be an empty string."
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the factory method for creating a tool deployment associated with the registration instance.
|
||||
*
|
||||
* @dataProvider add_tool_deployment_data_provider
|
||||
* @param array $args the arguments to the creation method.
|
||||
* @param array $expectations various expectations for the test cases.
|
||||
* @covers ::add_tool_deployment
|
||||
*/
|
||||
public function test_add_tool_deployment(array $args, array $expectations) {
|
||||
|
||||
if ($expectations['valid']) {
|
||||
$reg = application_registration::create(...array_values($args['registration']));
|
||||
$deployment = $reg->add_tool_deployment(...array_values($args['deployment']));
|
||||
$this->assertInstanceOf(deployment::class, $deployment);
|
||||
$this->assertEquals($args['deployment']['name'], $deployment->get_deploymentname());
|
||||
$this->assertEquals($args['deployment']['deploymentid'], $deployment->get_deploymentid());
|
||||
$this->assertEquals($reg->get_id(), $deployment->get_registrationid());
|
||||
} else {
|
||||
$reg = application_registration::create(...array_values($args['registration']));
|
||||
$this->expectException($expectations['exception']);
|
||||
$this->expectExceptionMessage($expectations['exceptionmessage']);
|
||||
$reg->add_tool_deployment(...array_values($args['deployment']));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for testing the add_tool_deployment method.
|
||||
*
|
||||
* @return array the array of test data.
|
||||
*/
|
||||
public function add_tool_deployment_data_provider(): array {
|
||||
return [
|
||||
'Valid, contains id on registration and valid deployment data provided' => [
|
||||
'args' => [
|
||||
'registration' => [
|
||||
'name' => 'Platform X',
|
||||
'platformid' => new \moodle_url('https://lms.example.com'),
|
||||
'clientid' => 'client-id-12345',
|
||||
'authrequesturl' => new \moodle_url('https://lms.example.com/auth'),
|
||||
'jwksurl' => new \moodle_url('https://lms.example.com/jwks'),
|
||||
'accesstokenurl' => new \moodle_url('https://lms.example.com/token'),
|
||||
'id' => 24
|
||||
],
|
||||
'deployment' => [
|
||||
'name' => 'Deployment at site level',
|
||||
'deploymentid' => 'id-123abc'
|
||||
]
|
||||
],
|
||||
'expectations' => [
|
||||
'valid' => true,
|
||||
]
|
||||
],
|
||||
'Invalid, missing id on registration' => [
|
||||
'args' => [
|
||||
'registration' => [
|
||||
'name' => 'Platform X',
|
||||
'platformid' => new \moodle_url('https://lms.example.com'),
|
||||
'clientid' => 'client-id-12345',
|
||||
'authrequesturl' => new \moodle_url('https://lms.example.com/auth'),
|
||||
'jwksurl' => new \moodle_url('https://lms.example.com/jwks'),
|
||||
'accesstokenurl' => new \moodle_url('https://lms.example.com/token'),
|
||||
],
|
||||
'deployment' => [
|
||||
'name' => 'Deployment at site level',
|
||||
'deploymentid' => 'id-123abc'
|
||||
]
|
||||
],
|
||||
'expectations' => [
|
||||
'valid' => false,
|
||||
'exception' => \coding_exception::class,
|
||||
'exceptionmessage' => "Can't add deployment to a resource_link that hasn't first been saved."
|
||||
]
|
||||
],
|
||||
'Invalid, id present on registration but empty deploymentname' => [
|
||||
'args' => [
|
||||
'registration' => [
|
||||
'name' => 'Platform X',
|
||||
'platformid' => new \moodle_url('https://lms.example.com'),
|
||||
'clientid' => 'client-id-12345',
|
||||
'authrequesturl' => new \moodle_url('https://lms.example.com/auth'),
|
||||
'jwksurl' => new \moodle_url('https://lms.example.com/jwks'),
|
||||
'accesstokenurl' => new \moodle_url('https://lms.example.com/token'),
|
||||
'id' => 24
|
||||
],
|
||||
'deployment' => [
|
||||
'name' => '',
|
||||
'deploymentid' => 'id-123abc'
|
||||
]
|
||||
],
|
||||
'expectations' => [
|
||||
'valid' => false,
|
||||
'exception' => \coding_exception::class,
|
||||
'exceptionmessage' => "Invalid 'deploymentname' arg. Cannot be an empty string."
|
||||
]
|
||||
],
|
||||
'Invalid, id present on registration but empty deploymentid' => [
|
||||
'args' => [
|
||||
'registration' => [
|
||||
'name' => 'Platform X',
|
||||
'platformid' => new \moodle_url('https://lms.example.com'),
|
||||
'clientid' => 'client-id-12345',
|
||||
'authrequesturl' => new \moodle_url('https://lms.example.com/auth'),
|
||||
'jwksurl' => new \moodle_url('https://lms.example.com/jwks'),
|
||||
'accesstokenurl' => new \moodle_url('https://lms.example.com/token'),
|
||||
'id' => 24
|
||||
],
|
||||
'deployment' => [
|
||||
'name' => 'Site deployment',
|
||||
'deploymentid' => ''
|
||||
]
|
||||
],
|
||||
'expectations' => [
|
||||
'valid' => false,
|
||||
'exception' => \coding_exception::class,
|
||||
'exceptionmessage' => "Invalid 'deploymentid' arg. Cannot be an empty string."
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
206
enrol/lti/tests/local/ltiadvantage/entity/context_test.php
Normal file
206
enrol/lti/tests/local/ltiadvantage/entity/context_test.php
Normal file
@ -0,0 +1,206 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
namespace enrol_lti\local\ltiadvantage\entity;
|
||||
|
||||
/**
|
||||
* Tests for context.
|
||||
*
|
||||
* @package enrol_lti
|
||||
* @copyright 2021 Jake Dallimore <jrhdallimore@gmail.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @coversDefaultClass \enrol_lti\local\ltiadvantage\entity\context
|
||||
*/
|
||||
class context_test extends \advanced_testcase {
|
||||
|
||||
/**
|
||||
* Test creation of the object instances.
|
||||
*
|
||||
* @dataProvider instantiation_data_provider
|
||||
* @param array $args the arguments to the creation method.
|
||||
* @param array $expectations various expectations for the test cases.
|
||||
* @covers ::create
|
||||
*/
|
||||
public function test_creation(array $args, array $expectations) {
|
||||
if (!$expectations['valid']) {
|
||||
$this->expectException($expectations['exception']);
|
||||
$this->expectExceptionMessage($expectations['exceptionmessage']);
|
||||
context::create(...array_values($args));
|
||||
} else {
|
||||
$context = context::create(...array_values($args));
|
||||
$this->assertEquals($args['deploymentid'], $context->get_deploymentid());
|
||||
$this->assertEquals($args['contextid'], $context->get_contextid());
|
||||
$this->assertEquals($args['types'], $context->get_types());
|
||||
$this->assertEquals($args['id'], $context->get_id());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for testing object instantiation.
|
||||
* @return array[] the data for testing.
|
||||
*/
|
||||
public function instantiation_data_provider(): array {
|
||||
return [
|
||||
'Creation of a course section context' => [
|
||||
'args' => [
|
||||
'deploymentid' => 24,
|
||||
'contextid' => 'context-123',
|
||||
'types' => [
|
||||
'http://purl.imsglobal.org/vocab/lis/v2/course#CourseSection'
|
||||
],
|
||||
'id' => null
|
||||
],
|
||||
'expectations' => [
|
||||
'valid' => true,
|
||||
]
|
||||
],
|
||||
'Creation of a course offering context' => [
|
||||
'args' => [
|
||||
'deploymentid' => 24,
|
||||
'contextid' => 'context-123',
|
||||
'types' => [
|
||||
'http://purl.imsglobal.org/vocab/lis/v2/course#CourseOffering'
|
||||
],
|
||||
'id' => null
|
||||
],
|
||||
'expectations' => [
|
||||
'valid' => true,
|
||||
]
|
||||
],
|
||||
'Creation of a course template context' => [
|
||||
'args' => [
|
||||
'deploymentid' => 24,
|
||||
'contextid' => 'context-123',
|
||||
'types' => [
|
||||
'http://purl.imsglobal.org/vocab/lis/v2/course#CourseTemplate'
|
||||
],
|
||||
'id' => null
|
||||
],
|
||||
'expectations' => [
|
||||
'valid' => true,
|
||||
]
|
||||
],
|
||||
'Creation of a course group context' => [
|
||||
'args' => [
|
||||
'deploymentid' => 24,
|
||||
'contextid' => 'context-123',
|
||||
'types' => [
|
||||
'http://purl.imsglobal.org/vocab/lis/v2/course#Group'
|
||||
],
|
||||
'id' => null
|
||||
],
|
||||
'expectations' => [
|
||||
'valid' => true,
|
||||
]
|
||||
],
|
||||
'Creation of an invalid context' => [
|
||||
'args' => [
|
||||
'deploymentid' => 24,
|
||||
'contextid' => 'context-123',
|
||||
'types' => [
|
||||
'http://example.com/invalid/context'
|
||||
],
|
||||
'id' => null
|
||||
],
|
||||
'expectations' => [
|
||||
'valid' => false,
|
||||
'exception' => \coding_exception::class,
|
||||
'exceptionmessage' => "Cannot set invalid context type 'http://example.com/invalid/context'."
|
||||
]
|
||||
],
|
||||
'Creation of a simple name context with type CourseTemplate' => [
|
||||
'args' => [
|
||||
'deploymentid' => 24,
|
||||
'contextid' => 'context-123',
|
||||
'types' => [
|
||||
'CourseTemplate'
|
||||
],
|
||||
'id' => null
|
||||
],
|
||||
'expectations' => [
|
||||
'valid' => true,
|
||||
]
|
||||
],
|
||||
'Creation of a simple name context with type CourseOffering' => [
|
||||
'args' => [
|
||||
'deploymentid' => 24,
|
||||
'contextid' => 'context-123',
|
||||
'types' => [
|
||||
'CourseOffering'
|
||||
],
|
||||
'id' => null
|
||||
],
|
||||
'expectations' => [
|
||||
'valid' => true,
|
||||
]
|
||||
],
|
||||
'Creation of a simple name context with type CourseSection' => [
|
||||
'args' => [
|
||||
'deploymentid' => 24,
|
||||
'contextid' => 'context-123',
|
||||
'types' => [
|
||||
'CourseSection'
|
||||
],
|
||||
'id' => null
|
||||
],
|
||||
'expectations' => [
|
||||
'valid' => true,
|
||||
]
|
||||
],
|
||||
'Creation of a simple name context with type Group' => [
|
||||
'args' => [
|
||||
'deploymentid' => 24,
|
||||
'contextid' => 'context-123',
|
||||
'types' => [
|
||||
'Group'
|
||||
],
|
||||
'id' => null
|
||||
],
|
||||
'expectations' => [
|
||||
'valid' => true,
|
||||
]
|
||||
],
|
||||
'Creation of a context with id' => [
|
||||
'args' => [
|
||||
'deploymentid' => 24,
|
||||
'contextid' => 'context-123',
|
||||
'types' => [
|
||||
'Group'
|
||||
],
|
||||
'id' => 24
|
||||
],
|
||||
'expectations' => [
|
||||
'valid' => true,
|
||||
]
|
||||
],
|
||||
'Creation of a context with invalid id' => [
|
||||
'args' => [
|
||||
'deploymentid' => 24,
|
||||
'contextid' => 'context-123',
|
||||
'types' => [
|
||||
'Group'
|
||||
],
|
||||
'id' => 0
|
||||
],
|
||||
'expectations' => [
|
||||
'valid' => false,
|
||||
'exception' => \coding_exception::class,
|
||||
'exceptionmessage' => "id must be a positive int"
|
||||
]
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
190
enrol/lti/tests/local/ltiadvantage/entity/deployment_test.php
Normal file
190
enrol/lti/tests/local/ltiadvantage/entity/deployment_test.php
Normal file
@ -0,0 +1,190 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
namespace enrol_lti\local\ltiadvantage\entity;
|
||||
|
||||
/**
|
||||
* Tests for deployment.
|
||||
*
|
||||
* @package enrol_lti
|
||||
* @copyright 2021 Jake Dallimore <jrhdallimore@gmail.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @coversDefaultClass \enrol_lti\local\ltiadvantage\entity\deployment
|
||||
*/
|
||||
class deployment_test extends \advanced_testcase {
|
||||
|
||||
/**
|
||||
* Test creation of the object instances.
|
||||
*
|
||||
* @dataProvider instantiation_data_provider
|
||||
* @param array $args the arguments to the creation method.
|
||||
* @param array $expectations various expectations for the test cases.
|
||||
* @covers ::create
|
||||
*/
|
||||
public function test_creation(array $args, array $expectations) {
|
||||
if (!$expectations['valid']) {
|
||||
$this->expectException($expectations['exception']);
|
||||
$this->expectExceptionMessage($expectations['exceptionmessage']);
|
||||
deployment::create(...array_values($args));
|
||||
} else {
|
||||
$deployment = deployment::create(...array_values($args));
|
||||
$this->assertEquals($args['deploymentname'], $deployment->get_deploymentname());
|
||||
$this->assertEquals($args['deploymentid'], $deployment->get_deploymentid());
|
||||
$this->assertEquals($args['registrationid'], $deployment->get_registrationid());
|
||||
$this->assertEquals($args['legacyconsumerkey'], $deployment->get_legacy_consumer_key());
|
||||
$this->assertEquals($args['id'], $deployment->get_id());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for testing object instantiation.
|
||||
* @return array the data for testing.
|
||||
*/
|
||||
public function instantiation_data_provider(): array {
|
||||
return [
|
||||
'Valid deployment creation, no id or legacy consumer key' => [
|
||||
'args' => [
|
||||
'registrationid' => 99,
|
||||
'deploymentid' => 'deployment-abcde',
|
||||
'deploymentname' => 'Global platform deployment',
|
||||
'id' => null,
|
||||
'legacyconsumerkey' => null,
|
||||
],
|
||||
'expectations' => [
|
||||
'valid' => true,
|
||||
]
|
||||
],
|
||||
'Valid deployment creation, with id, no legacy consumer key' => [
|
||||
'args' => [
|
||||
'registrationid' => 99,
|
||||
'deploymentid' => 'deployment-abcde',
|
||||
'deploymentname' => 'Global platform deployment',
|
||||
'id' => 45,
|
||||
'legacyconsumerkey' => null,
|
||||
],
|
||||
'expectations' => [
|
||||
'valid' => true,
|
||||
]
|
||||
],
|
||||
'Valid deployment creation, with id and legacy consumer key' => [
|
||||
'args' => [
|
||||
'registrationid' => 99,
|
||||
'deploymentid' => 'deployment-abcde',
|
||||
'deploymentname' => 'Global platform deployment',
|
||||
'id' => 45,
|
||||
'legacyconsumerkey' => '1bcb23dfff',
|
||||
],
|
||||
'expectations' => [
|
||||
'valid' => true,
|
||||
]
|
||||
],
|
||||
'Invalid deployment creation, invalid id' => [
|
||||
'args' => [
|
||||
'registrationid' => 99,
|
||||
'deploymentid' => 'deployment-abcde',
|
||||
'deploymentname' => 'Global platform deployment',
|
||||
'id' => 0,
|
||||
'legacyconsumerkey' => null,
|
||||
],
|
||||
'expectations' => [
|
||||
'valid' => false,
|
||||
'exception' => \coding_exception::class,
|
||||
'exceptionmessage' => 'id must be a positive int'
|
||||
]
|
||||
],
|
||||
'Invalid deployment creation, empty deploymentname' => [
|
||||
'args' => [
|
||||
'registrationid' => 99,
|
||||
'deploymentid' => 'deployment-abcde',
|
||||
'deploymentname' => '',
|
||||
'id' => null,
|
||||
'legacyconsumerkey' => null,
|
||||
],
|
||||
'expectations' => [
|
||||
'valid' => false,
|
||||
'exception' => \coding_exception::class,
|
||||
'exceptionmessage' => "Invalid 'deploymentname' arg. Cannot be an empty string."
|
||||
]
|
||||
],
|
||||
'Invalid deployment creation, empty deploymentid' => [
|
||||
'args' => [
|
||||
'registrationid' => 99,
|
||||
'deploymentid' => '',
|
||||
'deploymentname' => 'Global platform deployment',
|
||||
'id' => null,
|
||||
'legacyconsumerkey' => null,
|
||||
],
|
||||
'expectations' => [
|
||||
'valid' => false,
|
||||
'exception' => \coding_exception::class,
|
||||
'exceptionmessage' => "Invalid 'deploymentid' arg. Cannot be an empty string."
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Test verifying that a context can only be created from a deployment that has an id.
|
||||
*
|
||||
* @covers ::add_context
|
||||
*/
|
||||
public function test_add_context() {
|
||||
$deploymentwithid = deployment::create(123, 'deploymentid123', 'Global tool deployment', 55);
|
||||
$context = $deploymentwithid->add_context('context-id-123', ['CourseSection']);
|
||||
$this->assertInstanceOf(context::class, $context);
|
||||
$this->assertEquals(55, $context->get_deploymentid());
|
||||
|
||||
$deploymentwithoutid = deployment::create(123, 'deploymentid123', 'Global tool deployment');
|
||||
$this->expectException(\coding_exception::class);
|
||||
$this->expectExceptionMessage("Can't add context to a deployment that hasn't first been saved");
|
||||
$deploymentwithoutid->add_context('context-id-345', ['Group']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test verifying that a resource_link can only be created from a deployment that has an id.
|
||||
*
|
||||
* @covers ::add_resource_link
|
||||
*/
|
||||
public function test_add_resource_link() {
|
||||
$deploymentwithid = deployment::create(123, 'deploymentid123', 'Global tool deployment', 55);
|
||||
$resourcelink = $deploymentwithid->add_resource_link('res-link-id-123', 45);
|
||||
$this->assertInstanceOf(resource_link::class, $resourcelink);
|
||||
$this->assertEquals(55, $resourcelink->get_deploymentid());
|
||||
|
||||
$resourcelink2 = $deploymentwithid->add_resource_link('res-link-id-456', 45, 66);
|
||||
$this->assertEquals(66, $resourcelink2->get_contextid());
|
||||
|
||||
$deploymentwithoutid = deployment::create(123, 'deploymentid123', 'Global tool deployment');
|
||||
$this->expectException(\coding_exception::class);
|
||||
$this->expectExceptionMessage("Can't add resource_link to a deployment that hasn't first been saved");
|
||||
$deploymentwithoutid->add_resource_link('res-link-id-123', 45);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the setter set_legacy_consumer_key.
|
||||
*
|
||||
* @covers ::set_legacy_consumer_key
|
||||
*/
|
||||
public function test_set_legacy_consumer_key() {
|
||||
$deployment = deployment::create(12, 'deploy-id-123', 'Global tool deployment');
|
||||
$deployment->set_legacy_consumer_key(str_repeat('a', 255));
|
||||
$this->assertEquals(str_repeat('a', 255), $deployment->get_legacy_consumer_key());
|
||||
|
||||
$this->expectException(\coding_exception::class);
|
||||
$this->expectExceptionMessage('Legacy consumer key too long. Cannot exceed 255 chars.');
|
||||
$deployment->set_legacy_consumer_key(str_repeat('a', 256));
|
||||
}
|
||||
}
|
@ -0,0 +1,193 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
namespace enrol_lti\local\ltiadvantage\entity;
|
||||
|
||||
use enrol_lti\local\ltiadvantage\repository\legacy_consumer_repository;
|
||||
|
||||
/**
|
||||
* Tests for migration_claim.
|
||||
*
|
||||
* @package enrol_lti
|
||||
* @copyright 2021 Jake Dallimore <jrhdallimore@gmail.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @coversDefaultClass \enrol_lti\local\ltiadvantage\entity\migration_claim
|
||||
*/
|
||||
class migration_claim_test extends \advanced_testcase {
|
||||
/**
|
||||
* Setup run for each test case.
|
||||
*/
|
||||
protected function setUp(): void {
|
||||
$this->resetAfterTest();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a stub legacy_consumer_repository, allowing tests to verify claims using a predefined secret.
|
||||
*/
|
||||
protected function get_stub_legacy_consumer_repo() {
|
||||
$mockedlegacyconsumerrepo = $this->createStub(legacy_consumer_repository::class);
|
||||
$mockedlegacyconsumerrepo->method('get_consumer_secrets')
|
||||
->willReturn(['consumer_secret']);
|
||||
return $mockedlegacyconsumerrepo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test instantiation and getters of the migration_claim.
|
||||
*
|
||||
* @dataProvider migration_claim_provider
|
||||
* @param array $migrationclaimdata the lti1p1 migration claim.
|
||||
* @param string $deploymentid string id of the tool deployment.
|
||||
* @param string $platform string url of the issuer.
|
||||
* @param string $clientid string id of the client.
|
||||
* @param string $exp expiry time.
|
||||
* @param string $nonce nonce.
|
||||
* @param legacy_consumer_repository $legacyconsumerrepo legacy consumer repo instance.
|
||||
* @param array $expected array containing expectation data.
|
||||
* @covers ::__construct
|
||||
*/
|
||||
public function test_migration_claim(array $migrationclaimdata, string $deploymentid, string $platform,
|
||||
string $clientid, string $exp, string $nonce, legacy_consumer_repository $legacyconsumerrepo,
|
||||
array $expected) {
|
||||
|
||||
if (!empty($expected['exception'])) {
|
||||
$this->expectException($expected['exception']);
|
||||
$this->expectExceptionMessage($expected['exceptionmessage']);
|
||||
new migration_claim($migrationclaimdata, $deploymentid, $platform, $clientid, $exp, $nonce,
|
||||
$legacyconsumerrepo);
|
||||
} else {
|
||||
$migrationclaim = new migration_claim($migrationclaimdata, $deploymentid, $platform, $clientid, $exp,
|
||||
$nonce, $legacyconsumerrepo);
|
||||
$this->assertInstanceOf(migration_claim::class, $migrationclaim);
|
||||
$this->assertEquals($expected['user_id'], $migrationclaim->get_user_id());
|
||||
$this->assertEquals($expected['context_id'], $migrationclaim->get_context_id());
|
||||
$this->assertEquals($expected['tool_consumer_instance_guid'],
|
||||
$migrationclaim->get_tool_consumer_instance_guid());
|
||||
$this->assertEquals($expected['resource_link_id'], $migrationclaim->get_resource_link_id());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider testing migration_claim instantiation.
|
||||
*
|
||||
* @return array[] the test case data.
|
||||
*/
|
||||
public function migration_claim_provider(): array {
|
||||
// Note: See https://www.imsglobal.org/spec/lti/v1p3/migr#lti-1-1-migration-claim for details regarding the
|
||||
// correct generation of oauth_consumer_key_sign signature.
|
||||
return [
|
||||
'Invalid - missing oauth_consumer_key' => [
|
||||
'lti1p1migrationclaim' => [
|
||||
'oauth_consumer_key' => '',
|
||||
'oauth_consumer_key_sign' => 'abcd',
|
||||
],
|
||||
'deploymentid' => 'D12345',
|
||||
'platform' => 'https://lms.example.org/',
|
||||
'clientid' => 'a1b2c3d4',
|
||||
'exp' => '1622612930',
|
||||
'nonce' => 'j45j2j5nnjn24544',
|
||||
new legacy_consumer_repository(),
|
||||
'expected' => [
|
||||
'exception' => \coding_exception::class,
|
||||
'exceptionmessage' => "Missing 'oauth_consumer_key' property in lti1p1 migration claim."
|
||||
]
|
||||
],
|
||||
'Invalid - missing oauth_consumer_key_sign' => [
|
||||
'lti1p1migrationclaim' => [
|
||||
'oauth_consumer_key' => 'CONSUMER_1',
|
||||
'oauth_consumer_key_sign' => '',
|
||||
],
|
||||
'deploymentid' => 'D12345',
|
||||
'platform' => 'https://lms.example.org/',
|
||||
'clientid' => 'a1b2c3d4',
|
||||
'exp' => '1622612930',
|
||||
'nonce' => 'j45j2j5nnjn24544',
|
||||
new legacy_consumer_repository(),
|
||||
'expected' => [
|
||||
'exception' => \coding_exception::class,
|
||||
'exceptionmessage' => "Missing 'oauth_consumer_key_sign' property in lti1p1 migration claim."
|
||||
]
|
||||
],
|
||||
'Invalid - incorrect oauth_consumer_key_sign' => [
|
||||
'lti1p1migrationclaim' => [
|
||||
'oauth_consumer_key' => 'CONSUMER_1',
|
||||
'oauth_consumer_key_sign' => 'badsignature',
|
||||
],
|
||||
'deploymentid' => 'D12345',
|
||||
'platform' => 'https://lms.example.org/',
|
||||
'clientid' => 'a1b2c3d4',
|
||||
'exp' => '1622612930',
|
||||
'nonce' => 'j45j2j5nnjn24544',
|
||||
new legacy_consumer_repository(),
|
||||
'expected' => [
|
||||
'exception' => \coding_exception::class,
|
||||
'exceptionmessage' => "Invalid 'oauth_consumer_key_sign' signature in lti1p1 claim."
|
||||
]
|
||||
],
|
||||
'Valid - signature valid, map properties not provided' => [
|
||||
'lti1p1migrationclaim' => [
|
||||
'oauth_consumer_key' => 'CONSUMER_1',
|
||||
'oauth_consumer_key_sign' => base64_encode(
|
||||
hash_hmac(
|
||||
'sha256',
|
||||
'CONSUMER_1&D12345&https://lms.example.org/&a1b2c3d4&1622612930&j45j2j5nnjn24544',
|
||||
'consumer_secret'
|
||||
)
|
||||
),
|
||||
],
|
||||
'deploymentid' => 'D12345',
|
||||
'platform' => 'https://lms.example.org/',
|
||||
'clientid' => 'a1b2c3d4',
|
||||
'exp' => '1622612930',
|
||||
'nonce' => 'j45j2j5nnjn24544',
|
||||
$this->get_stub_legacy_consumer_repo(),
|
||||
'expected' => [
|
||||
'user_id' => null,
|
||||
'context_id' => null,
|
||||
'tool_consumer_instance_guid' => null,
|
||||
'resource_link_id' => null
|
||||
]
|
||||
],
|
||||
'Valid - signature valid, map properties are provided' => [
|
||||
'lti1p1migrationclaim' => [
|
||||
'oauth_consumer_key' => 'CONSUMER_1',
|
||||
'oauth_consumer_key_sign' => base64_encode(
|
||||
hash_hmac(
|
||||
'sha256',
|
||||
'CONSUMER_1&D12345&https://lms.example.org/&a1b2c3d4&1622612930&j45j2j5nnjn24544',
|
||||
'consumer_secret'
|
||||
)
|
||||
),
|
||||
'user_id' => '24',
|
||||
'context_id' => 'd345b',
|
||||
'tool_consumer_instance_guid' => '12345-123',
|
||||
'resource_link_id' => '4b6fa'
|
||||
],
|
||||
'deploymentid' => 'D12345',
|
||||
'platform' => 'https://lms.example.org/',
|
||||
'clientid' => 'a1b2c3d4',
|
||||
'exp' => '1622612930',
|
||||
'nonce' => 'j45j2j5nnjn24544',
|
||||
$this->get_stub_legacy_consumer_repo(),
|
||||
'expected' => [
|
||||
'user_id' => '24',
|
||||
'context_id' => 'd345b',
|
||||
'tool_consumer_instance_guid' => '12345-123',
|
||||
'resource_link_id' => '4b6fa'
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
101
enrol/lti/tests/local/ltiadvantage/entity/nrps_info_test.php
Normal file
101
enrol/lti/tests/local/ltiadvantage/entity/nrps_info_test.php
Normal file
@ -0,0 +1,101 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
namespace enrol_lti\local\ltiadvantage\entity;
|
||||
|
||||
/**
|
||||
* Tests for nrps_info.
|
||||
*
|
||||
* @package enrol_lti
|
||||
* @copyright 2021 Jake Dallimore <jrhdallimore@gmail.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @coversDefaultClass \enrol_lti\local\ltiadvantage\entity\nrps_info
|
||||
*/
|
||||
class nrps_info_test extends \advanced_testcase {
|
||||
|
||||
/**
|
||||
* Test creation of the object instances.
|
||||
*
|
||||
* @dataProvider instantiation_data_provider
|
||||
* @param array $args the arguments to the creation method.
|
||||
* @param array $expectations various expectations for the test cases.
|
||||
* @covers ::create
|
||||
*/
|
||||
public function test_create(array $args, array $expectations) {
|
||||
if (!$expectations['valid']) {
|
||||
$this->expectException($expectations['exception']);
|
||||
$this->expectExceptionMessage($expectations['exceptionmessage']);
|
||||
nrps_info::create(...array_values($args));
|
||||
} else {
|
||||
$nrpsinfo = nrps_info::create(...array_values($args));
|
||||
$this->assertEquals($args['contextmembershipsurl'], $nrpsinfo->get_context_memberships_url());
|
||||
$this->assertEquals($expectations['serviceversions'], $nrpsinfo->get_service_versions());
|
||||
$this->assertEquals('https://purl.imsglobal.org/spec/lti-nrps/scope/contextmembership.readonly',
|
||||
$nrpsinfo->get_service_scope());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for testing object instantiation.
|
||||
* @return array the data for testing.
|
||||
*/
|
||||
public function instantiation_data_provider(): array {
|
||||
return [
|
||||
'Valid creation' => [
|
||||
'args' => [
|
||||
'contextmembershipsurl' => new \moodle_url('https://lms.example.com/45/memberships'),
|
||||
'serviceversions' => ['1.0', '2.0'],
|
||||
],
|
||||
'expectations' => [
|
||||
'valid' => true,
|
||||
'serviceversions' => ['1.0', '2.0']
|
||||
]
|
||||
],
|
||||
'Missing service version' => [
|
||||
'args' => [
|
||||
'contextmembershipsurl' => new \moodle_url('https://lms.example.com/45/memberships'),
|
||||
'serviceversions' => [],
|
||||
],
|
||||
'expectations' => [
|
||||
'valid' => false,
|
||||
'exception' => \coding_exception::class,
|
||||
'exceptionmessage' => 'Service versions array cannot be empty'
|
||||
]
|
||||
],
|
||||
'Invalid service version' => [
|
||||
'args' => [
|
||||
'contextmembershipsurl' => new \moodle_url('https://lms.example.com/45/memberships'),
|
||||
'serviceversions' => ['1.1'],
|
||||
],
|
||||
'expectations' => [
|
||||
'valid' => false,
|
||||
'exception' => \coding_exception::class,
|
||||
'exceptionmessage' => "Invalid Names and Roles service version '1.1'"
|
||||
]
|
||||
],
|
||||
'Duplicate service version' => [
|
||||
'args' => [
|
||||
'contextmembershipsurl' => new \moodle_url('https://lms.example.com/45/memberships'),
|
||||
'serviceversions' => ['1.0', '1.0'],
|
||||
],
|
||||
'expectations' => [
|
||||
'valid' => true,
|
||||
'serviceversions' => ['1.0']
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
@ -0,0 +1,101 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
namespace enrol_lti\local\ltiadvantage\entity;
|
||||
|
||||
/**
|
||||
* Tests for registration_url.
|
||||
*
|
||||
* @package enrol_lti
|
||||
* @copyright 2021 Jake Dallimore <jrhdallimore@gmail.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @coversDefaultClass \enrol_lti\local\ltiadvantage\entity\registration_url
|
||||
*/
|
||||
class registration_url_test extends \advanced_testcase {
|
||||
|
||||
/**
|
||||
* Test the creation and validation of a registration_url instance.
|
||||
*
|
||||
* @dataProvider registration_url_data_provider
|
||||
* @param array $args the arguments to the constructor.
|
||||
* @param array $expectations various expectations for the test cases.
|
||||
* @covers ::__construct
|
||||
*/
|
||||
public function test_registration_url(array $args, array $expectations) {
|
||||
if ($expectations['valid']) {
|
||||
$regurl = new registration_url(...array_values($args));
|
||||
$this->assertEquals($expectations['expirytime'], $regurl->get_expiry_time());
|
||||
if (!empty($expectations['token'])) {
|
||||
$this->assertEquals($expectations['token'], $regurl->param('token'));
|
||||
} else {
|
||||
$this->assertNotEmpty($regurl->param('token'));
|
||||
}
|
||||
} else {
|
||||
$this->expectException($expectations['exception']);
|
||||
$this->expectExceptionMessage($expectations['exceptionmessage']);
|
||||
new registration_url(...array_values($args));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider used to test registration_url object creation.
|
||||
*
|
||||
* @return array the array of test data.
|
||||
*/
|
||||
public function registration_url_data_provider(): array {
|
||||
return [
|
||||
'Valid, required args only, expiry 0' => [
|
||||
'args' => [
|
||||
'expirytime' => 0
|
||||
],
|
||||
'expectations' => [
|
||||
'valid' => true,
|
||||
'expirytime' => 0,
|
||||
]
|
||||
],
|
||||
'Valid, required args only, expiry positive' => [
|
||||
'args' => [
|
||||
'expirytime' => 50
|
||||
],
|
||||
'expectations' => [
|
||||
'valid' => true,
|
||||
'expirytime' => 50,
|
||||
]
|
||||
],
|
||||
'Invalid, required args only, expiry negative' => [
|
||||
'args' => [
|
||||
'expirytime' => -70
|
||||
],
|
||||
'expectations' => [
|
||||
'valid' => false,
|
||||
'exception' => \coding_exception::class,
|
||||
'exceptionmessage' => 'Invalid registration_url expiry time. Must be greater than or equal to 0.'
|
||||
]
|
||||
],
|
||||
'Valid, all args provided' => [
|
||||
'args' => [
|
||||
'expirytime' => 56,
|
||||
'token' => 'token-abcde-12345'
|
||||
],
|
||||
'expectations' => [
|
||||
'valid' => true,
|
||||
'expirytime' => 56,
|
||||
'token' => 'token-abcde-12345'
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
199
enrol/lti/tests/local/ltiadvantage/entity/resource_link_test.php
Normal file
199
enrol/lti/tests/local/ltiadvantage/entity/resource_link_test.php
Normal file
@ -0,0 +1,199 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
namespace enrol_lti\local\ltiadvantage\entity;
|
||||
|
||||
/**
|
||||
* Tests for resource_link.
|
||||
*
|
||||
* @package enrol_lti
|
||||
* @copyright 2021 Jake Dallimore <jrhdallimore@gmail.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @coversDefaultClass \enrol_lti\local\ltiadvantage\entity\resource_link
|
||||
*/
|
||||
class resource_link_test extends \advanced_testcase {
|
||||
/**
|
||||
* Test creation of the object instances.
|
||||
*
|
||||
* @dataProvider instantiation_data_provider
|
||||
* @param array $args the arguments to the creation method.
|
||||
* @param array $expectations various expectations for the test cases.
|
||||
* @covers ::create
|
||||
*/
|
||||
public function test_create(array $args, array $expectations) {
|
||||
if (!$expectations['valid']) {
|
||||
$this->expectException($expectations['exception']);
|
||||
$this->expectExceptionMessage($expectations['exceptionmessage']);
|
||||
resource_link::create(...array_values($args));
|
||||
} else {
|
||||
$reslink = resource_link::create(...array_values($args));
|
||||
$this->assertEquals($args['resourcelinkid'], $reslink->get_resourcelinkid());
|
||||
$this->assertEquals($args['resourceid'], $reslink->get_resourceid());
|
||||
$this->assertEquals($args['deploymentid'], $reslink->get_deploymentid());
|
||||
$this->assertEquals($args['contextid'], $reslink->get_contextid());
|
||||
$this->assertEquals($args['id'], $reslink->get_id());
|
||||
$this->assertEquals(null, $reslink->get_grade_service());
|
||||
$this->assertEquals(null, $reslink->get_names_and_roles_service());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for testing object instantiation.
|
||||
* @return array the data for testing.
|
||||
*/
|
||||
public function instantiation_data_provider(): array {
|
||||
return [
|
||||
'Valid creation, no context or id provided' => [
|
||||
'args' => [
|
||||
'resourcelinkid' => 'res-link-id-123',
|
||||
'deploymentid' => 45,
|
||||
'resourceid' => 24,
|
||||
'contextid' => null,
|
||||
'id' => null
|
||||
],
|
||||
'expectations' => [
|
||||
'valid' => true
|
||||
]
|
||||
|
||||
],
|
||||
'Valid creation, context id provided, no id provided' => [
|
||||
'args' => [
|
||||
'resourcelinkid' => 'res-link-id-123',
|
||||
'deploymentid' => 45,
|
||||
'resourceid' => 24,
|
||||
'contextid' => 777,
|
||||
'id' => null
|
||||
],
|
||||
'expectations' => [
|
||||
'valid' => true
|
||||
]
|
||||
|
||||
],
|
||||
'Valid creation, context id and id provided' => [
|
||||
'args' => [
|
||||
'resourcelinkid' => 'res-link-id-123',
|
||||
'deploymentid' => 45,
|
||||
'resourceid' => 24,
|
||||
'contextid' => 777,
|
||||
'id' => 33
|
||||
],
|
||||
'expectations' => [
|
||||
'valid' => true
|
||||
]
|
||||
],
|
||||
'Invlid creation, empty resource link id string' => [
|
||||
'args' => [
|
||||
'resourcelinkid' => '',
|
||||
'deploymentid' => 45,
|
||||
'resourceid' => 24,
|
||||
'contextid' => null,
|
||||
'id' => null
|
||||
],
|
||||
'expectations' => [
|
||||
'valid' => false,
|
||||
'exception' => \coding_exception::class,
|
||||
'exceptionmessage' => 'Error: resourcelinkid cannot be an empty string'
|
||||
]
|
||||
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Test confirming that a grade service instance can be added to the object instance.
|
||||
*
|
||||
* @covers ::add_grade_service
|
||||
*/
|
||||
public function test_add_grade_service() {
|
||||
$reslink = resource_link::create('res-link-id-123', 24, 44);
|
||||
$this->assertNull($reslink->get_grade_service());
|
||||
$reslink->add_grade_service(
|
||||
new \moodle_url('https://platform.example.org/10/lineitems'),
|
||||
new \moodle_url('https://platform.example.org/10/lineitems/4/lineitem'),
|
||||
['https://purl.imsglobal.org/spec/lti-ags/scope/lineitem']
|
||||
);
|
||||
$gradeservice = $reslink->get_grade_service();
|
||||
$this->assertInstanceOf(ags_info::class, $gradeservice);
|
||||
$this->assertEquals(new \moodle_url('https://platform.example.org/10/lineitems'),
|
||||
$gradeservice->get_lineitemsurl());
|
||||
$this->assertEquals(new \moodle_url('https://platform.example.org/10/lineitems/4/lineitem'),
|
||||
$gradeservice->get_lineitemurl());
|
||||
$this->assertEquals(['https://purl.imsglobal.org/spec/lti-ags/scope/lineitem'], $gradeservice->get_scopes());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test confirming that a names and roles service instance can be added to the object instance.
|
||||
*
|
||||
* @covers ::add_names_and_roles_service
|
||||
*/
|
||||
public function test_add_names_and_roles_service() {
|
||||
$reslink = resource_link::create('res-link-id-123', 24, 44);
|
||||
$this->assertNull($reslink->get_names_and_roles_service());
|
||||
$reslink->add_names_and_roles_service(new \moodle_url('https://lms.example.com/10/memberships'), ['2.0']);
|
||||
$nrps = $reslink->get_names_and_roles_service();
|
||||
$this->assertInstanceOf(nrps_info::class, $nrps);
|
||||
$this->assertEquals(new \moodle_url('https://lms.example.com/10/memberships'),
|
||||
$nrps->get_context_memberships_url());
|
||||
$this->assertEquals(['2.0'], $nrps->get_service_versions());
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that a user can be created from a resource link that has an id.
|
||||
*
|
||||
* @covers ::add_user
|
||||
*/
|
||||
public function test_add_user() {
|
||||
$reslinkwithid = resource_link::create('res-link-id-123', 24, 44, 66, 33);
|
||||
$user = $reslinkwithid->add_user(2, 'platform-user-id-123', 'en', 'Sydney', 'AU', 'Test university', '99');
|
||||
$this->assertInstanceOf(user::class, $user);
|
||||
$this->assertEquals(33, $user->get_resourcelinkid());
|
||||
|
||||
$reslinkwithoutid = resource_link::create('res-link-id-123', 24, 44);
|
||||
$this->expectException(\coding_exception::class);
|
||||
$this->expectExceptionMessage("Can't add user to a resource_link that hasn't first been saved");
|
||||
$reslinkwithoutid->add_user(2, 'platform-user-id-123', 'en', 'Sydney', 'Australia', 'Test university', '99');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test confirming that the resourceid can be changed on the object.
|
||||
*
|
||||
* @covers ::set_resourceid
|
||||
*/
|
||||
public function test_set_resource_id() {
|
||||
$reslink = resource_link::create('res-link-id-123', 24, 44);
|
||||
$this->assertEquals(44, $reslink->get_resourceid());
|
||||
$reslink->set_resourceid(333);
|
||||
$this->assertEquals(333, $reslink->get_resourceid());
|
||||
$this->expectException(\coding_exception::class);
|
||||
$this->expectExceptionMessage('Resource id must be a positive int');
|
||||
$reslink->set_resourceid(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test confirming that the contextid can be changed on the object.
|
||||
*
|
||||
* @covers ::set_contextid
|
||||
*/
|
||||
public function test_set_context_id() {
|
||||
$reslink = resource_link::create('res-link-id-123', 24, 44);
|
||||
$this->assertEquals(null, $reslink->get_contextid());
|
||||
$reslink->set_contextid(333);
|
||||
$this->assertEquals(333, $reslink->get_contextid());
|
||||
$this->expectException(\coding_exception::class);
|
||||
$this->expectExceptionMessage('Context id must be a positive int');
|
||||
$reslink->set_contextid(0);
|
||||
}
|
||||
}
|
707
enrol/lti/tests/local/ltiadvantage/entity/user_test.php
Normal file
707
enrol/lti/tests/local/ltiadvantage/entity/user_test.php
Normal file
@ -0,0 +1,707 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
namespace enrol_lti\local\ltiadvantage\entity;
|
||||
|
||||
/**
|
||||
* Tests for user.
|
||||
*
|
||||
* @package enrol_lti
|
||||
* @copyright 2021 Jake Dallimore <jrhdallimore@gmail.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @coversDefaultClass \enrol_lti\local\ltiadvantage\entity\user
|
||||
*/
|
||||
class user_test extends \advanced_testcase {
|
||||
|
||||
/**
|
||||
* Test creation of a user instance using the factory method.
|
||||
*
|
||||
* @dataProvider create_data_provider
|
||||
* @param array $args the arguments to the creation method.
|
||||
* @param array $expectations various expectations for the test cases.
|
||||
* @covers ::create
|
||||
*/
|
||||
public function test_create(array $args, array $expectations) {
|
||||
if ($expectations['valid']) {
|
||||
$user = user::create(...array_values($args));
|
||||
$this->assertInstanceOf(user::class, $user);
|
||||
$this->assertEquals($expectations['id'], $user->get_id());
|
||||
$this->assertEquals($expectations['localid'], $user->get_localid());
|
||||
$this->assertEquals($expectations['resourcelinkid'], $user->get_resourcelinkid());
|
||||
$this->assertEquals($expectations['resourceid'], $user->get_resourceid());
|
||||
$this->assertEquals($expectations['deploymentid'], $user->get_deploymentid());
|
||||
$this->assertEquals($expectations['sourceid'], $user->get_sourceid());
|
||||
$this->assertEquals($expectations['lang'], $user->get_lang());
|
||||
$this->assertEquals($expectations['timezone'], $user->get_timezone());
|
||||
$this->assertEquals($expectations['city'], $user->get_city());
|
||||
$this->assertEquals($expectations['country'], $user->get_country());
|
||||
$this->assertEquals($expectations['institution'], $user->get_institution());
|
||||
$this->assertEquals($expectations['maildisplay'], $user->get_maildisplay());
|
||||
$this->assertEquals($expectations['lastgrade'], $user->get_lastgrade());
|
||||
$this->assertEquals($expectations['lastaccess'], $user->get_lastaccess());
|
||||
} else {
|
||||
$this->expectException($expectations['exception']);
|
||||
$this->expectExceptionMessage($expectations['exceptionmessage']);
|
||||
user::create(...array_values($args));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for testing the user::create() method.
|
||||
*
|
||||
* @return array the data for testing.
|
||||
*/
|
||||
public function create_data_provider(): array {
|
||||
return [
|
||||
'Valid create, only required args provided' => [
|
||||
'args' => [
|
||||
'resourceid' => 22,
|
||||
'userid' => 2,
|
||||
'deploymentid' => 33,
|
||||
'sourceid' => 'user-id-123',
|
||||
'lang' => 'en',
|
||||
'timezone' => '99'
|
||||
],
|
||||
'expectations' => [
|
||||
'valid' => true,
|
||||
'resourceid' => 22,
|
||||
'deploymentid' => 33,
|
||||
'sourceid' => 'user-id-123',
|
||||
'lang' => 'en',
|
||||
'timezone' => '99',
|
||||
'city' => '',
|
||||
'country' => '',
|
||||
'institution' => '',
|
||||
'maildisplay' => 2,
|
||||
'lastgrade' => 0.0,
|
||||
'lastaccess' => null,
|
||||
'id' => null,
|
||||
'localid' => 2,
|
||||
'resourcelinkid' => null,
|
||||
]
|
||||
],
|
||||
'Valid create, all args provided explicitly' => [
|
||||
'args' => [
|
||||
'resourceid' => 22,
|
||||
'userid' => 2,
|
||||
'deploymentid' => 33,
|
||||
'sourceid' => 'user-id-123',
|
||||
'lang' => 'en',
|
||||
'timezone' => '99',
|
||||
'city' => 'Melbourne',
|
||||
'country' => 'AU',
|
||||
'institution' => 'My institution',
|
||||
'maildisplay' => 1,
|
||||
'lastgrade' => 50.55,
|
||||
'lastaccess' => 14567888,
|
||||
'resourcelinkid' => 44,
|
||||
'id' => 22
|
||||
],
|
||||
'expectations' => [
|
||||
'valid' => true,
|
||||
'resourceid' => 22,
|
||||
'deploymentid' => 33,
|
||||
'sourceid' => 'user-id-123',
|
||||
'lang' => 'en',
|
||||
'timezone' => '99',
|
||||
'city' => 'Melbourne',
|
||||
'country' => 'AU',
|
||||
'institution' => 'My institution',
|
||||
'maildisplay' => 1,
|
||||
'lastgrade' => 50.55,
|
||||
'lastaccess' => 14567888,
|
||||
'resourcelinkid' => 44,
|
||||
'localid' => 2,
|
||||
'id' => 22,
|
||||
]
|
||||
],
|
||||
'Valid create, optional args explicitly nulled for default values' => [
|
||||
'args' => [
|
||||
'resourceid' => 22,
|
||||
'userid' => 2,
|
||||
'deploymentid' => 33,
|
||||
'sourceid' => 'user-id-123',
|
||||
'lang' => 'en',
|
||||
'timezone' => '99',
|
||||
'city' => 'Melbourne',
|
||||
'country' => 'AU',
|
||||
'institution' => 'My institution',
|
||||
'maildisplay' => null,
|
||||
'lastgrade' => null,
|
||||
'lastaccess' => null,
|
||||
'resourcelinkid' => null,
|
||||
'id' => null
|
||||
|
||||
],
|
||||
'expectations' => [
|
||||
'valid' => true,
|
||||
'resourceid' => 22,
|
||||
'deploymentid' => 33,
|
||||
'sourceid' => 'user-id-123',
|
||||
'lang' => 'en',
|
||||
'timezone' => '99',
|
||||
'city' => 'Melbourne',
|
||||
'country' => 'AU',
|
||||
'institution' => 'My institution',
|
||||
'maildisplay' => 2,
|
||||
'lastgrade' => 0.0,
|
||||
'lastaccess' => null,
|
||||
'resourcelinkid' => null,
|
||||
'localid' => 2,
|
||||
'id' => null
|
||||
]
|
||||
],
|
||||
'Invalid create, lang with bad value (fr not installed)' => [
|
||||
'args' => [
|
||||
'resourceid' => 22,
|
||||
'userid' => 2,
|
||||
'deploymentid' => 33,
|
||||
'sourceid' => 'user-id-123',
|
||||
'lang' => 'fr',
|
||||
'timezone' => '99',
|
||||
],
|
||||
'expectations' => [
|
||||
'valid' => false,
|
||||
'exception' => \coding_exception::class,
|
||||
'exceptionmessage' => "Invalid lang 'fr' provided."
|
||||
]
|
||||
],
|
||||
'Invalid create, timezone with bad value' => [
|
||||
'args' => [
|
||||
'resourceid' => 22,
|
||||
'userid' => 2,
|
||||
'deploymentid' => 33,
|
||||
'sourceid' => 'user-id-123',
|
||||
'lang' => 'en',
|
||||
'timezone' => 'NOT/FOUND',
|
||||
],
|
||||
'expectations' => [
|
||||
'valid' => false,
|
||||
'exception' => \coding_exception::class,
|
||||
'exceptionmessage' => "Invalid timezone 'NOT/FOUND' provided."
|
||||
]
|
||||
],
|
||||
'Invalid create, explicitly provided country with bad value' => [
|
||||
'args' => [
|
||||
'resourceid' => 22,
|
||||
'userid' => 2,
|
||||
'deploymentid' => 33,
|
||||
'sourceid' => 'user-id-123',
|
||||
'lang' => 'en',
|
||||
'timezone' => '99',
|
||||
'city' => '',
|
||||
'country' => 'FFF',
|
||||
],
|
||||
'expectations' => [
|
||||
'valid' => false,
|
||||
'exception' => \coding_exception::class,
|
||||
'exceptionmessage' => "Invalid country code 'FFF'."
|
||||
]
|
||||
],
|
||||
'Invalid create, explicit maildisplay with bad value' => [
|
||||
'args' => [
|
||||
'resourceid' => 22,
|
||||
'userid' => 2,
|
||||
'deploymentid' => 33,
|
||||
'sourceid' => 'user-id-123',
|
||||
'lang' => 'en',
|
||||
'timezone' => '99',
|
||||
'city' => '',
|
||||
'country' => '',
|
||||
'institution' => '',
|
||||
'maildisplay' => 3,
|
||||
],
|
||||
'expectations' => [
|
||||
'valid' => false,
|
||||
'exception' => \coding_exception::class,
|
||||
'exceptionmessage' => "Invalid maildisplay value '3'. Must be in the range {0..2}."
|
||||
]
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Test creation of a user instance from a resource link.
|
||||
*
|
||||
* @dataProvider create_from_resource_link_data_provider
|
||||
* @param array $args the arguments to the creation method.
|
||||
* @param array $expectations various expectations for the test cases.
|
||||
* @covers ::create_from_resource_link
|
||||
*/
|
||||
public function test_create_from_resource_link(array $args, array $expectations) {
|
||||
if ($expectations['valid']) {
|
||||
$user = user::create_from_resource_link(...array_values($args));
|
||||
$this->assertInstanceOf(user::class, $user);
|
||||
$this->assertEquals($expectations['id'], $user->get_id());
|
||||
$this->assertEquals($expectations['localid'], $user->get_localid());
|
||||
$this->assertEquals($expectations['resourcelinkid'], $user->get_resourcelinkid());
|
||||
$this->assertEquals($expectations['resourceid'], $user->get_resourceid());
|
||||
$this->assertEquals($expectations['deploymentid'], $user->get_deploymentid());
|
||||
$this->assertEquals($expectations['sourceid'], $user->get_sourceid());
|
||||
$this->assertEquals($expectations['lang'], $user->get_lang());
|
||||
$this->assertEquals($expectations['city'], $user->get_city());
|
||||
$this->assertEquals($expectations['country'], $user->get_country());
|
||||
$this->assertEquals($expectations['institution'], $user->get_institution());
|
||||
$this->assertEquals($expectations['timezone'], $user->get_timezone());
|
||||
$this->assertEquals($expectations['maildisplay'], $user->get_maildisplay());
|
||||
$this->assertEquals($expectations['lastgrade'], $user->get_lastgrade());
|
||||
$this->assertEquals($expectations['lastaccess'], $user->get_lastaccess());
|
||||
} else {
|
||||
$this->expectException($expectations['exception']);
|
||||
$this->expectExceptionMessage($expectations['exceptionmessage']);
|
||||
user::create_from_resource_link(...array_values($args));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider used in testing the user::create_from_resource_link() method.
|
||||
*
|
||||
* @return array the data for testing.
|
||||
*/
|
||||
public function create_from_resource_link_data_provider(): array {
|
||||
return [
|
||||
'Valid creation, all args provided explicitly' => [
|
||||
'args' => [
|
||||
'resourcelinkid' => 11,
|
||||
'resourceid' => 22,
|
||||
'userid' => 2,
|
||||
'deploymentid' => 33,
|
||||
'sourceid' => 'user-id-123',
|
||||
'lang' => 'en',
|
||||
'timezone' => '99',
|
||||
'city' => 'Melbourne',
|
||||
'country' => 'AU',
|
||||
'institution' => 'platform',
|
||||
'maildisplay' => 1
|
||||
],
|
||||
'expectations' => [
|
||||
'valid' => true,
|
||||
'id' => null,
|
||||
'localid' => 2,
|
||||
'resourcelinkid' => 11,
|
||||
'resourceid' => 22,
|
||||
'deploymentid' => 33,
|
||||
'sourceid' => 'user-id-123',
|
||||
'lang' => 'en',
|
||||
'timezone' => '99',
|
||||
'city' => 'Melbourne',
|
||||
'country' => 'AU',
|
||||
'institution' => 'platform',
|
||||
'maildisplay' => 1,
|
||||
'lastgrade' => 0.0,
|
||||
'lastaccess' => null
|
||||
]
|
||||
],
|
||||
'Valid creation, only required args provided, explicit values' => [
|
||||
'args' => [
|
||||
'resourcelinkid' => 11,
|
||||
'resourceid' => 22,
|
||||
'userid' => 2,
|
||||
'deploymentid' => 33,
|
||||
'sourceid' => 'user-id-123',
|
||||
'lang' => 'en',
|
||||
'timezone' => 'UTC'
|
||||
],
|
||||
'expectations' => [
|
||||
'valid' => true,
|
||||
'id' => null,
|
||||
'localid' => 2,
|
||||
'resourcelinkid' => 11,
|
||||
'resourceid' => 22,
|
||||
'deploymentid' => 33,
|
||||
'sourceid' => 'user-id-123',
|
||||
'lang' => 'en',
|
||||
'timezone' => 'UTC',
|
||||
'city' => '',
|
||||
'country' => '',
|
||||
'institution' => '',
|
||||
'maildisplay' => 2,
|
||||
'lastgrade' => 0.0,
|
||||
'lastaccess' => null
|
||||
]
|
||||
],
|
||||
'Invalid creation, only required args provided, empty sourceid' => [
|
||||
'args' => [
|
||||
'resourcelinkid' => 11,
|
||||
'resourceid' => 22,
|
||||
'user' => 2,
|
||||
'deploymentid' => 33,
|
||||
'sourceid' => '',
|
||||
'lang' => 'en',
|
||||
'timezone' => 'UTC'
|
||||
],
|
||||
'expectations' => [
|
||||
'valid' => false,
|
||||
'exception' => \coding_exception::class,
|
||||
'exceptionmessage' => 'Invalid sourceid value. Cannot be an empty string.'
|
||||
]
|
||||
],
|
||||
'Invalid creation, only required args provided, empty lang' => [
|
||||
'args' => [
|
||||
'resourcelinkid' => 11,
|
||||
'resourceid' => 22,
|
||||
'user' => 2,
|
||||
'deploymentid' => 33,
|
||||
'sourceid' => 'user-id-123',
|
||||
'lang' => '',
|
||||
'timezone' => 'UTC'
|
||||
],
|
||||
'expectations' => [
|
||||
'valid' => false,
|
||||
'exception' => \coding_exception::class,
|
||||
'exceptionmessage' => 'Invalid lang value. Cannot be an empty string.'
|
||||
]
|
||||
],
|
||||
'Invalid creation, only required args provided, empty timezone' => [
|
||||
'args' => [
|
||||
'resourcelinkid' => 11,
|
||||
'resourceid' => 22,
|
||||
'userid' => 2,
|
||||
'deploymentid' => 33,
|
||||
'sourceid' => 'user-id-123',
|
||||
'lang' => 'en',
|
||||
'timezone' => ''
|
||||
],
|
||||
'expectations' => [
|
||||
'valid' => false,
|
||||
'exception' => \coding_exception::class,
|
||||
'exceptionmessage' => 'Invalid timezone value. Cannot be an empty string.'
|
||||
]
|
||||
],
|
||||
'Invalid creation, only required args provided, invalid lang (fr not installed)' => [
|
||||
'args' => [
|
||||
'resourcelinkid' => 11,
|
||||
'resourceid' => 22,
|
||||
'userid' => 2,
|
||||
'deploymentid' => 33,
|
||||
'sourceid' => 'user-id-123',
|
||||
'lang' => 'fr',
|
||||
'timezone' => 'UTC'
|
||||
],
|
||||
'expectations' => [
|
||||
'valid' => false,
|
||||
'exception' => \coding_exception::class,
|
||||
'exceptionmessage' => "Invalid lang 'fr' provided."
|
||||
]
|
||||
],
|
||||
'Invalid creation, only required args provided, invalid timezone' => [
|
||||
'args' => [
|
||||
'resourcelinkid' => 11,
|
||||
'resourceid' => 22,
|
||||
'userid' => 2,
|
||||
'deploymentid' => 33,
|
||||
'sourceid' => 'user-id-123',
|
||||
'lang' => 'en',
|
||||
'timezone' => 'NOT/FOUND'
|
||||
],
|
||||
'expectations' => [
|
||||
'valid' => false,
|
||||
'exception' => \coding_exception::class,
|
||||
'exceptionmessage' => "Invalid timezone 'NOT/FOUND' provided."
|
||||
]
|
||||
],
|
||||
'Invalid creation, all args provided explicitly, invalid country' => [
|
||||
'args' => [
|
||||
'resourcelinkid' => 11,
|
||||
'resourceid' => 22,
|
||||
'userid' => 2,
|
||||
'deploymentid' => 33,
|
||||
'sourceid' => 'user-id-123',
|
||||
'lang' => 'en',
|
||||
'timezone' => '99',
|
||||
'city' => 'Melbourne',
|
||||
'country' => 'FFF',
|
||||
'institution' => 'platform',
|
||||
'maildisplay' => 1
|
||||
],
|
||||
'expectations' => [
|
||||
'valid' => false,
|
||||
'exception' => \coding_exception::class,
|
||||
'exceptionmessage' => "Invalid country code 'FFF'."
|
||||
]
|
||||
],
|
||||
'Invalid creation, all args provided explicitly, invalid maildisplay' => [
|
||||
'args' => [
|
||||
'resourcelinkid' => 11,
|
||||
'resourceid' => 22,
|
||||
'userid' => 2,
|
||||
'deploymentid' => 33,
|
||||
'sourceid' => 'user-id-123',
|
||||
'lang' => 'en',
|
||||
'timezone' => '99',
|
||||
'city' => 'Melbourne',
|
||||
'country' => 'AU',
|
||||
'institution' => 'platform',
|
||||
'maildisplay' => 4
|
||||
],
|
||||
'expectations' => [
|
||||
'valid' => false,
|
||||
'exception' => \coding_exception::class,
|
||||
'exceptionmessage' => "Invalid maildisplay value '4'. Must be in the range {0..2}."
|
||||
]
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to create a simple, working user for testing.
|
||||
*
|
||||
* @return user a user instance.
|
||||
*/
|
||||
protected function create_test_user(): user {
|
||||
$args = [
|
||||
'resourcelinkid' => 11,
|
||||
'resourceid' => 22,
|
||||
'userid' => 2,
|
||||
'deploymentid' => 33,
|
||||
'sourceid' => 'user-id-123',
|
||||
'lang' => 'en',
|
||||
'timezone' => 'UTC'
|
||||
];
|
||||
return user::create_from_resource_link(...array_values($args));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test the behaviour of the user setters and getters.
|
||||
*
|
||||
* @dataProvider setters_getters_data_provider
|
||||
* @param string $methodname the name of the setter
|
||||
* @param mixed $arg the argument to the setter
|
||||
* @param array $expectations the array of expectations
|
||||
* @covers ::__construct
|
||||
*/
|
||||
public function test_setters_and_getters(string $methodname, $arg, array $expectations) {
|
||||
$user = $this->create_test_user();
|
||||
$setter = 'set_'.$methodname;
|
||||
$getter = 'get_'.$methodname;
|
||||
if ($expectations['valid']) {
|
||||
$user->$setter($arg);
|
||||
if (isset($expectations['expectedvalue'])) {
|
||||
$this->assertEquals($expectations['expectedvalue'], $user->$getter());
|
||||
} else {
|
||||
$this->assertEquals($arg, $user->$getter());
|
||||
}
|
||||
|
||||
} else {
|
||||
$this->expectException($expectations['exception']);
|
||||
$this->expectExceptionMessage($expectations['exceptionmessage']);
|
||||
$user->$setter($arg);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for testing the user object setters.
|
||||
*
|
||||
* @return array the array of test data.
|
||||
*/
|
||||
public function setters_getters_data_provider(): array {
|
||||
return [
|
||||
'Testing set_resourcelinkid with valid id' => [
|
||||
'methodname' => 'resourcelinkid',
|
||||
'arg' => 8,
|
||||
'expectations' => [
|
||||
'valid' => true,
|
||||
]
|
||||
],
|
||||
'Testing set_resourcelinkid with invalid id' => [
|
||||
'methodname' => 'resourcelinkid',
|
||||
'arg' => -1,
|
||||
'expectations' => [
|
||||
'valid' => false,
|
||||
'exception' => \coding_exception::class,
|
||||
'exceptionmessage' => "Invalid resourcelinkid '-1' provided. Must be > 0."
|
||||
]
|
||||
],
|
||||
'Testing set_city with a non-empty string' => [
|
||||
'methodname' => 'city',
|
||||
'arg' => 'Melbourne',
|
||||
'expectations' => [
|
||||
'valid' => true,
|
||||
]
|
||||
],
|
||||
'Testing set_city with an empty string' => [
|
||||
'methodname' => 'city',
|
||||
'arg' => '',
|
||||
'expectations' => [
|
||||
'valid' => true,
|
||||
]
|
||||
],
|
||||
'Testing set_country with a valid country code' => [
|
||||
'methodname' => 'country',
|
||||
'arg' => 'AU',
|
||||
'expectations' => [
|
||||
'valid' => true,
|
||||
]
|
||||
],
|
||||
'Testing set_country with an empty string' => [
|
||||
'methodname' => 'country',
|
||||
'arg' => '',
|
||||
'expectations' => [
|
||||
'valid' => true,
|
||||
]
|
||||
],
|
||||
'Testing set_country with an invalid country code' => [
|
||||
'methodname' => 'country',
|
||||
'arg' => 'FFF',
|
||||
'expectations' => [
|
||||
'valid' => false,
|
||||
'exception' => \coding_exception::class,
|
||||
'exceptionmessage' => "Invalid country code 'FFF'."
|
||||
]
|
||||
],
|
||||
'Testing set_institution with a non-empty string' => [
|
||||
'methodname' => 'institution',
|
||||
'arg' => 'Some institution',
|
||||
'expectations' => [
|
||||
'valid' => true,
|
||||
]
|
||||
],
|
||||
'Testing set_institution with an empty string' => [
|
||||
'methodname' => 'institution',
|
||||
'arg' => '',
|
||||
'expectations' => [
|
||||
'valid' => true,
|
||||
]
|
||||
],
|
||||
'Testing set_timezone with a valid real timezone' => [
|
||||
'methodname' => 'timezone',
|
||||
'arg' => 'Pacific/Wallis',
|
||||
'expectations' => [
|
||||
'valid' => true,
|
||||
]
|
||||
],
|
||||
'Testing set_timezone with a valid server timezone value' => [
|
||||
'methodname' => 'timezone',
|
||||
'arg' => '99',
|
||||
'expectations' => [
|
||||
'valid' => true,
|
||||
]
|
||||
],
|
||||
'Testing set_timezone with an invalid timezone value' => [
|
||||
'methodname' => 'timezone',
|
||||
'arg' => 'NOT/FOUND',
|
||||
'expectations' => [
|
||||
'valid' => false,
|
||||
'exception' => \coding_exception::class,
|
||||
'exceptionmessage' => "Invalid timezone 'NOT/FOUND' provided."
|
||||
]
|
||||
],
|
||||
'Testing set_maildisplay with a valid int: 0' => [
|
||||
'methodname' => 'maildisplay',
|
||||
'arg' => '0',
|
||||
'expectations' => [
|
||||
'valid' => true,
|
||||
]
|
||||
],
|
||||
'Testing set_maildisplay with a valid int: 1' => [
|
||||
'methodname' => 'maildisplay',
|
||||
'arg' => '1',
|
||||
'expectations' => [
|
||||
'valid' => true,
|
||||
]
|
||||
],
|
||||
'Testing set_maildisplay with a valid int: 2' => [
|
||||
'methodname' => 'maildisplay',
|
||||
'arg' => '1',
|
||||
'expectations' => [
|
||||
'valid' => true,
|
||||
]
|
||||
],
|
||||
'Testing set_maildisplay with invalid int' => [
|
||||
'methodname' => 'maildisplay',
|
||||
'arg' => '-1',
|
||||
'expectations' => [
|
||||
'valid' => false,
|
||||
'exception' => \coding_exception::class,
|
||||
'exceptionmessage' => "Invalid maildisplay value '-1'. Must be in the range {0..2}."
|
||||
]
|
||||
],
|
||||
'Testing set_maildisplay with invalid int' => [
|
||||
'methodname' => 'maildisplay',
|
||||
'arg' => '3',
|
||||
'expectations' => [
|
||||
'valid' => false,
|
||||
'exception' => \coding_exception::class,
|
||||
'exceptionmessage' => "Invalid maildisplay value '3'. Must be in the range {0..2}."
|
||||
]
|
||||
],
|
||||
'Testing set_lang with valid lang code' => [
|
||||
'methodname' => 'lang',
|
||||
'arg' => 'en',
|
||||
'expectations' => [
|
||||
'valid' => true,
|
||||
]
|
||||
],
|
||||
'Testing set_lang with an empty string' => [
|
||||
'methodname' => 'lang',
|
||||
'arg' => '',
|
||||
'expectations' => [
|
||||
'valid' => false,
|
||||
'exception' => \coding_exception::class,
|
||||
'exceptionmessage' => 'Invalid lang value. Cannot be an empty string.'
|
||||
]
|
||||
],
|
||||
'Testing set_lang with an empty string' => [
|
||||
'methodname' => 'lang',
|
||||
'arg' => 'ff',
|
||||
'expectations' => [
|
||||
'valid' => false,
|
||||
'exception' => \coding_exception::class,
|
||||
'exceptionmessage' => "Invalid lang 'ff' provided."
|
||||
]
|
||||
],
|
||||
'Testing set_lastgrade with valid grade' => [
|
||||
'methodname' => 'lastgrade',
|
||||
'arg' => 0.0,
|
||||
'expectations' => [
|
||||
'valid' => true
|
||||
]
|
||||
],
|
||||
'Testing set_lastgrade with valid non zero grade' => [
|
||||
'methodname' => 'lastgrade',
|
||||
'arg' => 150.0,
|
||||
'expectations' => [
|
||||
'valid' => true
|
||||
]
|
||||
],
|
||||
'Testing set_lastgrade with valid non zero long decimal grade' => [
|
||||
'methodname' => 'lastgrade',
|
||||
'arg' => 150.777779,
|
||||
'expectations' => [
|
||||
'valid' => true,
|
||||
'expectedvalue' => 150.77778
|
||||
]
|
||||
],
|
||||
'Testing set_lastaccess with valid time' => [
|
||||
'methodname' => 'lastaccess',
|
||||
'arg' => 4,
|
||||
'expectations' => [
|
||||
'valid' => true
|
||||
]
|
||||
],
|
||||
'Testing set_lastaccess with invalid time' => [
|
||||
'methodname' => 'lastaccess',
|
||||
'arg' => -1,
|
||||
'expectations' => [
|
||||
'valid' => false,
|
||||
'exception' => \coding_exception::class,
|
||||
'exceptionmessage' => 'Cannot set negative access time'
|
||||
]
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user