예제 #1
0
def test_entry_unchanged(monkeypatch, feed_template, feed_context):
    feed = FeedFactory.create(enabled=True)
    params = {
        k: v
        for k, v in feed_context.items() if not k.endswith("date_str")
    }
    existing = EntryFactory.create(rss_feed=feed, **params)
    modified = existing.modified_at

    def mock_return(feed):
        return feed_template % feed_context

    monkeypatch.setattr(feeds, "get_source", mock_return)

    feeds.load_feed(feed)
    entries = Entry.objects.filter(modified_at__gt=existing.modified_at)
    existing.refresh_from_db()
    events = Event.objects.entry_updates()

    # No entries were updated
    assert list(entries) == []
    # No events were generated
    assert events.exists() is False
    # Existing Article is unchanged
    assert existing.modified_at == modified
예제 #2
0
def test_entry_added(monkeypatch, feed_template, feed_context):
    # feedparser can parse a file, url or string so we can use the get_url()
    # function in the feeds module to inject a string instead of the Blog's
    # url and get feedparser to parse it and return the entries.

    def mock_return(feed):
        return feed_template % feed_context

    monkeypatch.setattr(feeds, "get_source", mock_return)
    feed = FeedFactory.create(enabled=True)
    feeds.load_feed(feed)
    entries = Entry.objects.all()

    # Results contain added Entry
    assert len(entries) == 1

    # Verify the rss attributes are set to the values from the feed
    # Ensure microseconds on the date the entry was published are set
    # to zero, rather than the value when the entry is saved in case
    # the date is used to see if an entry has changed when the feed
    # is next loaded.

    entry = entries[0]

    assert entry.title == feed_context["title"]
    assert entry.author == feed_context["author"]
    assert entry.url == feed_context["url"]
    assert entry.date == feed_context["date"]
    assert entry.date.microsecond == 0
    assert entry.summary == feed_context["summary"]
    assert entry.identifier == feed_context["identifier"]
    assert entry.tags == feed_context["tags"]

    # Verify the Article attributes are initialised from the entry with
    # the following exceptions:
    #
    # 1. The article title is post-processed to remove trailing periods
    #    and all uppercase titles are corrected.
    #
    # 2. An Author object is created using the entry author.

    article = Article.objects.get(entry=entry)

    assert article.title is not None
    assert article.authors.first().name == entry.author
    assert article.url == entry.url
    assert article.date == entry.date
    assert article.summary == entry.summary
    assert article.entry == entry
    assert article.source == feed.source
    assert article.publish == feed.source.auto_publish

    # Verify the article and source are logged in an Event recording
    # that the Article was added.

    event = Event.objects.article_adds().get()

    assert event.data["article"]["pk"] == article.pk
    assert event.data["source"]["pk"] == article.source.pk
def test_blank_link(monkeypatch, feed_template, feed_context):
    """Feed entries with an empty link field are skipped"""

    def mock_return(feed):
        feed_context["url"] = ""
        return feed_template % feed_context

    monkeypatch.setattr(feeds, "get_source", mock_return)
    feeds.load_feed(FeedFactory.create(enabled=True))
    assert Entry.objects.exists() is False
def test_missing_title(monkeypatch, feed_template, feed_context):
    """Feed entries with no title field are skipped"""
    feed_template = feed_template.replace("<title>%(title)s</title>", "")

    def mock_return(feed):
        return feed_template % feed_context

    monkeypatch.setattr(feeds, "get_source", mock_return)
    feeds.load_feed(FeedFactory.create(enabled=True))
    assert Entry.objects.exists() is False
def test_missing_identifier(monkeypatch, feed_template, feed_context):
    """Feed entries with no identifier are loaded using the url as an identifier"""
    feed_template = feed_template.replace("<id>%(identifier)s</id>", "")

    def mock_return(feed):
        return feed_template % feed_context

    monkeypatch.setattr(feeds, "get_source", mock_return)
    feeds.load_feed(FeedFactory.create(enabled=True))
    assert Entry.objects.exists() is True
