package com.rssuper.parsing import com.rssuper.models.Enclosure import org.junit.Assert.assertEquals import org.junit.Assert.assertNotNull import org.junit.Assert.assertNull import org.junit.Test import org.junit.runner.RunWith import org.robolectric.RobolectricTestRunner import org.robolectric.annotation.Config @RunWith(RobolectricTestRunner::class) @Config(sdk = [24]) class AtomParserTest { @Test fun testParseBasicAtom() { val xml = """ Atom Feed Feed subtitle urn:uuid:feed-id-123 2024-01-01T12:00:00Z Atom Generator Entry 1 urn:uuid:entry-1 2024-01-01T10:00:00Z Summary of entry 1 Entry 2 urn:uuid:entry-2 2023-12-31T10:00:00Z Full content of entry 2 """.trimIndent() val feed = AtomParser.parse(xml, "https://example.com/feed.atom") assertNotNull(feed) assertEquals("Atom Feed", feed.title) assertEquals("https://example.com", feed.link) assertEquals("Feed subtitle", feed.subtitle) assertEquals(2, feed.items.size) val entry1 = feed.items[0] assertEquals("Entry 1", entry1.title) assertEquals("https://example.com/entry1", entry1.link) assertEquals("Summary of entry 1", entry1.description) assertNotNull(entry1.published) val entry2 = feed.items[1] assertEquals("Entry 2", entry2.title) assertEquals("Full content of entry 2", entry2.content) } @Test fun testParseAtomWithAuthor() { val xml = """ Author Feed urn:uuid:feed-id Entry with Author urn:uuid:entry John Doe john@example.com """.trimIndent() val feed = AtomParser.parse(xml, "https://example.com/feed.atom") assertNotNull(feed) val entry = feed.items[0] assertEquals("John Doe", entry.author) } @Test fun testParseAtomWithCategories() { val xml = """ Categorized Feed urn:uuid:feed-id Categorized Entry urn:uuid:entry """.trimIndent() val feed = AtomParser.parse(xml, "https://example.com/feed.atom") assertNotNull(feed) val entry = feed.items[0] assertEquals(2, entry.categories?.size) assertEquals("technology", entry.categories?.get(0)) assertEquals("programming", entry.categories?.get(1)) } @Test fun testParseAtomWithEnclosure() { val xml = """ Enclosure Feed urn:uuid:feed-id Episode urn:uuid:entry """.trimIndent() val feed = AtomParser.parse(xml, "https://example.com/feed.atom") assertNotNull(feed) val entry = feed.items[0] assertNotNull(entry.enclosure) assertEquals("https://example.com/ep.mp3", entry.enclosure?.url) assertEquals("audio/mpeg", entry.enclosure?.type) assertEquals(12345678L, entry.enclosure?.length) } @Test fun testParseAtomWithContent() { val xml = """ Content Feed urn:uuid:feed-id Entry urn:uuid:entry Short summary Full HTML content """.trimIndent() val feed = AtomParser.parse(xml, "https://example.com/feed.atom") assertNotNull(feed) val entry = feed.items[0] assertEquals("Full HTML content", entry.content) assertEquals("Short summary", entry.description) } @Test fun testParseAtomWithiTunesExtension() { val xml = """ Podcast urn:uuid:feed-id Episode urn:uuid:entry 3600 Episode summary """.trimIndent() val feed = AtomParser.parse(xml, "https://example.com/feed.atom") assertNotNull(feed) val entry = feed.items[0] assertEquals("Episode summary", entry.description) } @Test fun testParseAtomWithPublished() { val xml = """ Date Feed urn:uuid:feed-id 2024-06-15T12:00:00Z Entry urn:uuid:entry 2024-01-01T08:00:00Z 2024-01-02T10:00:00Z """.trimIndent() val feed = AtomParser.parse(xml, "https://example.com/feed.atom") assertNotNull(feed) val entry = feed.items[0] assertNotNull(entry.published) } @Test fun testParseAtomWithEmptyFeed() { val xml = """ Empty Feed urn:uuid:feed-id """.trimIndent() val feed = AtomParser.parse(xml, "https://example.com/feed.atom") assertNotNull(feed) assertEquals("Empty Feed", feed.title) assertEquals(0, feed.items.size) } @Test fun testParseAtomWithMissingFields() { val xml = """ Minimal Entry """.trimIndent() val feed = AtomParser.parse(xml, "https://example.com/feed.atom") assertNotNull(feed) assertEquals("Untitled Feed", feed.title) assertEquals(1, feed.items.size) assertEquals("Minimal Entry", feed.items[0].title) assertNull(feed.items[0].link) } }