Kaynağa Gözat

fix tests for FileStorages, add for FileManager and AssetsExtension

Olivier Massot 3 yıl önce
ebeveyn
işleme
3c1f37034e

+ 6 - 6
src/Service/Export/Model/LicenceCmf.php

@@ -93,7 +93,7 @@ class LicenceCmf implements ExportModelInterface
      *
      * @var File|null
      */
-    private ?File $personAvatarUri = null;
+    private ?File $personAvatar = null;
 
     /**
      * @return int
@@ -345,18 +345,18 @@ class LicenceCmf implements ExportModelInterface
     /**
      * @return File|null
      */
-    public function getPersonAvatarUri(): ?File
+    public function getPersonAvatar(): ?File
     {
-        return $this->personAvatarUri;
+        return $this->personAvatar;
     }
 
     /**
-     * @param File|null $personAvatarUri
+     * @param File|null $personAvatar
      * @return LicenceCmf
      */
-    public function setPersonAvatarUri(?File $personAvatarUri): LicenceCmf
+    public function setPersonAvatar(?File $personAvatar): LicenceCmf
     {
-        $this->personAvatarUri = $personAvatarUri;
+        $this->personAvatar = $personAvatar;
 
         return $this;
     }

+ 2 - 0
src/Service/Twig/AssetsExtension.php

@@ -15,6 +15,8 @@ use Twig\TwigFunction;
  *
  * This is particularly useful for exports, since wkhtmltoX can't resolve partial paths for assets, or download
  * files from the Opentalent API (the non-public ones at least)
+ *
+ * // TODO: à voir si c'est bien à sa place parmi les services
  */
 class AssetsExtension extends AbstractExtension
 {

+ 10 - 10
tests/Service/Export/BaseExporterTest.php

@@ -12,8 +12,8 @@ use App\Repository\Core\FileRepository;
 use App\Service\Export\BaseExporter;
 use App\Service\Export\Encoder\EncoderInterface;
 use App\Service\Export\Model\ExportModelInterface;
+use App\Service\File\Storage\LocalStorage;
 use App\Service\ServiceIterator\EncoderIterator;
-use App\Service\Storage\LocalStorage;
 use Doctrine\ORM\EntityManagerInterface;
 use PHPUnit\Framework\MockObject\MockObject;
 use PHPUnit\Framework\TestCase;
@@ -39,7 +39,7 @@ class BaseExporterTest extends TestCase
     private Environment $twig;
     private EncoderIterator $encoderIterator;
     private EntityManagerInterface $entityManager;
-    private LocalStorage $storage;
+    private LocalStorage $localStorage;
     private LoggerInterface $logger;
 
     public function setUp(): void {
@@ -48,7 +48,7 @@ class BaseExporterTest extends TestCase
         $this->twig = $this->getMockBuilder(Environment::class)->disableOriginalConstructor()->getMock();
         $this->encoderIterator = $this->getMockBuilder(EncoderIterator::class)->disableOriginalConstructor()->getMock();
         $this->entityManager = $this->getMockBuilder(EntityManagerInterface::class)->disableOriginalConstructor()->getMock();
-        $this->storage = $this->getMockBuilder(LocalStorage::class)->disableOriginalConstructor()->getMock();
+        $this->localStorage = $this->getMockBuilder(LocalStorage::class)->disableOriginalConstructor()->getMock();
         $this->logger = $this->getMockBuilder(LoggerInterface::class)->disableOriginalConstructor()->getMock();
     }
 
@@ -56,7 +56,7 @@ class BaseExporterTest extends TestCase
     {
         $exporter = $this->getMockBuilder(TestableBaseExporter::class)
             ->setMethodsExcept([$method, 'setAccessRepository', 'setFileRepository', 'setTwig', 'setEncoderIterator',
-                'setEntityManager', 'setStorage', 'setLogger'])
+                'setEntityManager', 'setLocalStorage', 'setLogger'])
             ->getMock();
 
         $exporter->setAccessRepository($this->accessRepository);
@@ -64,7 +64,7 @@ class BaseExporterTest extends TestCase
         $exporter->setTwig($this->twig);
         $exporter->setEncoderIterator($this->encoderIterator);
         $exporter->setEntityManager($this->entityManager);
