Improved attachment retrieval and added test cases

This commit is contained in:
lukas committed 2026-10-22 09:33:19 +00:00
1 parent 6f2fd40464
commit fde9661c2c
4 files changed
+91 -2

No files matched your search

+23 -2
View File
@@ -680,9 +680,30 @@ class ObjectRetriever implements CustomCacheAndLogInterface {
$this->putIntoCache($cacheId, $fileData, 0);
$this->logInfoWithTime('Fetched attachment <'.$filename.'> for <'.$object->getId().'> from Core API ['.$response->getStatusCode().'].', $ts);
} catch (ConnectException $e) {
// connection failed or timed out
$this->logInfoWithTime('Attachment <'.$filename.'> for <'.$object->getId().'> could not be retrieved from Core API (connection failed).', $ts);
throw new CoreAPIException($e->getMessage(), $e);
} catch (RequestException $e) {
if ($e->hasResponse() && $e->getResponse()->getStatusCode() == 404) {
// not found (404)
$this->logInfoWithTime('Attachment <'.$filename.'> for <'.$object->getId().'> not found in Core API.', $ts);
return null;
} else
if ($e->hasResponse()) {
// other API error (4xx, 5xx)
$statusCode = $e->getResponse()->getStatusCode();
$this->logInfoWithTime('Attachment <'.$filename.'> for <'.$object->getId().'> could not be retrieved from Core API ['.$statusCode.'].', $ts);
throw new CoreAPIException($e->getMessage(), $e);
} else {
// API error without response
$this->logInfoWithTime('Attachment <'.$filename.'> for <'.$object->getId().'> could not be retrieved from Core API (no status code).', $ts);
throw new CoreAPIException($e->getMessage(), $e);
}
} catch (Exception $e) {
$this->logInfoWithTime('Attachment <'.$filename.'> for <'.$object->getId().'> not found in Core API ['.$e->getResponse()->getStatusCode().'].', $ts);
// ignore exception - treat as non-existing file
// other exceptions
$this->logInfoWithTime('Attachment <'.$filename.'> for <'.$object->getId().'> could not be retrieved from Core API (unexpected exception).', $ts);
throw new CoreAPIException($e->getMessage(), $e);
}
}
@@ -115,6 +115,35 @@ class ObjectRetrieverMockTest extends \PHPUnit\Framework\TestCase {
$this->assertNull($content);
}
public function testWhenAPIThrowsErrorForAttachment() {
$this->setMockResponse(
new Response(200, ['Content-Type' => 'application/ld+json'],
'{"@id":"coid://cloudobjects.io/Test","coid://cloudobjects.io/isAtRevision":"1-abc"}'),
new Response(500)
);
$this->expectException(CoreAPIException::class);
$this->retriever->getAttachment(new IRI('coid://cloudobjects.io/Test'), 'file.txt');
}
public function testWhenAPITimesOutForAttachment() {
$this->setMockResponse(
new Response(200, ['Content-Type' => 'application/ld+json'],
'{"@id":"coid://cloudobjects.io/Test","coid://cloudobjects.io/isAtRevision":"1-abc"}'),
new ConnectException(
'cURL error 28: Operation timed out',
new Request('GET', 'cloudobjects.io')
)
);
try {
$this->retriever->getAttachment(new IRI('coid://cloudobjects.io/Test'), 'file.txt');
$this->fail('Expected CoreAPIException was not thrown.');
} catch (CoreAPIException $e) {
$this->assertInstanceOf(ConnectException::class, $e->getPrevious());
}
}
private function createFallbackStoreDirectory() : string {
$directory = sys_get_temp_dir().DIRECTORY_SEPARATOR.'clobj-fallback-'.uniqid();
mkdir($directory);
@@ -51,4 +51,34 @@ class ObjectRetrieverCacheTest extends \PHPUnit\Framework\TestCase {
$this->assertEquals($object2->getRevision(), $object3->getRevision());
}
public function testAttachmentCacheInRuntimeStorage() {
$cacheStorage = new VolatileRuntimeStorage;
$logger = new InMemoryLogger;
$coid = new IRI('coid://cloudobjects.io/Test');
$cacheId = (string)$coid.'#file.txt';
$retriever = new ObjectRetriever([
'cache_storage' => $cacheStorage,
'logger' => $logger
]);
$content1 = $retriever->getAttachment($coid, 'file.txt');
$this->assertEquals('Test file content', trim($content1));
$this->assertNotNull($cacheStorage->fetch($retriever->getCacheKey($cacheId)));
$this->assertStringContainsString('from Core API', $logger->getLastLogMessage());
// Reinitialize retriever with same cache storage to verify that cache is used
$retriever = new ObjectRetriever([
'cache_storage' => $cacheStorage,
'logger' => $logger
]);
$content2 = $retriever->getAttachment($coid, 'file.txt');
$this->assertEquals('Test file content', trim($content2));
$this->assertStringContainsString('from object cache', $logger->getLastLogMessage());
}
}
@@ -33,6 +33,15 @@ class ObjectRetrieverPublicTest extends \PHPUnit\Framework\TestCase {
$this->assertEquals('CloudObjects', $object->getProperty('http://www.w3.org/2000/01/rdf-schema#label')->getValue());
}
public function testGetTestObject() {
$coid = new IRI('coid://cloudobjects.io/Test');
$object = $this->retriever->getObjectNode($coid);
$this->assertNotNull($object);
$this->assertEquals((string)$coid, $object->getId());
$this->assertNotNull($object->getProperty('http://www.w3.org/2000/01/rdf-schema#label'));
$this->assertEquals('Test Object', $object->getProperty('http://www.w3.org/2000/01/rdf-schema#label')->getValue());
}
public function testGetRelatedObject() {
$coid = new IRI('coid://cloudobjects.io');
$object = $this->retriever->getCloudObject($coid);