Skip to content

Commit daef240

Browse files
authored
test: add test for FeedParser (RSS-Bridge#3754)
1 parent 5f37c72 commit daef240

File tree

4 files changed

+174
-25
lines changed

4 files changed

+174
-25
lines changed

bridges/ArsTechnicaBridge.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ class ArsTechnicaBridge extends FeedExpander
3030
public function collectData()
3131
{
3232
$url = 'https://feeds.arstechnica.com/arstechnica/' . $this->getInput('section');
33-
$this->collectExpandableDatas($url);
33+
$this->collectExpandableDatas($url, 10);
3434
}
3535

3636
protected function parseItem(array $item)

bridges/UrlebirdBridge.php

+41-21
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ class UrlebirdBridge extends BridgeAbstract
66
const NAME = 'urlebird.com';
77
const URI = 'https://urlebird.com/';
88
const DESCRIPTION = 'Bridge for urlebird.com';
9-
const CACHE_TIMEOUT = 10;
9+
const CACHE_TIMEOUT = 60 * 5;
1010
const PARAMETERS = [
1111
[
1212
'query' => [
@@ -21,50 +21,70 @@ class UrlebirdBridge extends BridgeAbstract
2121

2222
private $title;
2323

24-
private function fixURI($uri)
25-
{
26-
$path = parse_url($uri, PHP_URL_PATH);
27-
$encoded_path = array_map('urlencode', explode('/', $path));
28-
return str_replace($path, implode('/', $encoded_path), $uri);
29-
}
30-
3124
public function collectData()
3225
{
3326
switch ($this->getInput('query')[0]) {
34-
default:
35-
returnServerError('Please, enter valid username or hashtag!');
36-
break;
3727
case '@':
3828
$url = 'https://urlebird.com/user/' . substr($this->getInput('query'), 1) . '/';
3929
break;
4030
case '#':
4131
$url = 'https://urlebird.com/hash/' . substr($this->getInput('query'), 1) . '/';
4232
break;
33+
default:
34+
returnServerError('Please, enter valid username or hashtag!');
35+
break;
4336
}
4437

4538
$html = getSimpleHTMLDOM($url);
39+
$limit = 10;
40+
4641
$this->title = $html->find('title', 0)->innertext;
4742
$articles = $html->find('div.thumb');
43+
$articles = array_slice($articles, 0, $limit);
4844
foreach ($articles as $article) {
4945
$item = [];
50-
$item['uri'] = $this->fixURI($article->find('a', 2)->href);
51-
$article_content = getSimpleHTMLDOM($item['uri']);
52-
$item['author'] = $article->find('img', 0)->alt . ' (' .
53-
$article_content->find('a.user-video', 1)->innertext . ')';
54-
$item['title'] = $article_content->find('title', 0)->innertext;
55-
$item['enclosures'][] = $article_content->find('video', 0)->poster;
56-
$video = $article_content->find('video', 0);
46+
$itemUrl = $article->find('a', 2)->href;
47+
$item['uri'] = $this->encodePathSegments($itemUrl);
48+
49+
$dom = getSimpleHTMLDOM($item['uri']);
50+
$videoDiv = $dom->find('div.video', 0);
51+
52+
// timestamp
53+
$timestampH6 = $videoDiv->find('h6', 0);
54+
$datetimeString = str_replace('Posted ', '', $timestampH6->plaintext);
55+
$item['timestamp'] = $datetimeString;
56+
57+
$innertext = $dom->find('a.user-video', 1)->innertext;
58+
$alt = $article->find('img', 0)->alt;
59+
$item['author'] = $alt . ' (' . $innertext . ')';
60+
61+
$item['title'] = $dom->find('title', 0)->innertext;
62+
$item['enclosures'][] = $dom->find('video', 0)->poster;
63+
64+
$video = $dom->find('video', 0);
5765
$video->autoplay = null;
66+
5867
$item['content'] = $video->outertext . '<br>' .
59-
$article_content->find('div.music', 0) . '<br>' .
60-
$article_content->find('div.info2', 0)->innertext .
61-
'<br><br><a href="' . $article_content->find('video', 0)->src .
68+
$dom->find('div.music', 0) . '<br>' .
69+
$dom->find('div.info2', 0)->innertext .
70+
'<br><br><a href="' . $dom->find('video', 0)->src .
6271
'">Direct video link</a><br><br><a href="' . $item['uri'] .
6372
'">Post link</a><br><br>';
73+
6474
$this->items[] = $item;
6575
}
6676
}
6777

78+
private function encodePathSegments($url)
79+
{
80+
$path = parse_url($url, PHP_URL_PATH);
81+
$pathSegments = explode('/', $path);
82+
$encodedPathSegments = array_map('urlencode', $pathSegments);
83+
$encodedPath = implode('/', $encodedPathSegments);
84+
$result = str_replace($path, $encodedPath, $url);
85+
return $result;
86+
}
87+
6888
public function getName()
6989
{
7090
return $this->title ?: parent::getName();

lib/FeedParser.php

+4-3
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ public function parseRss2Item(\SimpleXMLElement $feedItem): array
142142
}
143143

144144
if (isset($feedItem->guid)) {
145+
// Pluck out a url from guid
145146
foreach ($feedItem->guid->attributes() as $attribute => $value) {
146147
if (
147148
$attribute === 'isPermaLink'
@@ -207,9 +208,9 @@ public function parseRss091Item(\SimpleXMLElement $feedItem): array
207208
'content' => null,
208209
'timestamp' => null,
209210
'author' => null,
210-
'uid' => null,
211-
'categories' => [],
212-
'enclosures' => [],
211+
//'uid' => null,
212+
//'categories' => [],
213+
//'enclosures' => [],
213214
];
214215
if (isset($feedItem->link)) {
215216
// todo: trim uri

tests/FeedParserTest.php

+128
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace RssBridge\Tests;
6+
7+
use PHPUnit\Framework\TestCase;
8+
9+
class FeedParserTest extends TestCase
10+
{
11+
public function testRss1()
12+
{
13+
$xml = <<<XML
14+
<?xml version="1.0" encoding="utf-8"?>
15+
<rdf:RDF
16+
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
17+
xmlns:cc="http://creativecommons.org/ns#"
18+
xmlns="http://purl.org/rss/1.0/"
19+
>
20+
<channel rdf:about="http://meerkat.oreillynet.com/?_fl=rss1.0">
21+
<title>hello feed</title>
22+
<link>http://meerkat.oreillynet.com</link>
23+
<description>Meerkat: An Open Wire Service</description>
24+
25+
<items>
26+
<rdf:Seq>
27+
<rdf:li resource="http://c.moreover.com/click/here.pl?r123" />
28+
</rdf:Seq>
29+
</items>
30+
</channel>
31+
32+
<item rdf:about="http://c.moreover.com/click/here.pl?r123">
33+
<title>XML: A Disruptive Technology</title>
34+
<link>http://c.moreover.com/click/here.pl?r123</link>
35+
<description>desc</description>
36+
</item>
37+
</rdf:RDF>
38+
XML;
39+
40+
$sut = new \FeedParser();
41+
$feed = $sut->parseFeed($xml);
42+
43+
$this->assertSame('hello feed', $feed['title']);
44+
$this->assertSame('http://meerkat.oreillynet.com', $feed['uri']);
45+
$this->assertSame(null, $feed['icon']);
46+
47+
$item = $feed['items'][0];
48+
$this->assertSame('XML: A Disruptive Technology', $item['title']);
49+
$this->assertSame('http://c.moreover.com/click/here.pl?r123', $item['uri']);
50+
$this->assertSame('desc', $item['content']);
51+
}
52+
53+
public function testRss2()
54+
{
55+
$xml = <<<XML
56+
<?xml version="1.0"?>
57+
<rss version="2.0">
58+
<channel>
59+
<title>hello feed</title>
60+
<link>https://example.com/</link>
61+
<image>
62+
<url>https://example.com/2.ico</url>
63+
</image>
64+
65+
<item>
66+
<title>hello world</title>
67+
<link>https://example.com/1</link>
68+
<description>desc2</description>
69+
<pubDate>Tue, 26 Apr 2022 00:00:00 +0200</pubDate>
70+
<author>root</author>
71+
<enclosure url="https://example.com/1.png"></enclosure>
72+
</item>
73+
</channel>
74+
</rss>
75+
XML;
76+
77+
$sut = new \FeedParser();
78+
$feed = $sut->parseFeed($xml);
79+
80+
$this->assertSame('hello feed', $feed['title']);
81+
$this->assertSame('https://example.com/', $feed['uri']);
82+
$this->assertSame('https://example.com/2.ico', $feed['icon']);
83+
84+
$item = $feed['items'][0];
85+
$this->assertSame('hello world', $item['title']);
86+
$this->assertSame('https://example.com/1', $item['uri']);
87+
$this->assertSame(1650924000, $item['timestamp']);
88+
$this->assertSame('root', $item['author']);
89+
$this->assertSame('desc2', $item['content']);
90+
$this->assertSame(['https://example.com/1.png'], $item['enclosures']);
91+
}
92+
93+
public function testAtom()
94+
{
95+
$xml = <<<XML
96+
<?xml version="1.0" encoding="UTF-8"?>
97+
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/">
98+
<title>hello feed</title>
99+
<link href="https://example.com/1"></link>
100+
<icon>https://example.com/2.ico</icon>
101+
102+
<entry>
103+
<title>hello world</title>
104+
<link href="https://example.com/1"></link>
105+
<author>
106+
<name>root</name>
107+
</author>
108+
<content type="html">html</content>
109+
<updated>2015-11-05T14:38:49+01:00</updated>
110+
</entry>
111+
</feed>
112+
XML;
113+
114+
$sut = new \FeedParser();
115+
$feed = $sut->parseFeed($xml);
116+
117+
$this->assertSame('hello feed', $feed['title']);
118+
$this->assertSame('https://example.com/1', $feed['uri']);
119+
$this->assertSame('https://example.com/2.ico', $feed['icon']);
120+
121+
$item = $feed['items'][0];
122+
$this->assertSame('hello world', $item['title']);
123+
$this->assertSame('https://example.com/1', $item['uri']);
124+
$this->assertSame(1446730729, $item['timestamp']);
125+
$this->assertSame('root', $item['author']);
126+
$this->assertSame('html', $item['content']);
127+
}
128+
}

0 commit comments

Comments
 (0)