[#4345] Fixed / expanded tests, re-enabled text/html feed processing
Signed-off-by: Cory Johns <johnsca@geek.net>
diff --git a/ForgeBlog/forgeblog/command/rssfeeds.py b/ForgeBlog/forgeblog/command/rssfeeds.py
index a8713b0..b900b55 100644
--- a/ForgeBlog/forgeblog/command/rssfeeds.py
+++ b/ForgeBlog/forgeblog/command/rssfeeds.py
@@ -175,15 +175,10 @@
if ct.type != 'text/html':
content += '[plain]%s[/plain]' % ct.value
else:
- if False:
- # FIXME: disabled until https://sourceforge.net/p/allura/tickets/4345
- # because the bad formatting from [plain] is worse than bad formatting from unintentional markdown syntax
- parser = MDHTMLParser()
- parser.feed(ct.value)
- parser.close() # must be before using the result_doc
- markdown_content = html2text.html2text(parser.result_doc, baseurl=e.link)
- else:
- markdown_content = html2text.html2text(ct.value, baseurl=e.link)
+ parser = MDHTMLParser()
+ parser.feed(ct.value)
+ parser.close() # must be before using the result_doc
+ markdown_content = html2text.html2text(parser.result_doc, baseurl=e.link)
content += markdown_content
else:
diff --git a/ForgeBlog/forgeblog/tests/test_commands.py b/ForgeBlog/forgeblog/tests/test_commands.py
index 4704520..df7125d 100644
--- a/ForgeBlog/forgeblog/tests/test_commands.py
+++ b/ForgeBlog/forgeblog/tests/test_commands.py
@@ -1,9 +1,12 @@
+from datetime import datetime, timedelta
import pylons
pylons.c = pylons.tmpl_context
pylons.g = pylons.app_globals
from pylons import c, g
from nose.tools import assert_equal
+from html2text import html2text
+
from ming.orm.ormsession import ThreadLocalORMSession
from alluratest.controller import setup_basic_test, setup_global_objects
@@ -13,13 +16,60 @@
from forgeblog import model as BM
from forgeblog.command import rssfeeds
+import mock
+
+
test_config = 'test.ini#main'
def setUp():
setup_basic_test()
setup_global_objects()
-def test_pull_rss_feeds():
+def _mock_feed(*entries):
+ class attrdict(dict):
+ def __getattr__(self, name):
+ return self[name]
+
+ feed = mock.Mock()
+ feed.bozo = False
+ feed.entries = []
+ for e in entries:
+ _mock_feed.i += 1
+ entry = attrdict(
+ content_type='text/plain',
+ title='Default Title %d' % _mock_feed.i,
+ subtitle='',
+ summary='',
+ link='http://example.com/',
+ updated=datetime.now()+timedelta(days=_mock_feed.i - 100))
+ entry.update(e)
+ entry['updated_parsed'] = entry['updated'].timetuple()
+ if 'content' in entry:
+ entry['content'] = [attrdict(type=entry['content_type'], value=entry['content'])]
+ feed.entries.append(entry)
+
+ return feed
+_mock_feed.i = 0
+
+@mock.patch.object(rssfeeds.feedparser, 'parse')
+def test_pull_rss_feeds(parsefeed):
+ parsefeed.return_value = _mock_feed(
+ dict(title='Test', subtitle='test', summary='This is a test'),
+ dict(content_type='text/plain', content='Test feed'),
+ dict(content_type='text/html', content=
+ "<p>1. foo</p>\n"
+ "\n"
+ "<p>\n"
+ "#foo bar <a href='baz'>baz</a>\n"
+ "foo bar\n"
+ "</p>\n"
+ "\n"
+ "<p>#foo bar <a href='baz'>\n"
+ "baz\n"
+ "</a></p>\n"
+ ),
+ )
+
base_app = M.AppConfig.query.find().all()[0]
tmp_app = M.AppConfig(tool_name=u'Blog', discussion_id=base_app.discussion_id,
project_id=base_app.project_id,
@@ -27,14 +77,31 @@
u'project_name': base_app.project.name,
u'mount_point': u'blog',
u'mount_label': u'Blog'})
- new_external_feeds = ['http://wordpress.org/news/feed/']
+ new_external_feeds = ['http://example.com/news/feed/']
BM.Globals(app_config_id=tmp_app._id, external_feeds=new_external_feeds)
ThreadLocalORMSession.flush_all()
cmd = rssfeeds.RssFeedsCommand('pull-rss-feeds')
cmd.run([test_config, '-a', tmp_app._id])
cmd.command()
- assert len(BM.BlogPost.query.find({'app_config_id': tmp_app._id}).all()) > 0
+ parsefeed.assert_called_with('http://example.com/news/feed/')
+ posts = BM.BlogPost.query.find({'app_config_id': tmp_app._id}).sort('timestamp', 1)
+ assert_equal(posts.count(), 3)
+ posts = posts.all()
+ assert_equal(posts[0].title, 'Test')
+ assert_equal(posts[0].text, '[plain]This is a test[/plain] [link](http://example.com/)')
+ assert_equal(posts[1].title, 'Default Title 2')
+ assert_equal(posts[1].text, '[plain]Test feed[/plain] [link](http://example.com/)')
+ assert_equal(posts[2].title, 'Default Title 3')
+ assert_equal(posts[2].text,
+ "[plain]1. foo[/plain]\n"
+ "\n"
+ "[plain]#foo bar [/plain][[plain]baz[/plain]](baz) "
+ "[plain]foo bar[/plain] \n"
+ "\n"
+ "[plain]#foo bar [/plain][ [plain]baz[/plain] ](baz)\n "
+ "[link](http://example.com/)"
+ )
def test_plaintext_parser():
parser = rssfeeds.MDHTMLParser()
@@ -89,7 +156,7 @@
)
def test_plaintext_preprocessor():
- html = g.markdown.convert(
+ text = html2text(
"[plain]1. foo[/plain]\n"
"\n"
"[plain]#foo bar [/plain]<a href='baz'>[plain]baz[/plain]</a>\n"
@@ -99,22 +166,15 @@
"[plain]baz[/plain]\n"
"</a>\n"
)
+ html = g.markdown.convert(text)
assert_equal(html,
- '<div class="markdown_content">'
- '1. foo\n'
- '\n'
- '<p>'
- '#foo bar <a href="../baz">baz</a><br />'
- 'foo bar'
- '</p><p>'
- '#foo bar <a href="../baz"><br />'
- 'baz<br />'
- '</a>'
- '</p></div>'
+ '<div class="markdown_content"><p>1. foo '
+ '#foo bar <a href="../baz">baz</a> foo bar '
+ '#foo bar <a href="../baz"> baz </a></p></div>'
)
def test_plaintext_preprocessor_wrapped():
- html = g.markdown.convert(
+ text = html2text(
"<p>[plain]1. foo[/plain]</p>\n"
"\n"
"<p>\n"
@@ -126,16 +186,10 @@
"[plain]baz[/plain]\n"
"</a></p>\n"
)
+ html = g.markdown.convert(text)
assert_equal(html,
- '<div class="markdown_content">'
- '<p>1. foo</p>\n'
+ '<div class="markdown_content">1. foo\n'
'\n'
- '<p>\n'
- '#foo bar <a href="../baz">baz</a>\n'
- 'foo bar\n'
- '</p>\n'
- '<p>#foo bar <a href="../baz">\n'
- 'baz\n'
- '</a></p>\n'
- '</div>'
+ '<p>#foo bar <a href="../baz">baz</a> foo bar </p>\n'
+ '<p>#foo bar <a href="../baz"> baz </a></p></div>'
)