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! +
+
+

Anne Author

who can be found at my-blog.com. + My profile picture +
+ + + 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