feat: read subscriptions from an Atom feed when a page lists no dated links
This commit is contained in:
parent
b0b86ef5b1
commit
fa51d5793d
9 changed files with 411 additions and 4 deletions
|
|
@ -7,6 +7,7 @@ import 'package:mews/application/controllers/reader_settings_controller.dart';
|
|||
import 'package:mews/application/controllers/subscriptions_controller.dart';
|
||||
import 'package:mews/database/database.dart';
|
||||
import 'package:mews/mews/document.dart';
|
||||
import 'package:mews/mews/parser.dart';
|
||||
|
||||
import 'fake_fetch.dart';
|
||||
|
||||
|
|
@ -207,6 +208,90 @@ void main() {
|
|||
expect(redraws, 2);
|
||||
});
|
||||
|
||||
test('a site publishing only through a feed still reports posts', () async {
|
||||
const site = 'https://feedonly.example/';
|
||||
const feed = 'https://feedonly.example/feed.xml';
|
||||
// A page with no dated links, but it declares a feed (spec 6.2).
|
||||
const page = '''
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>Feed Only</title>
|
||||
<meta name="mews-profile" content="0.1" />
|
||||
<link rel="alternate" type="application/atom+xml" href="feed.xml" />
|
||||
</head>
|
||||
<body><h1>Feed Only</h1><p>Nothing listed here.</p></body>
|
||||
</html>
|
||||
''';
|
||||
String feedWith(List<(String, String)> entries) => '''
|
||||
<feed xmlns="http://www.w3.org/2005/Atom">
|
||||
${entries.map((e) => '<entry><title>${e.$2}</title><link rel="alternate" href="${e.$1}" /><updated>2026-10-08T09:30:00Z</updated></entry>').join()}
|
||||
</feed>
|
||||
''';
|
||||
|
||||
final feeds = {feed: feedWith(const [('old.html', 'An older post')])};
|
||||
final subscriptions = SubscriptionsController(
|
||||
db: db,
|
||||
fetch: FakeFetch({site: page}, feeds: feeds),
|
||||
);
|
||||
await subscriptions.load();
|
||||
await subscriptions.toggle(parseMewsPage(source: page, url: site));
|
||||
|
||||
// What the feed already listed is the back catalogue, not news.
|
||||
expect(await db.unreadCount(), 0);
|
||||
expect((await db.allSubscriptions()).single.atomHref, feed);
|
||||
|
||||
// A post added to the feed later is new.
|
||||
feeds[feed] = feedWith(const [
|
||||
('new.html', 'A newer post'),
|
||||
('old.html', 'An older post'),
|
||||
]);
|
||||
await subscriptions.refreshAll();
|
||||
expect(await db.unreadCount(), 1);
|
||||
final entries = await db.riverEntries(unreadOnly: true);
|
||||
expect(entries.single.title, 'A newer post');
|
||||
|
||||
// Checking again reports nothing, because an address identifies a post.
|
||||
await subscriptions.refreshAll();
|
||||
expect(await db.unreadCount(), 1);
|
||||
});
|
||||
|
||||
test('a page listing dated links is not fetched twice', () async {
|
||||
const site = 'https://both.example/';
|
||||
const page = '''
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>Both</title>
|
||||
<meta name="mews-profile" content="0.1" />
|
||||
<link rel="alternate" type="application/atom+xml" href="feed.xml" />
|
||||
</head>
|
||||
<body><h1>Both</h1><ul>
|
||||
<li><a href="one.html">2026-10-08 The only post</a></li>
|
||||
</ul></body>
|
||||
</html>
|
||||
''';
|
||||
// The feed would answer, but a page that lists its own posts is enough,
|
||||
// so nothing asks for it.
|
||||
final subscriptions = SubscriptionsController(
|
||||
db: db,
|
||||
fetch: FakeFetch({site: page}, feeds: const {
|
||||
'https://both.example/feed.xml':
|
||||
'<feed xmlns="http://www.w3.org/2005/Atom"><entry><title>Duplicate</title>'
|
||||
'<link rel="alternate" href="one.html" /><updated>2026-10-08T09:30:00Z</updated>'
|
||||
'</entry></feed>',
|
||||
}),
|
||||
);
|
||||
await subscriptions.load();
|
||||
await subscriptions.toggle(parseMewsPage(source: page, url: site));
|
||||
await subscriptions.refreshAll();
|
||||
|
||||
// One post, under the title the page gave it.
|
||||
final entries = await db.riverEntries();
|
||||
expect(entries, hasLength(1));
|
||||
expect(entries.single.title, 'The only post');
|
||||
});
|
||||
|
||||
test('caches pages for offline reopening', () async {
|
||||
await db.saveCachedPage(CachedPagesCompanion.insert(
|
||||
url: 'https://example.com/page.html',
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue