Browse Source

Test relative URL resolution

master
J. King 4 years ago
parent
commit
a470491fb8
  1. 2
      lib/Parser/JSON/Feed.php
  2. 6
      lib/Url.php
  3. 35
      tests/cases/JSON/JSONTest.php
  4. 17
      tests/cases/JSON/feed.json

2
lib/Parser/JSON/Feed.php

@ -44,7 +44,7 @@ class Feed implements \JKingWeb\Lax\Parser\Feed {
/** Performs format-specific preparation and validation */ /** Performs format-specific preparation and validation */
protected function init(FeedStruct $feed): FeedStruct { protected function init(FeedStruct $feed): FeedStruct {
$type = preg_replace("/[\s;,].*/", "", trim(strtolower($this->contentType))); $type = $this->parseMediaType($this->contentType) ?? "";
if (strlen($type) && !in_array($type, self::MIME_TYPES)) { if (strlen($type) && !in_array($type, self::MIME_TYPES)) {
throw new Exception("notJSONType"); throw new Exception("notJSONType");
} }

6
lib/Url.php

@ -74,10 +74,10 @@ PCRE;
]; ];
protected $scheme = null; protected $scheme = null;
protected $host = null;
protected $port = null;
protected $user = ""; protected $user = "";
protected $pass = ""; protected $pass = "";
protected $host = null;
protected $port = null;
protected $path = null; protected $path = null;
protected $query = null; protected $query = null;
protected $fragment = null; protected $fragment = null;
@ -105,7 +105,7 @@ PCRE;
} }
} }
} }
if ($baseUrl && !strlen($this->scheme)) { if ($baseUrl && !$this->scheme) {
$this->resolve(self::fromUri($baseUrl)); $this->resolve(self::fromUri($baseUrl));
} }
foreach (["scheme", "path", "query", "fragment"] as $part) { foreach (["scheme", "path", "query", "fragment"] as $part) {

35
tests/cases/JSON/JSONTest.php

@ -11,7 +11,7 @@ namespace JKingWeb\Lax\TestCase\JSON;
Each test is a JSON object with the following keys: Each test is a JSON object with the following keys:
- `description`: a short human-readable description of the test - `description`: a short human-readable description of the test
- `base_url`: A base URL against which relative URLs should be resolved - `doc_url`: A fictitious URL where a newsfeed might be located, used for relative URL resolution
- `input`: The test input, as a string or directly as a JSON Feed structure - `input`: The test input, as a string or directly as a JSON Feed structure
- `output`: The result of the parsing upon success; described in more detail below - `output`: The result of the parsing upon success; described in more detail below
- `exception`: The exception ID thrown upon failure - `exception`: The exception ID thrown upon failure
@ -21,8 +21,10 @@ namespace JKingWeb\Lax\TestCase\JSON;
The test output is necessarily mangled due to the limits of JSON: The test output is necessarily mangled due to the limits of JSON:
- Any field which should be a URL should be written as a string, which - Any field which should be an absolute URL should be written as a string,
will be transformed accordingly which will be transformed accordingly. Relative URLs should be represented
as an array with the relative part first, followed by the base that should
be applied to it
- Any collections should be represented as arrays of objects, which will - Any collections should be represented as arrays of objects, which will
all be transformed accordingly all be transformed accordingly
- Rich text can either be supplied as a string (which will yield a Text object - Rich text can either be supplied as a string (which will yield a Text object
@ -54,13 +56,13 @@ use JKingWeb\Lax\Enclosure\Collection as EnclosureCollection;
*/ */
class JSONTest extends \PHPUnit\Framework\TestCase { class JSONTest extends \PHPUnit\Framework\TestCase {
/** @dataProvider provideJSONFeedVersion1 */ /** @dataProvider provideJSONFeedVersion1 */
public function testJSONFeedVersion1($input, string $type, $output): void { public function testJSONFeedVersion1($input, string $type, ?string $url, $output): void {
if (is_object($input)) { if (is_object($input)) {
$input = json_encode($input); $input = json_encode($input);
} elseif (!is_string($input)) { } elseif (!is_string($input)) {
throw new \Exception("Test input is invalid"); throw new \Exception("Test input is invalid");
} }
$p = new Parser($input, $type); $p = new Parser($input, $type, $url);
if ($output instanceof \Exception) { if ($output instanceof \Exception) {
$this->expectExceptionObject($output); $this->expectExceptionObject($output);
$p->parse(new Feed); $p->parse(new Feed);
@ -80,6 +82,7 @@ class JSONTest extends \PHPUnit\Framework\TestCase {
yield "$file #$index: {$test->description}" => [ yield "$file #$index: {$test->description}" => [
$test->input, $test->input,
$test->type ?? "", $test->type ?? "",
$test->doc_url ?? null,
$test->output, $test->output,
]; ];
} }
@ -105,10 +108,14 @@ class JSONTest extends \PHPUnit\Framework\TestCase {
$f->$k = $c; $f->$k = $c;
} elseif (in_array($k, ["meta", "sched"])) { } elseif (in_array($k, ["meta", "sched"])) {
foreach ($v as $kk => $vv) { foreach ($v as $kk => $vv) {
$f->$k->$kk = $vv; if ($kk === "url") {
$f->$k->$kk = $this->makeUrl($vv);
} else {
$f->$k->$kk = $vv;
}
} }
} elseif (in_array($k, ["url", "link", "icon", "image"])) { } elseif (in_array($k, ["url", "link", "icon", "image"])) {
$f->$k = new Url($v); $f->$k = $this->makeUrl($v);
} else { } else {
$f->$k = $v; $f->$k = $v;
} }
@ -120,7 +127,7 @@ class JSONTest extends \PHPUnit\Framework\TestCase {
$e = new Entry; $e = new Entry;
foreach ($entry as $k => $v) { foreach ($entry as $k => $v) {
if (in_array($k, ["link", "relatedLink", "banner"])) { if (in_array($k, ["link", "relatedLink", "banner"])) {
$e->$k = new Url($v); $e->$k = $this->makeUrl($v);
} elseif (in_array($k, ["dateCreated", "dateModified"])) { } elseif (in_array($k, ["dateCreated", "dateModified"])) {
$e->$k = new Date($v, new \DateTimeZone("UTC")); $e->$k = new Date($v, new \DateTimeZone("UTC"));
} elseif (in_array($k, ["title", "summary", "content"])) { } elseif (in_array($k, ["title", "summary", "content"])) {
@ -169,7 +176,7 @@ class JSONTest extends \PHPUnit\Framework\TestCase {
$p = new Person; $p = new Person;
foreach ($person as $k => $v) { foreach ($person as $k => $v) {
if (in_array($k, ["url", "avatar"])) { if (in_array($k, ["url", "avatar"])) {
$p->$k = new Url($v); $p->$k = $this->makeUrl($v);
} else { } else {
$p->$k = $v; $p->$k = $v;
} }
@ -181,11 +188,19 @@ class JSONTest extends \PHPUnit\Framework\TestCase {
$e = new Enclosure; $e = new Enclosure;
foreach ($enclosure as $k => $v) { foreach ($enclosure as $k => $v) {
if ($k === "urli") { if ($k === "urli") {
$e->$k = new Url($v); $e->$k = $this->makeUrl($v);
} else { } else {
$e->$k = $v; $e->$k = $v;
} }
} }
return $e; return $e;
} }
protected function makeUrl($url): ?Url {
if (is_array($url)) {
return new Url($url[0] ?? "", ($url[1] ?? null) ? new Url($url[1]) : null);
} else {
return new Url($url);
}
}
} }

17
tests/cases/JSON/feed.json

@ -240,5 +240,22 @@
"icon": "http://example.com/icon", "icon": "http://example.com/icon",
"image": "http://example.com/image" "image": "http://example.com/image"
} }
},
{
"description": "Relative URL resolution",
"doc_url": "http://example.com",
"input": {
"version": "https://jsonfeed.org/version/1",
"feed_url": "feed.json"
},
"output": {
"meta": {
"url": "http://example.com"
},
"format": "json",
"version": "1",
"id": "feed.json",
"url": ["feed.json", "http://example.com"]
}
} }
] ]
Loading…
Cancel
Save