diff --git a/src/DataPersister/FileDataDataPersister.php b/src/DataPersister/FileDataDataPersister.php index c68d8294fbbde3adbd61b5aec9759970499cf77f..165b856b7f082a811b5302e07c63b179038eca1d 100644 --- a/src/DataPersister/FileDataDataPersister.php +++ b/src/DataPersister/FileDataDataPersister.php @@ -64,6 +64,8 @@ class FileDataDataPersister extends AbstractController implements ContextAwareDa public function remove($data, array $context = []): void { // no need to check, because signature is checked by getting the data +// $i = $data->getIdentifier(); +// echo " FileDataPersister::remove(identifier: $i)\n"; assert($data instanceof FileData); diff --git a/src/DataProvider/FileDataDataProvider.php b/src/DataProvider/FileDataDataProvider.php index 427f34163d0fabdae9cc3290bc306f93affa8ba6..1062b029d2de094369e17a8c762fe7b60f6987e7 100644 --- a/src/DataProvider/FileDataDataProvider.php +++ b/src/DataProvider/FileDataDataProvider.php @@ -53,6 +53,7 @@ class FileDataDataProvider extends AbstractDataProvider protected function getFileDataById($id, array $filters): object { +// echo " FileDataProvider::getFileDataById($id, filters)\n"; $sig = $this->requestStack->getCurrentRequest()->headers->get('x-dbp-signature', ''); if (!$sig) { throw ApiError::withDetails(Response::HTTP_UNAUTHORIZED, 'Signature missing', 'blob:createFileData-missing-sig'); @@ -77,8 +78,10 @@ class FileDataDataProvider extends AbstractDataProvider } $fileData = $this->blobService->setBucket($fileData); - $fileData = $this->blobService->getLink($fileData); - $this->blobService->saveFileData($fileData); + if ($this->requestStack->getCurrentRequest()->getMethod() !== 'DELETE') { + $fileData = $this->blobService->getLink($fileData); + $this->blobService->saveFileData($fileData); + } return $fileData; } @@ -120,7 +123,7 @@ class FileDataDataProvider extends AbstractDataProvider assert($fileData instanceof FileData); $fileData->setBucket($bucket); $fileData = $this->blobService->getLink($fileData); - $this->blobService->saveFileData($fileData); +// $this->blobService->saveFileData($fileData); } return $fileDatas; @@ -149,10 +152,12 @@ class FileDataDataProvider extends AbstractDataProvider // check if signed params aer equal to request params if ($data['bucketID'] !== $bucketId) { + /** @noinspection ForgottenDebugOutputInspection */ dump($data['bucketID'], $bucketId); throw ApiError::withDetails(Response::HTTP_FORBIDDEN, 'BucketId change forbidden', 'blob:bucketid-change-forbidden'); } if ((int) $data['creationTime'] !== (int) $creationTime) { + /** @noinspection ForgottenDebugOutputInspection */ dump($data['creationTime'], $creationTime); throw ApiError::withDetails(Response::HTTP_FORBIDDEN, 'Creation Time change forbidden', 'blob:creationtime-change-forbidden'); } diff --git a/src/Entity/FileData.php b/src/Entity/FileData.php index 4131899bdc1fc6ee7ba16b929e9f14442beb2201..8310e6d6e305b789a457632c40c700927e3af912 100644 --- a/src/Entity/FileData.php +++ b/src/Entity/FileData.php @@ -112,10 +112,15 @@ use Symfony\Component\Serializer\Annotation\Groups; * }, * }, * "delete" = { + * "method" = "DELETE", * "path" = "/blob/files/{identifier}", * "openapi_context" = { * "tags" = {"Blob"}, * }, + * "denormalization_context" = { + * "jsonld_embed_context" = true, + * "groups" = {"BlobFiles:exists"} + * }, * } * }, * iri="https://schema.org/DigitalDocument", diff --git a/src/Service/BlobService.php b/src/Service/BlobService.php index 55a7edb61fb9719e86fcb2b67feec51117b4c244..ad36f8c8bce6c841263254cd2d66c7b9f4182739 100644 --- a/src/Service/BlobService.php +++ b/src/Service/BlobService.php @@ -58,9 +58,16 @@ class BlobService public function createFileData(Request $request): FileData { - $fileData = new FileData(); - - $fileData->setIdentifier((string) Uuid::v4()); + echo " BlobService::createFileData()\n"; + + if ($identifier = $request->get('identifier')) { + $fileData = $this->em->find(FileData::class, $identifier); + echo " load from store.\n"; + } else { + $fileData = new FileData(); + $fileData->setIdentifier((string)Uuid::v4()); + echo " create new.\n"; + } /** @var ?UploadedFile $uploadedFile */ $uploadedFile = $request->files->get('file'); @@ -132,12 +139,16 @@ class BlobService $this->em->persist($fileData); $this->em->flush(); } catch (\Exception $e) { + echo " error: {$e->getMessage()}\n"; + echo " fileData =" . print_r($fileData, true)."\n"; throw ApiError::withDetails(Response::HTTP_INTERNAL_SERVER_ERROR, 'File could not be saved!', 'blob:file-not-saved', ['message' => $e->getMessage()]); } } public function saveFile(FileData $fileData): ?FileData { + $i = $fileData->getIdentifier(); + echo " BlobService::saveFile(identifier: $i)\n"; $datasystemService = $this->datasystemService->getServiceByBucket($fileData->getBucket()); $fileData = $datasystemService->saveFile($fileData); @@ -154,6 +165,7 @@ class BlobService public function getFileData(string $identifier): FileData { + echo " BlobService::getFileData($identifier)\n"; /** @var FileData $fileData */ $fileData = $this->em ->getRepository(FileData::class) @@ -168,6 +180,7 @@ class BlobService public function getFileDataByBucketIDAndPrefix(string $bucketID, string $prefix): array { + echo " BlobService::getFileDataByBucketIDAndPrefix($bucketID, $prefix)\n"; $fileDatas = $this->em ->getRepository(FileData::class) ->findBy(['bucketID' => $bucketID, 'prefix' => $prefix]); @@ -228,6 +241,8 @@ class BlobService public function removeFileData(FileData $fileData) { +// $i = $fileData->getIdentifier(); +// echo " BlobService::removeFileData(identifier: {$i})\n"; $datasystemService = $this->datasystemService->getServiceByBucket($fileData->getBucket()); $datasystemService->removeFile($fileData); diff --git a/src/Service/DatasystemProviderServiceInterface.php b/src/Service/DatasystemProviderServiceInterface.php index 537983516d826894bd3d70fac6db2b74abd85344..80aa0925931deb54530d8e588982e7e1671863d7 100644 --- a/src/Service/DatasystemProviderServiceInterface.php +++ b/src/Service/DatasystemProviderServiceInterface.php @@ -9,11 +9,11 @@ use Dbp\Relay\BlobBundle\Helper\PoliciesStruct; interface DatasystemProviderServiceInterface { - public function saveFile(FileData &$fileData): ?FileData; + public function saveFile(FileData $fileData): ?FileData; - public function renameFile(FileData &$fileData): ?FileData; + public function renameFile(FileData $fileData): ?FileData; - public function getLink(FileData &$fileData, PoliciesStruct $policiesStruct): ?FileData; + public function getLink(FileData $fileData, PoliciesStruct $policiesStruct): ?FileData; - public function removeFile(FileData &$fileData): bool; + public function removeFile(FileData $fileData): bool; } diff --git a/tests/CurlGetTest.php b/tests/CurlGetTest.php index 29f24b1b2b3dbbe11048c17110d53260041ad78d..7e086d36a05d415285641e831155074a6abc37ec 100644 --- a/tests/CurlGetTest.php +++ b/tests/CurlGetTest.php @@ -12,33 +12,54 @@ use Dbp\Relay\BlobBundle\Service\BlobService; use Dbp\Relay\BlobBundle\Service\ConfigurationService; use Dbp\Relay\BlobBundle\Service\DatasystemProviderServiceInterface; use Dbp\Relay\CoreBundle\TestUtils\UserAuthTrait; +use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\Tools\SchemaTool; use Exception; use Symfony\Component\HttpFoundation\File\UploadedFile; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\HttpKernel\KernelInterface; +use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface; +use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface; +use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface; +use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface; use function uuid_is_valid; class DummyFileSystemService implements DatasystemProviderServiceInterface { - public function saveFile(FileData &$fileData): ?FileData + static $fd = []; + static $data = []; + + public function saveFile(FileData $fileData): ?FileData { + self::$fd[$fileData->getIdentifier()] = $fileData; + self::$data[$fileData->getIdentifier()] = $fileData->getFile(); + return $fileData; } - public function renameFile(FileData &$fileData): ?FileData + public function renameFile(FileData $fileData): ?FileData { + self::$fd[$fileData->getIdentifier()] = $fileData; + return $fileData; } - public function getLink(FileData &$fileData, PoliciesStruct $policiesStruct): ?FileData + public function getLink(FileData $fileData, PoliciesStruct $policiesStruct): ?FileData { - return $fileData; + $identifier = $fileData->getIdentifier(); + if(!isset(self::$fd[$identifier])) { + echo " DummyFileSystemService::getLink($identifier): not found!\n"; + return null; + } + + return self::$fd[$identifier]; } - public function removeFile(FileData &$fileData): bool + public function removeFile(FileData $fileData): bool { + unset(self::$fd[$fileData->getIdentifier()]); + unset(self::$data[$fileData->getIdentifier()]); + return true; } } @@ -47,15 +68,18 @@ class CurlGetTest extends ApiTestCase { use UserAuthTrait; - /** @var \Doctrine\ORM\EntityManagerInterface $entityManager */ + /** @var EntityManagerInterface $entityManager */ private $entityManager; + /** @var array[] $files */ + private $files; + /** * @throws Exception */ protected function setUp(): void { - /** @var KernelInterface $kernel */ + /** @var Kernel $kernel */ $kernel = self::bootKernel(); if ('test' !== $kernel->getEnvironment()) { @@ -66,12 +90,36 @@ class CurlGetTest extends ApiTestCase $metaData = $this->entityManager->getMetadataFactory()->getAllMetadata(); $schemaTool = new SchemaTool($this->entityManager); $schemaTool->updateSchema($metaData); + + $query = $this->entityManager->getConnection()->createQueryBuilder(); + $query->delete('blob_files')->executeQuery(); + + $this->files = [ + 0 => [ + 'name' => $n = 'Test.php', + 'path' => $p = __DIR__ . '/' . $n, + 'content' => $c = file_get_contents($p), + 'hash' => hash('sha256', $c), + 'size' => strlen($c), + 'mime' => 'application/x-php', + 'retention' => 'P1W', + ], + 1 => [ + 'name' => $n = 'Kernel.php', + 'path' => $p = __DIR__ . '/' . $n, + 'content' => $c = file_get_contents($p), + 'hash' => hash('sha256', $c), + 'size' => strlen($c), + 'mime' => 'application/x-php', + 'retention' => 'P1M', + ], + ]; } public function testGet(): void { try { - $client = $this->withUser('foobar'); + $client = static::createClient(); $configService = $client->getContainer()->get(ConfigurationService::class); $bucket = $configService->getBuckets()[0]; @@ -90,8 +138,10 @@ class CurlGetTest extends ApiTestCase $url = "/blob/files/?bucketID=$bucketId&prefix=$prefix&creationTime=$creationTime"; $options = [ 'headers' => [ + 'Accept' => 'application/ld+json', 'HTTP_ACCEPT' => 'application/ld+json', 'x-dbp-signature' => $token, + 'HTTP_X_DBP_SIGNATURE' => $token, ], ]; @@ -123,33 +173,19 @@ class CurlGetTest extends ApiTestCase * - get all blobs: no blobs available * * @return void + * @throws \Doctrine\DBAL\Exception + * @throws \JsonException + * @throws ClientExceptionInterface + * @throws RedirectionExceptionInterface + * @throws ServerExceptionInterface + * @throws TransportExceptionInterface */ public function testPostGetDelete(): void { try { - $files = [ - 0 => [ - 'name' => $n = 'Test.php', - 'path' => $p = __DIR__ . '/' . $n, - 'content' => $c = file_get_contents($p), - 'hash' => hash('sha256', $c), - 'size' => strlen($c), - 'mime' => 'application/x-php', - 'retention' => 'P1W', - ], - 1 => [ - 'name' => $n = 'Kernel.php', - 'path' => $p = __DIR__ . '/' . $n, - 'content' => $c = file_get_contents($p), - 'hash' => hash('sha256', $c), - 'size' => strlen($c), - 'mime' => 'application/x-php', - 'retention' => 'P1M', - ], - ]; - - $client = $this->withUser('foobar'); + $client = static::createClient(); + /** @var BlobService $blobService */ $blobService = $client->getContainer()->get(BlobService::class); $configService = $client->getContainer()->get(ConfigurationService::class); @@ -165,14 +201,16 @@ class CurlGetTest extends ApiTestCase // ======================================================= // POST a file // ======================================================= + echo "POST file[0]\n"; + $payload = [ 'bucketID' => $bucketId, 'creationTime' => $creationTime, 'prefix' => $prefix, - 'fileName' => $files[0]['name'], - 'fileHash' => $files[0]['hash'], + 'fileName' => $this->files[0]['name'], + 'fileHash' => $this->files[0]['hash'], 'notifyEmail' => $notifyEmail, - 'retentionDuration' => $files[0]['retention'], + 'retentionDuration' => $this->files[0]['retention'], 'additionalMetadata' => '', ]; @@ -180,7 +218,7 @@ class CurlGetTest extends ApiTestCase $requestPost = Request::create($url, 'POST', [], [], [ - 'file' => new UploadedFile($files[0]['path'], $files[0]['name'], $files[0]['mime']) + 'file' => new UploadedFile($this->files[0]['path'], $this->files[0]['name'], $this->files[0]['mime']) ], [ 'HTTP_ACCEPT' => 'application/ld+json', @@ -189,8 +227,8 @@ class CurlGetTest extends ApiTestCase ], "HTTP_ACCEPT: application/ld+json\r\n" . "HTTP_X_DBP_SIGNATURE: $token\r\n\r\n" - . "file=" . base64_encode($files[0]['content']) - . "&fileName={$files[0]['name']}&prefix=$prefix&bucketID=$bucketId" + . "file=" . base64_encode($this->files[0]['content']) + . "&fileName={$this->files[0]['name']}&prefix=$prefix&bucketID=$bucketId" ); $c = new CreateFileDataAction($blobService); try { @@ -204,19 +242,17 @@ class CurlGetTest extends ApiTestCase $this->assertEquals($prefix, $fileData->getPrefix(), 'File data prefix not correct.'); $this->assertObjectHasAttribute('identifier', $fileData, 'File data has no identifier.'); $this->assertTrue(uuid_is_valid($fileData->getIdentifier()), 'File data identifier is not a valid UUID.'); - $this->assertEquals($files[0]['name'], $fileData->getFileName(), 'File name not correct.'); - $files[0]['uuid'] = $fileData->getIdentifier(); - $files[0]['created'] = $fileData->getDateCreated(); - $files[0]['until'] = $fileData->getExistsUntil(); - $this->assertEquals( - $files[0]['created']->format('c'), - date('c', (int)$creationTime), - 'File creation time not correct.' - ); + $this->assertEquals($this->files[0]['name'], $fileData->getFileName(), 'File name not correct.'); + $this->files[0]['uuid'] = $fileData->getIdentifier(); + $this->files[0]['created'] = $fileData->getDateCreated(); + $this->files[0]['until'] = $fileData->getExistsUntil(); + echo " file identifier='{$this->files[0]['uuid']}' stored.\n"; // ======================================================= - // GET a file + // GET all files // ======================================================= + echo "GET all files (only 0)\n"; + $options = [ 'headers' => [ 'HTTP_ACCEPT' => 'application/ld+json', @@ -227,8 +263,11 @@ class CurlGetTest extends ApiTestCase /** @noinspection PhpInternalEntityUsedInspection */ $client->getKernelBrowser()->followRedirects(); + /** @var \ApiPlatform\Core\Bridge\Symfony\Bundle\Test\Response $response */ $response = $client->request('GET', $url, $options); - + if ($response->getStatusCode() !== 200) { + echo $response->getContent() . "\n"; + } $this->assertEquals(200, $response->getStatusCode()); $data = json_decode($response->getContent(), true, 512, JSON_THROW_ON_ERROR); @@ -237,24 +276,25 @@ class CurlGetTest extends ApiTestCase $this->assertArrayHasKey(0, $data['hydra:member']); $resultFile = $data['hydra:member'][0]; $this->assertEquals($prefix, $resultFile['prefix'], 'File data prefix not correct.'); - $this->assertEquals($files[0]['name'], $resultFile['fileName'], 'File name not correct.'); - $this->assertEquals($files[0]['size'], $resultFile['fileSize'], 'File size not correct.'); - $this->assertEquals($files[0]['uuid'], $resultFile['identifier'], 'File identifier not correct.'); + $this->assertEquals($this->files[0]['name'], $resultFile['fileName'], 'File name not correct.'); + $this->assertEquals($this->files[0]['size'], $resultFile['fileSize'], 'File size not correct.'); + $this->assertEquals($this->files[0]['uuid'], $resultFile['identifier'], 'File identifier not correct.'); $this->assertEquals($notifyEmail, $resultFile['notifyEmail'], 'File data notify email not correct.'); $this->assertCount(1, $data['hydra:member'], 'More files than expected'); -// dump($data); // ======================================================= // POST another file // ======================================================= + echo "POST file [1]\n"; + $payload = [ 'bucketID' => $bucketId, 'creationTime' => $creationTime, 'prefix' => $prefix, - 'fileName' => $files[1]['name'], - 'fileHash' => $files[1]['hash'], + 'fileName' => $this->files[1]['name'], + 'fileHash' => $this->files[1]['hash'], 'notifyEmail' => $notifyEmail, - 'retentionDuration' => $files[1]['retention'], + 'retentionDuration' => $this->files[1]['retention'], 'additionalMetadata' => '', ]; @@ -262,7 +302,7 @@ class CurlGetTest extends ApiTestCase $requestPost = Request::create($url, 'POST', [], [], [ - 'file' => new UploadedFile($files[1]['path'], $files[1]['name'], $files[1]['mime']) + 'file' => new UploadedFile($this->files[1]['path'], $this->files[1]['name'], $this->files[1]['mime']) ], [ 'HTTP_ACCEPT' => 'application/ld+json', @@ -271,8 +311,8 @@ class CurlGetTest extends ApiTestCase ], "HTTP_ACCEPT: application/ld+json\r\n" . "HTTP_X_DBP_SIGNATURE: $token\r\n\r\n" - . "file=" . base64_encode($files[1]['content']) - . "&fileName={$files[1]['name']}&prefix=$prefix&bucketID=$bucketId" + . "file=" . base64_encode($this->files[1]['content']) + . "&fileName={$this->files[1]['name']}&prefix=$prefix&bucketID=$bucketId" ); $c = new CreateFileDataAction($blobService); try { @@ -286,15 +326,17 @@ class CurlGetTest extends ApiTestCase $this->assertEquals($prefix, $fileData->getPrefix(), 'File data prefix not correct.'); $this->assertObjectHasAttribute('identifier', $fileData, 'File data has no identifier.'); $this->assertTrue(uuid_is_valid($fileData->getIdentifier()), 'File data identifier is not a valid UUID.'); - $this->assertEquals($files[1]['name'], $fileData->getFileName(), 'File name not correct.'); - $files[1]['uuid'] = $fileData->getIdentifier(); - $files[1]['created'] = $fileData->getDateCreated(); - $files[1]['until'] = $fileData->getExistsUntil(); - dump($fileData); + $this->assertEquals($this->files[1]['name'], $fileData->getFileName(), 'File name not correct.'); + $this->files[1]['uuid'] = $fileData->getIdentifier(); + $this->files[1]['created'] = $fileData->getDateCreated(); + $this->files[1]['until'] = $fileData->getExistsUntil(); + echo " file identifier='{$this->files[1]['uuid']}' stored.\n"; // ======================================================= // GET all files // ======================================================= + echo "GET all files (0 and 1)\n"; + $options = [ 'headers' => [ 'HTTP_ACCEPT' => 'application/ld+json', @@ -305,6 +347,7 @@ class CurlGetTest extends ApiTestCase /** @noinspection PhpInternalEntityUsedInspection */ $client->getKernelBrowser()->followRedirects(); + /** @var Response $response */ $response = $client->request('GET', $url, $options); $this->assertEquals(200, $response->getStatusCode()); @@ -315,19 +358,13 @@ class CurlGetTest extends ApiTestCase $this->assertCount(2, $data['hydra:member'], 'More files than expected'); foreach ($data['hydra:member'] as $resultFile) { $found = false; - foreach ($files as $file) { + foreach ($this->files as $file) { if ($file['uuid'] === $resultFile['identifier']) { $found = true; $this->assertEquals($prefix, $resultFile['prefix'], 'File prefix not correct.'); $this->assertEquals($file['name'], $resultFile['fileName'], 'File name not correct.'); $this->assertEquals($file['size'], $resultFile['fileSize'], 'File size not correct.'); - $this->assertEquals( - $file['created']->format('c'), - date('c', (int)$creationTime), - 'File creation time not correct.' - ); $until = $file['created']->add(new \DateInterval($file['retention'])); - dump([$until->format('c'), $resultFile['existsUntil']]); $this->assertEquals( $until->format('c'), $resultFile['existsUntil'], @@ -339,12 +376,12 @@ class CurlGetTest extends ApiTestCase } $this->assertTrue($found, 'Uploaded file not found.'); } -// dump($data['hydra:member']); -// dump($data); // ======================================================= // DELETE all files // ======================================================= + echo "DELETE all files (0 and 1)\n"; + $requestDelete = Request::create($url, 'DELETE', [], [], [], [ 'HTTP_ACCEPT' => 'application/ld+json', @@ -362,15 +399,166 @@ class CurlGetTest extends ApiTestCase } $query = $this->entityManager->getConnection()->createQueryBuilder(); - $files = $query->select('*') + $this->files = $query->select('*') ->from('blob_files') ->where("prefix = '$prefix' AND bucket_id = '$bucketId'") ->fetchAllAssociativeIndexed(); - $this->assertEmpty($files, 'Files not deleted'); + $this->assertEmpty($this->files, 'Files not deleted'); // ======================================================= // GET all files // ======================================================= + echo "GET all files (empty)\n"; + + /** @var Response $response */ + $response = $client->request('GET', $url, $options); + + $this->assertEquals(200, $response->getStatusCode()); + + $data = json_decode($response->getContent(), true, 512, JSON_THROW_ON_ERROR); + $this->assertArrayHasKey('hydra:view', $data); + $this->assertArrayHasKey('hydra:member', $data); + $this->assertCount(0, $data['hydra:member'], 'More files than expected'); + + } catch (\Throwable $e) { + echo $e->getTraceAsString() . "\n"; + $this->fail($e->getMessage()); + } + } + + public function testGetDeleteById() + { + try { + +// $client = $this->withUser('foobar'); + $client = static::createClient(); + /** @var BlobService $blobService */ + $blobService = $client->getContainer()->get(BlobService::class); + $configService = $client->getContainer()->get(ConfigurationService::class); + + $bucket = $configService->getBuckets()[0]; + $secret = $bucket->getPublicKey(); + $bucketId = $bucket->getIdentifier(); + $creationTime = date('U'); + $prefix = 'playground'; + $notifyEmail = 'eugen.neuber@tugraz.at'; + + $url = "/blob/files/?bucketID=$bucketId&prefix=$prefix&creationTime=$creationTime"; + + // ======================================================= + // POST a file + // ======================================================= + echo "POST file 0\n"; + + $payload = [ + 'bucketID' => $bucketId, + 'creationTime' => $creationTime, + 'prefix' => $prefix, + 'fileName' => $this->files[0]['name'], + 'fileHash' => $this->files[0]['hash'], + 'notifyEmail' => $notifyEmail, + 'retentionDuration' => $this->files[0]['retention'], + 'additionalMetadata' => '', + ]; + + $token = DenyAccessUnlessCheckSignature::create($secret, $payload); + + $requestPost = Request::create($url, 'POST', [], [], + [ + 'file' => new UploadedFile($this->files[0]['path'], $this->files[0]['name'], $this->files[0]['mime']) + ], + [ + 'HTTP_ACCEPT' => 'application/ld+json', +// 'x-dbp-signature' => $token, + 'HTTP_X_DBP_SIGNATURE' => $token, + ], + "HTTP_ACCEPT: application/ld+json\r\n" + . "HTTP_X_DBP_SIGNATURE: $token\r\n\r\n" + . "file=" . base64_encode($this->files[0]['content']) + . "&fileName={$this->files[0]['name']}&prefix=$prefix&bucketID=$bucketId" + ); + $c = new CreateFileDataAction($blobService); + try { + $fileData = $c->__invoke($requestPost); + } catch (\Throwable $e) { + echo $e->getTraceAsString() . "\n"; + $this->fail($e->getMessage()); + } + + $this->assertNotNull($fileData); + $this->assertEquals($prefix, $fileData->getPrefix(), 'File data prefix not correct.'); + $this->assertObjectHasAttribute('identifier', $fileData, 'File data has no identifier.'); + $this->assertTrue(uuid_is_valid($fileData->getIdentifier()), 'File data identifier is not a valid UUID.'); + $this->assertEquals($this->files[0]['name'], $fileData->getFileName(), 'File name not correct.'); + $this->files[0]['uuid'] = $fileData->getIdentifier(); + $this->files[0]['created'] = $fileData->getDateCreated(); + $this->files[0]['until'] = $fileData->getExistsUntil(); + echo " file identifier='{$this->files[0]['uuid']}' stored.\n"; + + // ======================================================= + // GET a file by id + // ======================================================= + echo "GET a file by id (0)\n"; + + $options = [ + 'headers' => [ + 'HTTP_ACCEPT' => 'application/ld+json', + 'x-dbp-signature' => $token, + ], + ]; + + /** @noinspection PhpInternalEntityUsedInspection */ + $client->getKernelBrowser()->followRedirects(); + + $this->assertArrayHasKey($this->files[0]['uuid'], DummyFileSystemService::$fd, 'File data not in dummy store.'); + /** @var Response $response */ + $response = $client->request('GET', $url . "/{$this->files[0]['uuid']}", $options); + + $this->assertEquals(200, $response->getStatusCode()); + // TODO: further checks... + + // ======================================================= + // DELETE a file by id + // ======================================================= + echo "DELETE a file by id\n"; + + $options = [ + 'headers' => [ + 'Accept' => 'application/ld+json', + 'HTTP_ACCEPT' => 'application/ld+json', + 'x-dbp-signature' => $token, + ], + ]; + + /** @noinspection PhpInternalEntityUsedInspection */ + $client->getKernelBrowser()->followRedirects(false); + + $url = "/blob/files/{$this->files[0]['uuid']}?prefix=$prefix&bucketID=$bucketId&creationTime=$creationTime"; + /** @var Response $response */ + $response = $client->request('DELETE', $url, $options); + + if ($response->getStatusCode() !== 200) { + echo $response->getContent() . "\n"; + } + $this->assertEquals(204, $response->getStatusCode()); + // TODO: further checks... + + $query = $this->entityManager->getConnection()->createQueryBuilder(); + $this->files = $query->select('*') + ->from('blob_files') + ->where("prefix = '$prefix' AND bucket_id = '$bucketId' AND identifier = '{$this->files[0]['uuid']}'") + ->fetchAllAssociativeIndexed(); + $this->assertEmpty($this->files, 'Files not deleted'); + + // ======================================================= + // GET all files + // ======================================================= + echo "GET all files\n"; + + /** @noinspection PhpInternalEntityUsedInspection */ + $client->getKernelBrowser()->followRedirects(); + + $url = "/blob/files/?bucketID=$bucketId&prefix=$prefix&creationTime=$creationTime"; /** @var Response $response */ $response = $client->request('GET', $url, $options); diff --git a/tests/Kernel.php b/tests/Kernel.php index 8acf6f1bbc45241392da5c5f7eceb457e0a687d8..6cfa0a14cc7a2cfd66fed079cded8f843626d6c5 100644 --- a/tests/Kernel.php +++ b/tests/Kernel.php @@ -54,6 +54,7 @@ class Kernel extends BaseKernel $container->extension('dbp_relay_blob', [ 'database_url' => 'sqlite:///var/dbp_relay_blob_test.db', +// 'database_url' => 'sqlite:///:memory:', 'buckets' => [ 'test_bucket' => [ 'service' => 'Dbp\Relay\BlobBundle\Tests\DummyFileSystemService',