def test_blank_tags(monkeypatch, feed_template, feed_context):
    """Feed entries with an empty tag field are loaded"""

    def mock_return(feed):
        feed_context["tags"] = ""
        return feed_template % feed_context

    monkeypatch.setattr(feeds, "get_source", mock_return)
    feeds.load_feed(FeedFactory.create(enabled=True))
    assert Entry.objects.get().tags == ""
def test_missing_tags(monkeypatch, feed_template, feed_context):
    """Feed entries with no tag field are loaded"""
    feed_template = feed_template.replace(
        '<category scheme="%(url)s" term="%(tags)s" />', ""
    )

    def mock_return(feed):
        return feed_template % feed_context

    monkeypatch.setattr(feeds, "get_source", mock_return)
    feeds.load_feed(FeedFactory.create(enabled=True))
    assert Entry.objects.get().tags == ""
def test_missing_summary(monkeypatch, feed_template, feed_context):
    """Feed entries with no summary field are loaded"""
    feed_template = feed_template.replace(
        '<summary type="text">%(summary)s</summary>', ""
    )

    def mock_return(feed):
        return feed_template % feed_context

    monkeypatch.setattr(feeds, "get_source", mock_return)
    feeds.load_feed(FeedFactory.create(enabled=True))
    assert Entry.objects.get().summary == ""
def test_missing_author(monkeypatch, feed_template, feed_context):
    """Feed entries with no author field are loaded"""
    feed_template = feed_template.replace(
        "<author><name>%(author)s</name></author>", ""
    )

    def mock_return(feed):
        return feed_template % feed_context

    monkeypatch.setattr(feeds, "get_source", mock_return)
    feeds.load_feed(FeedFactory.create(enabled=True))
    assert Entry.objects.get().author == ""
예제 #10
0
def test_entry_updated(monkeypatch, feed_template, feed_context):
    feed = FeedFactory.create(enabled=True, source__auto_publish=True)
    params = {
        k: v
        for k, v in feed_context.items() if not k.endswith("date_str")
    }
    existing = EntryFactory.create(rss_feed=feed, **params)

    feed_context["title"] = "Updated title"
    updated_title = feed_context["title"]

    feed.source.auto_publish = False
    feed.source.save()

    def mock_return(feed):
        return feed_template % feed_context

    monkeypatch.setattr(feeds, "get_source", mock_return)
    feeds.load_feed(feed)
    entries = Entry.objects.filter(modified_at__gt=existing.modified_at)

    # Results contains updated Entry
    assert len(entries) == 1

    # The title of the entry was updated. All other attributes
    # remain unchanged.

    entry = entries[0]

    assert entry.modified_at > existing.modified_at
    assert entry.title == updated_title
    assert entry.author == feed_context["author"]
    assert entry.url == feed_context["url"]
    assert entry.date == feed_context["date"]
    assert entry.date.microsecond == 0
    assert entry.summary == feed_context["summary"]
    assert entry.identifier == feed_context["identifier"]
    assert entry.tags == feed_context["tags"]

    # The Article created when the Entry was added was not updated.
    # Changing the default value for the auto_publish flag on the Source
    # should not affect whether existing Articles are published.

    article = entry.article

    assert article.title == "Article title"
    assert article.authors.first().name == entry.author
    assert article.url == existing.url
    assert article.date == existing.date
    assert article.summary == existing.summary
    assert article.entry == existing
    assert article.source == existing.rss_feed.source
    assert article.publish is True
예제 #11
0
    def load_feed(modeladmin, request, queryset):  # noqa
        for feed in queryset:
            try:
                # force the feed to be loaded by resetting the fields
                # used to send the Last-Modified or ETag headers.

                feed.loaded_at = None
                feed.etag = ""
                result = feeds.load_feed(feed)
            except DataError:
                logger.exception("Could not load feed", feed=feed.name)
                result = False

            if result:
                msg = _('The feed "%s" was loaded successfully.' % feed.name)
                messages.info(request, msg)
            else:
                msg = _('There was an error loading the feed "%s"' % feed.name)
                messages.error(request, msg)