CreateShortUrlActionTest.php 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. <?php
  2. declare(strict_types=1);
  3. namespace ShlinkioTest\Shlink\Rest\Action\ShortUrl;
  4. use Cake\Chronos\Chronos;
  5. use Laminas\Diactoros\ServerRequest;
  6. use Laminas\Diactoros\ServerRequestFactory;
  7. use Laminas\Diactoros\Uri;
  8. use PHPUnit\Framework\TestCase;
  9. use Prophecy\Argument;
  10. use Prophecy\Prophecy\ObjectProphecy;
  11. use Shlinkio\Shlink\Core\Entity\ShortUrl;
  12. use Shlinkio\Shlink\Core\Exception\ValidationException;
  13. use Shlinkio\Shlink\Core\Model\ShortUrlMeta;
  14. use Shlinkio\Shlink\Core\Service\UrlShortener;
  15. use Shlinkio\Shlink\Rest\Action\ShortUrl\CreateShortUrlAction;
  16. use function strpos;
  17. class CreateShortUrlActionTest extends TestCase
  18. {
  19. private const DOMAIN_CONFIG = [
  20. 'schema' => 'http',
  21. 'hostname' => 'foo.com',
  22. ];
  23. private CreateShortUrlAction $action;
  24. private ObjectProphecy $urlShortener;
  25. public function setUp(): void
  26. {
  27. $this->urlShortener = $this->prophesize(UrlShortener::class);
  28. $this->action = new CreateShortUrlAction($this->urlShortener->reveal(), self::DOMAIN_CONFIG);
  29. }
  30. /** @test */
  31. public function missingLongUrlParamReturnsError(): void
  32. {
  33. $this->expectException(ValidationException::class);
  34. $this->action->handle(new ServerRequest());
  35. }
  36. /**
  37. * @test
  38. * @dataProvider provideRequestBodies
  39. */
  40. public function properShortcodeConversionReturnsData(array $body, ShortUrlMeta $expectedMeta): void
  41. {
  42. $shortUrl = new ShortUrl('');
  43. $shorten = $this->urlShortener->urlToShortCode(
  44. Argument::type(Uri::class),
  45. Argument::type('array'),
  46. $expectedMeta,
  47. )->willReturn($shortUrl);
  48. $request = ServerRequestFactory::fromGlobals()->withParsedBody($body);
  49. $response = $this->action->handle($request);
  50. $this->assertEquals(200, $response->getStatusCode());
  51. $this->assertTrue(strpos($response->getBody()->getContents(), $shortUrl->toString(self::DOMAIN_CONFIG)) > 0);
  52. $shorten->shouldHaveBeenCalledOnce();
  53. }
  54. public function provideRequestBodies(): iterable
  55. {
  56. $fullMeta = [
  57. 'longUrl' => 'http://www.domain.com/foo/bar',
  58. 'validSince' => Chronos::now()->toAtomString(),
  59. 'validUntil' => Chronos::now()->toAtomString(),
  60. 'customSlug' => 'foo-bar-baz',
  61. 'maxVisits' => 50,
  62. 'findIfExists' => true,
  63. 'domain' => 'my-domain.com',
  64. ];
  65. yield [['longUrl' => 'http://www.domain.com/foo/bar'], ShortUrlMeta::createEmpty()];
  66. yield [$fullMeta, ShortUrlMeta::createFromRawData($fullMeta)];
  67. }
  68. /**
  69. * @test
  70. * @dataProvider provideInvalidDomains
  71. */
  72. public function anInvalidDomainReturnsError(string $domain): void
  73. {
  74. $shortUrl = new ShortUrl('');
  75. $urlToShortCode = $this->urlShortener->urlToShortCode(Argument::cetera())->willReturn($shortUrl);
  76. $request = (new ServerRequest())->withParsedBody([
  77. 'longUrl' => 'http://www.domain.com/foo/bar',
  78. 'domain' => $domain,
  79. ]);
  80. $this->expectException(ValidationException::class);
  81. $urlToShortCode->shouldNotBeCalled();
  82. $this->action->handle($request);
  83. }
  84. public function provideInvalidDomains(): iterable
  85. {
  86. yield ['localhost:80000'];
  87. yield ['127.0.0.1'];
  88. yield ['???/&%$&'];
  89. }
  90. }