Added fallback store feature
This commit is contained in:
1 parent
b3c810473f
commit
d3741e03ba
5 files changed
+408
-13
No files matched your search
@@ -9,7 +9,7 @@ namespace CloudObjects\SDK;
|
||||
use ML\IRI\IRI;
|
||||
use GuzzleHttp\Client, GuzzleHttp\Handler\MockHandler,
|
||||
GuzzleHttp\HandlerStack, GuzzleHttp\Psr7\Request, GuzzleHttp\Psr7\Response;
|
||||
use GuzzleHttp\Exception\ConnectException;
|
||||
use GuzzleHttp\Exception\ConnectException, GuzzleHttp\Exception\RequestException;
|
||||
use CloudObjects\SDK\Exceptions\CoreAPIException;
|
||||
|
||||
class ObjectRetrieverMockTest extends \PHPUnit\Framework\TestCase {
|
||||
@@ -90,4 +90,180 @@ class ObjectRetrieverMockTest extends \PHPUnit\Framework\TestCase {
|
||||
}
|
||||
}
|
||||
|
||||
private function createFallbackStoreDirectory() : string {
|
||||
$directory = sys_get_temp_dir().DIRECTORY_SEPARATOR.'clobj-fallback-'.uniqid();
|
||||
mkdir($directory);
|
||||
return $directory;
|
||||
}
|
||||
|
||||
private function removeDirectory(string $directory) {
|
||||
$files = new \RecursiveIteratorIterator(
|
||||
new \RecursiveDirectoryIterator($directory, \FilesystemIterator::SKIP_DOTS),
|
||||
\RecursiveIteratorIterator::CHILD_FIRST
|
||||
);
|
||||
foreach ($files as $file)
|
||||
$file->isDir() ? rmdir($file->getPathname()) : unlink($file->getPathname());
|
||||
rmdir($directory);
|
||||
}
|
||||
|
||||
public function testFallbackStoreSavesObjectInScope() {
|
||||
$directory = $this->createFallbackStoreDirectory();
|
||||
$this->retriever = new ObjectRetriever([
|
||||
'fallback_store_directory' => $directory,
|
||||
'fallback_store_scope' => 'example.com, cloudobjects.io',
|
||||
]);
|
||||
$body = '{"@id":"coid://cloudobjects.io/Test","http://www.w3.org/2000/01/rdf-schema#label":"Test"}';
|
||||
$this->setMockResponse(new Response(200, ['Content-Type' => 'application/ld+json'], $body));
|
||||
|
||||
try {
|
||||
$this->retriever->getObjectNode(new IRI('coid://cloudobjects.io/Test'));
|
||||
|
||||
$location = $directory.'/cloudobjects.io/Test/object.jsonld';
|
||||
$this->assertFileExists($location);
|
||||
$this->assertEquals($body, file_get_contents($location));
|
||||
} finally {
|
||||
$this->removeDirectory($directory);
|
||||
}
|
||||
}
|
||||
|
||||
public function testFallbackStoreSkipsObjectOutOfScope() {
|
||||
$directory = $this->createFallbackStoreDirectory();
|
||||
$this->retriever = new ObjectRetriever([
|
||||
'fallback_store_directory' => $directory,
|
||||
'fallback_store_scope' => [ 'example.com' ],
|
||||
]);
|
||||
$this->setMockResponse(new Response(200, ['Content-Type' => 'application/ld+json'],
|
||||
'{"@id":"coid://cloudobjects.io/Test"}'));
|
||||
|
||||
try {
|
||||
$this->retriever->getObjectNode(new IRI('coid://cloudobjects.io/Test'));
|
||||
$this->assertFileDoesNotExist($directory.'/cloudobjects.io/Test/object.jsonld');
|
||||
} finally {
|
||||
$this->removeDirectory($directory);
|
||||
}
|
||||
}
|
||||
|
||||
public function testFallbackStoreSavesAllObjectsWithWildcard() {
|
||||
$directory = $this->createFallbackStoreDirectory();
|
||||
$this->retriever = new ObjectRetriever([
|
||||
'fallback_store_directory' => $directory,
|
||||
'fallback_store_scope' => '*',
|
||||
]);
|
||||
$this->setMockResponse(new Response(200, ['Content-Type' => 'application/ld+json'],
|
||||
'{"@id":"coid://cloudobjects.io"}'));
|
||||
|
||||
try {
|
||||
$this->retriever->getObjectNode(new IRI('coid://cloudobjects.io'));
|
||||
$this->assertFileExists($directory.'/cloudobjects.io/object.jsonld');
|
||||
} finally {
|
||||
$this->removeDirectory($directory);
|
||||
}
|
||||
}
|
||||
|
||||
private function createRetrieverWithStoredObject(string $directory) {
|
||||
$this->retriever = new ObjectRetriever([
|
||||
'fallback_store_directory' => $directory,
|
||||
'fallback_store_scope' => '*',
|
||||
]);
|
||||
mkdir($directory.'/cloudobjects.io/Test', 0777, true);
|
||||
file_put_contents($directory.'/cloudobjects.io/Test/object.jsonld',
|
||||
'{"@id":"coid://cloudobjects.io/Test","http://www.w3.org/2000/01/rdf-schema#label":"Stored"}');
|
||||
}
|
||||
|
||||
public function testFallbackStoreUsedWhenAPIReturns500() {
|
||||
$directory = $this->createFallbackStoreDirectory();
|
||||
$this->createRetrieverWithStoredObject($directory);
|
||||
$this->setMockResponse(new Response(500));
|
||||
|
||||
try {
|
||||
$object = $this->retriever->getObjectNode(new IRI('coid://cloudobjects.io/Test'));
|
||||
$this->assertNotNull($object);
|
||||
$this->assertEquals('Stored', $object->getProperty('http://www.w3.org/2000/01/rdf-schema#label')->getValue());
|
||||
} finally {
|
||||
$this->removeDirectory($directory);
|
||||
}
|
||||
}
|
||||
|
||||
public function testFallbackStoreUsedWhenAPITimesOut() {
|
||||
$directory = $this->createFallbackStoreDirectory();
|
||||
$this->createRetrieverWithStoredObject($directory);
|
||||
$this->setMockResponse(new ConnectException(
|
||||
'cURL error 28: Operation timed out',
|
||||
new Request('GET', 'cloudobjects.io')
|
||||
));
|
||||
|
||||
try {
|
||||
$object = $this->retriever->getObjectNode(new IRI('coid://cloudobjects.io/Test'));
|
||||
$this->assertNotNull($object);
|
||||
$this->assertEquals('Stored', $object->getProperty('http://www.w3.org/2000/01/rdf-schema#label')->getValue());
|
||||
} finally {
|
||||
$this->removeDirectory($directory);
|
||||
}
|
||||
}
|
||||
|
||||
public function testFallbackStoreUsedWhenRequestFailsWithoutResponse() {
|
||||
$directory = $this->createFallbackStoreDirectory();
|
||||
$this->createRetrieverWithStoredObject($directory);
|
||||
$this->setMockResponse(new RequestException(
|
||||
'Request failed',
|
||||
new Request('GET', 'cloudobjects.io')
|
||||
));
|
||||
|
||||
try {
|
||||
$object = $this->retriever->getObjectNode(new IRI('coid://cloudobjects.io/Test'));
|
||||
$this->assertNotNull($object);
|
||||
$this->assertEquals('Stored', $object->getProperty('http://www.w3.org/2000/01/rdf-schema#label')->getValue());
|
||||
} finally {
|
||||
$this->removeDirectory($directory);
|
||||
}
|
||||
}
|
||||
|
||||
public function testErrorWhenRequestFailsWithoutResponseAndObjectNotInFallbackStore() {
|
||||
$directory = $this->createFallbackStoreDirectory();
|
||||
$this->retriever = new ObjectRetriever([
|
||||
'fallback_store_directory' => $directory,
|
||||
'fallback_store_scope' => '*',
|
||||
]);
|
||||
$this->setMockResponse(new RequestException(
|
||||
'Request failed',
|
||||
new Request('GET', 'cloudobjects.io')
|
||||
));
|
||||
|
||||
try {
|
||||
$this->expectException(CoreAPIException::class);
|
||||
$this->retriever->getObjectNode(new IRI('coid://cloudobjects.io/Test'));
|
||||
} finally {
|
||||
$this->removeDirectory($directory);
|
||||
}
|
||||
}
|
||||
|
||||
public function testFallbackStoreNotUsedOnClientError() {
|
||||
$directory = $this->createFallbackStoreDirectory();
|
||||
$this->createRetrieverWithStoredObject($directory);
|
||||
$this->setMockResponse(new Response(403));
|
||||
|
||||
try {
|
||||
$this->expectException(CoreAPIException::class);
|
||||
$this->retriever->getObjectNode(new IRI('coid://cloudobjects.io/Test'));
|
||||
} finally {
|
||||
$this->removeDirectory($directory);
|
||||
}
|
||||
}
|
||||
|
||||
public function testErrorWhenAPIThrowsErrorAndObjectNotInFallbackStore() {
|
||||
$directory = $this->createFallbackStoreDirectory();
|
||||
$this->retriever = new ObjectRetriever([
|
||||
'fallback_store_directory' => $directory,
|
||||
'fallback_store_scope' => '*',
|
||||
]);
|
||||
$this->setMockResponse(new Response(500));
|
||||
|
||||
try {
|
||||
$this->expectException(CoreAPIException::class);
|
||||
$this->retriever->getObjectNode(new IRI('coid://cloudobjects.io/Test'));
|
||||
} finally {
|
||||
$this->removeDirectory($directory);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
namespace CloudObjects\SDK;
|
||||
|
||||
use CloudObjects\SDK\Exceptions\InvalidSDKConfigurationException;
|
||||
|
||||
class ObjectRetrieverTest extends \PHPUnit\Framework\TestCase {
|
||||
|
||||
public function testFallbackStoreWithExistingDirectory() {
|
||||
$retriever = new ObjectRetriever([
|
||||
'fallback_store_directory' => sys_get_temp_dir(),
|
||||
'fallback_store_scope' => '*',
|
||||
]);
|
||||
$this->assertInstanceOf(ObjectRetriever::class, $retriever);
|
||||
}
|
||||
|
||||
public function testFallbackStoreWithMissingDirectory() {
|
||||
$this->expectException(InvalidSDKConfigurationException::class);
|
||||
new ObjectRetriever([
|
||||
'fallback_store_directory' => sys_get_temp_dir().'/does-not-exist-'.uniqid(),
|
||||
'fallback_store_scope' => '*',
|
||||
]);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in new issue
Block a user