You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

587 lines
27 KiB

  1. <?php
  2. use Symfony\Component\HttpFoundation\Request;
  3. use Symfony\Component\HttpFoundation\Response;
  4. class FeedTest extends PHPUnit\Framework\TestCase
  5. {
  6. private $http;
  7. public function setUp(): void
  8. {
  9. $this->client = new Parse();
  10. $this->client->http = new p3k\HTTP\Test(dirname(__FILE__).'/data/');
  11. $this->client->mc = null;
  12. }
  13. private function parse($params)
  14. {
  15. $request = new Request($params);
  16. $response = new Response();
  17. return $this->client->parse($request, $response);
  18. }
  19. public function testListOfHEntrys()
  20. {
  21. $url = 'http://feed.example.com/list-of-hentrys';
  22. $response = $this->parse(['url' => $url, 'expect' => 'feed']);
  23. $body = $response->getContent();
  24. $this->assertEquals(200, $response->getStatusCode());
  25. $result = json_decode($body);
  26. $this->assertEquals('mf2+html', $result->{'source-format'});
  27. $data = $result->data;
  28. $this->assertEquals('feed', $data->type);
  29. $this->assertEquals(4, count($data->items));
  30. $this->assertEquals('One', $data->items[0]->name);
  31. $this->assertEquals('article', $data->items[0]->{'post-type'});
  32. $this->assertEquals('Two', $data->items[1]->name);
  33. $this->assertEquals('article', $data->items[1]->{'post-type'});
  34. $this->assertEquals('Three', $data->items[2]->name);
  35. $this->assertEquals('Four', $data->items[3]->name);
  36. }
  37. public function testListOfHEntrysWithHCard()
  38. {
  39. $url = 'http://feed.example.com/list-of-hentrys-with-h-card';
  40. $response = $this->parse(['url' => $url, 'expect' => 'feed']);
  41. $body = $response->getContent();
  42. $this->assertEquals(200, $response->getStatusCode());
  43. $result = json_decode($body);
  44. $this->assertEquals('mf2+html', $result->{'source-format'});
  45. $data = $result->data;
  46. $this->assertEquals('feed', $data->type);
  47. $this->assertEquals(4, count($data->items));
  48. $this->assertEquals('One', $data->items[0]->name);
  49. $this->assertEquals('article', $data->items[0]->{'post-type'});
  50. $this->assertEquals('Two', $data->items[1]->name);
  51. $this->assertEquals('Three', $data->items[2]->name);
  52. $this->assertEquals('Four', $data->items[3]->name);
  53. // Check that the author h-card was matched up with each h-entry
  54. $this->assertEquals('Author Name', $data->items[0]->author->name);
  55. $this->assertEquals('Author Name', $data->items[1]->author->name);
  56. $this->assertEquals('Author Name', $data->items[2]->author->name);
  57. $this->assertEquals('Author Name', $data->items[3]->author->name);
  58. }
  59. public function testListOfHEntrysWithHCardNoExpect()
  60. {
  61. $url = 'http://feed.example.com/list-of-hentrys-with-h-card';
  62. $response = $this->parse(['url' => $url]);
  63. $body = $response->getContent();
  64. $this->assertEquals(200, $response->getStatusCode());
  65. $result = json_decode($body);
  66. $this->assertEquals('mf2+html', $result->{'source-format'});
  67. $data = $result->data;
  68. $this->assertEquals('feed', $data->type);
  69. $this->assertEquals(4, count($data->items));
  70. $this->assertEquals('One', $data->items[0]->name);
  71. $this->assertEquals('article', $data->items[0]->{'post-type'});
  72. $this->assertEquals('Two', $data->items[1]->name);
  73. $this->assertEquals('Three', $data->items[2]->name);
  74. $this->assertEquals('Four', $data->items[3]->name);
  75. // Check that the author h-card was matched up with each h-entry
  76. $this->assertEquals('Author Name', $data->items[0]->author->name);
  77. $this->assertEquals('Author Name', $data->items[1]->author->name);
  78. $this->assertEquals('Author Name', $data->items[2]->author->name);
  79. $this->assertEquals('Author Name', $data->items[3]->author->name);
  80. }
  81. public function testShortListOfHEntrysWithHCardNoExpect()
  82. {
  83. $url = 'http://feed.example.com/short-list-of-hentrys-with-h-card';
  84. $response = $this->parse(['url' => $url]);
  85. $body = $response->getContent();
  86. $this->assertEquals(200, $response->getStatusCode());
  87. $result = json_decode($body);
  88. $this->assertEquals('mf2+html', $result->{'source-format'});
  89. $data = $result->data;
  90. // In this case, this looks like a page permalink
  91. $this->assertEquals('entry', $data->type);
  92. // This test should find the h-entry rather than the h-card, because the h-card does not contain the page URL
  93. $this->assertEquals('http://feed.example.com/1', $data->url);
  94. $this->assertEquals('Author', $data->author->name);
  95. }
  96. public function testShortListOfHEntrysWithHCard()
  97. {
  98. $url = 'http://feed.example.com/short-list-of-hentrys-with-h-card';
  99. $response = $this->parse(['url' => $url, 'expect' => 'feed']);
  100. $body = $response->getContent();
  101. $this->assertEquals(200, $response->getStatusCode());
  102. $result = json_decode($body);
  103. $this->assertEquals('mf2+html', $result->{'source-format'});
  104. $data = $result->data;
  105. $this->assertEquals('feed', $data->type);
  106. // This test should find the h-entry rather than the h-card, because expect=feed
  107. $this->assertEquals('entry', $data->items[0]->type);
  108. $this->assertEquals('http://feed.example.com/1', $data->items[0]->url);
  109. $this->assertEquals('Author', $data->items[0]->author->name);
  110. }
  111. public function testTopLevelHFeed()
  112. {
  113. $url = 'http://feed.example.com/top-level-h-feed';
  114. $response = $this->parse(['url' => $url, 'expect' => 'feed']);
  115. $body = $response->getContent();
  116. $this->assertEquals(200, $response->getStatusCode());
  117. $result = json_decode($body);
  118. $this->assertEquals('mf2+html', $result->{'source-format'});
  119. $data = $result->data;
  120. $this->assertEquals('feed', $data->type);
  121. $this->assertEquals(4, count($data->items));
  122. $this->assertEquals('One', $data->items[0]->name);
  123. $this->assertEquals('Two', $data->items[1]->name);
  124. $this->assertEquals('Three', $data->items[2]->name);
  125. $this->assertEquals('Four', $data->items[3]->name);
  126. }
  127. public function testTopLevelHFeedWithChildAuthor()
  128. {
  129. $url = 'http://feed.example.com/h-feed-with-child-author';
  130. $response = $this->parse(['url' => $url, 'expect' => 'feed']);
  131. $body = $response->getContent();
  132. $this->assertEquals(200, $response->getStatusCode());
  133. $result = json_decode($body);
  134. $this->assertEquals('mf2+html', $result->{'source-format'});
  135. $data = $result->data;
  136. $this->assertEquals('feed', $data->type);
  137. $this->assertEquals(4, count($data->items));
  138. $this->assertEquals('One', $data->items[0]->name);
  139. $this->assertEquals('Two', $data->items[1]->name);
  140. $this->assertEquals('Three', $data->items[2]->name);
  141. $this->assertEquals('Four', $data->items[3]->name);
  142. $this->assertEquals('Author Name', $data->items[0]->author->name);
  143. $this->assertEquals('Author Name', $data->items[1]->author->name);
  144. $this->assertEquals('Author Name', $data->items[2]->author->name);
  145. $this->assertEquals('Author Name', $data->items[3]->author->name);
  146. }
  147. public function testHCardWithChildHEntrys()
  148. {
  149. $url = 'http://feed.example.com/h-card-with-child-h-entrys';
  150. $response = $this->parse(['url' => $url, 'expect' => 'feed']);
  151. $body = $response->getContent();
  152. $this->assertEquals(200, $response->getStatusCode());
  153. $result = json_decode($body);
  154. $this->assertEquals('mf2+html', $result->{'source-format'});
  155. $data = $result->data;
  156. $this->assertEquals('feed', $data->type);
  157. $this->assertEquals(4, count($data->items));
  158. $this->assertEquals('One', $data->items[0]->name);
  159. $this->assertEquals('Two', $data->items[1]->name);
  160. $this->assertEquals('Three', $data->items[2]->name);
  161. $this->assertEquals('Four', $data->items[3]->name);
  162. }
  163. public function testHCardWithSiblingHEntrys()
  164. {
  165. $url = 'http://feed.example.com/h-card-with-sibling-h-entrys';
  166. $response = $this->parse(['url' => $url, 'expect' => 'feed']);
  167. $body = $response->getContent();
  168. $this->assertEquals(200, $response->getStatusCode());
  169. $result = json_decode($body);
  170. $this->assertEquals('mf2+html', $result->{'source-format'});
  171. $data = $result->data;
  172. $this->assertEquals('feed', $data->type);
  173. $this->assertEquals(4, count($data->items));
  174. $this->assertEquals('One', $data->items[0]->name);
  175. $this->assertEquals('Two', $data->items[1]->name);
  176. $this->assertEquals('Three', $data->items[2]->name);
  177. $this->assertEquals('Four', $data->items[3]->name);
  178. // Check that the author h-card was matched up with each h-entry
  179. $this->assertEquals('Author Name', $data->items[0]->author->name);
  180. $this->assertEquals('Author Name', $data->items[1]->author->name);
  181. $this->assertEquals('Author Name', $data->items[2]->author->name);
  182. $this->assertEquals('Author Name', $data->items[3]->author->name);
  183. }
  184. public function testHCardWithChildHFeed()
  185. {
  186. $url = 'http://feed.example.com/h-card-with-child-h-feed';
  187. $response = $this->parse(['url' => $url, 'expect' => 'feed']);
  188. $body = $response->getContent();
  189. $this->assertEquals(200, $response->getStatusCode());
  190. $result = json_decode($body);
  191. $this->assertEquals('mf2+html', $result->{'source-format'});
  192. $data = $result->data;
  193. $this->assertEquals('feed', $data->type);
  194. $this->assertEquals(4, count($data->items));
  195. $this->assertEquals('One', $data->items[0]->name);
  196. $this->assertEquals('Two', $data->items[1]->name);
  197. $this->assertEquals('Three', $data->items[2]->name);
  198. $this->assertEquals('Four', $data->items[3]->name);
  199. // Check that the author h-card was matched up with each h-entry
  200. $this->assertEquals('Author Name', $data->items[0]->author->name);
  201. $this->assertEquals('Author Name', $data->items[1]->author->name);
  202. $this->assertEquals('Author Name', $data->items[2]->author->name);
  203. $this->assertEquals('Author Name', $data->items[3]->author->name);
  204. }
  205. public function testHCardWithChildHFeedNoExpect()
  206. {
  207. $url = 'http://feed.example.com/h-card-with-child-h-feed';
  208. $response = $this->parse(['url' => $url]);
  209. $body = $response->getContent();
  210. $this->assertEquals(200, $response->getStatusCode());
  211. $result = json_decode($body);
  212. $this->assertEquals('mf2+html', $result->{'source-format'});
  213. $data = $result->data;
  214. $this->assertEquals('card', $data->type);
  215. $this->assertEquals('Author Name', $data->name);
  216. }
  217. public function testJSONFeed()
  218. {
  219. $url = 'http://feed.example.com/jsonfeed';
  220. $response = $this->parse(['url' => $url, 'expect' => 'feed']);
  221. $body = $response->getContent();
  222. $this->assertEquals(200, $response->getStatusCode());
  223. $result = json_decode($body);
  224. $this->assertEquals('feed+json', $result->{'source-format'});
  225. $data = $result->data;
  226. $this->assertEquals(11, count($data->items));
  227. for($i=0; $i<8; $i++) {
  228. $this->assertEquals('entry', $data->items[$i]->type);
  229. $this->assertEquals('manton', $data->items[$i]->author->name);
  230. $this->assertEquals('http://www.manton.org', $data->items[$i]->author->url);
  231. $this->assertNotEmpty($data->items[$i]->url);
  232. $this->assertNotEmpty($data->items[$i]->uid);
  233. $this->assertNotEmpty($data->items[$i]->published);
  234. $this->assertNotEmpty($data->items[$i]->content->html);
  235. $this->assertNotEmpty($data->items[$i]->content->text);
  236. }
  237. $this->assertEquals('note', $data->items[0]->{'post-type'});
  238. $this->assertEquals('article', $data->items[4]->{'post-type'});
  239. $this->assertEquals('<p>Coming up on a year since I wrote about how <a href="http://www.manton.org/2016/11/todays-social-networks-are-broken.html">today’s social networks are broken</a>. Still what I believe.</p>', $data->items[7]->content->html);
  240. $this->assertEquals('Coming up on a year since I wrote about how today’s social networks are broken. Still what I believe.', $data->items[7]->content->text);
  241. $this->assertEquals('http://www.manton.org/2017/11/5979.html', $data->items[7]->url);
  242. $this->assertEquals('http://www.manton.org/2017/11/5979.html', $data->items[7]->uid);
  243. $this->assertEquals('2017-11-07T21:00:42+00:00', $data->items[7]->published);
  244. $this->assertEquals('feed', $data->type);
  245. }
  246. public function testJSONFeedFallbackAuthor()
  247. {
  248. $url = 'http://feed.example.com/jsonfeed-author';
  249. $response = $this->parse(['url' => $url, 'expect' => 'feed']);
  250. $body = $response->getContent();
  251. $this->assertEquals(200, $response->getStatusCode());
  252. $result = json_decode($body);
  253. $this->assertEquals('feed+json', $result->{'source-format'});
  254. $data = $result->data;
  255. $this->assertEquals(11, count($data->items));
  256. for($i=0; $i<8; $i++) {
  257. $this->assertEquals('entry', $data->items[$i]->type);
  258. $this->assertEquals('Manton Reece', $data->items[$i]->author->name);
  259. $this->assertEquals('https://www.manton.org/', $data->items[$i]->author->url);
  260. $this->assertEquals('https://micro.blog/manton/avatar.jpg', $data->items[$i]->author->photo);
  261. }
  262. }
  263. public function testJSONFeed1Point1()
  264. {
  265. $url = 'http://feed.example.com/jsonfeed-1.1';
  266. $response = $this->parse(['url' => $url, 'expect' => 'feed']);
  267. $body = $response->getContent();
  268. $this->assertEquals(200, $response->getStatusCode());
  269. $result = json_decode($body);
  270. $this->assertEquals('feed+json', $result->{'source-format'});
  271. $data = $result->data;
  272. $this->assertEquals(48, count($data->items));
  273. for($i=0; $i<8; $i++) {
  274. $this->assertEquals('entry', $data->items[$i]->type);
  275. $this->assertEquals('John Gruber', $data->items[$i]->author->name);
  276. $this->assertEquals('https://twitter.com/gruber', $data->items[$i]->author->url);
  277. $this->assertNotEmpty($data->items[$i]->url);
  278. $this->assertNotEmpty($data->items[$i]->uid);
  279. $this->assertNotEmpty($data->items[$i]->published);
  280. $this->assertNotEmpty($data->items[$i]->content->html);
  281. $this->assertNotEmpty($data->items[$i]->content->text);
  282. }
  283. $this->assertEquals('article', $data->items[0]->{'post-type'});
  284. $this->assertEquals('article', $data->items[4]->{'post-type'});
  285. $this->assertEquals('The Talk Show: “Blofeld-69-420”', $data->items[7]->name);
  286. $this->assertEquals('https://daringfireball.net/linked/2022/01/26/the-talk-show-335', $data->items[7]->url);
  287. $this->assertEquals('https://daringfireball.net/linked/2022/01/26/the-talk-show-335', $data->items[7]->uid);
  288. $this->assertEquals('2022-01-27T01:58:12Z', $data->items[7]->published);
  289. $this->assertEquals('feed', $data->type);
  290. }
  291. public function testJSONFeedTopLevelAuthor()
  292. {
  293. $url = 'http://feed.example.com/jsonfeed-top-level-author';
  294. $response = $this->parse(['url' => $url, 'expect' => 'feed']);
  295. $body = $response->getContent();
  296. $this->assertEquals(200, $response->getStatusCode());
  297. $result = json_decode($body, true);
  298. $this->assertEquals('feed+json', $result['source-format']);
  299. $data = $result['data'];
  300. $item = $data['items'][0];
  301. $this->assertEquals('Author Name', $item['author']['name']);
  302. $this->assertEquals('https://author.example.com', $item['author']['url']);
  303. }
  304. public function testJSONFeedRelativeImages()
  305. {
  306. $url = 'http://feed.example.com/jsonfeed';
  307. $response = $this->parse(['url' => $url, 'expect' => 'feed']);
  308. $body = $response->getContent();
  309. $this->assertEquals(200, $response->getStatusCode());
  310. $result = json_decode($body);
  311. $this->assertEquals('feed+json', $result->{'source-format'});
  312. $data = $result->data;
  313. // Relative image on an item that has a url
  314. $this->assertEquals('http://www.manton.org/2017/11/image.jpg', $data->items[9]->photo[0]);
  315. // Relative image on an item that has no URL, fall back to feed URL
  316. $this->assertEquals('http://feed.example.com/image.jpg', $data->items[10]->photo[0]);
  317. // Relative image inside the content html
  318. $this->assertStringContainsString('http://www.manton.org/2017/11/img.jpg', $data->items[9]->content->html);
  319. }
  320. public function testAtomFeed()
  321. {
  322. $url = 'http://feed.example.com/atom';
  323. $response = $this->parse(['url' => $url, 'expect' => 'feed']);
  324. $body = $response->getContent();
  325. $this->assertEquals(200, $response->getStatusCode());
  326. $result = json_decode($body);
  327. $this->assertEquals('xml', $result->{'source-format'});
  328. $data = $result->data;
  329. $this->assertEquals(8, count($data->items));
  330. for($i=0; $i<8; $i++) {
  331. $this->assertEquals('entry', $data->items[$i]->type);
  332. $this->assertEquals('note', $data->items[$i]->{'post-type'});
  333. $this->assertEquals('Tantek', $data->items[$i]->author->name);
  334. $this->assertEquals('http://tantek.com/', $data->items[$i]->author->url);
  335. $this->assertNotEmpty($data->items[$i]->url);
  336. $this->assertNotEmpty($data->items[$i]->published);
  337. $this->assertNotEmpty($data->items[$i]->content->html);
  338. $this->assertNotEmpty($data->items[$i]->content->text);
  339. }
  340. $this->assertEquals('2017-11-08T23:53:00-08:00', $data->items[0]->published);
  341. $this->assertEquals('http://tantek.com/2017/312/t3/tam-trail-run-first-trail-half', $data->items[0]->url);
  342. $this->assertEquals('went to MORE Pancakes! this morning @RunJanji pop-up on California st after #NPSF. Picked up a new running shirt.', $data->items[1]->content->text);
  343. $this->assertEquals('went to MORE Pancakes! this morning <a href="https://twitter.com/RunJanji">@RunJanji</a> pop-up on California st after #NPSF. Picked up a new running shirt.', $data->items[1]->content->html);
  344. $this->assertEquals('feed', $data->type);
  345. }
  346. public function testRSSFeed()
  347. {
  348. $url = 'http://feed.example.com/rss';
  349. $response = $this->parse(['url' => $url, 'expect' => 'feed']);
  350. $body = $response->getContent();
  351. $this->assertEquals(200, $response->getStatusCode());
  352. $result = json_decode($body);
  353. $this->assertEquals('xml', $result->{'source-format'});
  354. $data = $result->data;
  355. $this->assertEquals(10, count($data->items));
  356. for($i=0; $i<10; $i++) {
  357. $this->assertEquals('entry', $data->items[$i]->type);
  358. $this->assertEquals(($i == 4 ? 'article' : 'note'), $data->items[$i]->{'post-type'});
  359. $this->assertEquals('Ryan Barrett', $data->items[$i]->author->name);
  360. $this->assertEquals('https://snarfed.org/', $data->items[$i]->author->url);
  361. $this->assertNotEmpty($data->items[$i]->url);
  362. $this->assertNotEmpty($data->items[$i]->published);
  363. $this->assertNotEmpty($data->items[$i]->content->html);
  364. if($i > 1) {
  365. $this->assertNotEmpty($data->items[$i]->content->text);
  366. }
  367. }
  368. $this->assertEquals('2017-09-12T20:09:12+00:00', $data->items[9]->published);
  369. $this->assertEquals('https://snarfed.org/2017-09-12_25492', $data->items[9]->url);
  370. $this->assertEquals(
  371. '<p>new business cards <img src="https://s.w.org/images/core/emoji/2.3/72x72/1f602.png" alt="😂" /></p>
  372. <p><img src="https://i0.wp.com/snarfed.org/w/wp-content/uploads/2017/09/IMG_20170912_131414_767.jpg?w=696&amp;ssl=1" alt="IMG_20170912_131414_767.jpg?w=696&amp;ssl=1" /></p>', $data->items[9]->content->html
  373. );
  374. $this->assertEquals('new business cards', $data->items[9]->content->text);
  375. $this->assertEquals('feed', $data->type);
  376. }
  377. public function testPodcastFeed()
  378. {
  379. $url = 'http://feed.example.com/podcast-rss';
  380. $response = $this->parse(['url' => $url, 'expect' => 'feed']);
  381. $body = $response->getContent();
  382. $this->assertEquals(200, $response->getStatusCode());
  383. $result = json_decode($body);
  384. $this->assertEquals('xml', $result->{'source-format'});
  385. $data = $result->data;
  386. $this->assertEquals(12, count($data->items));
  387. for($i=0; $i<12; $i++) {
  388. $this->assertEquals('entry', $data->items[$i]->type);
  389. $this->assertEquals('audio', $data->items[$i]->{'post-type'});
  390. $this->assertEquals('Aaron Parecki', $data->items[$i]->author->name);
  391. $this->assertEquals('https://percolator.today/', $data->items[$i]->author->url);
  392. $this->assertNotEmpty($data->items[$i]->url);
  393. $this->assertNotEmpty($data->items[$i]->published);
  394. $this->assertNotEmpty($data->items[$i]->name);
  395. $this->assertNotEmpty($data->items[$i]->content->html);
  396. $this->assertNotEmpty($data->items[$i]->content->text);
  397. $this->assertNotEmpty($data->items[$i]->audio);
  398. }
  399. $this->assertEquals('Episode 1: Welcome', $data->items[11]->name);
  400. $this->assertEquals('https://percolator.today/episode/1', $data->items[11]->url);
  401. $this->assertEquals('2017-09-20T07:00:00+00:00', $data->items[11]->published);
  402. $this->assertEquals('https://percolator.today/redirect.php?url=https%3A%2F%2Fpercolator.today%2Fmedia%2FPercolator_Episode_1.mp3', $data->items[11]->audio[0]);
  403. $this->assertStringContainsString('What is Percolator? Some thoughts about multi-photos in Instagram.', $data->items[11]->content->text);
  404. $this->assertStringContainsString('What is Percolator? Some thoughts about multi-photos in Instagram.', $data->items[11]->content->html);
  405. $this->assertStringContainsString('<li><a href="https://indieweb.org/multi-photo_vs_collection">multi-photo vs collection</a></li>', $data->items[11]->content->html);
  406. $this->assertEquals('feed', $data->type);
  407. }
  408. public function testInstagramAtomFeed()
  409. {
  410. $url = 'http://feed.example.com/instagram-atom';
  411. $response = $this->parse(['url' => $url, 'expect' => 'feed']);
  412. $body = $response->getContent();
  413. $this->assertEquals(200, $response->getStatusCode());
  414. $result = json_decode($body);
  415. $this->assertEquals('xml', $result->{'source-format'});
  416. $data = $result->data;
  417. $this->assertEquals(12, count($data->items));
  418. $this->assertEquals('Marshall Kirkpatrick', $data->items[11]->author->name);
  419. $this->assertEquals('https://www.instagram.com/marshallk/', $data->items[11]->author->url);
  420. $this->assertEquals('https://www.instagram.com/p/BcFjw9SHYql/', $data->items[11]->url);
  421. $this->assertEquals('2017-11-29T17:04:00+00:00', $data->items[11]->published);
  422. // Should remove the "name" since it's a prefix of the content
  423. $this->assertObjectNotHasAttribute('name', $data->items[11]);
  424. $this->assertEquals('Sometimes my job requires me to listen to 55 minutes of an hour long phone call while I go for a long walk on a sunny morning and wait for my turn to give an update. Pretty nice!', $data->items[11]->content->text);
  425. }
  426. public function testAscraeus()
  427. {
  428. $url = 'http://source.example.com/ascraeus';
  429. $response = $this->parse(['url' => $url, 'expect' => 'feed']);
  430. $body = $response->getContent();
  431. $this->assertEquals(200, $response->getStatusCode());
  432. $data = json_decode($body)->data;
  433. $this->assertEquals('feed', $data->type);
  434. $this->assertEquals(20, count($data->items));
  435. }
  436. public function testAdactioLinks()
  437. {
  438. $url = 'http://feed.example.com/adactio-links';
  439. $response = $this->parse(['url' => $url, 'expect' => 'feed']);
  440. $body = $response->getContent();
  441. $this->assertEquals(200, $response->getStatusCode());
  442. $data = json_decode($body)->data;
  443. $this->assertEquals('feed', $data->type);
  444. // 20 h-entrys followed by one h-card, which should have been removed and used as the author instead
  445. $this->assertEquals(20, count($data->items));
  446. $this->assertEquals('http://feed.example.com/links/14501', $data->items[0]->url);
  447. $this->assertEquals('http://feed.example.com/links/14445', $data->items[19]->url);
  448. $item = $data->items[0];
  449. $this->assertEquals('Jeremy Keith', $item->author->name);
  450. $this->assertEquals('https://adactio.com/', $item->author->url);
  451. }
  452. public function testWaterpigsFeed()
  453. {
  454. $url = 'http://feed.example.com/waterpigs';
  455. $response = $this->parse(['url' => $url, 'expect' => 'feed']);
  456. $body = $response->getContent();
  457. $this->assertEquals(200, $response->getStatusCode());
  458. $data = json_decode($body)->data;
  459. $this->assertEquals('feed', $data->type);
  460. $this->assertEquals(21, count($data->items));
  461. $item = $data->items[16];
  462. $this->assertEquals('Barnaby Walters', $item->author->name);
  463. $this->assertEquals('https://waterpigs.co.uk', $item->author->url);
  464. }
  465. public function testRSSWithNoXMLTag()
  466. {
  467. $url = 'http://feed.example.com/rss-no-xml-tag';
  468. $response = $this->parse(['url' => $url, 'expect' => 'feed']);
  469. $body = $response->getContent();
  470. $this->assertEquals(200, $response->getStatusCode());
  471. $data = json_decode($body)->data;
  472. $this->assertEquals('feed', $data->type);
  473. }
  474. public function testAuthorFeedOnHomePage()
  475. {
  476. $url = 'http://feed.example.com/h-feed-author-is-feed';
  477. $response = $this->parse(['url' => $url, 'expect' => 'feed']);
  478. $body = $response->getContent();
  479. $this->assertEquals(200, $response->getStatusCode());
  480. $parsed = json_decode($body, true);
  481. $data = $parsed['data'];
  482. $this->assertEquals('feed', $data['type']);
  483. $this->assertEquals('http://author.example.com/h-feed-author', $data['items'][0]['author']['url']);
  484. $this->assertEquals('Author', $data['items'][0]['author']['name']);
  485. $this->assertEquals('http://author.example.com/h-feed-author', $data['items'][1]['author']['url']);
  486. $this->assertEquals('Author', $data['items'][1]['author']['name']);
  487. }
  488. public function testAuthorFeedOnHomePageInvalid()
  489. {
  490. $url = 'http://feed.example.com/h-feed-author-is-bad-feed';
  491. $response = $this->parse(['url' => $url, 'expect' => 'feed']);
  492. $body = $response->getContent();
  493. $this->assertEquals(200, $response->getStatusCode());
  494. $parsed = json_decode($body, true);
  495. $data = $parsed['data'];
  496. $this->assertEquals('feed', $data['type']);
  497. $this->assertEquals('http://author.example.com/h-feed-author-bad', $data['items'][0]['author']['url']);
  498. $this->assertEquals('http://author.example.com/h-feed-author-bad', $data['items'][1]['author']['url']);
  499. }
  500. }