featureManager = $this->createMock(FeatureManagerInterface::class); } public function testTheRealDocumentIsServedWhileTheFeatureIsOff(): void { $this->featureManager->method('isActive')->with('upload_replacement')->willReturn(false); $this->assertSame( '/srv/app/uploads/invoice/i/invoice-1.pdf', $this->handler()->getResolvedUploadFilepath($this->upload()) ); } public function testTheStandInIsServedWhileTheFeatureIsOn(): 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()) ); } public function testAMissingStandInFailsInsteadOfServingTheRealDocument(): void { $this->featureManager->method('isActive')->with('upload_replacement')->willReturn(true); $this->expectException(\RuntimeException::class); $this->expectExceptionMessage('/srv/app/assets/pdf/nope.pdf'); $this->handler(self::PROJECT_DIR, 'assets/pdf/nope.pdf') ->getResolvedUploadFilepath($this->upload()) ; } /** * The real location is never substituted: it is what writes target. */ public function testTheUploadFilepathIgnoresTheFeature(): void { $this->featureManager->method('isActive')->with('upload_replacement')->willReturn(true); $this->assertSame( '/srv/app/uploads/invoice/i/invoice-1.pdf', $this->handler()->getUploadFilepath($this->upload()) ); } private function handler( string $projectDir = self::PROJECT_DIR, 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, $replacementFile, ); } private function upload(): Upload { return (new Upload()) ->setType(Upload::TYPE_INVOICE) ->setFilename('invoice-1.pdf') ; } }