diff --git a/src/__tests__/rss2.spec.ts b/src/__tests__/rss2.spec.ts index dc520da..85b1081 100644 --- a/src/__tests__/rss2.spec.ts +++ b/src/__tests__/rss2.spec.ts @@ -217,6 +217,37 @@ describe("rss 2.0", () => { expect(actual).toMatchSnapshot(); }); + it("should emit podcast categories as text attributes", () => { + const podcastFeed = new Feed({ + title: "Feed Title", + id: "http://example.com/", + link: "http://example.com/", + podcast: true, + category: "History", + }); + const actual = podcastFeed.rss2(); + expect(actual).toContain(''); + expect(actual).toContain(''); + expect(actual).not.toContain("History"); + expect(actual).not.toContain("History"); + }); + + it("should escape & in podcast category attributes", () => { + const podcastFeed = new Feed({ + title: "Feed Title", + id: "http://example.com/", + link: "http://example.com/", + podcast: true, + category: "Society & Culture", + }); + const actual = podcastFeed.rss2(); + // unlike a text node, xml-js does not escape `&` inside an attribute value, + // so it must be escaped before being handed to the serializer + expect(actual).toContain(''); + expect(actual).toContain(''); + expect(actual).not.toContain('text="Society & Culture"'); + }); + it("should generate a valid feed with video", () => { const sampleFeed = new Feed({ title: "Feed Title", diff --git a/src/rss2.ts b/src/rss2.ts index d527fa9..548deb8 100644 --- a/src/rss2.ts +++ b/src/rss2.ts @@ -2,7 +2,7 @@ import * as convert from "xml-js"; import { generator } from "./config"; import type { Feed } from "./feed"; import type { Author, Category, Enclosure, Extension, Item } from "./typings"; -import { sanitizeUrl } from "./utils"; +import { sanitize, sanitizeUrl } from "./utils"; export default (ins: Feed) => { const { options, extensions } = ins; @@ -201,8 +201,12 @@ export default (ins: Feed) => { base.rss._attributes["xmlns:googleplay"] = "http://www.google.com/schemas/play-podcasts/1.0"; base.rss._attributes["xmlns:itunes"] = "http://www.itunes.com/dtds/podcast-1.0.dtd"; if (options.category) { - base.rss.channel["googleplay:category"] = options.category; - base.rss.channel["itunes:category"] = options.category; + base.rss.channel["googleplay:category"] = { + _attributes: { text: sanitize(options.category) }, + }; + base.rss.channel["itunes:category"] = { + _attributes: { text: sanitize(options.category) }, + }; } if (options.author?.email) { base.rss.channel["googleplay:owner"] = options.author.email;