Test Feed
https://example.com
-
Article 1
https://example.com/1
';
$parser = new FeedParser($xml);
$this->assertTrue($parser->init());
$this->assertEquals(FeedParser::FEED_RSS, $parser->get_type());
$this->assertEquals('Test Feed', $parser->get_title());
$this->assertEquals('https://example.com', $parser->get_link());
$this->assertCount(1, $parser->get_items());
}
public function testParseRssFeedWithMultipleItems(): void {
$xml = '
Multi-Item Feed
https://example.com
- Item 1
- Item 2
- Item 3
';
$parser = new FeedParser($xml);
$parser->init();
$this->assertCount(3, $parser->get_items());
}
public function testRssFeedTrimsWhitespaceInTitleAndLink(): void {
$xml = '
Whitespace Title
https://example.com
';
$parser = new FeedParser($xml);
$parser->init();
$this->assertEquals('Whitespace Title', $parser->get_title());
$this->assertEquals('https://example.com', $parser->get_link());
}
// ===== Atom Feed Tests =====
public function testParseValidAtomFeed(): void {
$xml = '
Atom Feed
Entry 1
';
$parser = new FeedParser($xml);
$this->assertTrue($parser->init());
$this->assertEquals(FeedParser::FEED_ATOM, $parser->get_type());
$this->assertEquals('Atom Feed', $parser->get_title());
$this->assertEquals('https://example.com', $parser->get_link());
$this->assertCount(1, $parser->get_items());
}
public function testAtomFeedWithAlternateLinkRel(): void {
$xml = '
Test
';
$parser = new FeedParser($xml);
$parser->init();
$this->assertEquals('https://example.com/alternate', $parser->get_link());
}
public function testAtom03Feed(): void {
$xml = '
Atom 0.3 Feed
Old Entry
';
$parser = new FeedParser($xml);
$this->assertTrue($parser->init());
$this->assertEquals(FeedParser::FEED_ATOM, $parser->get_type());
$this->assertEquals('Atom 0.3 Feed', $parser->get_title());
$this->assertCount(1, $parser->get_items());
}
// ===== RDF/RSS 1.0 Feed Tests =====
public function testParseRdfFeed(): void {
$xml = '
RDF Feed
https://example.com
-
RDF Item
';
$parser = new FeedParser($xml);
$this->assertTrue($parser->init());
$this->assertEquals(FeedParser::FEED_RDF, $parser->get_type());
$this->assertEquals('RDF Feed', $parser->get_title());
$this->assertEquals('https://example.com', $parser->get_link());
$this->assertCount(1, $parser->get_items());
}
// ===== Error Handling Tests =====
public function testInvalidXmlReturnsError(): void {
$xml = '';
$parser = new FeedParser($xml);
$this->assertFalse($parser->init());
$this->assertNotEmpty($parser->error());
}
public function testUnknownFeedTypeReturnsError(): void {
$xml = '';
$parser = new FeedParser($xml);
$this->assertFalse($parser->init());
$this->assertEquals(FeedParser::FEED_UNKNOWN, $parser->get_type());
$this->assertStringContainsString('Unknown/unsupported feed type', $parser->error());
}
public function testEmptyXmlReturnsError(): void {
$parser = new FeedParser('');
$this->assertFalse($parser->init());
$this->assertStringContainsString('Empty feed data', $parser->error());
}
public function testLibxmlErrorsAreCollected(): void {
$xml = 'Test';
$parser = new FeedParser($xml);
$errors = $parser->errors();
$this->assertNotEmpty($errors);
}
// ===== Feed Type Detection Tests =====
public function testGetTypeBeforeInitReturnsUnknown(): void {
$xml = '';
$parser = new FeedParser($xml);
// get_type() before init() should detect type automatically
$this->assertEquals(FeedParser::FEED_RSS, $parser->get_type());
}
public function testGetTypeCachesResult(): void {
$xml = '';
$parser = new FeedParser($xml);
$type1 = $parser->get_type();
$type2 = $parser->get_type();
$this->assertEquals($type1, $type2);
}
// ===== Link Extraction Tests =====
public function testGetLinksFromAtomFeed(): void {
$xml = '
Test
';
$parser = new FeedParser($xml);
$parser->init();
$selfLinks = $parser->get_links('self');
$this->assertCount(1, $selfLinks);
$this->assertEquals('https://example.com/self', $selfLinks[0]);
$hubLinks = $parser->get_links('hub');
$this->assertCount(1, $hubLinks);
$this->assertEquals('https://example.com/hub', $hubLinks[0]);
}
public function testGetLinksFromRssFeed(): void {
$xml = '
Test
';
$parser = new FeedParser($xml);
$parser->init();
$selfLinks = $parser->get_links('self');
$this->assertCount(1, $selfLinks);
$this->assertEquals('https://example.com/self', $selfLinks[0]);
}
public function testGetLinksWithoutRelReturnsAllLinks(): void {
$xml = '
Test
';
$parser = new FeedParser($xml);
$parser->init();
$allLinks = $parser->get_links('');
$this->assertCount(2, $allLinks);
}
// ===== Empty/Missing Data Tests =====
public function testFeedWithoutTitleReturnsEmptyString(): void {
$xml = '
https://example.com
';
$parser = new FeedParser($xml);
$parser->init();
$this->assertEquals('', $parser->get_title());
}
public function testFeedWithoutLinkReturnsEmptyString(): void {
$xml = '
Test
';
$parser = new FeedParser($xml);
$parser->init();
$this->assertEquals('', $parser->get_link());
}
public function testFeedWithoutItemsReturnsEmptyArray(): void {
$xml = '
Empty Feed
';
$parser = new FeedParser($xml);
$parser->init();
$this->assertCount(0, $parser->get_items());
}
// ===== RSS Link Attribute Handling =====
public function testRssLinkWithHrefAttribute(): void {
$xml = '
Test
';
$parser = new FeedParser($xml);
$parser->init();
$this->assertEquals('https://example.com/href-link', $parser->get_link());
}
public function testRssLinkWithNodeValue(): void {
$xml = '
Test
https://example.com/node-link
';
$parser = new FeedParser($xml);
$parser->init();
$this->assertEquals('https://example.com/node-link', $parser->get_link());
}
}