urlShortener = $this->prophesize(UrlShortener::class); $this->stringifier = $this->prophesize(ShortUrlStringifierInterface::class); $this->stringifier->stringify(Argument::type(ShortUrl::class))->willReturn(''); $command = new CreateShortUrlCommand( $this->urlShortener->reveal(), $this->stringifier->reveal(), new UrlShortenerOptions(['defaultShortCodesLength' => 5, 'domain' => ['hostname' => self::DEFAULT_DOMAIN]]), ); $this->commandTester = $this->testerForCommand($command); } /** @test */ public function properShortCodeIsCreatedIfLongUrlIsCorrect(): void { $shortUrl = ShortUrl::createEmpty(); $urlToShortCode = $this->urlShortener->shorten(Argument::cetera())->willReturn($shortUrl); $stringify = $this->stringifier->stringify($shortUrl)->willReturn('stringified_short_url'); $this->commandTester->execute([ 'longUrl' => 'http://domain.com/foo/bar', '--max-visits' => '3', ]); $output = $this->commandTester->getDisplay(); self::assertEquals(ExitCodes::EXIT_SUCCESS, $this->commandTester->getStatusCode()); self::assertStringContainsString('stringified_short_url', $output); $urlToShortCode->shouldHaveBeenCalledOnce(); $stringify->shouldHaveBeenCalledOnce(); } /** @test */ public function exceptionWhileParsingLongUrlOutputsError(): void { $url = 'http://domain.com/invalid'; $this->urlShortener->shorten(Argument::cetera())->willThrow(InvalidUrlException::fromUrl($url)) ->shouldBeCalledOnce(); $this->commandTester->execute(['longUrl' => $url]); $output = $this->commandTester->getDisplay(); self::assertEquals(ExitCodes::EXIT_FAILURE, $this->commandTester->getStatusCode()); self::assertStringContainsString('Provided URL http://domain.com/invalid is invalid.', $output); } /** @test */ public function providingNonUniqueSlugOutputsError(): void { $urlToShortCode = $this->urlShortener->shorten(Argument::cetera())->willThrow( NonUniqueSlugException::fromSlug('my-slug'), ); $this->commandTester->execute(['longUrl' => 'http://domain.com/invalid', '--custom-slug' => 'my-slug']); $output = $this->commandTester->getDisplay(); self::assertEquals(ExitCodes::EXIT_FAILURE, $this->commandTester->getStatusCode()); self::assertStringContainsString('Provided slug "my-slug" is already in use', $output); $urlToShortCode->shouldHaveBeenCalledOnce(); } /** @test */ public function properlyProcessesProvidedTags(): void { $shortUrl = ShortUrl::createEmpty(); $urlToShortCode = $this->urlShortener->shorten( Argument::that(function (ShortUrlMeta $meta) { $tags = $meta->getTags(); Assert::assertEquals(['foo', 'bar', 'baz', 'boo', 'zar'], $tags); return true; }), )->willReturn($shortUrl); $stringify = $this->stringifier->stringify($shortUrl)->willReturn('stringified_short_url'); $this->commandTester->execute([ 'longUrl' => 'http://domain.com/foo/bar', '--tags' => ['foo,bar', 'baz', 'boo,zar,baz'], ]); $output = $this->commandTester->getDisplay(); self::assertEquals(ExitCodes::EXIT_SUCCESS, $this->commandTester->getStatusCode()); self::assertStringContainsString('stringified_short_url', $output); $urlToShortCode->shouldHaveBeenCalledOnce(); $stringify->shouldHaveBeenCalledOnce(); } /** * @test * @dataProvider provideDomains */ public function properlyProcessesProvidedDomain(array $input, ?string $expectedDomain): void { $shorten = $this->urlShortener->shorten( Argument::that(function (ShortUrlMeta $meta) use ($expectedDomain) { Assert::assertEquals($expectedDomain, $meta->getDomain()); return true; }), )->willReturn(ShortUrl::createEmpty()); $input['longUrl'] = 'http://domain.com/foo/bar'; $this->commandTester->execute($input); self::assertEquals(ExitCodes::EXIT_SUCCESS, $this->commandTester->getStatusCode()); $shorten->shouldHaveBeenCalledOnce(); } public function provideDomains(): iterable { yield 'no domain' => [[], null]; yield 'non-default domain foo' => [['--domain' => 'foo.com'], 'foo.com']; yield 'non-default domain bar' => [['-d' => 'bar.com'], 'bar.com']; yield 'default domain' => [['--domain' => self::DEFAULT_DOMAIN], null]; } /** * @test * @dataProvider provideFlags */ public function urlValidationHasExpectedValueBasedOnProvidedFlags(array $options, ?bool $expectedValidateUrl): void { $shortUrl = ShortUrl::createEmpty(); $urlToShortCode = $this->urlShortener->shorten( Argument::that(function (ShortUrlMeta $meta) use ($expectedValidateUrl) { Assert::assertEquals($expectedValidateUrl, $meta->doValidateUrl()); return $meta; }), )->willReturn($shortUrl); $options['longUrl'] = 'http://domain.com/foo/bar'; $this->commandTester->execute($options); $urlToShortCode->shouldHaveBeenCalledOnce(); } public function provideFlags(): iterable { yield 'no flags' => [[], null]; yield 'validate-url' => [['--validate-url' => true], true]; } }