def check_iter_locked(db_path, pre_stuff, iter_stuff): """Actual implementation of test_errors_locked, so it can be reused.""" # WAL provides more concurrency; some things won't to block with it enabled. storage = Storage(db_path, wal_enabled=False) feed = FeedData('one') entry = EntryData('one', 'entry', datetime(2010, 1, 1), title='entry') storage.add_feed(feed.url, datetime(2010, 1, 2)) storage.add_or_update_entry( EntryUpdateIntent(entry, entry.updated, datetime(2010, 1, 1), 0, 0)) storage.add_feed('two', datetime(2010, 1, 1)) storage.add_or_update_entry( EntryUpdateIntent(entry._replace(feed_url='two'), entry.updated, datetime(2010, 1, 1), 0, 0)) storage.set_feed_metadata('two', '1', 1) storage.set_feed_metadata('two', '2', 2) storage.add_feed_tag('two', '1') storage.add_feed_tag('two', '2') if pre_stuff: pre_stuff(storage) rv = iter_stuff(storage) next(rv) # shouldn't raise an exception storage = Storage(db_path, timeout=0, wal_enabled=False) storage.mark_as_read_unread(feed.url, entry.id, 1) storage = Storage(db_path, timeout=0) storage.mark_as_read_unread(feed.url, entry.id, 0)
def _make_feed(number, updated=None, **kwargs): return FeedData( f'{number}', updated, kwargs.pop('title', f'Feed #{number}'), kwargs.pop('link', f'http://www.example.com/{number}'), **kwargs, )
def test_object_id(): assert Feed('url').object_id == 'url' assert Entry('entry', 'updated', feed=Feed('url')).object_id == ('url', 'entry') assert EntrySearchResult('url', 'entry').object_id == ('url', 'entry') assert FeedData('url').object_id == 'url' assert EntryData('url', 'entry', 'updated').object_id == ('url', 'entry') assert FeedError('url').object_id == 'url' assert EntryError('url', 'entry').object_id == ('url', 'entry')
def test_no_mime_type(monkeypatch, parse, make_url, data_dir): """Like test_parse with _make_http_url_missing_content_type, but with an URL parser. """ monkeypatch.chdir(data_dir.dirname) feed_path = data_dir.join('custom') feed_url = make_url(feed_path) def custom_parser(url, file, headers=None): return FeedData(url=url, title=file.read().decode('utf-8')), [] parse.mount_parser_by_url(feed_url, custom_parser) feed, entries, _, _ = parse(feed_url) with open(str(feed_path), encoding='utf-8') as f: expected_feed = FeedData(url=feed_url, title=f.read()) assert feed == expected_feed assert entries == []
def check_errors_locked(db_path, pre_stuff, do_stuff, exc_type): """Actual implementation of test_errors_locked, so it can be reused.""" # WAL provides more concurrency; some things won't to block with it enabled. storage = Storage(db_path, wal_enabled=False) storage.db.execute("PRAGMA busy_timeout = 0;") feed = FeedData('one') entry = EntryData('one', 'entry', datetime(2010, 1, 2)) storage.add_feed(feed.url, datetime(2010, 1, 1)) storage.add_or_update_entry( EntryUpdateIntent(entry, entry.updated, datetime(2010, 1, 1), 0, 0)) in_transaction = threading.Event() can_return_from_transaction = threading.Event() def target(): storage = Storage(db_path, wal_enabled=False) storage.db.isolation_level = None storage.db.execute("BEGIN EXCLUSIVE;") in_transaction.set() can_return_from_transaction.wait() storage.db.execute("ROLLBACK;") if pre_stuff: pre_stuff(storage, feed, entry) thread = threading.Thread(target=target) thread.start() in_transaction.wait() try: with pytest.raises(exc_type) as excinfo: do_stuff(storage, feed, entry) assert 'locked' in str(excinfo.value.__cause__) finally: can_return_from_transaction.set() thread.join()
def make_feed(feed_url, url, soup): return FeedData(url=feed_url, title=soup.title and soup.title.text, link=url)
import datetime from reader import Content from reader import Enclosure from reader._types import EntryData from reader._types import FeedData feed = FeedData(url='{}empty.atom'.format(url_base)) entries = [ EntryData( feed_url=feed.url, id='urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a', updated=None, # added by feedparser link='urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a', ) ]
def custom_parser(url, file, headers=None): return FeedData(url=url, title=file.read().decode('utf-8')), []
import datetime from reader import Content from reader import Enclosure from reader._types import EntryData from reader._types import FeedData feed = FeedData(url='{}relative.rss'.format(url_base), link='{}file.html'.format(rel_base)) entries = [ EntryData( feed_url=feed.url, id='7bd204c6-1655-4c27-aeee-53f933c5395f', updated=None, link='{}blog/post/1'.format(rel_base), summary='one <a href="{}target">two</a> three'.format(rel_base), content=( Content(value='<script>evil</script> content', type='text/plain', language=None), Content(value='content', type='text/html', language=None), ), enclosures=( # for RSS feedparser doesn't make relative links absolute # (it does for Atom) Enclosure(href='enclosure?q=a#fragment'), ), ) ]
import datetime from reader import Content from reader import Enclosure from reader._types import EntryData from reader._types import FeedData feed = FeedData(url='{}empty.rss'.format(url_base)) entries = [ EntryData(feed_url=feed.url, id='7bd204c6-1655-4c27-aeee-53f933c5395f', updated=None) ]
import datetime from reader import Content from reader import Enclosure from reader._types import EntryData from reader._types import FeedData feed = FeedData(url='{}invalid.json'.format(url_base), ) entries = [ EntryData( feed_url=feed.url, id='2', updated=None, enclosures=( Enclosure(href='control'), Enclosure(href='float size', length=100), Enclosure(href='non-number size'), ), ), EntryData( feed_url=feed.url, id='3.1415', title='float id', updated=None, ), EntryData( feed_url=feed.url, id='author name', updated=None, ),
import datetime from reader import Content from reader import Enclosure from reader._types import EntryData from reader._types import FeedData feed = FeedData( url='{}full.atom'.format(url_base), updated=datetime.datetime(2003, 12, 13, 18, 30, 2), title='Example Feed', link='http://example.org/', author='John Doe', ) entries = [ EntryData( feed_url=feed.url, id='urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a', updated=datetime.datetime(2003, 12, 13, 18, 30, 2), title='Atom-Powered Robots Run Amok', link='http://example.org/2003/12/13/atom03', author='John Doe', published=datetime.datetime(2003, 12, 13, 17, 17, 51), summary='Some text.', content=( # the text/plain type comes from feedparser Content(value='content', type='text/plain'), Content(value='content with type', type='text/whatever'), Content(value='content with lang', type='text/plain',
import datetime from reader import Content from reader import Enclosure from reader._types import EntryData from reader._types import FeedData feed = FeedData( url='{}empty.json'.format(url_base), ) entries = [ EntryData( feed_url=feed.url, id='1', updated=None, content=( Content( value='content', type='text/plain', ), ), ), ]
import datetime from reader import Content from reader import Enclosure from reader._types import EntryData from reader._types import FeedData feed = FeedData( url='{}full.rss'.format(url_base), updated=datetime.datetime(2010, 9, 6, 0, 1), title='RSS Title', link='http://www.example.com/main.html', author='Example editor ([email protected])', ) entries = [ EntryData( feed_url=feed.url, id='7bd204c6-1655-4c27-aeee-53f933c5395f', updated=datetime.datetime(2009, 9, 6, 16, 20), title='Example entry', link='http://www.example.com/blog/post/1', author='Example editor', published=None, summary='Here is some text containing an interesting description.', content=( # the text/plain type comes from feedparser Content(value='Example content', type='text/plain'), ), enclosures=(