From 356e68ca3e5d9f80604c2e754e6524b649dd67cd Mon Sep 17 00:00:00 2001
From: Alejandro Celaya <alejandro@alejandrocelaya.com>
Date: Tue, 2 Feb 2021 20:51:28 +0100
Subject: [PATCH] Documented new title prop in swagger docs

---
 docs/swagger/definitions/ShortUrl.json        |  6 ++++++
 docs/swagger/paths/v1_short-urls.json         | 13 +++++++++---
 docs/swagger/paths/v1_short-urls_shorten.json |  3 ++-
 .../paths/v1_short-urls_{shortCode}.json      | 20 ++++++++++++++-----
 module/Core/src/Entity/ShortUrl.php           |  3 +++
 module/Core/src/Model/ShortUrlEdit.php        | 14 +++++++++++++
 .../test-api/Action/ListShortUrlsTest.php     |  6 ++++++
 .../test-api/Fixtures/ShortUrlsFixture.php    |  1 +
 8 files changed, 57 insertions(+), 9 deletions(-)

diff --git a/docs/swagger/definitions/ShortUrl.json b/docs/swagger/definitions/ShortUrl.json
index 66d20115..3e4c6ead 100644
--- a/docs/swagger/definitions/ShortUrl.json
+++ b/docs/swagger/definitions/ShortUrl.json
@@ -34,7 +34,13 @@
         },
         "domain": {
             "type": "string",
+            "nullable": true,
             "description": "The domain in which the short URL was created. Null if it belongs to default domain."
+        },
+        "title": {
+            "type": "string",
+            "nullable": true,
+            "description": "A descriptive title of the short URL."
         }
     }
 }
diff --git a/docs/swagger/paths/v1_short-urls.json b/docs/swagger/paths/v1_short-urls.json
index 1dc10978..c3db1f05 100644
--- a/docs/swagger/paths/v1_short-urls.json
+++ b/docs/swagger/paths/v1_short-urls.json
@@ -137,7 +137,8 @@
                                         "validUntil": null,
                                         "maxVisits": 100
                                     },
-                                    "domain": null
+                                    "domain": null,
+                                    "title": "Welcome to Steam"
                                 },
                                 {
                                     "shortCode": "12Kb3",
@@ -153,7 +154,8 @@
                                         "validUntil": null,
                                         "maxVisits": null
                                     },
-                                    "domain":  null
+                                    "domain":  null,
+                                    "title": null
                                 },
                                 {
                                     "shortCode": "123bA",
@@ -167,7 +169,8 @@
                                         "validUntil": null,
                                         "maxVisits": null
                                     },
-                                    "domain":  "example.com"
+                                    "domain":  "example.com",
+                                    "title": null
                                 }
                             ],
                             "pagination": {
@@ -264,6 +267,10 @@
                             "validateUrl": {
                                 "description": "Tells if the long URL should or should not be validated as a reachable URL. If not provided, it will fall back to app-level config",
                                 "type": "boolean"
+                            },
+                            "title": {
+                                "type": "string",
+                                "description": "A descriptive title of the short URL."
                             }
                         }
                     }
diff --git a/docs/swagger/paths/v1_short-urls_shorten.json b/docs/swagger/paths/v1_short-urls_shorten.json
index c31c0cd9..b6184d8d 100644
--- a/docs/swagger/paths/v1_short-urls_shorten.json
+++ b/docs/swagger/paths/v1_short-urls_shorten.json
@@ -73,7 +73,8 @@
                             "validUntil": null,
                             "maxVisits": 100
                         },
-                        "domain": null
+                        "domain": null,
+                        "title": null
                     },
                     "text/plain": "https://doma.in/abc123"
                 }
diff --git a/docs/swagger/paths/v1_short-urls_{shortCode}.json b/docs/swagger/paths/v1_short-urls_{shortCode}.json
index 6cfa3c97..2281d9b8 100644
--- a/docs/swagger/paths/v1_short-urls_{shortCode}.json
+++ b/docs/swagger/paths/v1_short-urls_{shortCode}.json
@@ -53,7 +53,8 @@
                             "validUntil": null,
                             "maxVisits": 100
                         },
-                        "domain": null
+                        "domain": null,
+                        "title": null
                     }
                 }
             },
@@ -118,15 +119,18 @@
                             },
                             "validSince": {
                                 "description": "The date (in ISO-8601 format) from which this short code will be valid",
-                                "type": "string"
+                                "type": "string",
+                                "nullable": true
                             },
                             "validUntil": {
                                 "description": "The date (in ISO-8601 format) until which this short code will be valid",
-                                "type": "string"
+                                "type": "string",
+                                "nullable": true
                             },
                             "maxVisits": {
                                 "description": "The maximum number of allowed visits for this short code",
-                                "type": "number"
+                                "type": "number",
+                                "nullable": true
                             },
                             "validateUrl": {
                                 "description": "Tells if the long URL (if provided) should or should not be validated as a reachable URL. If not provided, it will fall back to app-level config",
@@ -138,6 +142,11 @@
                                     "type": "string"
                                 },
                                 "description": "The list of tags to set to the short URL."
+                            },
+                            "title": {
+                                "type": "string",
+                                "description": "A descriptive title of the short URL.",
+                                "nullable": true
                             }
                         }
                     }
@@ -174,7 +183,8 @@
                             "validUntil": null,
                             "maxVisits": 100
                         },
-                        "domain": null
+                        "domain": null,
+                        "title": "Shlink - The URL shortener"
                     }
                 }
             },