-        $exporter->setStorage($this->storage);
+        $exporter->setLocalStorage($this->localStorage);
         $exporter->setLogger($this->logger);
 
         return $exporter;
@@ -106,7 +106,7 @@ class BaseExporterTest extends TestCase
         $file = $this->getMockBuilder(File::class)->disableOriginalConstructor()->getMock();
         $this->fileRepository->method('find')->with(456, null, null)->willReturn($file);
 
-        $this->storage->expects(self::once())->method('writeFile')->with($file, $data, $access);
+        $this->localStorage->expects(self::once())->method('writeFile')->with($file, $data, $access);
 
         $exporter->export($exportRequest);
     }
@@ -138,7 +138,7 @@ class BaseExporterTest extends TestCase
         $file = $this->getMockBuilder(File::class)->disableOriginalConstructor()->getMock();
         $exporter->expects(self::once())->method('prepareFile')->willReturn($file);
 
-        $this->storage->expects(self::once())->method('writeFile')->with($file, $data, $access);
+        $this->localStorage->expects(self::once())->method('writeFile')->with($file, $data, $access);
 
         $exporter->export($exportRequest);
     }
@@ -155,7 +155,7 @@ class BaseExporterTest extends TestCase
 
         $this->accessRepository->method('find')->with(123, null, null)->willReturn(null);
 
-        $this->storage->expects(self::never())->method('writeFile');
+        $this->localStorage->expects(self::never())->method('writeFile');
 
         $this->expectException(\RuntimeException::class);
         $this->expectExceptionMessage('Unable to determine the user; abort.');
@@ -186,7 +186,7 @@ class BaseExporterTest extends TestCase
         $access->method('getOrganization')->willReturn(null);
         $this->accessRepository->method('find')->with(123, null, null)->willReturn($access);
 
-        $this->storage->expects(self::never())->method('writeFile');
+        $this->localStorage->expects(self::never())->method('writeFile');
 
         $this->expectException(\RuntimeException::class);
         $this->expectExceptionMessage('Unable to determine the organization of the curent user; abort.');
@@ -212,7 +212,7 @@ class BaseExporterTest extends TestCase
 
         $file = $this->getMockBuilder(File::class)->disableOriginalConstructor()->getMock();
 
-        $this->storage->expects(self::once())
+        $this->localStorage->expects(self::once())
             ->method('prepareFile')
             ->with(
                 $access, 'Foo.pdf', FileTypeEnum::UNKNOWN(), $access, true, 'NOBODY', 'application/pdf', false

+ 15 - 8
tests/Service/Export/LicenceCmfExporterTest.php

@@ -15,8 +15,9 @@ use App\Repository\Organization\OrganizationRepository;
 use App\Service\Export\Encoder\PdfEncoder;
 use App\Service\Export\LicenceCmfExporter;
 use App\Service\Export\Model\LicenceCmf;
+use App\Service\File\FileManager;
 use App\Service\ServiceIterator\EncoderIterator;
-use App\Service\Storage\LocalStorage;
+use App\Service\File\Storage\LocalStorage;
 use App\Tests\TestToolsTrait;
 use Doctrine\Common\Collections\Collection;
 use Doctrine\ORM\EntityManagerInterface;
@@ -34,7 +35,8 @@ class LicenceCmfExporterTest extends TestCase
     private MockObject | Environment $twig;
     private MockObject | EncoderIterator $encoderIterator;
     private MockObject | EntityManagerInterface $em;
-    private MockObject | LocalStorage $storage;
+    private MockObject | LocalStorage $localStorage;
+    private MockObject | FileManager $fileManager;
     private MockObject | OrganizationRepository $organizationRepo;
     private MockObject | Access $access;
     private MockObject | Organization $organization;
@@ -56,7 +58,8 @@ 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(LocalStorage::class)->disableOriginalConstructor()->getMock();
+        $this->localStorage = $this->getMockBuilder(LocalStorage::class)->disableOriginalConstructor()->getMock();
+        $this->fileManager = $this->getMockBuilder(FileManager::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();
@@ -76,14 +79,15 @@ class LicenceCmfExporterTest extends TestCase
         $exporter = $this->getMockBuilder(LicenceCmfExporter::class)
             ->setConstructorArgs([$this->organizationRepo])
             ->setMethodsExcept(['setAccessRepository', 'setTwig', 'setEncoderIterator',
-                'setEntityManager', 'setEntityManager', 'setStorage', $methodUnderTest])
+                'setEntityManager', 'setEntityManager', 'setLocalStorage', 'setFileManager', $methodUnderTest])
             ->getMock();
 
         $exporter->setAccessRepository($this->accessRepo);
         $exporter->setTwig($this->twig);
         $exporter->setEncoderIterator($this->encoderIterator);
         $exporter->setEntityManager($this->em);
