Bläddra i källkod

refactor storages and implements Api1Storage

Olivier Massot 3 år sedan
förälder
incheckning
97176f156c

+ 4 - 0
.env.docker

@@ -10,6 +10,10 @@ DATABASE_URL=mysql://root:mysql660@db:3306/opentalent?serverVersion=5.7
 CORS_ALLOW_ORIGIN=^https?://(localhost|127\.0\.0\.1)(:[0-9]+)|local.admin.opentalent.fr|local.app.opentalent.fr?$
 ###< nelmio/cors-bundle ###
 
+###> api v1 ###
+API1_BASE_URL=http://api/api
+###< files management ###
+
 ###> BlackFire configuration ###
 BLACKFIRE_CLIENT_ID=988fcba8-552d-48df-a9c2-035c76535b69
 BLACKFIRE_CLIENT_TOKEN=8cfbeb263d044da9678dc2612531504da3790c308da7448e35724a5da91c136f

+ 4 - 0
.env.preprod

@@ -10,6 +10,10 @@ DATABASE_URL=mysql://root:mysql2iopenservice369566@preprod:3306/opentalent?serve
 CORS_ALLOW_ORIGIN=^https?://(localhost|127\.0\.0\.1)(:[0-9]+)$
 ###< nelmio/cors-bundle ###
 
+###> api v1 ###
+API1_BASE_URL=https://api.preprod.opentalent.fr/api
+###< files management ###
+
 ###> typo3 client ###
 TYPO3_BASE_URI=http://preprod.opentalent.fr/ohcluses
 ###< typo3 client ###

+ 4 - 0
.env.prod

@@ -12,6 +12,10 @@ DATABASE_URL=mysql://root:mysql2iopenservice369566@prod-back:3306/opentalent?ser
 CORS_ALLOW_ORIGIN=^https?://(localhost|127\.0\.0\.1)(:[0-9]+)$
 ###< nelmio/cors-bundle ###
 
+###> api v1 ###
+API1_BASE_URL=https://api.opentalent.fr/api
+###< files management ###
+
 ###> BlackFire configuration ###
 BLACKFIRE_CLIENT_ID=988fcba8-552d-48df-a9c2-035c76535b69
 BLACKFIRE_CLIENT_TOKEN=8cfbeb263d044da9678dc2612531504da3790c308da7448e35724a5da91c136f

+ 4 - 0
.env.test

@@ -2,6 +2,10 @@
 APP_DEBUG=1
 ###< symfony/framework-bundle ###
 
+###> api v1 ###
+API1_BASE_URL=https://api.test.opentalent.fr/api
+###< files management ###
+
 # define your env variables for the test env here
 KERNEL_CLASS='App\Kernel'
 APP_SECRET='$ecretf0rt3st'

+ 2 - 0
config/packages/framework.yaml

@@ -36,3 +36,5 @@ framework:
                 base_uri: '%env(MOBYT_API_BASE_URI)%'
                 headers:
                     Content-Type: 'application/json'
+            api_client:
+                base_uri: '%env(API1_BASE_URL)%'

+ 1 - 0
config/routes.yaml

@@ -6,6 +6,7 @@ swagger_ui:
   path: /docs
   controller: api_platform.swagger.action.ui
 
+# todo: comment ça s'articule avec le LocalStorage ça?
 ot_internal_secure_file_download:
   path: /_internal/secure/files/{id}
   controller: App\Controller\FileController::downloadFile

+ 1 - 0
config/services.yaml

@@ -9,6 +9,7 @@ services:
         autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.
         bind:
             $opentalentConfig: '%kernel.project_dir%%env(OPENTALENT_CONFIG)%'
+            $api1BaseUrl: '%env(API1_BASE_URL)%'
             $internalFilesUploadUri: '%env(INTERNAL_FILES_DOWNLOAD_URI)%'
             $bindfileBufferFile: '%env(BIND_FILE_BUFFER_FILE)%'
             $contextAwareDataPersister: '@api_platform.doctrine.orm.data_persister'

+ 1 - 1
src/ApiResources/DownloadRequest.php

@@ -7,7 +7,7 @@ use ApiPlatform\Core\Annotation\ApiProperty;
 use ApiPlatform\Core\Annotation\ApiResource;
 
 /**
- * A request for a file from the FileStorage
+ * A request for a file from the LocalStorage
  */
 #[ApiResource(
     collectionOperations:[],

