diff --git a/src/Concern/GeneratesDefinition.php b/src/Concern/GeneratesDefinition.php new file mode 100644 index 0000000..c5a2c47 --- /dev/null +++ b/src/Concern/GeneratesDefinition.php @@ -0,0 +1,51 @@ +generateDefinition($box, $uri)); + } + + public function generateDefinition(Entity\Box $box, UriInterface $uri) + { + $json = [ + $this->nameKey => $box->path(), + 'versions' => [] + ]; + + foreach ($box->versions() as $version => $providers) { + if (empty($providers)) { + continue; + } + $versionedProviders = []; + foreach ($providers as $provider) { + $versionedProviders[] = [ + 'name' => (string)$provider, + 'url' => (string)$uri->withPath($this->resolveUriPath($box, $version, $provider)) + ]; + } + $json['versions'][] = [ + 'version' => (string)$version, + 'providers' => $versionedProviders + ]; + } + + return $json; + } +} \ No newline at end of file diff --git a/src/Http/Response/Api/BoxDefinition.php b/src/Http/Response/Api/BoxDefinition.php index 1cf9ab4..f24738e 100644 --- a/src/Http/Response/Api/BoxDefinition.php +++ b/src/Http/Response/Api/BoxDefinition.php @@ -7,9 +7,9 @@ namespace Phagrancy\Http\Response\Api; +use Phagrancy\Concern\GeneratesDefinition; use Phagrancy\Http\Response\Json; use Phagrancy\Model\Entity; -use Psr\Http\Message\UriInterface; /** * Box JSON definition response @@ -19,28 +19,15 @@ class BoxDefinition extends Json { - public function __construct(Entity\Box $box, UriInterface $uri) + use GeneratesDefinition; + + /** + * @var string The key name for the definition. API uses tag, non-API uses name + */ + protected $nameKey = 'tag'; + + protected function resolveUriPath(Entity\Box $box, $version, $provider) { - $json = [ - 'tag' => $box->path(), - 'versions' => [] - ]; - foreach ($box->versions() as $version => $providers) { - if (empty($providers)) { - continue; - } - $vpbs = []; - foreach ($providers as $provider) { - $vpbs[] = [ - 'name' => $provider, - 'url' => (string)$uri->withPath("/api/v1/box/{$box->path()}/version/{$version}/provider/{$provider}") - ]; - } - $json['versions'][] = [ - 'version' => $version, - 'providers' => $vpbs - ]; - } - parent::__construct($json); + return "/api/v1/box/{$box->path()}/version/{$version}/provider/{$provider}"; } } \ No newline at end of file diff --git a/src/Http/Response/BoxDefinition.php b/src/Http/Response/BoxDefinition.php index 97bfb2f..6b9e3ad 100644 --- a/src/Http/Response/BoxDefinition.php +++ b/src/Http/Response/BoxDefinition.php @@ -7,8 +7,8 @@ namespace Phagrancy\Http\Response; +use Phagrancy\Concern\GeneratesDefinition; use Phagrancy\Model\Entity; -use Psr\Http\Message\UriInterface; /** * Box JSON definition response @@ -18,29 +18,15 @@ class BoxDefinition extends Json { - public function __construct(Entity\Box $box, UriInterface $uri) - { - $json = [ - 'name' => (string)$box->path(), - 'versions' => [] - ]; - foreach ($box->versions() as $version => $providers) { - if (empty($providers)) { - continue; - } - $vpbs = []; - foreach ($providers as $provider) { - $vpbs[] = [ - 'name' => (string)$provider, - 'url' => (string)$uri->withPath("/{$box->path()}/{$version}/{$provider}") - ]; - } - $json['versions'][] = [ - 'version' => strval($version), - 'providers' => $vpbs - ]; - } + use GeneratesDefinition; + + /** + * @var string The key name for the definition. API uses tag, non-API uses name + */ + protected $nameKey = 'name'; - parent::__construct($json); + protected function resolveUriPath(Entity\Box $box, $version, $provider) + { + return "/{$box->path()}/{$version}/{$provider}"; } } diff --git a/src/Model/Input/ValidatesVersion.php b/src/Model/Input/ValidatesVersion.php index 2a54a31..81fec27 100644 --- a/src/Model/Input/ValidatesVersion.php +++ b/src/Model/Input/ValidatesVersion.php @@ -26,9 +26,10 @@ trait ValidatesVersion */ public function validateVersion() { - $error = "Version must be of the format x.y.z where x, y, and z are all integers, or follow SemVer 2.0.0";; + $error = "Version must be of the format x.y.z where x, y, and z are all integers"; return function ($value) use ($error) { - if (!preg_match('/^v?(0|[1-9]\d*)(?:\.(0|[1-9]\d*)){0,2}(?:(\.|-)[\da-z+_-]+)*$/i', $value)) { + // we support a subset of SemVer + if (!preg_match('/^(\d+)(?:\.(\d+)){0,2}(?:-[\da-z]+)*$/', $value)) { return $error; } diff --git a/tests/unit/Model/Input/ValidatesVersionTest.php b/tests/unit/Model/Input/ValidatesVersionTest.php index b511045..6346d7d 100644 --- a/tests/unit/Model/Input/ValidatesVersionTest.php +++ b/tests/unit/Model/Input/ValidatesVersionTest.php @@ -23,10 +23,11 @@ public function provideGoodVersions() ['20180609'], ['20180609.13425'], ['1.2.3'], - ['1.alpha_a'], - ['1.2.3.alpha'], - ['1.2.3.0+b'], - ['1.2.3-alpha.10.beta.0+build.unicorn.rainbow'], + ['1.2.3-alpha'], + ['1.2.3-alpha-build'], + ['1-beta'], + ['1.2-charlie'], + ['0.1'] ]; } @@ -34,6 +35,12 @@ public function provideBadVersions() { return [ ['1.-1'], + ['v5'], + ['1.alpha_a'], + ['1.2.3.alpha'], + ['1.2.3.0+b'], + ['1.2.3-alpha build'], + ['1.2.3-alpha.10.beta.0+build.unicorn.rainbow'], ]; }