fix: replace only missing uploads with dummy document

This commit is contained in:
fromme committed 2026-09-26 12:13:16 +02:00
1 parent 69b8e549ee
commit 80c6016da3
2 files changed
+72 -31

No files matched your search

+50 -25
View File
@@ -12,59 +12,86 @@ use Oneup\UploaderBundle\Uploader\Orphanage\OrphanageManager;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
use Psr\Log\NullLogger;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\HttpFoundation\RequestStack;
/**
* The stand-in document is gated by the upload_replacement feature and by nothing else - not by
* the environment, not by whether a path happens to be configured. That, and the fact that a
* missing stand-in is an error rather than a silent fall back to the genuine file, is what is
* pinned here.
* The stand-in document fills a gap, it never covers a file that is there: environments other
* than prod run on anonymized copies of the production database but never carry over the uploaded
* files. A file that is present - one uploaded while testing - has to come back untouched, or the
* upload flow could not be exercised at all. That, and the fact that the feature is the only
* thing gating the fallback, is what is pinned here.
*/
class UploadHandlerTest extends TestCase
{
private const PROJECT_DIR = '/srv/app';
private const REPLACEMENT_FILE = 'assets/pdf/chicken.pdf';
private const UPLOAD_PATH = 'uploads/invoice/i/invoice-1.pdf';
private FeatureManagerInterface&MockObject $featureManager;
private Filesystem $filesystem;
private string $projectDir;
protected function setUp(): void
{
$this->featureManager = $this->createMock(FeatureManagerInterface::class);
$this->filesystem = new Filesystem();
$this->projectDir = sprintf('%s/upload-handler-%s', sys_get_temp_dir(), uniqid());
$this->filesystem->mkdir($this->projectDir.'/'.\dirname(self::REPLACEMENT_FILE));
$this->filesystem->dumpFile($this->projectDir.'/'.self::REPLACEMENT_FILE, '%PDF-1.4 stand-in');
}
public function testTheRealDocumentIsServedWhileTheFeatureIsOff(): void
protected function tearDown(): void
{
$this->featureManager->method('isActive')->with('upload_replacement')->willReturn(false);
$this->filesystem->remove($this->projectDir);
}
/**
* The point of the whole feature: a document uploaded while testing is served as it is.
*/
public function testAnExistingUploadIsServedEvenWhileTheFeatureIsOn(): void
{
$this->featureManager->method('isActive')->with('upload_replacement')->willReturn(true);
$this->filesystem->dumpFile($this->projectDir.'/'.self::UPLOAD_PATH, '%PDF-1.4 the real one');
$this->assertSame(
'/srv/app/uploads/invoice/i/invoice-1.pdf',
$this->projectDir.'/'.self::UPLOAD_PATH,
$this->handler()->getResolvedUploadFilepath($this->upload())
);
}
public function testTheStandInIsServedWhileTheFeatureIsOn(): void
public function testAMissingUploadIsReplacedWhileTheFeatureIsOn(): void
{
$this->featureManager->method('isActive')->with('upload_replacement')->willReturn(true);
// the real file of the repository, so the path resolves to something that exists
$handler = $this->handler(\dirname(__DIR__, 3), self::REPLACEMENT_FILE);
$this->assertSame(
\dirname(__DIR__, 3).'/'.self::REPLACEMENT_FILE,
$handler->getResolvedUploadFilepath($this->upload())
$this->projectDir.'/'.self::REPLACEMENT_FILE,
$this->handler()->getResolvedUploadFilepath($this->upload())
);
}
public function testAMissingStandInFailsInsteadOfServingTheRealDocument(): void
/**
* Without the feature a missing file stays missing - the callers turn that into their own
* error, e.g. the 404 of the download controller.
*/
public function testAMissingUploadIsLeftAloneWhileTheFeatureIsOff(): void
{
$this->featureManager->method('isActive')->with('upload_replacement')->willReturn(false);
$this->assertSame(
$this->projectDir.'/'.self::UPLOAD_PATH,
$this->handler()->getResolvedUploadFilepath($this->upload())
);
}
public function testAMissingStandInIsAMisconfigurationAndFails(): void
{
$this->featureManager->method('isActive')->with('upload_replacement')->willReturn(true);
$this->expectException(\RuntimeException::class);
$this->expectExceptionMessage('/srv/app/assets/pdf/nope.pdf');
$this->expectExceptionMessage($this->projectDir.'/assets/pdf/nope.pdf');
$this->handler(self::PROJECT_DIR, 'assets/pdf/nope.pdf')
->getResolvedUploadFilepath($this->upload())
;
$this->handler('assets/pdf/nope.pdf')->getResolvedUploadFilepath($this->upload());
}
/**
@@ -75,22 +102,20 @@ class UploadHandlerTest extends TestCase
$this->featureManager->method('isActive')->with('upload_replacement')->willReturn(true);
$this->assertSame(
'/srv/app/uploads/invoice/i/invoice-1.pdf',
$this->projectDir.'/'.self::UPLOAD_PATH,
$this->handler()->getUploadFilepath($this->upload())
);
}
private function handler(
string $projectDir = self::PROJECT_DIR,
string $replacementFile = self::REPLACEMENT_FILE,
): UploadHandler {
private function handler(string $replacementFile = self::REPLACEMENT_FILE): UploadHandler
{
return new UploadHandler(
$this->createMock(RequestStack::class),
$this->createMock(OrphanageManager::class),
$this->createMock(Sanitizer::class),
new NullLogger(),
$this->featureManager,
$projectDir,
$this->projectDir,
$replacementFile,
);
}