Repository: laminas/laminas-feed
Pull request #98: Fix: PodcastIndex feed extension and tests
Author: login: nb823
Labels: name: Bug
description: Something isn't working
Created: 2025-05-12T16:42:11Z | Merged: 2025-05-13T09:35:51Z

|    Q          |   A
|-------------- | ------
| Documentation | no
| Bugfix        | yes
| BC Break      | no
| New Feature   | no
| RFC           | no
| QA            | no

Fix for Issue: https://github.com/laminas/laminas-feed/issues/96

- Made a small fix on the PodcastIndex extension renderer
- Added two tests to check on the feed podcastindex tags generated


Diff:
diff --git a/src/Writer/Extension/PodcastIndex/Renderer/Feed.php b/src/Writer/Extension/PodcastIndex/Renderer/Feed.php
index d44f06ac..7a991bd3 100644
--- a/src/Writer/Extension/PodcastIndex/Renderer/Feed.php
+++ b/src/Writer/Extension/PodcastIndex/Renderer/Feed.php
@@ -74,7 +74,7 @@ protected function setFunding(DOMDocument $dom, DOMElement $root): void
         if ($funding === null) {
             return;
         }
-        $el   = $dom->createElement('podcast:locked');
+        $el   = $dom->createElement('podcast:funding');
         $text = $dom->createTextNode((string) $funding['title']);
         $el->appendChild($text);
         $el->setAttribute('url', $funding['url']);
diff --git a/test/Writer/Renderer/Extension/PodcastIndex/FeedTest.php b/test/Writer/Renderer/Extension/PodcastIndex/FeedTest.php
new file mode 100644
index 00000000..64861ba6
--- /dev/null
+++ b/test/Writer/Renderer/Extension/PodcastIndex/FeedTest.php
@@ -0,0 +1,57 @@
+<?php
+
+declare(strict_types=1);
+
+namespace LaminasTest\Feed\Writer\Renderer\Extension\PodcastIndex;
+
+use Laminas\Feed\Writer;
+use Laminas\Feed\Writer\Renderer;
+use PHPUnit\Framework\TestCase;
+
+class FeedTest extends TestCase
+{
+    protected Writer\Feed $validWriter;
+
+    protected function setUp(): void
+    {
+        Writer\Writer::reset();
+
+        $this->validWriter = new Writer\Feed();
+        $this->validWriter->setTitle('This is a test feed.');
+        $this->validWriter->setDescription('This is a test description.');
+        $this->validWriter->setLink('http://www.example.com');
+        $this->validWriter->setType('rss');
+    }
+
+    protected function tearDown(): void
+    {
+        Writer\Writer::reset();
+    }
+
+    public function testRendersLockedTag(): void
+    {
+        $locked = [
+            'value' => 'yes',
+            'owner' => 'john.doe@example.com',
+        ];
+        $this->validWriter->setPodcastIndexLocked($locked);
+
+        $rssFeed = new Renderer\Feed\Rss($this->validWriter);
+        $xml     = $rssFeed->render()->saveXml();
+        $this->assertStringContainsString('<podcast:locked', $xml);
+    }
+
+    public function testRendersFundingTag(): void
+    {
+        $funding = [
+            'title' => 'Support the show!',
+            'url'   => 'http://example.com/donate',
+        ];
+        $this->validWriter->setPodcastIndexFunding($funding);
+
+        $rssFeed = new Renderer\Feed\Rss($this->validWriter);
+        $xml     = $rssFeed->render()->saveXml();
+
+        $this->assertStringContainsString('<podcast:funding', $xml);
+    }
+}


Reviews:
user: login: gsteel
body: LGTM @nb823 - Just a couple of tweaks to satisfy CI and this can be merged & released
state: CHANGES_REQUESTED
author_association: MEMBER
submitted_at: 2025-05-13T07:43:14Z
user: login: gsteel
body: Thank you @nb823! Much appreciated
state: APPROVED
author_association: MEMBER
submitted_at: 2025-05-13T09:33:59Z

