4
0

rssViewTest.php 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. <?php
  2. declare(strict_types=1);
  3. final class rssViewTest extends \PHPUnit\Framework\TestCase {
  4. #[\Override]
  5. public static function setUpBeforeClass(): void {
  6. // `FreshRSS_View` needs a system configuration; the shipped defaults are enough to render a feed.
  7. Minz_Configuration::register('system', FRESHRSS_PATH . '/config.default.php', FRESHRSS_PATH . '/config.default.php');
  8. }
  9. /** @param array<string,mixed> $enclosure */
  10. private static function renderEntryWithEnclosure(array $enclosure): string {
  11. $entry = new FreshRSS_Entry(1, 'guid', 'Title', '', 'Content', 'https://example.net/article', 1700000000);
  12. $entry->_attribute('enclosures', [$enclosure]);
  13. $view = new FreshRSS_View();
  14. $view->_path('index/rss.phtml');
  15. $view->internal_rendering = true;
  16. $view->rss_title = 'Test';
  17. $view->rss_url = 'https://example.net/rss';
  18. $view->html_url = 'https://example.net/';
  19. $view->description = 'Test';
  20. $view->entries = [$entry];
  21. return $view->renderToString();
  22. }
  23. /** An enclosure with several `<media:credit>` must keep them all, see https://github.com/FreshRSS/FreshRSS/issues/5066 */
  24. public function test_rss_multipleEnclosureCredits(): void {
  25. $rss = self::renderEntryWithEnclosure([
  26. 'url' => 'https://example.net/audio.mp3',
  27. 'type' => 'audio/mpeg',
  28. 'credit' => ['Alice', 'Bob', 'Carol'],
  29. ]);
  30. self::assertStringContainsString(
  31. '<media:credit>Alice</media:credit><media:credit>Bob</media:credit><media:credit>Carol</media:credit>', $rss);
  32. }
  33. /** Entries older than FreshRSS 1.24 store a single credit as a string instead of an array */
  34. public function test_rss_legacySingleEnclosureCredit(): void {
  35. $rss = self::renderEntryWithEnclosure([
  36. 'url' => 'https://example.net/audio.mp3',
  37. 'type' => 'audio/mpeg',
  38. 'credit' => 'Alice',
  39. ]);
  40. self::assertStringContainsString('<media:credit>Alice</media:credit>', $rss);
  41. }
  42. /** BitTorrent enclosures must also be exposed as RSS 2.0 `<enclosure>` for clients that ignore Media RSS */
  43. public function test_rss_enclosureForBitTorrent(): void {
  44. $rss = self::renderEntryWithEnclosure([
  45. 'url' => 'https://example.net/file.torrent',
  46. 'type' => 'application/x-bittorrent',
  47. 'length' => 12216,
  48. ]);
  49. self::assertStringContainsString(
  50. '<enclosure url="https://example.net/file.torrent" type="application/x-bittorrent" length="12216"/>', $rss);
  51. }
  52. /** A magnet link is a torrent even without a MIME type */
  53. public function test_rss_enclosureForMagnetWithoutType(): void {
  54. $rss = self::renderEntryWithEnclosure([
  55. 'url' => 'magnet:?xt=urn:btih:0123456789abcdef',
  56. ]);
  57. self::assertStringContainsString(
  58. '<enclosure url="magnet:?xt=urn:btih:0123456789abcdef" type="application/x-bittorrent"/>', $rss);
  59. }
  60. /** Images / audio / video must not be duplicated as RSS 2.0 `<enclosure>` */
  61. public function test_rss_noEnclosureForImageAttachment(): void {
  62. $rss = self::renderEntryWithEnclosure([
  63. 'url' => 'https://example.net/cover.jpg',
  64. 'type' => 'image/jpeg',
  65. 'medium' => 'image',
  66. ]);
  67. self::assertStringNotContainsString('<enclosure', $rss);
  68. }
  69. }