-        $exporter->setStorage($this->storage);
+        $exporter->setLocalStorage($this->localStorage);
+        $exporter->setFileManager($this->fileManager);
 
         return $exporter;
     }
@@ -118,7 +122,7 @@ class LicenceCmfExporterTest extends TestCase
         $this->parent->expects(self::once())->method('getName')->willReturn('my_network');
         $this->organization->method('getLogo')->willReturn($this->logo);
         $this->logo->method('getId')->willReturn(1);
-        $this->storage->method('getDownloadIri')->willReturn('http:://foo.bar/1');
+        $this->fileManager->method('getDownloadIri')->willReturn('http:://foo.bar/1');
         $this->president->method('getId')->willReturn(1);
         $this->president->method('getGender')->willReturn('M');
         $this->president->method('getGivenName')->willReturn('Joe');
@@ -148,12 +152,15 @@ class LicenceCmfExporterTest extends TestCase
 
         $licence = $modelCollection->getLicences()[0];
 
+        $logo = $this->getMockBuilder(File::class)->getMock();
+        $qrCode = $this->getMockBuilder(File::class)->getMock();
+
         $this->assertEquals('my_network', $licence->getFederationName());
         $this->assertEquals(true, $licence->isOrganizationLicence());
         $this->assertEquals(2020, $licence->getYear());
         $this->assertEquals('931572', $licence->getColor());
-        $this->assertEquals('http:://foo.bar/1', $licence->getQrCodeUri());
-        $this->assertEquals('http:://foo.bar/1', $licence->getLogoUri());
+        $this->assertEquals($qrCode, $licence->getQrCode());
+        $this->assertEquals($logo, $licence->getLogo());
     }
 
     /**

+ 12 - 6
tests/Service/Export/Model/LicenceCmfTest.php

@@ -2,6 +2,7 @@
 
 namespace App\Tests\Service\Export\Model;
 
+use App\Entity\Core\File;
 use App\Service\Export\Model\LicenceCmf;
 use PHPUnit\Framework\TestCase;
 
@@ -39,6 +40,11 @@ class LicenceCmfTest extends TestCase
      * @see LicenceCmf::getPersonAvatarUri()
      */
     public function testSetters(): void {
+
+        $logo = $this->getMockBuilder(File::class)->getMock();
+        $qrCode = $this->getMockBuilder(File::class)->getMock();
+        $avatar = $this->getMockBuilder(File::class)->getMock();
+
         $model = new LicenceCmf();
         $model
             ->setId(1)
@@ -48,13 +54,13 @@ class LicenceCmfTest extends TestCase
             ->setOrganizationIdentifier('123')
             ->setFederationName('bar')
             ->setColor('#55555')
-            ->setLogoUri('/file/1')
-            ->setQrCodeUri('file/2')
+            ->setLogo($logo)
+            ->setQrCode($qrCode)
             ->setPersonId(2)
             ->setPersonGender('MR')
             ->setPersonFirstName('Don Diego')
             ->setPersonLastName('De la Vega')
-            ->setPersonAvatarUri('/file/3');
+            ->setPersonAvatar($avatar);
 
         $this->assertEquals(1, $model->getId());
         $this->assertEquals(2020, $model->getYear());
@@ -63,13 +69,13 @@ class LicenceCmfTest extends TestCase
         $this->assertEquals('123', $model->getOrganizationIdentifier());
         $this->assertEquals('bar', $model->getFederationName());
         $this->assertEquals('#55555', $model->getColor());
-        $this->assertEquals('/file/1', $model->getLogoUri());
-        $this->assertEquals('file/2', $model->getQrCodeUri());
+        $this->assertEquals($logo, $model->getLogo());
+        $this->assertEquals($qrCode, $model->getQrCode());
         $this->assertEquals(2, $model->getPersonId());
         $this->assertEquals('MR', $model->getPersonGender());
         $this->assertEquals('Don Diego', $model->getPersonFirstName());
         $this->assertEquals('De la Vega', $model->getPersonLastName());
-        $this->assertEquals('/file/3', $model->getPersonAvatarUri());
+        $this->assertEquals($avatar, $model->getPersonAvatar());
     }
 
 }

