From dc4aab2cab97b9cbbdbe7cc2e3a24761ba774679 Mon Sep 17 00:00:00 2001
From: Alejandro Celaya <alejandrocelaya@gmail.com>
Date: Sun, 18 Jun 2023 10:36:45 +0200
Subject: [PATCH] Replace traits with external data providers in API tests

---
 composer.json                                 |  4 ++++
 .../test-api/Action/DeleteShortUrlTest.php    | 14 +++++++----
 .../Rest/test-api/Action/EditShortUrlTest.php | 10 ++++----
 .../test-api/Action/ResolveShortUrlTest.php   | 14 +++++++----
 .../test-api/Action/ShortUrlVisitsTest.php    | 13 +++++------
 ...persTrait.php => ApiTestDataProviders.php} | 23 ++++---------------
 module/Rest/test-api/Utils/UrlBuilder.php     | 23 +++++++++++++++++++
 7 files changed, 60 insertions(+), 41 deletions(-)
 rename module/Rest/test-api/Utils/{NotFoundUrlHelpersTrait.php => ApiTestDataProviders.php} (62%)
 create mode 100644 module/Rest/test-api/Utils/UrlBuilder.php

diff --git a/composer.json b/composer.json
index c3eafb2e..67aee336 100644
--- a/composer.json
+++ b/composer.json
@@ -148,6 +148,10 @@
             "@test:unit:ci",
             "@infect:ci:unit"
         ],
