feat: add quotations from marked text, with citations and sharing

This commit is contained in:
randogoth 2026-10-12 10:37:32 +03:00
parent 0e2027c9e2
commit e6e84fdc01
25 changed files with 1558 additions and 4 deletions

View file

@ -231,4 +231,61 @@ void main() {
expect(await db.allClientCertificates(), isEmpty);
expect(await db.bindingFor('capsule.example', 1965), isNull);
});
test('quotations are saved with their page and narrow by a search', () async {
await db.addQuotation(
quote: 'A fine sentence about cats.',
pageUrl: 'https://example.com/cats.html',
pageTitle: 'On cats',
author: 'A. Author',
);
await db.addQuotation(
quote: 'A dog is a dog is a dog.',
pageUrl: 'https://example.com/dogs.html',
);
expect(await db.countQuotations(), 2);
// Saved within the same clock tick, the id tiebreak keeps the order they
// were saved in; the page's title and author ride along.
final kept = await db.quotationsList();
expect(kept.first.pageUrl, 'https://example.com/cats.html');
expect(kept.first.pageTitle, 'On cats');
expect(kept.first.author, 'A. Author');
// A search matches the quoted text, the title, the author or the
// address; it does not have to know which one it hit.
expect((await db.quotationsList(query: 'cats')).length, 1);
expect((await db.quotationsList(query: 'Author')).single.pageUrl,
'https://example.com/cats.html');
expect((await db.quotationsList(query: 'dogs.html')).single.quote,
'A dog is a dog is a dog.');
// Ordered by page, a page without a title sorts under its address.
final byPage = await db.quotationsList(sort: QuotationSort.page);
expect(byPage.first.pageUrl, 'https://example.com/cats.html');
// A quotation of a page the reader's site lists as a post carries the
// site's own title, so its citation can name it.
await db.addSubscription('https://example.com/index.html', 'Signal Bars', null);
await db.addEntries('https://example.com/index.html',
[_entry('https://example.com/2026-10-08-retro.html')]);
await db.addQuotation(
quote: 'The finest retro handsets.',
pageUrl: 'https://example.com/2026-10-08-retro.html',
pageTitle: 'Collecting retro phones',
);
final post = (await db.quotationsList())
.firstWhere((q) => q.pageUrl.contains('retro'));
expect(post.siteTitle, 'Signal Bars');
expect(await db.siteTitleOf('https://example.com/index.html'),
'Signal Bars');
expect(await db.siteTitleOf('https://unknown.example/'), isNull);
// One quotation by its id, for the actions that share or remove it.
final id = kept.last.id;
expect((await db.quotationById(id))?.quote, 'A dog is a dog is a dog.');
await db.removeQuotation(id);
expect(await db.quotationById(id), isNull);
// The retro quotation from the site-title check remains.
expect(await db.countQuotations(), 2);
});
}