storage = $this->createStub(FilesystemOperator::class); $this->em = $this->createStub(EntityManagerInterface::class); $this->importRepository = $this->createStub(ImportRepository::class); $this->bus = $this->createStub(MessageBusInterface::class); $this->user = new User(); $idProp = new \ReflectionProperty(User::class, 'id'); $idProp->setValue($this->user, 1); $token = $this->createStub(TokenInterface::class); $token->method('getUser')->willReturn($this->user); $tokenStorage = $this->createStub(TokenStorageInterface::class); $tokenStorage->method('getToken')->willReturn($token); $container = $this->createStub(ContainerInterface::class); $container->method('has')->willReturnCallback(static fn(string $id): bool => match ($id) { 'security.token_storage' => true, 'serializer' => false, default => false, }); $container->method('get')->willReturnCallback(static fn(string $id) => match ($id) { 'security.token_storage' => $tokenStorage, default => null, }); $this->controller = new ImportController(); $this->controller->setContainer($container); } private function createRequest(): Request { $tmpFile = tempnam(sys_get_temp_dir(), 'import_test_'); file_put_contents($tmpFile, "Date,Name,Year,Letterboxd URI,Rating\n2024-01-01,Inception,2010,https://letterboxd.com/film/inception/,5"); $uploadedFile = new UploadedFile($tmpFile, 'films.csv', 'text/csv', null, true); return Request::create('/api/imports', 'POST', files: ['file' => $uploadedFile]); } private function configureEmWithImportCapture(?Import &$capturedImport): void { $this->em->method('persist')->willReturnCallback(function (object $entity) use (&$capturedImport): void { if ($entity instanceof Import) { $capturedImport = $entity; $idProp = new \ReflectionProperty(Import::class, 'id'); $idProp->setValue($entity, 42); } }); } public function testSetsImportStatusToFailedWhenStorageWriteThrows(): void { $this->importRepository->method('hasActiveImport')->willReturn(false); $capturedImport = null; $this->configureEmWithImportCapture($capturedImport); $this->storage->method('write')->willThrowException(new \RuntimeException('Storage unavailable')); $bus = $this->createMock(MessageBusInterface::class); $bus->expects($this->never())->method('dispatch'); $response = $this->controller->create($this->createRequest(), $this->storage, $this->em, $this->importRepository, $bus); $this->assertSame(Import::STATUS_FAILED, $capturedImport->getStatus()); $this->assertSame(500, $response->getStatusCode()); } public function testSetsImportStatusToFailedWhenBusDispatchThrows(): void { $this->importRepository->method('hasActiveImport')->willReturn(false); $capturedImport = null; $this->configureEmWithImportCapture($capturedImport); $this->storage->method('write')->willReturnCallback(static fn() => null); $this->bus->method('dispatch')->willThrowException(new \RuntimeException('Bus unavailable')); $response = $this->controller->create($this->createRequest(), $this->storage, $this->em, $this->importRepository, $this->bus); $this->assertSame(Import::STATUS_FAILED, $capturedImport->getStatus()); $this->assertSame(500, $response->getStatusCode()); } }