diff --git a/config/test/test_config.global.php b/config/test/test_config.global.php index 069268b5..3de2584e 100644 --- a/config/test/test_config.global.php +++ b/config/test/test_config.global.php @@ -14,6 +14,13 @@ return [ 'debug' => true, ConfigAggregator::ENABLE_CACHE => false, + 'url_shortener' => [ + 'domain' => [ + 'schema' => 'http', + 'hostname' => 'doma.in', + ], + ], + 'zend-expressive-swoole' => [ 'swoole-http-server' => [ 'port' => 9999, diff --git a/module/Common/test-db/ApiTest/ApiTestCase.php b/module/Common/test-db/ApiTest/ApiTestCase.php index 1aae1065..29959837 100644 --- a/module/Common/test-db/ApiTest/ApiTestCase.php +++ b/module/Common/test-db/ApiTest/ApiTestCase.php @@ -8,6 +8,8 @@ use Fig\Http\Message\StatusCodeInterface; use GuzzleHttp\ClientInterface; use PHPUnit\Framework\TestCase; use Psr\Http\Message\ResponseInterface; +use Shlinkio\Shlink\Rest\Authentication\Plugin\ApiKeyHeaderPlugin; +use function Shlinkio\Shlink\Common\json_decode; use function sprintf; abstract class ApiTestCase extends TestCase implements StatusCodeInterface, RequestMethodInterface @@ -29,4 +31,21 @@ abstract class ApiTestCase extends TestCase implements StatusCodeInterface, Requ { return self::$client->request($method, sprintf('%s%s', self::PATH_PREFX, $uri), $options); } + + /** + * @throws \GuzzleHttp\Exception\GuzzleException + */ + protected function callApiWithKey(string $method, string $uri, array $options = []): ResponseInterface + { + $headers = $options['headers'] ?? []; + $headers[ApiKeyHeaderPlugin::HEADER_NAME] = 'valid_api_key'; + $options['headers'] = $headers; + + return $this->callApi($method, $uri, $options); + } + + protected function getJsonResponsePayload(ResponseInterface $resp): array + { + return json_decode((string) $resp->getBody()); + } } diff --git a/module/Rest/test-api/Action/ListShortUrlsTest.php b/module/Rest/test-api/Action/ListShortUrlsTest.php new file mode 100644 index 00000000..3e63da8b --- /dev/null +++ b/module/Rest/test-api/Action/ListShortUrlsTest.php @@ -0,0 +1,64 @@ +callApiWithKey(self::METHOD_GET, '/short-urls'); + $respPayload = $this->getJsonResponsePayload($resp); + + $this->assertEquals(self::STATUS_OK, $resp->getStatusCode()); + $this->assertEquals([ + 'shortUrls' => [ + 'data' => [ + [ + 'shortCode' => 'abc123', + 'shortUrl' => 'http://doma.in/abc123', + 'longUrl' => 'https://shlink.io', + 'dateCreated' => '2019-01-01T00:00:00+00:00', + 'visitsCount' => 3, + 'tags' => ['foo'], + 'originalUrl' => 'https://shlink.io', + ], + [ + 'shortCode' => 'def456', + 'shortUrl' => 'http://doma.in/def456', + 'longUrl' => + 'https://blog.alejandrocelaya.com/2017/12/09' + . '/acmailer-7-0-the-most-important-release-in-a-long-time/', + 'dateCreated' => '2019-01-01T00:00:00+00:00', + 'visitsCount' => 2, + 'tags' => ['foo', 'bar'], + 'originalUrl' => + 'https://blog.alejandrocelaya.com/2017/12/09' + . '/acmailer-7-0-the-most-important-release-in-a-long-time/', + ], + [ + 'shortCode' => 'custom', + 'shortUrl' => 'http://doma.in/custom', + 'longUrl' => 'https://shlink.io', + 'dateCreated' => '2019-01-01T00:00:00+00:00', + 'visitsCount' => 0, + 'tags' => [], + 'originalUrl' => 'https://shlink.io', + ], + ], + 'pagination' => [ + 'currentPage' => 1, + 'pagesCount' => 1, + 'itemsPerPage' => 10, + 'itemsInCurrentPage' => 3, + 'totalItems' => 3, + ], + ], + ], $respPayload); + } +} diff --git a/module/Rest/test-api/Fixtures/ShortUrlsFixture.php b/module/Rest/test-api/Fixtures/ShortUrlsFixture.php index 438b819e..62c16c74 100644 --- a/module/Rest/test-api/Fixtures/ShortUrlsFixture.php +++ b/module/Rest/test-api/Fixtures/ShortUrlsFixture.php @@ -6,6 +6,7 @@ namespace ShlinkioApiTest\Shlink\Rest\Fixtures; use Cake\Chronos\Chronos; use Doctrine\Common\DataFixtures\AbstractFixture; use Doctrine\Common\Persistence\ObjectManager; +use ReflectionObject; use Shlinkio\Shlink\Core\Entity\ShortUrl; use Shlinkio\Shlink\Core\Model\ShortUrlMeta; @@ -18,19 +19,19 @@ class ShortUrlsFixture extends AbstractFixture */ public function load(ObjectManager $manager): void { - $abcShortUrl = (new ShortUrl('https://shlink.io'))->setShortCode('abc123'); + $abcShortUrl = $this->setShortUrlDate(new ShortUrl('https://shlink.io'))->setShortCode('abc123'); $manager->persist($abcShortUrl); - $defShortUrl = (new ShortUrl( - 'https://shlink.io', + $defShortUrl = $this->setShortUrlDate(new ShortUrl( + 'https://blog.alejandrocelaya.com/2017/12/09/acmailer-7-0-the-most-important-release-in-a-long-time/', ShortUrlMeta::createFromParams(Chronos::now()->addDays(3)) ))->setShortCode('def456'); $manager->persist($defShortUrl); - $customShortUrl = new ShortUrl( + $customShortUrl = $this->setShortUrlDate(new ShortUrl( 'https://shlink.io', ShortUrlMeta::createFromParams(null, null, 'custom', 2) - ); + )); $manager->persist($customShortUrl); $manager->flush(); @@ -38,4 +39,14 @@ class ShortUrlsFixture extends AbstractFixture $this->addReference('abc123_short_url', $abcShortUrl); $this->addReference('def456_short_url', $defShortUrl); } + + private function setShortUrlDate(ShortUrl $shortUrl): ShortUrl + { + $ref = new ReflectionObject($shortUrl); + $dateProp = $ref->getProperty('dateCreated'); + $dateProp->setAccessible(true); + $dateProp->setValue($shortUrl, Chronos::create(2019, 1, 1, 0, 0, 0)); + + return $shortUrl; + } } diff --git a/module/Rest/test-api/Middleware/AuthenticationTest.php b/module/Rest/test-api/Middleware/AuthenticationTest.php index a4692b9d..c87b3c01 100644 --- a/module/Rest/test-api/Middleware/AuthenticationTest.php +++ b/module/Rest/test-api/Middleware/AuthenticationTest.php @@ -22,7 +22,7 @@ class AuthenticationTest extends ApiTestCase try { $this->callApi(self::METHOD_GET, '/short-codes'); } catch (ClientException $e) { - ['error' => $error, 'message' => $message] = json_decode((string) $e->getResponse()->getBody()); + ['error' => $error, 'message' => $message] = $this->getJsonResponsePayload($e->getResponse()); $this->assertEquals(self::STATUS_UNAUTHORIZED, $e->getCode()); $this->assertEquals(RestUtils::INVALID_AUTHORIZATION_ERROR, $error);