diff --git a/src/Endpoint.php b/src/Endpoint.php
index cd304bf..bcfd9d6 100644
--- a/src/Endpoint.php
+++ b/src/Endpoint.php
@@ -109,19 +109,20 @@ class Endpoint
private function parseAuthor(Crawler $document): Author
{
+ if (!$document->count()) {
+ return new Author();
+ }
+
$card = $document->filter('.h-card');
if (!$card->count()) {
- $card = $document->closest('.h-card');
+ return $this->parseAuthor($document->ancestors());
}
- if ($card && $card->count()) {
- $name = $card->filter('.p-name')?->text("");
- $url = $card->filter('.u-url')->count() ? $card->filter('.u-url')->attr('href') : "";
- $photo = $card->filter('.u-photo')->count() ? $card->filter('.u-photo')->attr('src') : "";
+ $name = $card->filter('.p-name')?->text($card->text(""));
+ $url = $card->filter('.u-url')->count() ? $card->filter('.u-url')->attr('href') : ($card->attr('href') ?? "");
+ $photo = $card->filter('.u-photo')->count() ? $card->filter('.u-photo')->attr('src') : "";
- return new Author(null, $name, $url, $photo);
- }
- return new Author();
+ return new Author(null, $name, $url, $photo);
}
}
\ No newline at end of file
diff --git a/tests/EndpointTest.php b/tests/EndpointTest.php
index a64abf9..11b5f9c 100644
--- a/tests/EndpointTest.php
+++ b/tests/EndpointTest.php
@@ -459,4 +459,150 @@ class EndpointTest extends TestCase
$endpoint = new Endpoint($mockClient, $mockGateway);
$endpoint->receiveWebmention($source, $target);
}
+
+ public function testItShouldParseAnAuthorCardWithAMinimalHCard()
+ {
+ $source = "https://my-valid-source-url.com";
+ $target = "https://lewisdale.dev/post/a-post-page";
+
+ $content = <<
+
+
+
+
+ @post: That's a great idea!
+
+ microformats.org
+
+
+
+
+ HTML;
+
+ $mockClient = $this->createMock(HttpClientInterface::class);
+ $mockResponse = $this->createMock(ResponseInterface::class);
+ $mockGateway = $this->createMock(WebmentionGatewayInterface::class);
+
+ $mockClient->expects($this->once())
+ ->method('request')
+ ->with($this->identicalTo('GET'), $this->identicalTo($source))
+ ->will($this->returnValue($mockResponse));
+
+ $mockResponse->method('getStatusCode')
+ ->will($this->returnValue(200));
+
+ $mockResponse->method('getContent')
+ ->willReturn($content);
+
+ $expected = new \Lewisdale\Webmentions\Models\Author(
+ null,
+ "microformats.org",
+ "https://microformats.org/",
+ ""
+ );
+ $mockGateway->expects($this->once())
+ ->method('save')
+ ->with($this->objectContains('author', $expected));
+
+ $endpoint = new Endpoint($mockClient, $mockGateway);
+ $endpoint->receiveWebmention($source, $target);
+ }
+
+ public function testItShouldParseAnAuthorCardWithAVeryMinimalHCard()
+ {
+ $source = "https://my-valid-source-url.com";
+ $target = "https://lewisdale.dev/post/a-post-page";
+
+ $content = <<
+
+
+
+
+ @post: That's a great idea!
+ microformats.org
+
+
+
+ HTML;
+
+ $mockClient = $this->createMock(HttpClientInterface::class);
+ $mockResponse = $this->createMock(ResponseInterface::class);
+ $mockGateway = $this->createMock(WebmentionGatewayInterface::class);
+
+ $mockClient->expects($this->once())
+ ->method('request')
+ ->with($this->identicalTo('GET'), $this->identicalTo($source))
+ ->will($this->returnValue($mockResponse));
+
+ $mockResponse->method('getStatusCode')
+ ->will($this->returnValue(200));
+
+ $mockResponse->method('getContent')
+ ->willReturn($content);
+
+ $expected = new \Lewisdale\Webmentions\Models\Author(
+ null,
+ "microformats.org",
+ "https://microformats.org/",
+ ""
+ );
+ $mockGateway->expects($this->once())
+ ->method('save')
+ ->with($this->objectContains('author', $expected));
+
+ $endpoint = new Endpoint($mockClient, $mockGateway);
+ $endpoint->receiveWebmention($source, $target);
+ }
+
+ public function testItShouldParseAnAuthorCardOutsideTheEntrry()
+ {
+ $source = "https://my-valid-source-url.com";
+ $target = "https://lewisdale.dev/post/a-post-page";
+
+ $content = <<
+
+
+
+
+ @post: That's a great idea!
+
+
+
+
+ HTML;
+
+ $mockClient = $this->createMock(HttpClientInterface::class);
+ $mockResponse = $this->createMock(ResponseInterface::class);
+ $mockGateway = $this->createMock(WebmentionGatewayInterface::class);
+
+ $mockClient->expects($this->once())
+ ->method('request')
+ ->with($this->identicalTo('GET'), $this->identicalTo($source))
+ ->will($this->returnValue($mockResponse));
+
+ $mockResponse->method('getStatusCode')
+ ->will($this->returnValue(200));
+
+ $mockResponse->method('getContent')
+ ->willReturn($content);
+
+ $expected = new \Lewisdale\Webmentions\Models\Author(
+ null,
+ "Anne Author",
+ "https://my-blog.com",
+ "https://dummyimage.com/100x100/fff/aaa"
+ );
+ $mockGateway->expects($this->once())
+ ->method('save')
+ ->with($this->objectContains('author', $expected));
+
+ $endpoint = new Endpoint($mockClient, $mockGateway);
+ $endpoint->receiveWebmention($source, $target);
+ }
}
\ No newline at end of file