+        "infect:test:db": [
+            "@test:db:sqlite:ci",
+            "@infect:ci:db"
+        ],
         "infect:test:api": [
             "@test:api:ci",
             "@infect:ci:api"
diff --git a/module/Rest/test-api/Action/DeleteShortUrlTest.php b/module/Rest/test-api/Action/DeleteShortUrlTest.php
index e15910ac..7bd3dfea 100644
--- a/module/Rest/test-api/Action/DeleteShortUrlTest.php
+++ b/module/Rest/test-api/Action/DeleteShortUrlTest.php
@@ -5,24 +5,28 @@ declare(strict_types=1);
 namespace ShlinkioApiTest\Shlink\Rest\Action;
 
 use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\DataProviderExternal;
 use PHPUnit\Framework\Attributes\Test;
 use Shlinkio\Shlink\TestUtils\ApiTest\ApiTestCase;
-use ShlinkioApiTest\Shlink\Rest\Utils\NotFoundUrlHelpersTrait;
+use ShlinkioApiTest\Shlink\Rest\Utils\ApiTestDataProviders;
+use ShlinkioApiTest\Shlink\Rest\Utils\UrlBuilder;
 
 use function sprintf;
 
 class DeleteShortUrlTest extends ApiTestCase
 {
-    use NotFoundUrlHelpersTrait;
-
-    #[Test, DataProvider('provideInvalidUrls')]
+    #[Test, DataProviderExternal(ApiTestDataProviders::class, 'invalidUrlsProvider')]
     public function notFoundErrorIsReturnWhenDeletingInvalidUrl(
         string $shortCode,
         ?string $domain,
         string $expectedDetail,
         string $apiKey,
     ): void {
-        $resp = $this->callApiWithKey(self::METHOD_DELETE, $this->buildShortUrlPath($shortCode, $domain), [], $apiKey);
+        $resp = $this->callApiWithKey(
+            self::METHOD_DELETE,
+            UrlBuilder::buildShortUrlPath($shortCode, $domain),
+            apiKey: $apiKey,
+        );
         $payload = $this->getJsonResponsePayload($resp);
 
         self::assertEquals(self::STATUS_NOT_FOUND, $resp->getStatusCode());
diff --git a/module/Rest/test-api/Action/EditShortUrlTest.php b/module/Rest/test-api/Action/EditShortUrlTest.php
index 22833970..befb5131 100644
--- a/module/Rest/test-api/Action/EditShortUrlTest.php
+++ b/module/Rest/test-api/Action/EditShortUrlTest.php
@@ -9,16 +9,16 @@ use GuzzleHttp\Psr7\Query;
 use GuzzleHttp\RequestOptions;
 use Laminas\Diactoros\Uri;
 use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\DataProviderExternal;
 use PHPUnit\Framework\Attributes\Test;
 use Shlinkio\Shlink\TestUtils\ApiTest\ApiTestCase;
-use ShlinkioApiTest\Shlink\Rest\Utils\NotFoundUrlHelpersTrait;
+use ShlinkioApiTest\Shlink\Rest\Utils\ApiTestDataProviders;
+use ShlinkioApiTest\Shlink\Rest\Utils\UrlBuilder;
 
 use function sprintf;
 
 class EditShortUrlTest extends ApiTestCase
 {
-    use NotFoundUrlHelpersTrait;
-
     #[Test, DataProvider('provideMeta')]
     public function metadataCanBeReset(array $meta): void
     {
@@ -99,14 +99,14 @@ class EditShortUrlTest extends ApiTestCase
         yield 'invalid URL' => ['http://foo', self::STATUS_BAD_REQUEST, 'INVALID_URL'];
     }
 
-    #[Test, DataProvider('provideInvalidUrls')]
+    #[Test, DataProviderExternal(ApiTestDataProviders::class, 'invalidUrlsProvider')]
     public function tryingToEditInvalidUrlReturnsNotFoundError(
         string $shortCode,
         ?string $domain,
         string $expectedDetail,
         string $apiKey,
     ): void {
-        $url = $this->buildShortUrlPath($shortCode, $domain);
+        $url = UrlBuilder::buildShortUrlPath($shortCode, $domain);
         $resp = $this->callApiWithKey(self::METHOD_PATCH, $url, [RequestOptions::JSON => []], $apiKey);
         $payload = $this->getJsonResponsePayload($resp);
 
diff --git a/module/Rest/test-api/Action/ResolveShortUrlTest.php b/module/Rest/test-api/Action/ResolveShortUrlTest.php
index 08bc6cb0..b13de872 100644
--- a/module/Rest/test-api/Action/ResolveShortUrlTest.php
+++ b/module/Rest/test-api/Action/ResolveShortUrlTest.php
@@ -7,16 +7,16 @@ namespace ShlinkioApiTest\Shlink\Rest\Action;
 use Cake\Chronos\Chronos;
 use GuzzleHttp\RequestOptions;
 use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\DataProviderExternal;
 use PHPUnit\Framework\Attributes\Test;
 use Shlinkio\Shlink\TestUtils\ApiTest\ApiTestCase;
-use ShlinkioApiTest\Shlink\Rest\Utils\NotFoundUrlHelpersTrait;
+use ShlinkioApiTest\Shlink\Rest\Utils\ApiTestDataProviders;
+use ShlinkioApiTest\Shlink\Rest\Utils\UrlBuilder;
 
 use function sprintf;
 
 class ResolveShortUrlTest extends ApiTestCase
 {
-    use NotFoundUrlHelpersTrait;
-
     #[Test, DataProvider('provideDisabledMeta')]
     public function shortUrlIsProperlyResolvedEvenWhenNotEnabled(array $disabledMeta): void
     {
@@ -42,14 +42,18 @@ class ResolveShortUrlTest extends ApiTestCase
         yield 'maxVisits reached' => [['maxVisits' => 1]];
     }
 
-    #[Test, DataProvider('provideInvalidUrls')]
+    #[Test, DataProviderExternal(ApiTestDataProviders::class, 'invalidUrlsProvider')]
     public function tryingToResolveInvalidUrlReturnsNotFoundError(
         string $shortCode,
         ?string $domain,
         string $expectedDetail,
         string $apiKey,
     ): void {
-        $resp = $this->callApiWithKey(self::METHOD_GET, $this->buildShortUrlPath($shortCode, $domain), [], $apiKey);
+        $resp = $this->callApiWithKey(
+            self::METHOD_GET,
+            UrlBuilder::buildShortUrlPath($shortCode, $domain),
+            apiKey: $apiKey,
+        );
         $payload = $this->getJsonResponsePayload($resp);
 
         self::assertEquals(self::STATUS_NOT_FOUND, $resp->getStatusCode());
diff --git a/module/Rest/test-api/Action/ShortUrlVisitsTest.php b/module/Rest/test-api/Action/ShortUrlVisitsTest.php
index 70659ed8..6a7e6a7e 100644
--- a/module/Rest/test-api/Action/ShortUrlVisitsTest.php
+++ b/module/Rest/test-api/Action/ShortUrlVisitsTest.php
@@ -7,18 +7,18 @@ namespace ShlinkioApiTest\Shlink\Rest\Action;
 use GuzzleHttp\Psr7\Query;
 use Laminas\Diactoros\Uri;
 use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\DataProviderExternal;
 use PHPUnit\Framework\Attributes\Test;
 use Shlinkio\Shlink\Common\Paginator\Paginator;
 use Shlinkio\Shlink\TestUtils\ApiTest\ApiTestCase;
-use ShlinkioApiTest\Shlink\Rest\Utils\NotFoundUrlHelpersTrait;
+use ShlinkioApiTest\Shlink\Rest\Utils\ApiTestDataProviders;
+use ShlinkioApiTest\Shlink\Rest\Utils\UrlBuilder;
 
 use function sprintf;
 
 class ShortUrlVisitsTest extends ApiTestCase
 {
-    use NotFoundUrlHelpersTrait;
-
-    #[Test, DataProvider('provideInvalidUrls')]
+    #[Test, DataProviderExternal(ApiTestDataProviders::class, 'invalidUrlsProvider')]
     public function tryingToGetVisitsForInvalidUrlReturnsNotFoundError(
         string $shortCode,
         ?string $domain,
@@ -27,9 +27,8 @@ class ShortUrlVisitsTest extends ApiTestCase
     ): void {
         $resp = $this->callApiWithKey(
             self::METHOD_GET,
-            $this->buildShortUrlPath($shortCode, $domain, '/visits'),
-            [],
-            $apiKey,
+            UrlBuilder::buildShortUrlPath($shortCode, $domain, '/visits'),
+            apiKey: $apiKey,
         );
         $payload = $this->getJsonResponsePayload($resp);
 
diff --git a/module/Rest/test-api/Utils/NotFoundUrlHelpersTrait.php b/module/Rest/test-api/Utils/ApiTestDataProviders.php
similarity index 62%
rename from module/Rest/test-api/Utils/NotFoundUrlHelpersTrait.php
rename to module/Rest/test-api/Utils/ApiTestDataProviders.php
index 9645f707..0189535b 100644
--- a/module/Rest/test-api/Utils/NotFoundUrlHelpersTrait.php
+++ b/module/Rest/test-api/Utils/ApiTestDataProviders.php
@@ -4,14 +4,9 @@ declare(strict_types=1);
 
 namespace ShlinkioApiTest\Shlink\Rest\Utils;
 
-use GuzzleHttp\Psr7\Query;
-use Laminas\Diactoros\Uri;
-
-use function sprintf;
-
-trait NotFoundUrlHelpersTrait
+class ApiTestDataProviders
 {
-    public static function provideInvalidUrls(): iterable
+    public static function invalidUrlsProvider(): iterable
     {
         yield 'invalid shortcode' => ['invalid', null, 'No URL found with short code "invalid"', 'valid_api_key'];
         yield 'invalid shortcode without domain' => [
@@ -20,7 +15,7 @@ trait NotFoundUrlHelpersTrait
             'No URL found with short code "abc123" for domain "example.com"',
             'valid_api_key',
         ];
-        yield 'invalid shortcode + domain' => [
+        yield 'invalid shortcode and custom domain' => [
             'custom-with-domain',
             'example.com',
             'No URL found with short code "custom-with-domain" for domain "example.com"',
@@ -32,21 +27,11 @@ trait NotFoundUrlHelpersTrait
             'No URL found with short code "ghi789"',
             'author_api_key',
         ];
-        yield 'valid shortcode + domain with invalid API key' => [
+        yield 'valid shortcode and custom domain with invalid API key' => [
             'custom-with-domain',
             'some-domain.com',
             'No URL found with short code "custom-with-domain" for domain "some-domain.com"',
             'domain_api_key',
         ];
     }
-
-    public function buildShortUrlPath(string $shortCode, ?string $domain, string $suffix = ''): string
-    {
-        $url = new Uri(sprintf('/short-urls/%s%s', $shortCode, $suffix));
-        if ($domain !== null) {
-            $url = $url->withQuery(Query::build(['domain' => $domain]));
-        }
-
-        return (string) $url;
-    }
 }
diff --git a/module/Rest/test-api/Utils/UrlBuilder.php b/module/Rest/test-api/Utils/UrlBuilder.php
new file mode 100644
index 00000000..6de96a81
--- /dev/null
+++ b/module/Rest/test-api/Utils/UrlBuilder.php
@@ -0,0 +1,23 @@
+<?php
+
+declare(strict_types=1);
+
+namespace ShlinkioApiTest\Shlink\Rest\Utils;
+
+use GuzzleHttp\Psr7\Query;
+use Laminas\Diactoros\Uri;
+
+use function sprintf;
+
+class UrlBuilder
+{
+    public static function buildShortUrlPath(string $shortCode, ?string $domain, string $suffix = ''): string
+    {
+        $url = new Uri(sprintf('/short-urls/%s%s', $shortCode, $suffix));
+        if ($domain !== null) {
+            $url = $url->withQuery(Query::build(['domain' => $domain]));
+        }
+
+        return $url->__toString();
+    }
+}