diff --git a/tests/lib/TaskProcessing/TaskProcessingTest.php b/tests/lib/TaskProcessing/TaskProcessingTest.php index 81c34d4e9c3..381f90f2354 100644 --- a/tests/lib/TaskProcessing/TaskProcessingTest.php +++ b/tests/lib/TaskProcessing/TaskProcessingTest.php @@ -260,6 +260,69 @@ class FailingSyncProvider implements IProvider, ISynchronousProvider { } } + +class FailingSyncProviderWithUserFacingError implements IProvider, ISynchronousProvider { + public const ERROR_MESSAGE = 'Failure'; + public const USER_FACING_ERROR_MESSAGE = 'User-facing Failure'; + public function getId(): string { + return 'test:sync:fail:user-facing'; + } + + public function getName(): string { + return self::class; + } + + public function getTaskTypeId(): string { + return TextToText::ID; + } + + public function getExpectedRuntime(): int { + return 10; + } + + public function getOptionalInputShape(): array { + return [ + 'optionalKey' => new ShapeDescriptor('optional Key', 'AN optional key', EShapeType::Text), + ]; + } + + public function getOptionalOutputShape(): array { + return [ + 'optionalKey' => new ShapeDescriptor('optional Key', 'AN optional key', EShapeType::Text), + ]; + } + + public function process(?string $userId, array $input, callable $reportProgress): array { + $e = new ProcessingException(self::ERROR_MESSAGE); + $e->setUserFacingMessage(self::USER_FACING_ERROR_MESSAGE); + throw $e; + } + + public function getInputShapeEnumValues(): array { + return []; + } + + public function getInputShapeDefaults(): array { + return []; + } + + public function getOptionalInputShapeEnumValues(): array { + return []; + } + + public function getOptionalInputShapeDefaults(): array { + return []; + } + + public function getOutputShapeEnumValues(): array { + return []; + } + + public function getOptionalOutputShapeEnumValues(): array { + return []; + } +} + class BrokenSyncProvider implements IProvider, ISynchronousProvider { public function getId(): string { return 'test:sync:broken-output'; @@ -547,6 +610,7 @@ class TaskProcessingTest extends \Test\TestCase { $this->providers = [ SuccessfulSyncProvider::class => new SuccessfulSyncProvider(), FailingSyncProvider::class => new FailingSyncProvider(), + FailingSyncProviderWithUserFacingError::class => new FailingSyncProviderWithUserFacingError(), BrokenSyncProvider::class => new BrokenSyncProvider(), AsyncProvider::class => new AsyncProvider(), AudioToImage::class => new AudioToImage(), @@ -726,6 +790,36 @@ class TaskProcessingTest extends \Test\TestCase { self::assertEquals(FailingSyncProvider::ERROR_MESSAGE, $task->getErrorMessage()); } + public function testProviderShouldBeRegisteredAndFailWithUserFacingMessage(): void { + $this->registrationContext->expects($this->any())->method('getTaskProcessingProviders')->willReturn([ + new ServiceRegistration('test', FailingSyncProviderWithUserFacingError::class) + ]); + self::assertCount(1, $this->manager->getAvailableTaskTypes()); + self::assertCount(1, $this->manager->getAvailableTaskTypeIds()); + self::assertTrue($this->manager->hasProviders()); + $task = new Task(TextToText::ID, ['input' => 'Hello'], 'test', null); + self::assertNull($task->getId()); + self::assertEquals(Task::STATUS_UNKNOWN, $task->getStatus()); + $this->manager->scheduleTask($task); + self::assertNotNull($task->getId()); + self::assertEquals(Task::STATUS_SCHEDULED, $task->getStatus()); + + $this->eventDispatcher->expects($this->once())->method('dispatchTyped')->with(new IsInstanceOf(TaskFailedEvent::class)); + + $backgroundJob = new SynchronousBackgroundJob( + Server::get(ITimeFactory::class), + $this->manager, + $this->jobList, + Server::get(LoggerInterface::class), + ); + $backgroundJob->start($this->jobList); + + $task = $this->manager->getTask($task->getId()); + self::assertEquals(Task::STATUS_FAILED, $task->getStatus()); + self::assertEquals(FailingSyncProviderWithUserFacingError::ERROR_MESSAGE, $task->getErrorMessage()); + self::assertEquals(FailingSyncProviderWithUserFacingError::USER_FACING_ERROR_MESSAGE, $task->getUserFacingErrorMessage()); + } + public function testProviderShouldBeRegisteredAndFailOutputValidation(): void { $this->registrationContext->expects($this->any())->method('getTaskProcessingProviders')->willReturn([ new ServiceRegistration('test', BrokenSyncProvider::class)