+ 134 - 0
tests/Service/File/FileManagerTest.php

@@ -0,0 +1,134 @@
+<?php
+
+namespace App\Tests\Service\File;
+
+use ApiPlatform\Core\Api\IriConverterInterface;
+use App\ApiResources\DownloadRequest;
+use App\Entity\Core\File;
+use App\Enum\Core\FileHostEnum;
+use App\Service\File\Exception\FileNotFoundException;
+use App\Service\File\FileManager;
+use App\Service\File\Storage\ApiLegacyStorage;
+use App\Service\File\Storage\FileStorageInterface;
+use App\Service\File\Storage\LocalStorage;
+use PHPUnit\Framework\TestCase;
+
+class FileManagerTest extends TestCase
+{
+    private LocalStorage $localStorage;
+    private ApiLegacyStorage $apiLegacyStorage;
+    private IriConverterInterface $iriConverter;
+
+    public function setUp(): void
+    {
+        $this->localStorage = $this->getMockBuilder(LocalStorage::class)->disableOriginalConstructor()->getMock();
+        $this->apiLegacyStorage = $this->getMockBuilder(ApiLegacyStorage::class)->disableOriginalConstructor()->getMock();
+        $this->iriConverter = $this->getMockBuilder(IriConverterInterface::class)->disableOriginalConstructor()->getMock();
+    }
+
+    public function getFileManagerMockFor(string $methodName) {
+        return $this->getMockBuilder(FileManager::class)
+            ->setConstructorArgs([$this->localStorage, $this->apiLegacyStorage, $this->iriConverter])
+            ->setMethodsExcept([$methodName])
+            ->getMock();
+    }
+
+    public function testGetStorageFor(): void {
+        $fileManager = $this->getFileManagerMockFor('getStorageFor');
+
+        $file1 = $this->getMockBuilder(File::class)->getMock();
+        $file1->method('getHost')->willReturn(FileHostEnum::API1()->getValue());
+
+        $file2 = $this->getMockBuilder(File::class)->getMock();
+        $file2->method('getHost')->willReturn(FileHostEnum::AP2I()->getValue());
+
+        $this->assertEquals(
+            $fileManager->getStorageFor($file1),
+            $this->apiLegacyStorage
+        );
+
+        $this->assertEquals(
+            $fileManager->getStorageFor($file2),
+            $this->localStorage
+        );
+    }
+
+    public function testGetStorageForUnknown(): void {
+        $fileManager = $this->getFileManagerMockFor('getStorageFor');
+
+        $file = $this->getMockBuilder(File::class)->getMock();
+        $file->method('getHost')->willReturn('unknown');
+
+        $this->expectException(FileNotFoundException::class);
+
+        $fileManager->getStorageFor($file);
+    }
+
+    public function testRead(): void {
+        $fileManager = $this->getFileManagerMockFor('read');
+
+        $file = $this->getMockBuilder(File::class)->getMock();
+
+        $storage = $this->getMockBuilder(FileStorageInterface::class)->getMock();
+        $storage->expects(self::once())->method('read')->with($file)->willReturn('foo');
+
+        $fileManager->expects(self::once())->method('getStorageFor')->with($file)->willReturn($storage);
+
+        $this->assertEquals(
+            $fileManager->read($file),
+            'foo'
+        );
+    }
+
+    /**
+     * @see LocalStorage::guessMimeTypeFromFilename()
+     */
+    public function testGuessMimeTypeFromFilename(): void {
+        $this->assertEquals('application/pdf', FileManager::guessMimeTypeFromFilename('file.pdf'));
+        $this->assertEquals('text/csv', FileManager::guessMimeTypeFromFilename('file.csv'));
+        $this->assertEquals('text/plain', FileManager::guessMimeTypeFromFilename('file.txt'));
+        $this->assertEquals('application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', FileManager::guessMimeTypeFromFilename('file.xlsx'));
+        $this->assertEquals('application/xml', FileManager::guessMimeTypeFromFilename('file.xml'));
+
+        $this->assertEquals(null, FileManager::guessMimeTypeFromFilename('file'));
+        $this->assertEquals(null, FileManager::guessMimeTypeFromFilename('file.invalid'));
+    }
+
+    /**
+     * @see LocalStorage::getMimeTypeFromExt()
+     */
+    public function testGuessMimeTypeFromExt(): void {
+        $this->assertEquals('application/pdf', FileManager::getMimeTypeFromExt('pdf'));
+        $this->assertEquals('text/csv', FileManager::getMimeTypeFromExt('csv'));
+        $this->assertEquals('text/plain', FileManager::getMimeTypeFromExt('txt'));
+        $this->assertEquals('application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', FileManager::getMimeTypeFromExt('xlsx'));
+        $this->assertEquals('application/xml', FileManager::getMimeTypeFromExt('xml'));
+
+        $this->assertEquals('text/plain', FileManager::getMimeTypeFromExt('.txt'));
+        $this->assertEquals(null, FileManager::getMimeTypeFromExt(''));
+        $this->assertEquals(null, FileManager::getMimeTypeFromExt('invalid'));
+    }
+
+    /**
+     * @see LocalStorage::getDownloadIri()
+     */
+    public function testGetDownloadIri(): void
+    {
+        $fileManager = $this->getFileManagerMockFor('getDownloadIri');
+
+        $file = $this->getMockBuilder(File::class)->getMock();
+        $file->method('getId')->willReturn(1);
+
+        $this->iriConverter
+            ->expects(self::once())
+            ->method('getItemIriFromResourceClass')
+            ->with(DownloadRequest::class, ['fileId' => 1])
+            ->willReturn('/api/download/1');
+
+        $this->assertEquals(
+            '/api/download/1',
+            $fileManager->getDownloadIri($file)
+        );
+    }
+
+}

