Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions src/formats/atom/atom.conformance.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -390,4 +390,24 @@ describe('Atom enclosure mapping (RFC 4287 §4.2.7.2)', () => {
)
expect(xml).not.toContain('1800')
})

it('ignores enclosure.title (JSON Feed-only attachment field, no Atom mapping)', () => {
const xml = toAtom({
...withEnclosure,
items: [
{
...withEnclosure.items[0],
enclosure: {
url: 'https://example.com/ep1.mp3',
type: 'audio/mpeg',
title: 'Episode 1',
},
},
],
})
expect(xml).toContain(
'<link rel="enclosure" href="https://example.com/ep1.mp3" type="audio/mpeg"/>',
)
expect(xml).not.toContain('Episode 1')
})
})
1 change: 1 addition & 0 deletions src/formats/json/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ function jsonItem(item: FeedItem, v1: boolean, base?: string): Record<string, un
}
if (enclosure.length !== undefined) attachment.size_in_bytes = enclosure.length
if (enclosure.duration !== undefined) attachment.duration_in_seconds = enclosure.duration
if (enclosure.title) attachment.title = enclosure.title
return attachment
})
if (attachments.length) o.attachments = attachments
Expand Down
38 changes: 38 additions & 0 deletions src/formats/json/json.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -454,6 +454,44 @@ describe('toJSONFeed', () => {
expect(json.items[0].attachments[0].duration_in_seconds).toBeUndefined()
})

it('maps enclosure.title to the attachment title', () => {
const json = JSON.parse(
toJSONFeed({
options: { title: 't', link: 'https://example.com/' },
items: [
{
title: 'a',
link: 'https://example.com/1',
content: '<p>b</p>',
enclosure: {
url: 'https://example.com/a.mp3',
type: 'audio/mpeg',
title: 'Episode 1',
},
},
],
}),
)
expect(json.items[0].attachments[0].title).toBe('Episode 1')
})

it('omits the attachment title when the enclosure has no title', () => {
const json = JSON.parse(
toJSONFeed({
options: { title: 't', link: 'https://example.com/' },
items: [
{
title: 'a',
link: 'https://example.com/1',
content: '<p>b</p>',
enclosure: { url: 'https://example.com/a.mp3', type: 'audio/mpeg' },
},
],
}),
)
expect(json.items[0].attachments[0].title).toBeUndefined()
})

it('pretty-prints with 2-space indentation', () => {
const out = toJSONFeed(
{ options: { title: 't', link: 'https://example.com/' }, items: [] },
Expand Down
2 changes: 2 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ export interface Enclosure {
length?: number
/** Duration in seconds. JSON Feed `duration_in_seconds`; no RSS/Atom enclosure equivalent. */
duration?: number
/** Attachment name. JSON Feed `title`; Atom link `title`; no RSS equivalent. */
title?: string
}

/** `itunes:owner` — the podcast's admin contact, shown only to Apple Podcasts, never in the UI. */
Expand Down
Loading