+ 27 - 10
src/DataProvider/DownloadRequestDataProvider.php → src/DataProvider/Core/DownloadRequestDataProvider.php

@@ -1,25 +1,29 @@
 <?php
 declare(strict_types=1);
 
-namespace App\DataProvider;
+namespace App\DataProvider\Core;
 
 use ApiPlatform\Core\DataProvider\ItemDataProviderInterface;
 use ApiPlatform\Core\DataProvider\RestrictedDataProviderInterface;
 use App\ApiResources\DownloadRequest;
 use App\Enum\Core\FileStatusEnum;
 use App\Repository\Core\FileRepository;
-use App\Service\Storage\FileStorage;
-use Symfony\Component\HttpFoundation\Response;
+use App\Service\Storage\Api1Storage;
+use App\Service\Storage\LocalStorage;
+use App\Service\Utils\UrlBuilder;
 use Symfony\Component\HttpFoundation\HeaderUtils;
+use Symfony\Component\HttpFoundation\RedirectResponse;
+use Symfony\Component\HttpFoundation\Response;
 
 /**
- * Custom provider pour le téléchargement des fichiers du FileStorage
+ * Custom provider pour le téléchargement des fichiers du LocalStorage
  */
 final class DownloadRequestDataProvider implements ItemDataProviderInterface, RestrictedDataProviderInterface
 {
     public function __construct(
         private FileRepository $fileRepository,
-        private FileStorage $storage,
+        private LocalStorage   $localStorage,
+        private Api1Storage    $api1Storage
     )
     {}
 
@@ -28,7 +32,7 @@ final class DownloadRequestDataProvider implements ItemDataProviderInterface, Re
         return DownloadRequest::class === $resourceClass;
     }
 
-    public function getItem(string $resourceClass, $id, string $operationName = null, array $context = []): Response
+    public function getItem(string $resourceClass, $id, string $operationName = null, array $context = []): Response | RedirectResponse
     {
         $file = $this->fileRepository->find($id);
         if (empty($file)) {
@@ -37,11 +41,24 @@ final class DownloadRequestDataProvider implements ItemDataProviderInterface, Re
         if ($file->getStatus() !== FileStatusEnum::READY()->getValue()) {
             throw new \RuntimeException("File " . $id . " has " . $file->getStatus() . " status; abort.");
         }
-        if ($file->getHost() === 'api') {
-            throw new \RuntimeException('Incorrect host for file ' . $id . '');
-        }
 
-        $content = $this->storage->read($file);
+        $storage = $file->getHost() === 'ap2i' ? $this->localStorage : $this->api1Storage;
+
+//        if ($file->getHost() === 'api') {
+//            $headers = [
+//                'x-accessid' => $_REQUEST['AccessId'],
+//                'SFSESSID' => $_REQUEST['SFSESSID'],
+//                'BEARER' => $_REQUEST['BEARER'],
+//                'authorization' => 'BEARER ' . $_REQUEST['BEARER'],
+//            ];
+//
+//            $url = UrlBuilder::concatPath($this->api1BaseUrl, 'files/' . $file->getId() .'/download');
+//
+//            return new RedirectResponse($url, 302, $headers);
+//        }
+
+        $content = $storage->read($file);
+        var_dump($content);
 
         // @see https://symfony.com/doc/current/components/http_foundation.html#serving-files
         $response = new Response($content);

+ 4 - 4
src/Service/Export/BaseExporter.php

@@ -10,7 +10,7 @@ use App\Repository\Access\AccessRepository;
 use App\Repository\Core\FileRepository;
 use App\Service\Export\Model\ExportModelInterface;
 use App\Service\ServiceIterator\EncoderIterator;
-use App\Service\Storage\FileStorage;
+use App\Service\Storage\LocalStorage;
 use App\Service\Utils\StringsUtils;
 use Doctrine\ORM\EntityManagerInterface;
 use Psr\Log\LoggerInterface;
@@ -28,7 +28,7 @@ abstract class BaseExporter implements ExporterInterface
     protected Environment $twig;
     protected EncoderIterator $encoderIterator;
     protected EntityManagerInterface $entityManager;
-    protected FileStorage $storage;
+    protected LocalStorage $storage;
     protected LoggerInterface $logger;
 
     #[Required]
@@ -47,7 +47,7 @@ abstract class BaseExporter implements ExporterInterface
     public function setEntityManager(EntityManagerInterface $entityManager): void
     { $this->entityManager = $entityManager; }
     #[Required]
-    public function setStorage(FileStorage $storage): void
+    public function setStorage(LocalStorage $storage): void
     { $this->storage = $storage; }
     #[Required]
     public function setLogger(LoggerInterface $logger): void
@@ -124,7 +124,7 @@ abstract class BaseExporter implements ExporterInterface
             $requester,
             true,
             'NOBODY',
-            FileStorage::getMimeTypeFromExt($exportRequest->getFormat()),
+            LocalStorage::getMimeTypeFromExt($exportRequest->getFormat()),
             $flushFile
         );
     }

