<?php
// SyndicationTest.php
// Created: 2024-10-03
// Updated: 2025-01-18

declare(strict_types=1);

use PHPUnit\Framework\TestCase;
use PHPUnit\Framework\Attributes\CoversClass;
use Index\Syndication\{FeedBuilder,FeedItemBuilder};

#[CoversClass(FeedBuilder::class)]
#[CoversClass(FeedItemBuilder::class)]
final class SyndicationTest extends TestCase {
    private const BLANK_FEED = <<<XML
    <?xml version="1.0" encoding="UTF-8"?>
    <rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
      <channel>
        <title>Feed</title>
      </channel>
    </rss>

    XML;

    private const NO_ITEMS_FEED = <<<XML
    <?xml version="1.0" encoding="UTF-8"?>
    <rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
      <channel>
        <title>Index RSS</title>
        <pubDate>Thu, 03 Oct 24 20:06:25 +0000</pubDate>
        <link>https://example.railgun.sh/articles</link>
        <description><![CDATA[<b>This should accept HTML!</b>]]></description>
        <atom:link href="https://example.railgun.sh/feed.xml" ref="self" type="application/rss+xml"/>
      </channel>
    </rss>

    XML;

    private const ITEMS_FEED = <<<XML
    <?xml version="1.0" encoding="UTF-8"?>
    <rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
      <channel>
        <title>Index RSS</title>
        <pubDate>Thu, 03 Oct 24 20:06:25 +0000</pubDate>
        <link>https://example.railgun.sh/articles</link>
        <description><![CDATA[<b>This should accept HTML!</b>]]></description>
        <atom:link href="https://example.railgun.sh/feed.xml" ref="self" type="application/rss+xml"/>
        <item>
          <title>Article 1</title>
          <pubDate>Sat, 28 Sep 24 01:13:05 +0000</pubDate>
          <link>https://example.railgun.sh/articles/1</link>
          <guid>https://example.railgun.sh/articles/1</guid>
          <comments>https://example.railgun.sh/articles/1#comments</comments>
          <description><![CDATA[<p>This is an article!</p>
    <p>It has <b>HTML</b> and <em>multiple lines</em> and all that <u>awesome</u> stuff!!!!</p>
    <h2>Meaning it can also have sections</h2>
    <p>Technology is so cool...</p>]]></description>
          <atom:author>
            <atom:name>flashwave</atom:name>
            <atom:uri>https://example.railgun.sh/author/1</atom:uri>
          </atom:author>
        </item>
        <item>
          <title>Article 2</title>
          <pubDate>Sun, 29 Sep 24 04:59:45 +0000</pubDate>
          <link>https://example.railgun.sh/articles/2</link>
          <guid>https://example.railgun.sh/articles/2</guid>
          <comments>https://example.railgun.sh/articles/2#comments</comments>
          <description><![CDATA[<p>hidden author spooky</p>]]></description>
        </item>
        <item>
          <title>Article 3 without a description</title>
          <pubDate>Mon, 30 Sep 24 08:46:25 +0000</pubDate>
          <link>https://example.railgun.sh/articles/3</link>
          <guid>https://example.railgun.sh/articles/3</guid>
          <comments>https://example.railgun.sh/articles/3#comments</comments>
          <atom:author>
            <atom:name>Anonymous</atom:name>
          </atom:author>
        </item>
      </channel>
    </rss>

    XML;

    public function testFeedBuilder(): void {
        $feed = new FeedBuilder;

        $this->assertEquals(self::BLANK_FEED, $feed->toXmlString());

        $feed->title = 'Index RSS';
        $feed->description = '<b>This should accept HTML!</b>';
        $feed->updatedAt = 1727985985;
        $feed->contentUrl = 'https://example.railgun.sh/articles';
        $feed->feedUrl = 'https://example.railgun.sh/feed.xml';

        $this->assertEquals(self::NO_ITEMS_FEED, $feed->toXmlString());

        $feed->createEntry(function($item) {
            $item->title = 'Article 1';
            $item->description = <<<HTML
            <p>This is an article!</p>
            <p>It has <b>HTML</b> and <em>multiple lines</em> and all that <u>awesome</u> stuff!!!!</p>
            <h2>Meaning it can also have sections</h2>
            <p>Technology is so cool...</p>
            HTML;
            $item->createdAt = 1727485985;
            $item->contentUrl = 'https://example.railgun.sh/articles/1';
            $item->commentsUrl = 'https://example.railgun.sh/articles/1#comments';
            $item->authorName = 'flashwave';
            $item->authorUrl = 'https://example.railgun.sh/author/1';
        });
        $feed->createEntry(function($item) {
            $item->title = 'Article 2';
            $item->description = <<<HTML
            <p>hidden author spooky</p>
            HTML;
            $item->createdAt = 1727585985;
            $item->contentUrl = 'https://example.railgun.sh/articles/2';
            $item->commentsUrl = 'https://example.railgun.sh/articles/2#comments';
        });
        $feed->createEntry(function($item) {
            $item->title = 'Article 3 without a description';
            $item->createdAt = 1727685985;
            $item->contentUrl = 'https://example.railgun.sh/articles/3';
            $item->commentsUrl = 'https://example.railgun.sh/articles/3#comments';
            $item->authorName = 'Anonymous';
        });

        $this->assertEquals(self::ITEMS_FEED, $feed->toXmlString());
    }
}