Skip to content

Commit

Permalink
Merge pull request #23 from oat-sa/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
ekkinox committed Jul 28, 2021
2 parents 4c880e5 + 1221f8d commit dbdd5cc
Show file tree
Hide file tree
Showing 4 changed files with 157 additions and 39 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
CHANGELOG
=========

4.1.0
-----

* Added methods to BasicOutcomeServiceClient to work with claim
* Updated documentation

4.0.0
-----

Expand Down
42 changes: 27 additions & 15 deletions doc/tool.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,9 @@ This library provides a [BasicOutcomeServiceClient](../src/Service/Client/BasicO
- [replace result](https://www.imsglobal.org/spec/lti-bo/v1p1#replaceresult)
- [delete result](https://www.imsglobal.org/spec/lti-bo/v1p1#deleteresult)

You can use:
- `readResultForPayload()` to [read a result](https://www.imsglobal.org/spec/lti-bo/v1p1#readresult) for a received LTI message payload
- `readResult()` to [read a result](https://www.imsglobal.org/spec/lti-bo/v1p1#readresult) from a given basic outcome url and result sourced id
- `replaceResultForPayload()` to [replace a result](https://www.imsglobal.org/spec/lti-bo/v1p1#replaceresult) for a received LTI message payload, with given score and language
- `replaceResult()` to [replace a result](https://www.imsglobal.org/spec/lti-bo/v1p1#replaceresult) for a given basic outcome url, result sourced id, score and language
- `deleteResultForPayload()` to [delete a result](https://www.imsglobal.org/spec/lti-bo/v1p1#deleteresult) for a received LTI message payload
- `deleteResult()` to [delete a result](https://www.imsglobal.org/spec/lti-bo/v1p1#deleteresult) for a given basic outcome url and result sourced id

## Usage

To read a result:
### Read a result

```php
<?php
Expand All @@ -45,10 +37,16 @@ $client = new BasicOutcomeServiceCLient();

$response = $client->readResultForPayload(
$registration, // [required] as the tool, it will call the platform of this registration
$payload // [required] from the LTI message payload containing the basic outcome claim result sourced id (got at LTI launch)
$payload // [required] for the LTI message payload containing the basic outcome claim result sourced id (got at LTI launch)
);

// you also can directly read a result for a given basic outcome claim
$response = $client->readResultForClaim(
$registration, // [required] as the tool, it will call the platform of this registration
$payload->getBasicOutcome() // [required] for the basic outcome claim result sourced id (got at LTI launch)
);

// or you also can directly read a result from given URL and result sourced id (avoid claim construction)
// or you also can directly read a result from given URL and result sourced id
$response = $client->readResult(
$registration, // [required] as the tool, it will call the platform of this registration
'https://example.com/basic-outcome', // [required] to a given basic outcome service url
Expand All @@ -72,7 +70,7 @@ if ($response->isSuccess()) {
}
```

To replace a result:
### Replace a result

```php
<?php
Expand All @@ -98,7 +96,15 @@ $response = $client->replaceResultForPayload(
'en' // [optional] for a given language
);

// or you also can directly replace a result on given URL, result sourced id, score and language (avoid claim construction)
// you also can directly replace a result for a given basic outcome claim, score and language
$response = $client->replaceResultForClaim(
$registration, // [required] as the tool, it will call the platform of this registration
$payload->getBasicOutcome(), // [required] for the basic outcome claim result sourced id (got at LTI launch)
0.42, // [required] for a given score
'en' // [optional] for a given language
);

// or you also can directly replace a result on given URL, result sourced id, score and language
$response = $client->replaceResult(
$registration, // [required] as the tool, it will call the platform of this registration
'https://example.com/basic-outcome', // [required] to a given basic outcome service url
Expand All @@ -118,7 +124,7 @@ if ($response->isSuccess()) {
}
```

To delete a result:
### Delete a result

```php
<?php
Expand All @@ -142,7 +148,13 @@ $response = $client->deleteResultForPayload(
$payload // [required] for the LTI message payload containing the basic outcome claim result sourced id (got at LTI launch)
);

// or you also can directly delete a result on given URL and result sourced id (avoid claim construction)
// you also can directly delete a result for a given basic outcome claim
$response = $client->deleteResultForClaim(
$registration, // [required] as the tool, it will call the platform of this registration
$payload->getBasicOutcome() // [required] for the basic outcome claim result sourced id (got at LTI launch)
);

// or you also can directly delete a result on given URL and result sourced id
$response = $client->deleteResult(
$registration, // [required] as the tool, it will call the platform of this registration
'https://example.com/basic-outcome', // [required] to a given basic outcome service url
Expand Down
99 changes: 78 additions & 21 deletions src/Service/Client/BasicOutcomeServiceClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
use OAT\Library\Lti1p3BasicOutcome\Service\BasicOutcomeServiceInterface;
use OAT\Library\Lti1p3Core\Exception\LtiException;
use OAT\Library\Lti1p3Core\Exception\LtiExceptionInterface;
use OAT\Library\Lti1p3Core\Message\Payload\Claim\BasicOutcomeClaim;
use OAT\Library\Lti1p3Core\Message\Payload\LtiMessagePayloadInterface;
use OAT\Library\Lti1p3Core\Registration\RegistrationInterface;
use OAT\Library\Lti1p3Core\Service\Client\LtiServiceClient;
Expand Down Expand Up @@ -78,23 +79,41 @@ public function readResultForPayload(
LtiMessagePayloadInterface $payload
): BasicOutcomeResponseInterface {
try {
$basicOutcomeClaim = $payload->getBasicOutcome();
$claim = $payload->getBasicOutcome();

if (null === $basicOutcomeClaim) {
if (null === $claim) {
throw new InvalidArgumentException('Provided payload does not contain basic outcome claim');
}

return $this->readResultForClaim($registration, $claim);

} catch (Throwable $exception) {
throw new LtiException(
sprintf('Read result for payload error: %s', $exception->getMessage()),
$exception->getCode(),
$exception
);
}
}

/**
* @see https://www.imsglobal.org/spec/lti-bo/v1p1#readresult
* @throws LtiExceptionInterface
*/
public function readResultForClaim(
RegistrationInterface $registration,
BasicOutcomeClaim $claim
): BasicOutcomeResponseInterface {
try {
return $this->readResult(
$registration,
$basicOutcomeClaim->getLisOutcomeServiceUrl(),
$basicOutcomeClaim->getLisResultSourcedId()
$claim->getLisOutcomeServiceUrl(),
$claim->getLisResultSourcedId()
);

} catch (LtiExceptionInterface $exception) {
throw $exception;
} catch (Throwable $exception) {
throw new LtiException(
sprintf('Read result error for payload: %s', $exception->getMessage()),
sprintf('Read result for claim error: %s', $exception->getMessage()),
$exception->getCode(),
$exception
);
Expand Down Expand Up @@ -142,25 +161,45 @@ public function replaceResultForPayload(
string $language = 'en'
): BasicOutcomeResponseInterface {
try {
$basicOutcomeClaim = $payload->getBasicOutcome();
$claim = $payload->getBasicOutcome();

if (null === $basicOutcomeClaim) {
if (null === $claim) {
throw new InvalidArgumentException('Provided payload does not contain basic outcome claim');
}

return $this->replaceResultForClaim($registration, $claim, $score, $language);

} catch (Throwable $exception) {
throw new LtiException(
sprintf('Replace result for payload error: %s', $exception->getMessage()),
$exception->getCode(),
$exception
);
}
}

/**
* @see https://www.imsglobal.org/spec/lti-bo/v1p1#replaceresult
* @throws LtiExceptionInterface
*/
public function replaceResultForClaim(
RegistrationInterface $registration,
BasicOutcomeClaim $claim,
float $score,
string $language = 'en'
): BasicOutcomeResponseInterface {
try {
return $this->replaceResult(
$registration,
$basicOutcomeClaim->getLisOutcomeServiceUrl(),
$basicOutcomeClaim->getLisResultSourcedId(),
$claim->getLisOutcomeServiceUrl(),
$claim->getLisResultSourcedId(),
$score,
$language
);

} catch (LtiExceptionInterface $exception) {
throw $exception;
} catch (Throwable $exception) {
throw new LtiException(
sprintf('Replace result error for payload: %s', $exception->getMessage()),
sprintf('Replace result for claim error: %s', $exception->getMessage()),
$exception->getCode(),
$exception
);
Expand Down Expand Up @@ -214,23 +253,41 @@ public function deleteResultForPayload(
LtiMessagePayloadInterface $payload
): BasicOutcomeResponseInterface {
try {
$basicOutcomeClaim = $payload->getBasicOutcome();
$claim = $payload->getBasicOutcome();

if (null === $basicOutcomeClaim) {
if (null === $claim) {
throw new InvalidArgumentException('Provided payload does not contain basic outcome claim');
}

return $this->deleteResultForClaim($registration, $claim);

} catch (Throwable $exception) {
throw new LtiException(
sprintf('Delete result for payload error: %s', $exception->getMessage()),
$exception->getCode(),
$exception
);
}
}

/**
* @see https://www.imsglobal.org/spec/lti-bo/v1p1#deleteresult
* @throws LtiExceptionInterface
*/
public function deleteResultForClaim(
RegistrationInterface $registration,
BasicOutcomeClaim $claim
): BasicOutcomeResponseInterface {
try {
return $this->deleteResult(
$registration,
$basicOutcomeClaim->getLisOutcomeServiceUrl(),
$basicOutcomeClaim->getLisResultSourcedId()
$claim->getLisOutcomeServiceUrl(),
$claim->getLisResultSourcedId()
);

} catch (LtiExceptionInterface $exception) {
throw $exception;
} catch (Throwable $exception) {
throw new LtiException(
sprintf('Delete result error for payload: %s', $exception->getMessage()),
sprintf('Delete result for claim error: %s', $exception->getMessage()),
$exception->getCode(),
$exception
);
Expand Down
49 changes: 46 additions & 3 deletions tests/Unit/Service/Client/BasicOutcomeServiceClientTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
use OAT\Library\Lti1p3Core\Message\Payload\Builder\MessagePayloadBuilder;
use OAT\Library\Lti1p3Core\Message\Payload\Claim\BasicOutcomeClaim;
use OAT\Library\Lti1p3Core\Message\Payload\LtiMessagePayload;
use OAT\Library\Lti1p3Core\Message\Payload\MessagePayload;
use OAT\Library\Lti1p3Core\Registration\RegistrationInterface;
use OAT\Library\Lti1p3Core\Service\Client\LtiServiceClientInterface;
use OAT\Library\Lti1p3Core\Tests\Traits\DomainTestingTrait;
Expand Down Expand Up @@ -127,7 +128,7 @@ public function testReadResultForPayloadSuccess(): void
public function testReadResultForPayloadFailure(): void
{
$this->expectException(LtiExceptionInterface::class);
$this->expectExceptionMessage('Read result error for payload: Provided payload does not contain basic outcome claim');
$this->expectExceptionMessage('Read result for payload error: Provided payload does not contain basic outcome claim');

$registration = $this->createTestRegistration();

Expand Down Expand Up @@ -159,6 +160,20 @@ public function testReadResultForPayloadClientFailure(): void
$this->subject->readResultForPayload($registration, $payload);
}

public function testReadResultForClaimClientFailure(): void
{
$this->expectException(LtiExceptionInterface::class);
$this->expectExceptionMessage('Read result for claim error: Read result error: Cannot send basic outcome: custom error');

$registration = $this->createTestRegistration();

$claim = new BasicOutcomeClaim('sourcedId', 'http://platform.com/basic-outcome');

$this->prepareClientMockForFailure();

$this->subject->readResultForClaim($registration, $claim);
}

public function testReadResultSuccess(): void
{
$registration = $this->createTestRegistration();
Expand Down Expand Up @@ -265,7 +280,7 @@ public function testReplaceResultForPayloadSuccess(): void
public function testReplaceResultForPayloadFailure(): void
{
$this->expectException(LtiExceptionInterface::class);
$this->expectExceptionMessage('Replace result error for payload: Provided payload does not contain basic outcome claim');
$this->expectExceptionMessage('Replace result for payload error: Provided payload does not contain basic outcome claim');

$registration = $this->createTestRegistration();

Expand Down Expand Up @@ -297,6 +312,20 @@ public function testReplaceResultForPayloadClientFailure(): void
$this->subject->replaceResultForPayload($registration, $payload, 0.42, 'en');
}

public function testReplaceResultForClaimClientFailure(): void
{
$this->expectException(LtiExceptionInterface::class);
$this->expectExceptionMessage('Replace result for claim error: Replace result error: Cannot send basic outcome: custom error');

$registration = $this->createTestRegistration();

$claim = new BasicOutcomeClaim('sourcedId', 'http://platform.com/basic-outcome');

$this->prepareClientMockForFailure();

$this->subject->replaceResultForClaim($registration, $claim, 0.42, 'en');
}

public function testReplaceResultSuccess(): void
{
$registration = $this->createTestRegistration();
Expand Down Expand Up @@ -407,7 +436,7 @@ public function testDeleteResultForPayloadSuccess(): void
public function testDeleteResultForPayloadFailure(): void
{
$this->expectException(LtiExceptionInterface::class);
$this->expectExceptionMessage('Delete result error for payload: Provided payload does not contain basic outcome claim');
$this->expectExceptionMessage('Delete result for payload error: Provided payload does not contain basic outcome claim');

$registration = $this->createTestRegistration();

Expand Down Expand Up @@ -439,6 +468,20 @@ public function testDeleteResultForPayloadClientFailure(): void
$this->subject->deleteResultForPayload($registration, $payload);
}

public function testDeleteResultForClaimClientFailure(): void
{
$this->expectException(LtiExceptionInterface::class);
$this->expectExceptionMessage('Delete result for claim error: Delete result error: Cannot send basic outcome: custom error');

$registration = $this->createTestRegistration();

$claim = new BasicOutcomeClaim('sourcedId', 'http://platform.com/basic-outcome');

$this->prepareClientMockForFailure();

$this->subject->deleteResultForClaim($registration, $claim);
}

public function testDeleteResultSuccess(): void
{
$registration = $this->createTestRegistration();
Expand Down

0 comments on commit dbdd5cc

Please sign in to comment.