+ 1 - 1
src/Service/Export/LicenceCmfExporter.php

@@ -10,7 +10,7 @@ use App\Service\Export\Model\LicenceCmf;
 use App\Enum\Access\FunctionEnum;
 use App\Repository\Organization\OrganizationRepository;
 use App\Service\Export\Model\LicenceCmfCollection;
-use App\Service\Storage\FileStorage;
+use App\Service\Storage\LocalStorage;
 
 /**
  * Exporte la licence CMF de la structure ou du ou des access, au format demandé

+ 58 - 0
src/Service/Storage/Api1Storage.php

@@ -0,0 +1,58 @@
+<?php
+
+namespace App\Service\Storage;
+
+use App\Entity\Core\File;
+use App\Service\Utils\UrlBuilder;
+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 Symfony\Contracts\HttpClient\HttpClientInterface;
+
+/**
+ * Read and write files into the Opentalent API v1 storage
+ */
+class Api1Storage implements FileStorageInterface
+{
+    public function __construct(
+        private HttpClientInterface $api_client
+    )
+    {}
+
+    /**
+     * Reads the given file and returns its content as a string
+     *
+     * @param File $file
+     * @return string
+     */
+    public function read(File $file): string
+    {
+        $headers = [
+            'x-accessid' => $_REQUEST['AccessId'],
+            'SFSESSID' => $_REQUEST['SFSESSID'],
+            'BEARER' => $_REQUEST['BEARER'],
+            'authorization' => 'BEARER ' . $_REQUEST['BEARER'],
+        ];
+
+        try {
+            $response = $this->api_client->request(
+                'POST',
+                'api/files/' . $file->getId() .'/download',
+                ['headers' => $headers]
+            );
+            $content = $response->getContent();
+        } catch (ClientExceptionInterface $e) {
+            throw new \RuntimeException("File " . $file->getId() . " not found", 0, $e);
+        } catch (ServerExceptionInterface | RedirectionExceptionInterface | TransportExceptionInterface $e) {
+            throw new \RuntimeException("File could not be fetched because of a server error", 0, $e);
+        }
+
+        // When the user isn't well authenticated, the api may redirect to the login page or to the portail
+        if (str_contains($content, "<!DOCTYPE html>") && str_contains($content, "This website is powered by TYPO3")) {
+            throw new \RuntimeException("Permission error");
+        }
+
+        return $content;
+    }
+}

+ 10 - 0
src/Service/Storage/FileStorageInterface.php

@@ -0,0 +1,10 @@
+<?php
+
+namespace App\Service\Storage;
+
+use App\Entity\Core\File;
+
+interface FileStorageInterface
+{
+    public function read(File $file): string;
+}

+ 1 - 1
src/Service/Storage/FileStorage.php → src/Service/Storage/LocalStorage.php

@@ -25,7 +25,7 @@ use RuntimeException;
 /**
  * Read and write files into the file storage
  */