diff --git a/module/Core/src/Entity/ShortUrl.php b/module/Core/src/Entity/ShortUrl.php
index fd061996..ba7f34f4 100644
--- a/module/Core/src/Entity/ShortUrl.php
+++ b/module/Core/src/Entity/ShortUrl.php
@@ -184,6 +184,9 @@ class ShortUrl extends AbstractEntity
             $relationResolver = $relationResolver ?? new SimpleShortUrlRelationResolver();
             $this->tags = $relationResolver->resolveTags($shortUrlEdit->tags());
         }
+        if ($shortUrlEdit->hasTitle()) {
+            $this->title = $shortUrlEdit->title();
+        }
     }
 
     /**
diff --git a/module/Core/src/Model/ShortUrlEdit.php b/module/Core/src/Model/ShortUrlEdit.php
index b8cb0e0c..ddb7d317 100644
--- a/module/Core/src/Model/ShortUrlEdit.php
+++ b/module/Core/src/Model/ShortUrlEdit.php
@@ -25,6 +25,8 @@ final class ShortUrlEdit
     private ?int $maxVisits = null;
     private bool $tagsPropWasProvided = false;
     private array $tags = [];
+    private bool $titlePropWasProvided = false;
+    private ?string $title = null;
     private ?bool $validateUrl = null;
 
     private function __construct()
@@ -56,6 +58,7 @@ final class ShortUrlEdit
         $this->validUntilPropWasProvided = array_key_exists(ShortUrlInputFilter::VALID_UNTIL, $data);
         $this->maxVisitsPropWasProvided = array_key_exists(ShortUrlInputFilter::MAX_VISITS, $data);
         $this->tagsPropWasProvided = array_key_exists(ShortUrlInputFilter::TAGS, $data);
+        $this->titlePropWasProvided = array_key_exists(ShortUrlInputFilter::TITLE, $data);
 
         $this->longUrl = $inputFilter->getValue(ShortUrlInputFilter::LONG_URL);
         $this->validSince = parseDateField($inputFilter->getValue(ShortUrlInputFilter::VALID_SINCE));
@@ -63,6 +66,7 @@ final class ShortUrlEdit
         $this->maxVisits = getOptionalIntFromInputFilter($inputFilter, ShortUrlInputFilter::MAX_VISITS);
         $this->validateUrl = getOptionalBoolFromInputFilter($inputFilter, ShortUrlInputFilter::VALIDATE_URL);
         $this->tags = $inputFilter->getValue(ShortUrlInputFilter::TAGS);
+        $this->title = $inputFilter->getValue(ShortUrlInputFilter::TITLE);
     }
 
     public function longUrl(): ?string
@@ -118,6 +122,16 @@ final class ShortUrlEdit
         return $this->tagsPropWasProvided;
     }
 
+    public function title(): ?string
+    {
+        return $this->title;
+    }
+
+    public function hasTitle(): bool
+    {
+        return $this->titlePropWasProvided;
+    }
+
     public function doValidateUrl(): ?bool
     {
         return $this->validateUrl;
diff --git a/module/Rest/test-api/Action/ListShortUrlsTest.php b/module/Rest/test-api/Action/ListShortUrlsTest.php
index e38374c8..2c7f35ae 100644
--- a/module/Rest/test-api/Action/ListShortUrlsTest.php
+++ b/module/Rest/test-api/Action/ListShortUrlsTest.php
@@ -25,6 +25,7 @@ class ListShortUrlsTest extends ApiTestCase
             'maxVisits' => null,
         ],
         'domain' => null,
+        'title' => 'Shlink',
     ];
     private const SHORT_URL_DOCS = [
         'shortCode' => 'ghi789',
@@ -39,6 +40,7 @@ class ListShortUrlsTest extends ApiTestCase
             'maxVisits' => null,
         ],
         'domain' => null,
+        'title' => null,
     ];
     private const SHORT_URL_CUSTOM_SLUG_AND_DOMAIN = [
         'shortCode' => 'custom-with-domain',
@@ -53,6 +55,7 @@ class ListShortUrlsTest extends ApiTestCase
             'maxVisits' => null,
         ],
         'domain' => 'some-domain.com',
+        'title' => null,
     ];
     private const SHORT_URL_META = [
         'shortCode' => 'def456',
@@ -69,6 +72,7 @@ class ListShortUrlsTest extends ApiTestCase
             'maxVisits' => null,
         ],
         'domain' => null,
+        'title' => null,
     ];
     private const SHORT_URL_CUSTOM_SLUG = [
         'shortCode' => 'custom',
@@ -83,6 +87,7 @@ class ListShortUrlsTest extends ApiTestCase
             'maxVisits' => 2,
         ],
         'domain' => null,
+        'title' => null,
     ];
     private const SHORT_URL_CUSTOM_DOMAIN = [
         'shortCode' => 'ghi789',
@@ -99,6 +104,7 @@ class ListShortUrlsTest extends ApiTestCase
             'maxVisits' => null,
         ],
         'domain' => 'example.com',
+        'title' => null,
     ];
 
     /**
diff --git a/module/Rest/test-api/Fixtures/ShortUrlsFixture.php b/module/Rest/test-api/Fixtures/ShortUrlsFixture.php
index 93defe90..426bc4f4 100644
--- a/module/Rest/test-api/Fixtures/ShortUrlsFixture.php
+++ b/module/Rest/test-api/Fixtures/ShortUrlsFixture.php
@@ -34,6 +34,7 @@ class ShortUrlsFixture extends AbstractFixture implements DependentFixtureInterf
                 'apiKey' => $authorApiKey,
                 'longUrl' => 'https://shlink.io',
                 'tags' => ['foo'],
+                'title' => 'Shlink',
             ]), $relationResolver),
             '2018-05-01',
         );