diff --git a/Tests/Unit/Service/EventExecutionServiceTest.php b/Tests/Unit/Service/EventExecutionServiceTest.php new file mode 100644 index 0000000..87f25fe --- /dev/null +++ b/Tests/Unit/Service/EventExecutionServiceTest.php @@ -0,0 +1,165 @@ +resetSingletonInstances = true; + } + + public static function lockDataProvider(): \Traversable + { + yield "Lock can be acquired, method will return true" => [ + 'acquireResult' => true, + 'exception' => null, + 'expectedResult' => true, + ]; + yield "Lock can not be acquired, method will return false" => [ + 'acquireResult' => false, + 'exception' => null, + 'expectedResult' => false, + ]; + yield "Acquire throws exception, method will return false" => [ + 'acquireResult' => false, + 'exception' => new LockAcquireException(), + 'expectedResult' => false, + ]; + } + + #[Test] + #[DataProvider('lockDataProvider')] + public function verifyLockBehaviour(bool $acquireResult, LockingException|null $exception, bool $expectedResult): void + { + $serverRepositoryMock = $this->createMock(ServerRepository::class); + $eventRepositoryMock = $this->createMock(EventRepository::class); + $moduleRepositoryMock = $this->createMock(ModuleRepository::class); + $loggingServiceMock = $this->createMock(LoggingService::class); + $persistenceManagerInterfaceMock = $this->createMock(PersistenceManagerInterface::class); + $connectionPoolMock = $this->createMock(ConnectionPool::class); + $schedulerTaskRepositoryMock = $this->createMock(SchedulerTaskRepository::class); + $extensionConfigurationMock = $this->createMock(ExtensionConfiguration::class); + + $lockerMock = $this->createMock(LockingStrategyInterface::class); + if ($exception !== null) { + $lockerMock->expects(self::once()) + ->method('acquire') + ->with(LockingStrategyInterface::LOCK_CAPABILITY_EXCLUSIVE) + ->willThrowException($exception); + } else { + $lockerMock->expects(self::once()) + ->method('acquire') + ->with(LockingStrategyInterface::LOCK_CAPABILITY_EXCLUSIVE) + ->willReturn($acquireResult); + } + $lockFactoryMock = $this->createMock(LockFactory::class); + $lockFactoryMock->expects(self::once()) + ->method('createLocker') + ->with('4ap_sync', LockingStrategyInterface::LOCK_CAPABILITY_EXCLUSIVE) + ->willReturn($lockerMock); + GeneralUtility::setSingletonInstance(LockFactory::class, $lockFactoryMock); + + $eventExecutionService = new EventExecutionService( + $serverRepositoryMock, + $eventRepositoryMock, + $moduleRepositoryMock, + $loggingServiceMock, + $persistenceManagerInterfaceMock, + $connectionPoolMock, + $schedulerTaskRepositoryMock, + $extensionConfigurationMock, + ); + + self::assertEquals( + $expectedResult, + $eventExecutionService->lock() + ); + } + + public static function unlockDataProvider(): \Traversable + { + yield "Lock can be released, method will return true" => [ + 'released' => true, + 'exception' => null, + 'expectedResult' => true, + ]; + yield "Lock can not be released, method will return false" => [ + 'released' => false, + 'exception' => null, + 'expectedResult' => false, + ]; + yield "Release the lock will throws exception, method will return false" => [ + 'released' => false, + 'exception' => new LockingException(), + 'expectedResult' => false, + ]; + } + + #[Test] + #[DataProvider('unlockDataProvider')] + public function verifyUnLockBehaviour(bool $released, LockingException|null $exception, bool $expectedResult): void + { + $serverRepositoryMock = $this->createMock(ServerRepository::class); + $eventRepositoryMock = $this->createMock(EventRepository::class); + $moduleRepositoryMock = $this->createMock(ModuleRepository::class); + $loggingServiceMock = $this->createMock(LoggingService::class); + $persistenceManagerInterfaceMock = $this->createMock(PersistenceManagerInterface::class); + $connectionPoolMock = $this->createMock(ConnectionPool::class); + $schedulerTaskRepositoryMock = $this->createMock(SchedulerTaskRepository::class); + $extensionConfigurationMock = $this->createMock(ExtensionConfiguration::class); + + $lockerMock = $this->createMock(LockingStrategyInterface::class); + if ($exception !== null) { + $lockerMock->expects(self::once()) + ->method('release') + ->willThrowException($exception); + } else { + $lockerMock->expects(self::once()) + ->method('release') + ->willReturn($released); + } + + $lockFactoryMock = $this->createMock(LockFactory::class); + $lockFactoryMock->expects(self::once()) + ->method('createLocker') + ->with('4ap_sync', LockingStrategyInterface::LOCK_CAPABILITY_EXCLUSIVE) + ->willReturn($lockerMock); + GeneralUtility::setSingletonInstance(LockFactory::class, $lockFactoryMock); + + $eventExecutionService = new EventExecutionService( + $serverRepositoryMock, + $eventRepositoryMock, + $moduleRepositoryMock, + $loggingServiceMock, + $persistenceManagerInterfaceMock, + $connectionPoolMock, + $schedulerTaskRepositoryMock, + $extensionConfigurationMock, + ); + + self::assertEquals( + $expectedResult, + $eventExecutionService->unlock() + ); + } +} diff --git a/composer.json b/composer.json index b8239a7..092cdaa 100644 --- a/composer.json +++ b/composer.json @@ -29,7 +29,8 @@ "ext-curl": "*" }, "require-dev": { - "phpunit/phpunit": "^8.5" + "phpunit/phpunit": "^10.5", + "typo3/testing-framework": "^8.0.1" }, "autoload": { "psr-4": {