+ 2 - 2
tests/Service/Storage/ApiLegacyStorageTest.php → tests/Service/File/Storage/ApiLegacyStorageTest.php

@@ -1,10 +1,10 @@
 <?php
 
-namespace App\Tests\Service\Storage;
+namespace App\Tests\Service\File\Storage;
 
 use App\Entity\Core\File;
 use App\Service\ApiLegacy\ApiLegacyRequestService;
-use App\Service\Storage\ApiLegacyStorage;
+use App\Service\File\Storage\ApiLegacyStorage;
 use PHPUnit\Framework\TestCase;
 
 class ApiLegacyStorageTest extends TestCase

+ 2 - 55
tests/Service/Storage/LocalStorageTest.php → tests/Service/File/Storage/LocalStorageTest.php

@@ -1,6 +1,6 @@
 <?php
 
-namespace App\Tests\Service\Storage;
+namespace App\Tests\Service\File\Storage;
 
 use ApiPlatform\Core\Api\IriConverterInterface;
 use App\ApiResources\DownloadRequest;
@@ -11,7 +11,7 @@ use App\Entity\Person\Person;
 use App\Enum\Core\FileStatusEnum;
 use App\Enum\Core\FileTypeEnum;
 use App\Repository\Access\AccessRepository;
-use App\Service\Storage\LocalStorage;
+use App\Service\File\Storage\LocalStorage;
 use DateTime;
 use Doctrine\ORM\EntityManagerInterface;
 use Gaufrette\Filesystem;
@@ -85,30 +85,6 @@ class LocalStorageTest extends TestCase
         $this->assertFalse($fileStorage->exists($file));
     }
 