-class FileStorage
+class LocalStorage implements FileStorageInterface
 {
     /**
      * Key of the gaufrette storage, as defined in config/packages/knp_gaufrette.yaml

+ 3 - 3
tests/Service/Export/LicenceCmfExporterTest.php

@@ -15,7 +15,7 @@ use App\Service\Export\LicenceCmfExporter;
 use App\Service\Export\Model\LicenceCmf;
 use App\Service\Export\Model\LicenceCmfCollection;
 use App\Service\ServiceIterator\EncoderIterator;
-use App\Service\Storage\FileStorage;
+use App\Service\Storage\LocalStorage;
 use App\Tests\TestToolsTrait;
 use Doctrine\Common\Collections\Collection;
 use Doctrine\ORM\EntityManagerInterface;
@@ -32,7 +32,7 @@ class LicenceCmfExporterTest extends TestCase
     private MockObject | Environment $twig;
     private MockObject | EncoderIterator $encoderIterator;
     private MockObject | EntityManagerInterface $em;
-    private MockObject | FileStorage $storage;
+    private MockObject | LocalStorage $storage;
     private MockObject | OrganizationRepository $organizationRepo;
     private MockObject | Access $access;
     private MockObject | Organization $organization;
@@ -54,7 +54,7 @@ class LicenceCmfExporterTest extends TestCase
         $this->encoderIterator = $this->getMockBuilder(EncoderIterator::class)->disableOriginalConstructor()->getMock();
         $this->encoder = $this->getMockBuilder(PdfEncoder::class)->disableOriginalConstructor()->getMock();
         $this->em = $this->getMockBuilder(EntityManagerInterface::class)->disableOriginalConstructor()->getMock();
-        $this->storage = $this->getMockBuilder(FileStorage::class)->disableOriginalConstructor()->getMock();
+        $this->storage = $this->getMockBuilder(LocalStorage::class)->disableOriginalConstructor()->getMock();
         $this->organizationRepo = $this->getMockBuilder(OrganizationRepository::class)->disableOriginalConstructor()->getMock();
         $this->access = $this->getMockBuilder(Access::class)->getMock();
         $this->organization = $this->getMockBuilder(Organization::class)->getMock();

+ 42 - 42
tests/Service/Storage/FileStorageTest.php

@@ -9,14 +9,14 @@ use App\Entity\Person\Person;
 use App\Enum\Core\FileStatusEnum;
 use App\Enum\Core\FileTypeEnum;
 use App\Repository\Access\AccessRepository;
-use App\Service\Storage\FileStorage;
+use App\Service\Storage\LocalStorage;
 use Doctrine\ORM\EntityManagerInterface;
 use Gaufrette\Filesystem;
 use JetBrains\PhpStorm\Pure;
 use Knp\Bundle\GaufretteBundle\FilesystemMap;
 use PHPUnit\Framework\TestCase;
 
-class TestableFileStorage extends FileStorage {
+class TestableLocalStorage extends LocalStorage {
     public const FS_KEY = parent::FS_KEY;
 
     public function getPrefix(mixed $owner, bool $isTemporary, string $type = null): string {
@@ -44,11 +44,11 @@ class FileStorageTest extends TestCase
         $this->iriConverter = $this->getMockBuilder(IriConverterInterface::class)->disableOriginalConstructor()->getMock();
 
         $this->filesystem = $this->getMockBuilder(Filesystem::class)->disableOriginalConstructor()->getMock();
-        $this->filesystemMap->method('get')->with(TestableFileStorage::FS_KEY)->willReturn($this->filesystem);
+        $this->filesystemMap->method('get')->with(TestableLocalStorage::FS_KEY)->willReturn($this->filesystem);
     }
 
     public function testExists(): void {
-        $fileStorage = $this->getMockBuilder(TestableFileStorage::class)
+        $fileStorage = $this->getMockBuilder(TestableLocalStorage::class)
             ->setConstructorArgs([$this->filesystemMap, $this->entityManager, $this->accessRepository, $this->iriConverter])
             ->setMethodsExcept(['exists'])
             ->getMock();
@@ -62,7 +62,7 @@ class FileStorageTest extends TestCase
     }
 
     public function testExistsInexistant(): void {
-        $fileStorage = $this->getMockBuilder(TestableFileStorage::class)
+        $fileStorage = $this->getMockBuilder(TestableLocalStorage::class)
             ->setConstructorArgs([$this->filesystemMap, $this->entityManager, $this->accessRepository, $this->iriConverter])
             ->setMethodsExcept(['exists'])
             ->getMock();
@@ -77,7 +77,7 @@ class FileStorageTest extends TestCase
 
     public function testGetDownloadIri(): void
     {
-        $fileStorage = $this->getMockBuilder(TestableFileStorage::class)
+        $fileStorage = $this->getMockBuilder(TestableLocalStorage::class)
             ->setConstructorArgs([$this->filesystemMap, $this->entityManager, $this->accessRepository, $this->iriConverter])
             ->setMethodsExcept(['getDownloadIri'])
             ->getMock();
@@ -99,7 +99,7 @@ class FileStorageTest extends TestCase
 
     public function testListByOwner(): void
     {
-        $fileStorage = $this->getMockBuilder(TestableFileStorage::class)
+        $fileStorage = $this->getMockBuilder(TestableLocalStorage::class)
             ->setConstructorArgs([$this->filesystemMap, $this->entityManager, $this->accessRepository, $this->iriConverter])
             ->setMethodsExcept(['listByOwner'])
             ->getMock();
@@ -118,7 +118,7 @@ class FileStorageTest extends TestCase
 
     public function testRead(): void
     {
-        $fileStorage = $this->getMockBuilder(TestableFileStorage::class)
+        $fileStorage = $this->getMockBuilder(TestableLocalStorage::class)
             ->setConstructorArgs([$this->filesystemMap, $this->entityManager, $this->accessRepository, $this->iriConverter])
             ->setMethodsExcept(['read'])
             ->getMock();
@@ -136,7 +136,7 @@ class FileStorageTest extends TestCase
 
     public function testPrepareFile(): void
     {
-        $fileStorage = $this->getMockBuilder(TestableFileStorage::class)
+        $fileStorage = $this->getMockBuilder(TestableLocalStorage::class)
             ->setConstructorArgs([$this->filesystemMap, $this->entityManager, $this->accessRepository, $this->iriConverter])
             ->setMethodsExcept(['prepareFile'])
             ->getMock();
@@ -174,7 +174,7 @@ class FileStorageTest extends TestCase
 
     public function testPrepareFileDefaultValues(): void
     {
-        $fileStorage = $this->getMockBuilder(TestableFileStorage::class)
+        $fileStorage = $this->getMockBuilder(TestableLocalStorage::class)
             ->setConstructorArgs([$this->filesystemMap, $this->entityManager, $this->accessRepository, $this->iriConverter])
             ->setMethodsExcept(['prepareFile'])
             ->getMock();
@@ -200,7 +200,7 @@ class FileStorageTest extends TestCase
 
     public function testPrepareFileNoFlush(): void
     {
-        $fileStorage = $this->getMockBuilder(TestableFileStorage::class)
+        $fileStorage = $this->getMockBuilder(TestableLocalStorage::class)
             ->setConstructorArgs([$this->filesystemMap, $this->entityManager, $this->accessRepository, $this->iriConverter])
             ->setMethodsExcept(['prepareFile'])
             ->getMock();
@@ -226,7 +226,7 @@ class FileStorageTest extends TestCase
     }
 
     public function testWriteFileNewFile(): void {
-        $fileStorage = $this->getMockBuilder(TestableFileStorage::class)
+        $fileStorage = $this->getMockBuilder(TestableLocalStorage::class)
             ->setConstructorArgs([$this->filesystemMap, $this->entityManager, $this->accessRepository, $this->iriConverter])
             ->setMethodsExcept(['writeFile'])
             ->getMock();
@@ -277,7 +277,7 @@ class FileStorageTest extends TestCase
     }
 
     public function testWriteFileExistingFile(): void {
-        $fileStorage = $this->getMockBuilder(TestableFileStorage::class)
+        $fileStorage = $this->getMockBuilder(TestableLocalStorage::class)
             ->setConstructorArgs([$this->filesystemMap, $this->entityManager, $this->accessRepository, $this->iriConverter])
             ->setMethodsExcept(['writeFile'])
             ->getMock();
@@ -327,7 +327,7 @@ class FileStorageTest extends TestCase
 
     public function testWriteFileExistingButMissingFile(): void
     {
-        $fileStorage = $this->getMockBuilder(TestableFileStorage::class)
+        $fileStorage = $this->getMockBuilder(TestableLocalStorage::class)
             ->setConstructorArgs([$this->filesystemMap, $this->entityManager, $this->accessRepository, $this->iriConverter])
             ->setMethodsExcept(['writeFile'])
             ->getMock();
@@ -357,7 +357,7 @@ class FileStorageTest extends TestCase
     }
 
     public function testWriteFileWithAccessOwner(): void {
-        $fileStorage = $this->getMockBuilder(TestableFileStorage::class)
+        $fileStorage = $this->getMockBuilder(TestableLocalStorage::class)
             ->setConstructorArgs([$this->filesystemMap, $this->entityManager, $this->accessRepository, $this->iriConverter])
             ->setMethodsExcept(['writeFile'])
             ->getMock();
@@ -398,7 +398,7 @@ class FileStorageTest extends TestCase
 
     public function testWriteFileWithNoName(): void
     {
-        $fileStorage = $this->getMockBuilder(TestableFileStorage::class)
+        $fileStorage = $this->getMockBuilder(TestableLocalStorage::class)
             ->setConstructorArgs([$this->filesystemMap, $this->entityManager, $this->accessRepository, $this->iriConverter])
             ->setMethodsExcept(['writeFile'])
             ->getMock();
@@ -415,7 +415,7 @@ class FileStorageTest extends TestCase
     }
 
     public function testMakeFile(): void {
-        $fileStorage = $this->getMockBuilder(TestableFileStorage::class)
+        $fileStorage = $this->getMockBuilder(TestableLocalStorage::class)
             ->setConstructorArgs([$this->filesystemMap, $this->entityManager, $this->accessRepository, $this->iriConverter])
             ->setMethodsExcept(['makeFile'])
             ->getMock();
@@ -448,7 +448,7 @@ class FileStorageTest extends TestCase
     }
 
     public function testDelete(): void {
-        $fileStorage = $this->getMockBuilder(TestableFileStorage::class)
+        $fileStorage = $this->getMockBuilder(TestableLocalStorage::class)
             ->setConstructorArgs([$this->filesystemMap, $this->entityManager, $this->accessRepository, $this->iriConverter])
             ->setMethodsExcept(['delete'])
             ->getMock();
@@ -471,7 +471,7 @@ class FileStorageTest extends TestCase
     }
 
     public function testDeleteFailed(): void {
-        $fileStorage = $this->getMockBuilder(TestableFileStorage::class)
+        $fileStorage = $this->getMockBuilder(TestableLocalStorage::class)
             ->setConstructorArgs([$this->filesystemMap, $this->entityManager, $this->accessRepository, $this->iriConverter])
             ->setMethodsExcept(['delete'])
             ->getMock();
@@ -495,7 +495,7 @@ class FileStorageTest extends TestCase
     }
 
     public function testGetPrefixAccess(): void {
-        $fileStorage = $this->getMockBuilder(TestableFileStorage::class)
+        $fileStorage = $this->getMockBuilder(TestableLocalStorage::class)
             ->setConstructorArgs([$this->filesystemMap, $this->entityManager, $this->accessRepository, $this->iriConverter])
             ->setMethodsExcept(['getPrefix'])
             ->getMock();
@@ -513,7 +513,7 @@ class FileStorageTest extends TestCase
     }
 
     public function testGetPrefixOrganization(): void {
-        $fileStorage = $this->getMockBuilder(TestableFileStorage::class)
+        $fileStorage = $this->getMockBuilder(TestableLocalStorage::class)
             ->setConstructorArgs([$this->filesystemMap, $this->entityManager, $this->accessRepository, $this->iriConverter])
             ->setMethodsExcept(['getPrefix'])
             ->getMock();
@@ -527,7 +527,7 @@ class FileStorageTest extends TestCase
     }
 
     public function testGetPrefixPerson(): void {
-        $fileStorage = $this->getMockBuilder(TestableFileStorage::class)
+        $fileStorage = $this->getMockBuilder(TestableLocalStorage::class)
             ->setConstructorArgs([$this->filesystemMap, $this->entityManager, $this->accessRepository, $this->iriConverter])
             ->setMethodsExcept(['getPrefix'])
             ->getMock();
@@ -541,7 +541,7 @@ class FileStorageTest extends TestCase
     }
 
     public function testGetPrefixTemp(): void {
-        $fileStorage = $this->getMockBuilder(TestableFileStorage::class)
+        $fileStorage = $this->getMockBuilder(TestableLocalStorage::class)
             ->setConstructorArgs([$this->filesystemMap, $this->entityManager, $this->accessRepository, $this->iriConverter])
             ->setMethodsExcept(['getPrefix'])
             ->getMock();
@@ -555,7 +555,7 @@ class FileStorageTest extends TestCase
     }
 
     public function testGetPrefixWithType(): void {
-        $fileStorage = $this->getMockBuilder(TestableFileStorage::class)
+        $fileStorage = $this->getMockBuilder(TestableLocalStorage::class)
             ->setConstructorArgs([$this->filesystemMap, $this->entityManager, $this->accessRepository, $this->iriConverter])
             ->setMethodsExcept(['getPrefix'])
             ->getMock();
@@ -569,30 +569,30 @@ class FileStorageTest extends TestCase
     }
 
     public function testGuessMimeTypeFromFilename(): void {
-        $this->assertEquals('application/pdf', TestableFileStorage::guessMimeTypeFromFilename('file.pdf'));
-        $this->assertEquals('text/csv', TestableFileStorage::guessMimeTypeFromFilename('file.csv'));
-        $this->assertEquals('text/plain', TestableFileStorage::guessMimeTypeFromFilename('file.txt'));
-        $this->assertEquals('application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', TestableFileStorage::guessMimeTypeFromFilename('file.xlsx'));
-        $this->assertEquals('application/xml', TestableFileStorage::guessMimeTypeFromFilename('file.xml'));
-
-        $this->assertEquals(null, TestableFileStorage::guessMimeTypeFromFilename('file'));
-        $this->assertEquals(null, TestableFileStorage::guessMimeTypeFromFilename('file.invalid'));
+        $this->assertEquals('application/pdf', TestableLocalStorage::guessMimeTypeFromFilename('file.pdf'));
+        $this->assertEquals('text/csv', TestableLocalStorage::guessMimeTypeFromFilename('file.csv'));
+        $this->assertEquals('text/plain', TestableLocalStorage::guessMimeTypeFromFilename('file.txt'));
+        $this->assertEquals('application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', TestableLocalStorage::guessMimeTypeFromFilename('file.xlsx'));
+        $this->assertEquals('application/xml', TestableLocalStorage::guessMimeTypeFromFilename('file.xml'));
+
+        $this->assertEquals(null, TestableLocalStorage::guessMimeTypeFromFilename('file'));
+        $this->assertEquals(null, TestableLocalStorage::guessMimeTypeFromFilename('file.invalid'));
     }
 
     public function testGuessMimeTypeFromExt(): void {
-        $this->assertEquals('application/pdf', TestableFileStorage::getMimeTypeFromExt('pdf'));
-        $this->assertEquals('text/csv', TestableFileStorage::getMimeTypeFromExt('csv'));
-        $this->assertEquals('text/plain', TestableFileStorage::getMimeTypeFromExt('txt'));
-        $this->assertEquals('application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', TestableFileStorage::getMimeTypeFromExt('xlsx'));
-        $this->assertEquals('application/xml', TestableFileStorage::getMimeTypeFromExt('xml'));
-
-        $this->assertEquals('text/plain', TestableFileStorage::getMimeTypeFromExt('.txt'));
-        $this->assertEquals(null, TestableFileStorage::getMimeTypeFromExt(''));
-        $this->assertEquals(null, TestableFileStorage::getMimeTypeFromExt('invalid'));
+        $this->assertEquals('application/pdf', TestableLocalStorage::getMimeTypeFromExt('pdf'));
+        $this->assertEquals('text/csv', TestableLocalStorage::getMimeTypeFromExt('csv'));
+        $this->assertEquals('text/plain', TestableLocalStorage::getMimeTypeFromExt('txt'));
+        $this->assertEquals('application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', TestableLocalStorage::getMimeTypeFromExt('xlsx'));
+        $this->assertEquals('application/xml', TestableLocalStorage::getMimeTypeFromExt('xml'));
+
+        $this->assertEquals('text/plain', TestableLocalStorage::getMimeTypeFromExt('.txt'));
+        $this->assertEquals(null, TestableLocalStorage::getMimeTypeFromExt(''));
+        $this->assertEquals(null, TestableLocalStorage::getMimeTypeFromExt('invalid'));
     }
 
     public function testGetOrganizationAndPersonFromOwner(): void {
-        $fileStorage = $this->getMockBuilder(TestableFileStorage::class)
+        $fileStorage = $this->getMockBuilder(TestableLocalStorage::class)
             ->setConstructorArgs([$this->filesystemMap, $this->entityManager, $this->accessRepository, $this->iriConverter])
             ->setMethodsExcept(['getOrganizationAndPersonFromOwner'])
             ->getMock();