import 'package:flutter_test/flutter_test.dart'; import 'package:mews/mews/atom.dart'; import 'package:mews/mews/parser.dart'; const defaultNamespaced = ''' Signal Bars Collecting retro phones tag:example.com,2026:retro 2026-10-08T09:30:00Z First post 2026-09-21T12:00:00Z '''; const prefixed = ''' Reading the bars 2026-10-09T08:00:00Z '''; void main() { test('reads entries from a feed in the default namespace', () { final entries = parseAtomEntries( source: defaultNamespaced, feedUrl: 'https://example.com/feed.xml'); expect(entries, hasLength(2)); // Newest first, like the dated links a page lists. expect(entries.first.title, 'Collecting retro phones'); expect(entries.first.date, DateTime.utc(2026, 10, 8, 9, 30)); // Relative links resolve against the feed's own address. expect(entries.first.url, 'https://example.com/2026-10-08-retro.html'); // A link without a rel is the alternate one. expect(entries.last.url, 'https://example.com/2026-09-21-first.html'); // published stands in when updated is absent. expect(entries.last.date, DateTime.utc(2026, 9, 21, 12)); }); test('reads a feed using an atom prefix', () { final entries = parseAtomEntries(source: prefixed, feedUrl: 'https://example.com/feed.xml'); expect(entries.single.title, 'Reading the bars'); expect(entries.single.url, 'https://example.com/bars.html'); }); test('falls back to the id when it is a web address', () { const source = ''' No link here https://example.com/no-link.html 2026-10-08T09:30:00Z '''; final entries = parseAtomEntries(source: source, feedUrl: 'https://example.com/feed.xml'); expect(entries.single.url, 'https://example.com/no-link.html'); }); test('skips entries with nothing to identify or date them', () { const source = ''' No date No address tag:example.com,2026:nope 2026-10-08T09:30:00Z Unreadable date last Tuesday '''; expect( parseAtomEntries(source: source, feedUrl: 'https://example.com/feed.xml'), isEmpty); }); test('a malformed feed is an error, not a guess', () { expect( () => parseAtomEntries( source: 'Half', feedUrl: 'https://example.com/feed.xml'), throwsA(isA<MewsParseException>()), ); }); test('an empty feed reads as no entries', () { expect( parseAtomEntries( source: '<feed xmlns="http://www.w3.org/2005/Atom"></feed>', feedUrl: 'https://example.com/feed.xml'), isEmpty); }); }