-    /**
-     * @see LocalStorage::getDownloadIri()
-     */
-    public function testGetDownloadIri(): void
-    {
-        $fileStorage = $this->getMockBuilder(TestableLocalStorage::class)
-            ->setConstructorArgs([$this->filesystemMap, $this->entityManager, $this->accessRepository, $this->iriConverter])
-            ->setMethodsExcept(['getDownloadIri'])
-            ->getMock();
-
-        $file = $this->getMockBuilder(File::class)->getMock();
-        $file->method('getId')->willReturn(1);
-
-        $this->iriConverter
-            ->expects(self::once())
-            ->method('getItemIriFromResourceClass')
-            ->with(DownloadRequest::class, ['fileId' => 1])
-            ->willReturn('/api/download/1');
-
-        $this->assertEquals(
-            '/api/download/1',
-            $fileStorage->getDownloadIri($file)
-        );
-    }
 
     /**
      * @see LocalStorage::listByOwner()
@@ -634,35 +610,6 @@ class LocalStorageTest extends TestCase
         $this->assertEquals('organization/1/licence_cmf', $prefix);
     }
 
-    /**
-     * @see LocalStorage::guessMimeTypeFromFilename()
-     */
-    public function testGuessMimeTypeFromFilename(): void {
-        $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'));
-    }
-
-    /**
-     * @see LocalStorage::getMimeTypeFromExt()
-     */
-    public function testGuessMimeTypeFromExt(): void {
-        $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'));
-    }
-
     /**
      * @see LocalStorage::getOrganizationAndPersonFromOwner()
      */

+ 77 - 0
tests/Service/Twig/AssetsExtensionTest.php

@@ -0,0 +1,77 @@
+<?php
+
+namespace App\Tests\Service\Twig;
+
+use App\Entity\Core\File;
+use App\Service\File\FileManager;
+use App\Service\Twig\AssetsExtension;
+use App\Service\Utils\Path;
+use PHPUnit\Framework\TestCase;
+
+class AssetsExtensionTest extends TestCase
+{
+    private FileManager $fileManager;
+
+    public function setUp(): void {
+        $this->fileManager = $this->getMockBuilder(FileManager::class)->disableOriginalConstructor()->getMock();
+    }
+
+    public function testGetFunctions(): void {
+        $assetsExtension = $this
+            ->getMockBuilder(AssetsExtension::class)
+            ->setConstructorArgs([$this->fileManager])
+            ->setMethodsExcept(['getFunctions'])
+            ->getMock();
+
+        $functions = $assetsExtension->getFunctions();
+
+        $this->assertCount(2, $functions);
+
+        $this->assertEquals('absPath', $functions[0]->getName());
+        $this->assertEquals('toBase64Src', $functions[1]->getName());
+    }
+
+    public function testAbsPath(): void {
+        $assetsExtension = $this
+            ->getMockBuilder(AssetsExtension::class)
+            ->setConstructorArgs([$this->fileManager])
+            ->setMethodsExcept(['absPath'])
+            ->getMock();
+
+        $publicDir = Path::getProjectDir();
+
+        $this->assertEquals(
+            $publicDir . '/public/foo',
+            $assetsExtension->absPath('foo')
+        );
+
+        $this->assertEquals(
+            $publicDir . '/public/foo/bar',
+            $assetsExtension->absPath('foo/bar')
+        );
+
+        $this->assertEquals(
+            $publicDir . '/public',
+            $assetsExtension->absPath('')
+        );
+    }
+
+    public function testToBase64Src(): void {
+        $assetsExtension = $this
+            ->getMockBuilder(AssetsExtension::class)
+            ->setConstructorArgs([$this->fileManager])
+            ->setMethodsExcept(['toBase64Src'])
+            ->getMock();
+
+        $file = $this->getMockBuilder(File::class)->getMock();
+        $file->method('getMimeType')->willReturn('mime');
+
+        $this->fileManager->method('read')->with($file)->willReturn('foo');
+
+        $this->assertEquals(
+            'data:mime;base64,' . base64_encode('foo'),
+            $assetsExtension->toBase64Src($file)
+        );
+
+    }
+}