Review comments:
diff_hunk: @@ -0,0 +1,59 @@
+<?php
+
+declare(strict_types=1);
+
+namespace LaminasTest\Feed\Writer\Renderer\Extension\PodcastIndex;
+
+use Laminas\Feed\Writer;
+use Laminas\Feed\Writer\Renderer;
+use PHPUnit\Framework\TestCase;
+
+class FeedTest extends TestCase
+{
+    protected Writer\Feed $validWriter;
+
+    protected function setUp(): void
+    {
+        Writer\Writer::reset();
+
+        $this->validWriter = new Writer\Feed();
+        $this->validWriter->setTitle('This is a test feed.');
+        $this->validWriter->setDescription('This is a test description.');
+        $this->validWriter->setLink('http://www.example.com');
+        $this->validWriter->setType('rss');
+    }
+
+    protected function tearDown(): void
+    {
+        Writer\Writer::reset();
+    }
+
+    public function testRendersLockedTag(): void
+    {
+        $locked = [
+            'value' => 'yes',
+            'owner' => 'john.doe@example.com',
+        ];
+        $this->validWriter->setPodcastIndexLocked($locked);
+
+        $rssFeed = new Renderer\Feed\Rss($this->validWriter);
+        /** @var string $xml */
path: test/Writer/Renderer/Extension/PodcastIndex/FeedTest.php
user: login: gsteel
body: If you're worried this might not be a string, add an assertion after the assignment, otherwise just drop it to stop Psalm complaining.
created_at: 2025-05-13T07:41:12Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,59 @@
+<?php
+
+declare(strict_types=1);
+
+namespace LaminasTest\Feed\Writer\Renderer\Extension\PodcastIndex;
+
+use Laminas\Feed\Writer;
+use Laminas\Feed\Writer\Renderer;
+use PHPUnit\Framework\TestCase;
+
+class FeedTest extends TestCase
+{
+    protected Writer\Feed $validWriter;
+
+    protected function setUp(): void
+    {
+        Writer\Writer::reset();
+
+        $this->validWriter = new Writer\Feed();
+        $this->validWriter->setTitle('This is a test feed.');
+        $this->validWriter->setDescription('This is a test description.');
+        $this->validWriter->setLink('http://www.example.com');
+        $this->validWriter->setType('rss');
+    }
+
+    protected function tearDown(): void
+    {
+        Writer\Writer::reset();
+    }
+
+    public function testRendersLockedTag(): void
+    {
+        $locked = [
+            'value' => 'yes',
+            'owner' => 'john.doe@example.com',
+        ];
+        $this->validWriter->setPodcastIndexLocked($locked);
+
+        $rssFeed = new Renderer\Feed\Rss($this->validWriter);
+        /** @var string $xml */
+        $xml = $rssFeed->render()->saveXml();
+        $this->assertStringContainsString('<podcast:locked', $xml);
+    }
+
+    public function testRendersFundingTag(): void
+    {
+        $funding = [
+            'title' => 'Support the show!',
+            'url' => 'http://example.com/donate',
+        ];
+        $this->validWriter->setPodcastIndexFunding($funding);
+
+        $rssFeed = new Renderer\Feed\Rss($this->validWriter);
+        /** @var string $xml */
path: test/Writer/Renderer/Extension/PodcastIndex/FeedTest.php
user: login: gsteel
body: Same here with `@var` switch to an assertion, or simply remove it.
created_at: 2025-05-13T07:41:51Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,59 @@
+<?php
+
+declare(strict_types=1);
+
+namespace LaminasTest\Feed\Writer\Renderer\Extension\PodcastIndex;
+
+use Laminas\Feed\Writer;
+use Laminas\Feed\Writer\Renderer;
+use PHPUnit\Framework\TestCase;
+
+class FeedTest extends TestCase
+{
+    protected Writer\Feed $validWriter;
+
+    protected function setUp(): void
+    {
+        Writer\Writer::reset();
+
+        $this->validWriter = new Writer\Feed();
+        $this->validWriter->setTitle('This is a test feed.');
+        $this->validWriter->setDescription('This is a test description.');
+        $this->validWriter->setLink('http://www.example.com');
+        $this->validWriter->setType('rss');
+    }
+
+    protected function tearDown(): void
+    {
+        Writer\Writer::reset();
+    }
+
+    public function testRendersLockedTag(): void
+    {
+        $locked = [
+            'value' => 'yes',
+            'owner' => 'john.doe@example.com',
+        ];
+        $this->validWriter->setPodcastIndexLocked($locked);
+
+        $rssFeed = new Renderer\Feed\Rss($this->validWriter);
+        /** @var string $xml */
+        $xml = $rssFeed->render()->saveXml();
+        $this->assertStringContainsString('<podcast:locked', $xml);
+    }
+
+    public function testRendersFundingTag(): void
+    {
+        $funding = [
+            'title' => 'Support the show!',
+            'url' => 'http://example.com/donate',
path: test/Writer/Renderer/Extension/PodcastIndex/FeedTest.php
user: login: gsteel
body: ```suggestion
            'url'   => 'http://example.com/donate',
```
created_at: 2025-05-13T07:42:20Z
author_association: MEMBER

PR comments:
user: login: nb823
created_at: 2025-05-13T08:21:35Z
body: @gsteel Unfortunately, my local CodeSniffer and Psalm plugins stumble upon different lines of code, so that I only see the above problems after pushing the new commits. The lines you mentioned above were already just a reaction on the previous check fails I got here. Now, after another update, there is still simple formatting issues open that I don't know how to solve, since I cannot see what exact lines are failing.
author_association: CONTRIBUTOR
user: login: gsteel
created_at: 2025-05-13T08:25:31Z
body: @nb823 Assuming you have run `composer install` locally, from the project root `vendor/bin/phpcs`, `vendor/bin/phpcbf` and `vendor/bin/psalm` should all work "out of the box", (also assuming you have a supported version of PHP available locally)
author_association: MEMBER
user: login: gsteel
created_at: 2025-05-13T08:26:33Z
body: If Psalm is causing problems - Also try `vendor/bin/psalm --no-cache --threads=1` to verify SA passes
author_association: MEMBER
user: login: nb823
created_at: 2025-05-13T09:34:54Z
body: > from the project root `vendor/bin/phpcs`, `vendor/bin/phpcbf` and `vendor/bin/psalm` should all work "out of the box"

Thank you for the hint to run those scripts directly @gsteel 
Now it passes all checks.


author_association: CONTRIBUTOR