RSS: fix tests with feedparser 6.

Mocks the urllib API it uses instead of an internal function.
This commit is contained in:
Valentin Lorentz 2020-09-19 10:15:23 +02:00
parent f4d6bd11be
commit 0102d64cf4

View File

@ -28,8 +28,12 @@
# POSSIBILITY OF SUCH DAMAGE. # POSSIBILITY OF SUCH DAMAGE.
### ###
import functools
from unittest.mock import patch
import sys import sys
import feedparser import feedparser
from supybot.test import * from supybot.test import *
import supybot.conf as conf import supybot.conf as conf
import supybot.utils.minisix as minisix import supybot.utils.minisix as minisix
@ -53,12 +57,26 @@ not_well_formed = """<?xml version="1.0" encoding="utf-8"?>
</rss> </rss>
""" """
def constant(content):
if minisix.PY3: class MockResponse:
content = content.encode() headers = {}
def f(*args, **kwargs): url = ''
return minisix.io.BytesIO(content) def read(self):
return f return self._data.encode()
def close(self):
pass
def mock_urllib(f):
mock = MockResponse()
@functools.wraps(f)
def newf(self):
with patch("urllib.request.OpenerDirector.open", return_value=mock):
f(self, mock)
return newf
url = 'http://www.advogato.org/rss/articles.xml' url = 'http://www.advogato.org/rss/articles.xml'
class RSSTestCase(ChannelPluginTestCase): class RSSTestCase(ChannelPluginTestCase):
@ -82,9 +100,9 @@ class RSSTestCase(ChannelPluginTestCase):
finally: finally:
self.assertNotError('rss remove xkcd') self.assertNotError('rss remove xkcd')
def testInitialAnnounceNewest(self): @mock_urllib
old_open = feedparser._open_resource def testInitialAnnounceNewest(self, mock):
feedparser._open_resource = constant(xkcd_new) mock._data = xkcd_new
timeFastForward(1.1) timeFastForward(1.1)
try: try:
with conf.supybot.plugins.RSS.sortFeedItems.context('newestFirst'): with conf.supybot.plugins.RSS.sortFeedItems.context('newestFirst'):
@ -95,11 +113,10 @@ class RSSTestCase(ChannelPluginTestCase):
finally: finally:
self._feedMsg('rss announce remove xkcd') self._feedMsg('rss announce remove xkcd')
self._feedMsg('rss remove xkcd') self._feedMsg('rss remove xkcd')
feedparser._open_resource = old_open
def testInitialAnnounceOldest(self): @mock_urllib
old_open = feedparser._open_resource def testInitialAnnounceOldest(self, mock):
feedparser._open_resource = constant(xkcd_new) mock._data = xkcd_new
timeFastForward(1.1) timeFastForward(1.1)
try: try:
with conf.supybot.plugins.RSS.initialAnnounceHeadlines.context(1): with conf.supybot.plugins.RSS.initialAnnounceHeadlines.context(1):
@ -110,11 +127,10 @@ class RSSTestCase(ChannelPluginTestCase):
finally: finally:
self._feedMsg('rss announce remove xkcd') self._feedMsg('rss announce remove xkcd')
self._feedMsg('rss remove xkcd') self._feedMsg('rss remove xkcd')
feedparser._open_resource = old_open
def testNoInitialAnnounce(self): @mock_urllib
old_open = feedparser._open_resource def testNoInitialAnnounce(self, mock):
feedparser._open_resource = constant(xkcd_old) mock._data = xkcd_old
timeFastForward(1.1) timeFastForward(1.1)
try: try:
with conf.supybot.plugins.RSS.initialAnnounceHeadlines.context(0): with conf.supybot.plugins.RSS.initialAnnounceHeadlines.context(0):
@ -124,11 +140,10 @@ class RSSTestCase(ChannelPluginTestCase):
finally: finally:
self._feedMsg('rss announce remove xkcd') self._feedMsg('rss announce remove xkcd')
self._feedMsg('rss remove xkcd') self._feedMsg('rss remove xkcd')
feedparser._open_resource = old_open
def testAnnounce(self): @mock_urllib
old_open = feedparser._open_resource def testAnnounce(self, mock):
feedparser._open_resource = constant(xkcd_old) mock._data = xkcd_old
timeFastForward(1.1) timeFastForward(1.1)
try: try:
self.assertError('rss announce add xkcd') self.assertError('rss announce add xkcd')
@ -139,7 +154,7 @@ class RSSTestCase(ChannelPluginTestCase):
with conf.supybot.plugins.RSS.waitPeriod.context(1): with conf.supybot.plugins.RSS.waitPeriod.context(1):
timeFastForward(1.1) timeFastForward(1.1)
self.assertNoResponse(' ', timeout=0.1) self.assertNoResponse(' ', timeout=0.1)
feedparser._open_resource = constant(xkcd_new) mock._data = xkcd_new
self.assertNoResponse(' ', timeout=0.1) self.assertNoResponse(' ', timeout=0.1)
timeFastForward(1.1) timeFastForward(1.1)
self.assertRegexp(' ', 'Chaos') self.assertRegexp(' ', 'Chaos')
@ -148,11 +163,10 @@ class RSSTestCase(ChannelPluginTestCase):
finally: finally:
self._feedMsg('rss announce remove xkcd') self._feedMsg('rss announce remove xkcd')
self._feedMsg('rss remove xkcd') self._feedMsg('rss remove xkcd')
feedparser._open_resource = old_open
def testMaxAnnounces(self): @mock_urllib
old_open = feedparser._open_resource def testMaxAnnounces(self, mock):
feedparser._open_resource = constant(xkcd_old) mock._data = xkcd_old
timeFastForward(1.1) timeFastForward(1.1)
try: try:
self.assertError('rss announce add xkcd') self.assertError('rss announce add xkcd')
@ -164,7 +178,7 @@ class RSSTestCase(ChannelPluginTestCase):
with conf.supybot.plugins.RSS.maximumAnnounceHeadlines.context(1): with conf.supybot.plugins.RSS.maximumAnnounceHeadlines.context(1):
timeFastForward(1.1) timeFastForward(1.1)
self.assertNoResponse(' ', timeout=0.1) self.assertNoResponse(' ', timeout=0.1)
feedparser._open_resource = constant(xkcd_new) mock._data = xkcd_new
log.debug('set return value to: %r', xkcd_new) log.debug('set return value to: %r', xkcd_new)
self.assertNoResponse(' ', timeout=0.1) self.assertNoResponse(' ', timeout=0.1)
timeFastForward(1.1) timeFastForward(1.1)
@ -173,11 +187,10 @@ class RSSTestCase(ChannelPluginTestCase):
finally: finally:
self._feedMsg('rss announce remove xkcd') self._feedMsg('rss announce remove xkcd')
self._feedMsg('rss remove xkcd') self._feedMsg('rss remove xkcd')
feedparser._open_resource = old_open
def testAnnounceAnonymous(self): @mock_urllib
old_open = feedparser._open_resource def testAnnounceAnonymous(self, mock):
feedparser._open_resource = constant(xkcd_old) mock._data = xkcd_old
timeFastForward(1.1) timeFastForward(1.1)
try: try:
self.assertNotError('rss announce add http://xkcd.com/rss.xml') self.assertNotError('rss announce add http://xkcd.com/rss.xml')
@ -185,18 +198,17 @@ class RSSTestCase(ChannelPluginTestCase):
with conf.supybot.plugins.RSS.waitPeriod.context(1): with conf.supybot.plugins.RSS.waitPeriod.context(1):
timeFastForward(1.1) timeFastForward(1.1)
self.assertNoResponse(' ', timeout=0.1) self.assertNoResponse(' ', timeout=0.1)
feedparser._open_resource = constant(xkcd_new) mock._data = xkcd_new
self.assertNoResponse(' ', timeout=0.1) self.assertNoResponse(' ', timeout=0.1)
timeFastForward(1.1) timeFastForward(1.1)
self.assertRegexp(' ', 'Telescopes') self.assertRegexp(' ', 'Telescopes')
finally: finally:
self._feedMsg('rss announce remove http://xkcd.com/rss.xml') self._feedMsg('rss announce remove http://xkcd.com/rss.xml')
self._feedMsg('rss remove http://xkcd.com/rss.xml') self._feedMsg('rss remove http://xkcd.com/rss.xml')
feedparser._open_resource = old_open
def testAnnounceReload(self): @mock_urllib
old_open = feedparser._open_resource def testAnnounceReload(self, mock):
feedparser._open_resource = constant(xkcd_old) mock._data = xkcd_old
timeFastForward(1.1) timeFastForward(1.1)
try: try:
with conf.supybot.plugins.RSS.waitPeriod.context(1): with conf.supybot.plugins.RSS.waitPeriod.context(1):
@ -210,29 +222,27 @@ class RSSTestCase(ChannelPluginTestCase):
finally: finally:
self._feedMsg('rss announce remove xkcd') self._feedMsg('rss announce remove xkcd')
self._feedMsg('rss remove xkcd') self._feedMsg('rss remove xkcd')
feedparser._open_resource = old_open
def testReload(self): @mock_urllib
old_open = feedparser._open_resource def testReload(self, mock):
feedparser._open_resource = constant(xkcd_old) mock._data = xkcd_old
timeFastForward(1.1) timeFastForward(1.1)
try: try:
with conf.supybot.plugins.RSS.waitPeriod.context(1): with conf.supybot.plugins.RSS.waitPeriod.context(1):
self.assertNotError('rss add xkcd http://xkcd.com/rss.xml') self.assertNotError('rss add xkcd http://xkcd.com/rss.xml')
self.assertNotError('rss announce add xkcd') self.assertNotError('rss announce add xkcd')
self.assertRegexp(' ', 'Snake Facts') self.assertRegexp(' ', 'Snake Facts')
feedparser._open_resource = constant(xkcd_new) mock._data = xkcd_new
self.assertNotError('reload RSS') self.assertNotError('reload RSS')
self.assertRegexp(' ', 'Telescopes') self.assertRegexp(' ', 'Telescopes')
finally: finally:
self._feedMsg('rss announce remove xkcd') self._feedMsg('rss announce remove xkcd')
self._feedMsg('rss remove xkcd') self._feedMsg('rss remove xkcd')
feedparser._open_resource = old_open
def testReloadNoDelay(self): @mock_urllib
def testReloadNoDelay(self, mock):
# https://github.com/ProgVal/Limnoria/issues/922 # https://github.com/ProgVal/Limnoria/issues/922
old_open = feedparser._open_resource mock._data = xkcd_old
feedparser._open_resource = constant(xkcd_old)
timeFastForward(1.1) timeFastForward(1.1)
try: try:
with conf.supybot.plugins.RSS.waitPeriod.context(1): with conf.supybot.plugins.RSS.waitPeriod.context(1):
@ -243,11 +253,10 @@ class RSSTestCase(ChannelPluginTestCase):
finally: finally:
self._feedMsg('rss announce remove xkcd') self._feedMsg('rss announce remove xkcd')
self._feedMsg('rss remove xkcd') self._feedMsg('rss remove xkcd')
feedparser._open_resource = old_open
def testReannounce(self): @mock_urllib
old_open = feedparser._open_resource def testReannounce(self, mock):
feedparser._open_resource = constant(xkcd_old) mock._data = xkcd_old
timeFastForward(1.1) timeFastForward(1.1)
try: try:
self.assertError('rss announce add xkcd') self.assertError('rss announce add xkcd')
@ -260,7 +269,7 @@ class RSSTestCase(ChannelPluginTestCase):
timeFastForward(1.1) timeFastForward(1.1)
self.assertNoResponse(' ', timeout=0.1) self.assertNoResponse(' ', timeout=0.1)
self._feedMsg('rss announce remove xkcd') self._feedMsg('rss announce remove xkcd')
feedparser._open_resource = constant(xkcd_new) mock._data = xkcd_new
timeFastForward(1.1) timeFastForward(1.1)
self.assertNoResponse(' ', timeout=0.1) self.assertNoResponse(' ', timeout=0.1)
self.assertNotError('rss announce add xkcd') self.assertNotError('rss announce add xkcd')
@ -271,11 +280,10 @@ class RSSTestCase(ChannelPluginTestCase):
finally: finally:
self._feedMsg('rss announce remove xkcd') self._feedMsg('rss announce remove xkcd')
self._feedMsg('rss remove xkcd') self._feedMsg('rss remove xkcd')
feedparser._open_resource = old_open
def testFeedSpecificFormat(self): @mock_urllib
old_open = feedparser._open_resource def testFeedSpecificFormat(self, mock):
feedparser._open_resource = constant(xkcd_old) mock._data = xkcd_old
timeFastForward(1.1) timeFastForward(1.1)
try: try:
self.assertNotError('rss add xkcd http://xkcd.com/rss.xml') self.assertNotError('rss add xkcd http://xkcd.com/rss.xml')
@ -287,11 +295,10 @@ class RSSTestCase(ChannelPluginTestCase):
finally: finally:
self._feedMsg('rss remove xkcd') self._feedMsg('rss remove xkcd')
self._feedMsg('rss remove xkcdsec') self._feedMsg('rss remove xkcdsec')
feedparser._open_resource = old_open
def testFeedSpecificWaitPeriod(self): @mock_urllib
old_open = feedparser._open_resource def testFeedSpecificWaitPeriod(self, mock):
feedparser._open_resource = constant(xkcd_old) mock._data = xkcd_old
timeFastForward(1.1) timeFastForward(1.1)
try: try:
self.assertNotError('rss add xkcd1 http://xkcd.com/rss.xml') self.assertNotError('rss add xkcd1 http://xkcd.com/rss.xml')
@ -304,7 +311,7 @@ class RSSTestCase(ChannelPluginTestCase):
with conf.supybot.plugins.RSS.feeds.xkcd1.waitPeriod.context(1): with conf.supybot.plugins.RSS.feeds.xkcd1.waitPeriod.context(1):
timeFastForward(1.1) timeFastForward(1.1)
self.assertNoResponse(' ', timeout=0.1) self.assertNoResponse(' ', timeout=0.1)
feedparser._open_resource = constant(xkcd_new) mock._data = xkcd_new
self.assertNoResponse(' ', timeout=0.1) self.assertNoResponse(' ', timeout=0.1)
timeFastForward(1.1) timeFastForward(1.1)
self.assertRegexp(' ', 'xkcd1.*Chaos') self.assertRegexp(' ', 'xkcd1.*Chaos')
@ -317,30 +324,23 @@ class RSSTestCase(ChannelPluginTestCase):
self._feedMsg('rss remove xkcd1') self._feedMsg('rss remove xkcd1')
self._feedMsg('rss announce remove xkcd2') self._feedMsg('rss announce remove xkcd2')
self._feedMsg('rss remove xkcd2') self._feedMsg('rss remove xkcd2')
feedparser._open_resource = old_open
def testDescription(self): @mock_urllib
def testDescription(self, mock):
timeFastForward(1.1) timeFastForward(1.1)
with conf.supybot.plugins.RSS.format.context('$description'): with conf.supybot.plugins.RSS.format.context('$description'):
old_open = feedparser._open_resource mock._data = xkcd_new
feedparser._open_resource = constant(xkcd_new) self.assertRegexp('rss http://xkcd.com/rss.xml',
try: 'On the other hand, the refractor\'s')
self.assertRegexp('rss http://xkcd.com/rss.xml',
'On the other hand, the refractor\'s')
finally:
feedparser._open_resource = old_open
def testBadlyFormedFeedWithNoItems(self): @mock_urllib
def testBadlyFormedFeedWithNoItems(self, mock):
# This combination will cause the RSS command to show the last parser # This combination will cause the RSS command to show the last parser
# error. # error.
old_open = feedparser._open_resource
timeFastForward(1.1) timeFastForward(1.1)
feedparser._open_resource = constant(not_well_formed) mock._data = not_well_formed
try: self.assertRegexp('rss http://example.com/',
self.assertRegexp('rss http://example.com/', 'Parser error')
'Parser error')
finally:
feedparser._open_resource = old_open
if network: if network:
timeout = 5 # Note this applies also to the above tests timeout = 5 # Note this applies also to the above tests