deleter = $this->createMock(ShortUrlVisitsDeleterInterface::class); $this->commandTester = $this->testerForCommand(new DeleteShortUrlVisitsCommand($this->deleter)); } #[Test, DataProvider('provideCancellingInputs')] public function executionIsAbortedIfManuallyCancelled(array $input): void { $this->deleter->expects($this->never())->method('deleteShortUrlVisits'); $this->commandTester->setInputs($input); $exitCode = $this->commandTester->execute(['shortCode' => 'foo']); $output = $this->commandTester->getDisplay(); self::assertEquals(ExitCode::EXIT_SUCCESS, $exitCode); self::assertStringContainsString('Operation aborted', $output); } public static function provideCancellingInputs(): iterable { yield 'default input' => [[]]; yield 'no' => [['no']]; yield 'n' => [['n']]; } #[Test, DataProvider('provideErrorArgs')] public function warningIsPrintedInCaseOfNotFoundShortUrl(array $args, string $expectedError): void { $this->deleter->expects($this->once())->method('deleteShortUrlVisits')->willThrowException( new ShortUrlNotFoundException(), ); $this->commandTester->setInputs(['yes']); $exitCode = $this->commandTester->execute($args); $output = $this->commandTester->getDisplay(); self::assertEquals(ExitCode::EXIT_WARNING, $exitCode); self::assertStringContainsString($expectedError, $output); } public static function provideErrorArgs(): iterable { yield 'domain' => [['shortCode' => 'foo'], 'Short URL not found for "foo"']; yield 'no domain' => [['shortCode' => 'foo', '--domain' => 's.test'], 'Short URL not found for "s.test/foo"']; } #[Test] public function successMessageIsPrintedForValidShortUrls(): void { $this->deleter->expects($this->once())->method('deleteShortUrlVisits')->willReturn(new BulkDeleteResult(5)); $this->commandTester->setInputs(['yes']); $exitCode = $this->commandTester->execute(['shortCode' => 'foo']); $output = $this->commandTester->getDisplay(); self::assertEquals(ExitCode::EXIT_SUCCESS, $exitCode); self::assertStringContainsString('Successfully deleted 5 visits', $output); } }