"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "test/test_templating.py" between
roundup-1.6.1.tar.gz and roundup-2.0.0.tar.gz

About: Roundup is an highly customisable issue-tracking system with command-line, web and e-mail interfaces (written in Python).

test_templating.py  (roundup-1.6.1):test_templating.py  (roundup-2.0.0)
from __future__ import print_function
import unittest import unittest
from cgi import FieldStorage, MiniFieldStorage from cgi import FieldStorage, MiniFieldStorage
from roundup.cgi.templating import * from roundup.cgi.templating import *
from test_actions import MockNull, true from .test_actions import MockNull, true
import pytest
from .pytest_patcher import mark_class
if ReStructuredText:
skip_rst = lambda func, *args, **kwargs: func
else:
skip_rst = mark_class(pytest.mark.skip(
reason='ReStructuredText not available'))
if StructuredText:
skip_stext = lambda func, *args, **kwargs: func
else:
skip_stext = mark_class(pytest.mark.skip(
reason='StructuredText not available'))
import roundup.cgi.templating
if roundup.cgi.templating._import_mistune():
skip_mistune = lambda func, *args, **kwargs: func
else:
skip_mistune = mark_class(pytest.mark.skip(
reason='mistune not available'))
if roundup.cgi.templating._import_markdown2():
skip_markdown2 = lambda func, *args, **kwargs: func
else:
skip_markdown2 = mark_class(pytest.mark.skip(
reason='markdown2 not available'))
if roundup.cgi.templating._import_markdown():
skip_markdown = lambda func, *args, **kwargs: func
else:
skip_markdown = mark_class(pytest.mark.skip(
reason='markdown not available'))
from roundup.anypy.strings import u2s, s2u
class MockDatabase(MockNull): class MockDatabase(MockNull):
def getclass(self, name): def getclass(self, name):
return self.classes[name] return self.classes[name]
# setup for csrf testing of otks database api # setup for csrf testing of otks database api
storage = {} storage = {}
def set(self, key, **props): def set(self, key, **props):
MockDatabase.storage[key] = {} MockDatabase.storage[key] = {}
MockDatabase.storage[key].update(props) MockDatabase.storage[key].update(props)
skipping to change at line 44 skipping to change at line 81
self.client.form = self.form self.client.form = self.form
# add client props for testing anti_csrf_nonce # add client props for testing anti_csrf_nonce
self.client.session_api = MockNull(_sid="1234567890") self.client.session_api = MockNull(_sid="1234567890")
self.client.db.getuid = lambda : 10 self.client.db.getuid = lambda : 10
self.client.db.config = {'WEB_CSRF_TOKEN_LIFETIME': 10 } self.client.db.config = {'WEB_CSRF_TOKEN_LIFETIME': 10 }
class HTMLDatabaseTestCase(TemplatingTestCase): class HTMLDatabaseTestCase(TemplatingTestCase):
def test_HTMLDatabase___getitem__(self): def test_HTMLDatabase___getitem__(self):
db = HTMLDatabase(self.client) db = HTMLDatabase(self.client)
self.assert_(isinstance(db['issue'], HTMLClass)) self.assertTrue(isinstance(db['issue'], HTMLClass))
# following assertions are invalid # following assertions are invalid
# since roundup/cgi/templating.py r1.173. # since roundup/cgi/templating.py r1.173.
# HTMLItem is function, not class, # HTMLItem is function, not class,
# but HTMLUserClass and HTMLUser are passed on. # but HTMLUserClass and HTMLUser are passed on.
# these classes are no more. they have ceased to be. # these classes are no more. they have ceased to be.
#self.assert_(isinstance(db['user'], HTMLUserClass)) #self.assertTrue(isinstance(db['user'], HTMLUserClass))
#self.assert_(isinstance(db['issue1'], HTMLItem)) #self.assertTrue(isinstance(db['issue1'], HTMLItem))
#self.assert_(isinstance(db['user1'], HTMLUser)) #self.assertTrue(isinstance(db['user1'], HTMLUser))
def test_HTMLDatabase___getattr__(self): def test_HTMLDatabase___getattr__(self):
db = HTMLDatabase(self.client) db = HTMLDatabase(self.client)
self.assert_(isinstance(db.issue, HTMLClass)) self.assertTrue(isinstance(db.issue, HTMLClass))
# see comment in test_HTMLDatabase___getitem__ # see comment in test_HTMLDatabase___getitem__
#self.assert_(isinstance(db.user, HTMLUserClass)) #self.assertTrue(isinstance(db.user, HTMLUserClass))
#self.assert_(isinstance(db.issue1, HTMLItem)) #self.assertTrue(isinstance(db.issue1, HTMLItem))
#self.assert_(isinstance(db.user1, HTMLUser)) #self.assertTrue(isinstance(db.user1, HTMLUser))
def test_HTMLDatabase_classes(self): def test_HTMLDatabase_classes(self):
db = HTMLDatabase(self.client) db = HTMLDatabase(self.client)
db._db.classes = {'issue':MockNull(), 'user': MockNull()} db._db.classes = {'issue':MockNull(), 'user': MockNull()}
db.classes() db.classes()
class FunctionsTestCase(TemplatingTestCase): class FunctionsTestCase(TemplatingTestCase):
def test_lookupIds(self): def test_lookupIds(self):
db = HTMLDatabase(self.client) db = HTMLDatabase(self.client)
def lookup(key): def lookup(key):
if key == 'ok': if key == 'ok':
return '1' return '1'
if key == 'fail': if key == 'fail':
raise KeyError, 'fail' raise KeyError('fail')
return key return key
db._db.classes = {'issue': MockNull(lookup=lookup)} db._db.classes = {'issue': MockNull(lookup=lookup)}
prop = MockNull(classname='issue') prop = MockNull(classname='issue')
self.assertEqual(lookupIds(db._db, prop, ['1','2']), ['1','2']) self.assertEqual(lookupIds(db._db, prop, ['1','2']), ['1','2'])
self.assertEqual(lookupIds(db._db, prop, ['ok','2']), ['1','2']) self.assertEqual(lookupIds(db._db, prop, ['ok','2']), ['1','2'])
self.assertEqual(lookupIds(db._db, prop, ['ok', 'fail'], 1), self.assertEqual(lookupIds(db._db, prop, ['ok', 'fail'], 1),
['1', 'fail']) ['1', 'fail'])
self.assertEqual(lookupIds(db._db, prop, ['ok', 'fail']), ['1']) self.assertEqual(lookupIds(db._db, prop, ['ok', 'fail']), ['1'])
def test_lookupKeys(self): def test_lookupKeys(self):
skipping to change at line 151 skipping to change at line 188
* create nonce via module function with default lifetime * create nonce via module function with default lifetime
''' '''
# the value below is number of seconds in a week. # the value below is number of seconds in a week.
week_seconds = 604800 week_seconds = 604800
otks=self.client.db.getOTKManager() otks=self.client.db.getOTKManager()
for test in [ 'module', 'template', 'default_time' ]: for test in [ 'module', 'template', 'default_time' ]:
print "Testing:", test print("Testing:", test)
if test == 'module': if test == 'module':
# test the module function # test the module function
nonce1 = anti_csrf_nonce(self, self.client, lifetime=1) nonce1 = anti_csrf_nonce(self.client, lifetime=1)
# lifetime * 60 is the offset # lifetime * 60 is the offset
greater_than = week_seconds - 1 * 60 greater_than = week_seconds - 1 * 60
elif test == 'template': elif test == 'template':
# call the function through the TemplatingUtils class # call the function through the TemplatingUtils class
cls = TemplatingUtils(self.client) cls = TemplatingUtils(self.client)
nonce1 = cls.anti_csrf_nonce(lifetime=5) nonce1 = cls.anti_csrf_nonce(lifetime=5)
greater_than = week_seconds - 5 * 60 greater_than = week_seconds - 5 * 60
elif test == 'default_time': elif test == 'default_time':
# use the module function but with no lifetime # use the module function but with no lifetime
nonce1 = anti_csrf_nonce(self, self.client) nonce1 = anti_csrf_nonce(self.client)
# see above for web nonce lifetime. # see above for web nonce lifetime.
greater_than = week_seconds - 10 * 60 greater_than = week_seconds - 10 * 60
self.assertEqual(len(nonce1), 64) self.assertEqual(len(nonce1), 64)
uid = otks.get(nonce1, 'uid', default=None) uid = otks.get(nonce1, 'uid', default=None)
sid = otks.get(nonce1, 'sid', default=None) sid = otks.get(nonce1, 'sid', default=None)
timestamp = otks.get(nonce1, '__timestamp', default=None) timestamp = otks.get(nonce1, '__timestamp', default=None)
self.assertEqual(uid, 10) self.assertEqual(uid, 10)
self.assertEqual(sid, self.client.session_api._sid) self.assertEqual(sid, self.client.session_api._sid)
now = time.time() now = time.time()
print "now, timestamp, greater, difference", \ print("now, timestamp, greater, difference",
now, timestamp, greater_than, now - timestamp now, timestamp, greater_than, now - timestamp)
# lower bound of the difference is above. Upper bound # lower bound of the difference is above. Upper bound
# of difference is run time between time.time() in # of difference is run time between time.time() in
# the call to anti_csrf_nonce and the time.time() call # the call to anti_csrf_nonce and the time.time() call
# that assigns ts above. I declare that difference # that assigns ts above. I declare that difference
# to be less than 1 second for this to pass. # to be less than 1 second for this to pass.
self.assertEqual(True, self.assertEqual(True,
greater_than <= now - timestamp < (greater_than + 1) ) greater_than <= now - timestamp < (greater_than + 1) )
def test_string_url_quote(self): def test_string_url_quote(self):
skipping to change at line 211 skipping to change at line 248
def test_string_plain_or_hyperlinked(self): def test_string_plain_or_hyperlinked(self):
''' test that email obscures the email ''' ''' test that email obscures the email '''
p = StringHTMLProperty(self.client, 'test', '1', None, 'test', 'A string <b> with rouilj@example.com embedded &lt; html</b>') p = StringHTMLProperty(self.client, 'test', '1', None, 'test', 'A string <b> with rouilj@example.com embedded &lt; html</b>')
self.assertEqual(p.plain(), 'A string <b> with rouilj@example.com embedd ed &lt; html</b>') self.assertEqual(p.plain(), 'A string <b> with rouilj@example.com embedd ed &lt; html</b>')
self.assertEqual(p.plain(escape=1), 'A string &lt;b&gt; with rouilj@exam ple.com embedded &amp;lt; html&lt;/b&gt;') self.assertEqual(p.plain(escape=1), 'A string &lt;b&gt; with rouilj@exam ple.com embedded &amp;lt; html&lt;/b&gt;')
self.assertEqual(p.plain(hyperlink=1), 'A string &lt;b&gt; with <a href= "mailto:rouilj@example.com">rouilj@example.com</a> embedded &amp;lt; html&lt;/b& gt;') self.assertEqual(p.plain(hyperlink=1), 'A string &lt;b&gt; with <a href= "mailto:rouilj@example.com">rouilj@example.com</a> embedded &amp;lt; html&lt;/b& gt;')
self.assertEqual(p.plain(escape=1, hyperlink=1), 'A string &lt;b&gt; wit h <a href="mailto:rouilj@example.com">rouilj@example.com</a> embedded &amp;lt; h tml&lt;/b&gt;') self.assertEqual(p.plain(escape=1, hyperlink=1), 'A string &lt;b&gt; wit h <a href="mailto:rouilj@example.com">rouilj@example.com</a> embedded &amp;lt; h tml&lt;/b&gt;')
self.assertEqual(p.hyperlinked(), 'A string &lt;b&gt; with <a href="mail to:rouilj@example.com">rouilj@example.com</a> embedded &amp;lt; html&lt;/b&gt;') self.assertEqual(p.hyperlinked(), 'A string &lt;b&gt; with <a href="mail to:rouilj@example.com">rouilj@example.com</a> embedded &amp;lt; html&lt;/b&gt;')
@skip_rst
def test_string_rst(self):
p = StringHTMLProperty(self.client, 'test', '1', None, 'test', u2s(u'A s
tring with cmeerw@example.com *embedded* \u00df'))
# test case to make sure include directive is disabled
q = StringHTMLProperty(self.client, 'test', '1', None, 'test', u2s(u'\n\
n.. include:: XyZrMt.html\n\n<badtag>\n\n'))
q_result=u'''<div class="document">
<div class="system-message">
<p class="system-message-title">System Message: WARNING/2 (<tt class="docutils">
&lt;string&gt;</tt>, line 3)</p>
<p>&quot;include&quot; directive disabled.</p>
<pre class="literal-block">
.. include:: XyZrMt.html
</pre>
</div>
<p>&lt;badtag&gt;</p>
</div>
'''
# test case to make sure raw directive is disabled
r = StringHTMLProperty(self.client, 'test', '1', None, 'test', u2s(u'\n
\n.. raw:: html\n\n <badtag>\n\n'))
r_result='''<div class="document">
<div class="system-message">
<p class="system-message-title">System Message: WARNING/2 (<tt class="docutils">
&lt;string&gt;</tt>, line 3)</p>
<p>&quot;raw&quot; directive disabled.</p>
<pre class="literal-block">
.. raw:: html
&lt;badtag&gt;
</pre>
</div>
</div>
'''
# test case to make sure javascript url's aren't turned into links
s = StringHTMLProperty(self.client, 'test', '1', None, 'test', u2s(u'<ba
dtag>\njavascript:badcode'))
s_result = '<div class="document">\n<p>&lt;badtag&gt;\njavascript:badcod
e</p>\n</div>\n'
self.assertEqual(p.rst(), u2s(u'<div class="document">\n<p>A string with
<a class="reference external" href="mailto:cmeerw&#64;example.com">cmeerw&#64;e
xample.com</a> <em>embedded</em> \u00df</p>\n</div>\n'))
self.assertEqual(q.rst(), u2s(q_result))
self.assertEqual(r.rst(), u2s(r_result))
self.assertEqual(s.rst(), u2s(s_result))
@skip_stext
def test_string_stext(self):
p = StringHTMLProperty(self.client, 'test', '1', None, 'test', u2s(u'A s
tring with cmeerw@example.com *embedded* \u00df'))
self.assertEqual(p.stext(), u2s(u'<p>A string with <a href="mailto:cmeer
w@example.com">cmeerw@example.com</a> <em>embedded</em> \u00df</p>\n'))
def test_string_field(self): def test_string_field(self):
p = StringHTMLProperty(self.client, 'test', '1', None, 'test', 'A string <b> with rouilj@example.com embedded &lt; html</b>') p = StringHTMLProperty(self.client, 'test', '1', None, 'test', 'A string <b> with rouilj@example.com embedded &lt; html</b>')
self.assertEqual(p.field(), '<input type="text" name="test1@test" value= "A string &lt;b&gt; with rouilj@example.com embedded &amp;lt; html&lt;/b&gt;" si ze="30">') self.assertEqual(p.field(), '<input name="test1@test" size="30" type="te xt" value="A string &lt;b&gt; with rouilj@example.com embedded &amp;lt; html&lt; /b&gt;">')
def test_string_multiline(self): def test_string_multiline(self):
p = StringHTMLProperty(self.client, 'test', '1', None, 'test', 'A string <b> with rouilj@example.com embedded &lt; html</b>') p = StringHTMLProperty(self.client, 'test', '1', None, 'test', 'A string <b> with rouilj@example.com embedded &lt; html</b>')
self.assertEqual(p.multiline(), '<textarea name="test1@test" id="test1@ test" rows="5" cols="40">A string &lt;b&gt; with rouilj@example.com embedded &am p;lt; html&lt;/b&gt;</textarea>') self.assertEqual(p.multiline(), '<textarea name="test1@test" id="test1@ test" rows="5" cols="40">A string &lt;b&gt; with rouilj@example.com embedded &am p;lt; html&lt;/b&gt;</textarea>')
self.assertEqual(p.multiline(rows=300, cols=100, **{'class':'css_class'} ), '<textarea class="css_class" name="test1@test" id="test1@test" rows="300" col s="100">A string &lt;b&gt; with rouilj@example.com embedded &amp;lt; html&lt;/b& gt;</textarea>') self.assertEqual(p.multiline(rows=300, cols=100, **{'class':'css_class'} ), '<textarea class="css_class" name="test1@test" id="test1@test" rows="300" col s="100">A string &lt;b&gt; with rouilj@example.com embedded &amp;lt; html&lt;/b& gt;</textarea>')
def test_url_match(self): def test_url_match(self):
'''Test the URL regular expression in StringHTMLProperty. '''Test the URL regular expression in StringHTMLProperty.
''' '''
def t(s, nothing=False, **groups): def t(s, nothing=False, **groups):
m = StringHTMLProperty.hyper_re.search(s) m = StringHTMLProperty.hyper_re.search(s)
if nothing: if nothing:
if m: if m:
self.assertEquals(m, None, '%r matched (%r)'%(s, m.groupdict ())) self.assertEqual(m, None, '%r matched (%r)'%(s, m.groupdict( )))
return return
else: else:
self.assertNotEquals(m, None, '%r did not match'%s) self.assertNotEqual(m, None, '%r did not match'%s)
d = m.groupdict() d = m.groupdict()
for g in groups: for g in groups:
self.assertEquals(d[g], groups[g], '%s %r != %r in %r'%(g, d[g], self.assertEqual(d[g], groups[g], '%s %r != %r in %r'%(g, d[g],
groups[g], s)) groups[g], s))
#t('123.321.123.321', 'url') #t('123.321.123.321', 'url')
t('http://localhost/', url='http://localhost/') t('http://localhost/', url='http://localhost/')
t('http://roundup.net/', url='http://roundup.net/') t('http://roundup.net/', url='http://roundup.net/')
t('http://richard@localhost/', url='http://richard@localhost/') t('http://richard@localhost/', url='http://richard@localhost/')
t('http://richard:sekrit@localhost/', t('http://richard:sekrit@localhost/',
url='http://richard:sekrit@localhost/') url='http://richard:sekrit@localhost/')
t('<HTTP://roundup.net/>', url='HTTP://roundup.net/') t('<HTTP://roundup.net/>', url='HTTP://roundup.net/')
t('www.a.ex', url='www.a.ex') t('www.a.ex', url='www.a.ex')
skipping to change at line 265 skipping to change at line 350
t('user:pass@www.host.net', url='user:pass@www.host.net') t('user:pass@www.host.net', url='user:pass@www.host.net')
t('123.35', nothing=True) t('123.35', nothing=True)
t('-.3535', nothing=True) t('-.3535', nothing=True)
def test_url_replace(self): def test_url_replace(self):
p = StringHTMLProperty(self.client, 'test', '1', None, 'test', '') p = StringHTMLProperty(self.client, 'test', '1', None, 'test', '')
def t(s): return p.hyper_re.sub(p._hyper_repl, s) def t(s): return p.hyper_re.sub(p._hyper_repl, s)
ae = self.assertEqual ae = self.assertEqual
ae(t('item123123123123'), 'item123123123123') ae(t('item123123123123'), 'item123123123123')
ae(t('http://roundup.net/'), ae(t('http://roundup.net/'),
'<a href="http://roundup.net/" rel="nofollow">http://roundup.net/</a> ') '<a href="http://roundup.net/" rel="nofollow noopener">http://roundup .net/</a>')
ae(t('&lt;HTTP://roundup.net/&gt;'), ae(t('&lt;HTTP://roundup.net/&gt;'),
'&lt;<a href="HTTP://roundup.net/" rel="nofollow">HTTP://roundup.net/ </a>&gt;') '&lt;<a href="HTTP://roundup.net/" rel="nofollow noopener">HTTP://rou ndup.net/</a>&gt;')
ae(t('&lt;http://roundup.net/&gt;.'), ae(t('&lt;http://roundup.net/&gt;.'),
'&lt;<a href="http://roundup.net/" rel="nofollow">http://roundup.net /</a>&gt;.') '&lt;<a href="http://roundup.net/" rel="nofollow noopener">http://ro undup.net/</a>&gt;.')
ae(t('&lt;www.roundup.net&gt;'), ae(t('&lt;www.roundup.net&gt;'),
'&lt;<a href="http://www.roundup.net" rel="nofollow">www.roundup.net< /a>&gt;') '&lt;<a href="http://www.roundup.net" rel="nofollow noopener">www.rou ndup.net</a>&gt;')
ae(t('(www.roundup.net)'), ae(t('(www.roundup.net)'),
'(<a href="http://www.roundup.net" rel="nofollow">www.roundup.net</a> )') '(<a href="http://www.roundup.net" rel="nofollow noopener">www.roundu p.net</a>)')
ae(t('foo http://msdn.microsoft.com/en-us/library/ms741540(VS.85).aspx b ar'), ae(t('foo http://msdn.microsoft.com/en-us/library/ms741540(VS.85).aspx b ar'),
'foo <a href="http://msdn.microsoft.com/en-us/library/ms741540(VS.85) .aspx" rel="nofollow">' 'foo <a href="http://msdn.microsoft.com/en-us/library/ms741540(VS.85) .aspx" rel="nofollow noopener">'
'http://msdn.microsoft.com/en-us/library/ms741540(VS.85).aspx</a> bar ') 'http://msdn.microsoft.com/en-us/library/ms741540(VS.85).aspx</a> bar ')
ae(t('(e.g. http://en.wikipedia.org/wiki/Python_(programming_language))' ), ae(t('(e.g. http://en.wikipedia.org/wiki/Python_(programming_language))' ),
'(e.g. <a href="http://en.wikipedia.org/wiki/Python_(programming_lang uage)" rel="nofollow">' '(e.g. <a href="http://en.wikipedia.org/wiki/Python_(programming_lang uage)" rel="nofollow noopener">'
'http://en.wikipedia.org/wiki/Python_(programming_language)</a>)') 'http://en.wikipedia.org/wiki/Python_(programming_language)</a>)')
ae(t('(e.g. http://en.wikipedia.org/wiki/Python_(programming_language)). '), ae(t('(e.g. http://en.wikipedia.org/wiki/Python_(programming_language)). '),
'(e.g. <a href="http://en.wikipedia.org/wiki/Python_(programming_lang uage)" rel="nofollow">' '(e.g. <a href="http://en.wikipedia.org/wiki/Python_(programming_lang uage)" rel="nofollow noopener">'
'http://en.wikipedia.org/wiki/Python_(programming_language)</a>).') 'http://en.wikipedia.org/wiki/Python_(programming_language)</a>).')
ae(t('(e.g. http://en.wikipedia.org/wiki/Python_(programming_language))& gt;.'), ae(t('(e.g. http://en.wikipedia.org/wiki/Python_(programming_language))& gt;.'),
'(e.g. <a href="http://en.wikipedia.org/wiki/Python_(programming_lang uage)" rel="nofollow">' '(e.g. <a href="http://en.wikipedia.org/wiki/Python_(programming_lang uage)" rel="nofollow noopener">'
'http://en.wikipedia.org/wiki/Python_(programming_language)</a>)&gt;. ') 'http://en.wikipedia.org/wiki/Python_(programming_language)</a>)&gt;. ')
ae(t('(e.g. http://en.wikipedia.org/wiki/Python_(programming_language&gt ;)).'), ae(t('(e.g. http://en.wikipedia.org/wiki/Python_(programming_language&gt ;)).'),
'(e.g. <a href="http://en.wikipedia.org/wiki/Python_(programming_lang uage" rel="nofollow">' '(e.g. <a href="http://en.wikipedia.org/wiki/Python_(programming_lang uage" rel="nofollow noopener">'
'http://en.wikipedia.org/wiki/Python_(programming_language</a>&gt;)). ') 'http://en.wikipedia.org/wiki/Python_(programming_language</a>&gt;)). ')
for c in '.,;:!': for c in '.,;:!':
# trailing punctuation is not included # trailing punctuation is not included
ae(t('http://roundup.net/%c ' % c), ae(t('http://roundup.net/%c ' % c),
'<a href="http://roundup.net/" rel="nofollow">http://roundup.net/ </a>%c ' % c) '<a href="http://roundup.net/" rel="nofollow noopener">http://rou ndup.net/</a>%c ' % c)
# but it's included if it's part of the URL # but it's included if it's part of the URL
ae(t('http://roundup.net/%c/' % c), ae(t('http://roundup.net/%c/' % c),
'<a href="http://roundup.net/%c/" rel="nofollow">http://roundup.n et/%c/</a>' % (c, c)) '<a href="http://roundup.net/%c/" rel="nofollow noopener">http:// roundup.net/%c/</a>' % (c, c))
''' def test_input_html4(self):
# boolean attributes are just the attribute name
# indicate with attr=None or attr="attr"
# e.g. disabled
input=input_html4(required=None, size=30)
self.assertEqual(input, '<input required size="30" type="text">')
input=input_html4(required="required", size=30)
self.assertEqual(input, '<input required="required" size="30" type="text
">')
attrs={"required": None, "class": "required", "size": 30}
input=input_html4(**attrs)
self.assertEqual(input, '<input class="required" required size="30" type
="text">')
attrs={"disabled": "disabled", "class": "required", "size": 30}
input=input_html4(**attrs)
self.assertEqual(input, '<input class="required" disabled="disabled" siz
e="30" type="text">')
def test_input_xhtml(self):
# boolean attributes are attribute name="attribute name"
# indicate with attr=None or attr="attr"
# e.g. disabled="disabled"
input=input_xhtml(required=None, size=30)
self.assertEqual(input, '<input required="required" size="30" type="text
"/>')
input=input_xhtml(required="required", size=30)
self.assertEqual(input, '<input required="required" size="30" type="text
"/>')
attrs={"required": None, "class": "required", "size": 30}
input=input_xhtml(**attrs)
self.assertEqual(input, '<input class="required" required="required" siz
e="30" type="text"/>')
attrs={"disabled": "disabled", "class": "required", "size": 30}
input=input_xhtml(**attrs)
self.assertEqual(input, '<input class="required" disabled="disabled" siz
e="30" type="text"/>')
# common markdown test cases
class MarkdownTests:
def test_string_markdown(self):
p = StringHTMLProperty(self.client, 'test', '1', None, 'test', u2s(u'A s
tring with <br> *embedded* \u00df'))
self.assertEqual(p.markdown().strip(), u2s(u'<p>A string with &lt;br&gt;
<em>embedded</em> \u00df</p>'))
def test_string_markdown_link(self):
p = StringHTMLProperty(self.client, 'test', '1', None, 'test', u2s(u'A l
ink <http://localhost>'))
self.assertEqual(p.markdown().strip(), u2s(u'<p>A link <a href="http://l
ocalhost">http://localhost</a></p>'))
def test_string_markdown_link(self):
# markdown2 and markdown escape the email address
try:
from html import unescape as html_unescape
except ImportError:
from HTMLParser import HTMLParser
html_unescape = HTMLParser().unescape
p = StringHTMLProperty(self.client, 'test', '1', None, 'test', u2s(u'A l
ink <cmeerw@example.com>'))
self.assertEqual(html_unescape(p.markdown().strip()), u2s(u'<p>A link <a
href="mailto:cmeerw@example.com">cmeerw@example.com</a></p>'))
def test_string_markdown_javascript_link(self):
# make sure we don't get a "javascript:" link
p = StringHTMLProperty(self.client, 'test', '1', None, 'test', u2s(u'<ja
vascript:alert(1)>'))
self.assertTrue(p.markdown().find('href="javascript:') == -1)
p = StringHTMLProperty(self.client, 'test', '1', None, 'test', u2s(u'[li
nk](javascript:alert(1))'))
self.assertTrue(p.markdown().find('href="javascript:') == -1)
def test_string_markdown_code_block(self):
p = StringHTMLProperty(self.client, 'test', '1', None, 'test', u2s(u'emb
edded code block\n\n```\nline 1\nline 2\n```\n\nnew paragraph'))
self.assertEqual(p.markdown().strip().replace('\n\n', '\n'), u2s(u'<p>em
bedded code block</p>\n<pre><code>line 1\nline 2\n</code></pre>\n<p>new paragrap
h</p>'))
@skip_mistune
class MistuneTestCase(TemplatingTestCase, MarkdownTests) :
def setUp(self):
TemplatingTestCase.setUp(self)
from roundup.cgi import templating
self.__markdown = templating.markdown
templating.markdown = templating._import_mistune()
def tearDown(self):
from roundup.cgi import templating
templating.markdown = self.__markdown
@skip_markdown2
class Markdown2TestCase(TemplatingTestCase, MarkdownTests) :
def setUp(self):
TemplatingTestCase.setUp(self)
from roundup.cgi import templating
self.__markdown = templating.markdown
templating.markdown = templating._import_markdown2()
def tearDown(self):
from roundup.cgi import templating
templating.markdown = self.__markdown
@skip_markdown
class MarkdownTestCase(TemplatingTestCase, MarkdownTests) :
def setUp(self):
TemplatingTestCase.setUp(self)
from roundup.cgi import templating
self.__markdown = templating.markdown
templating.markdown = templating._import_markdown()
def tearDown(self):
from roundup.cgi import templating
templating.markdown = self.__markdown
class NoMarkdownTestCase(TemplatingTestCase) :
def setUp(self):
TemplatingTestCase.setUp(self)
from roundup.cgi import templating
self.__markdown = templating.markdown
templating.markdown = None
def tearDown(self):
from roundup.cgi import templating
templating.markdown = self.__markdown
def test_string_markdown(self):
p = StringHTMLProperty(self.client, 'test', '1', None, 'test', u2s(u'A s
tring http://localhost with cmeerw@example.com <br> *embedded* \u00df'))
self.assertEqual(p.markdown(), u2s(u'A string <a href="http://localhost"
rel="nofollow noopener">http://localhost</a> with <a href="mailto:cmeerw@exampl
e.com">cmeerw@example.com</a> &lt;br&gt; *embedded* \u00df'))
class NoRstTestCase(TemplatingTestCase) :
def setUp(self):
TemplatingTestCase.setUp(self)
from roundup.cgi import templating
self.__ReStructuredText = templating.ReStructuredText
templating.ReStructuredText = None
def tearDown(self):
from roundup.cgi import templating
templating.ReStructuredText = self.__ReStructuredText
def test_string_rst(self):
p = StringHTMLProperty(self.client, 'test', '1', None, 'test', u2s(u'A s
tring with cmeerw@example.com *embedded* \u00df'))
self.assertEqual(p.rst(), u2s(u'A string with <a href="mailto:cmeerw@exa
mple.com">cmeerw@example.com</a> *embedded* \u00df'))
class NoStextTestCase(TemplatingTestCase) :
def setUp(self):
TemplatingTestCase.setUp(self)
from roundup.cgi import templating
self.__StructuredText = templating.StructuredText
templating.StructuredText = None
def tearDown(self):
from roundup.cgi import templating
templating.StructuredText = self.__StructuredText
def test_string_stext(self):
p = StringHTMLProperty(self.client, 'test', '1', None, 'test', u2s(u'A s
tring with cmeerw@example.com *embedded* \u00df'))
self.assertEqual(p.stext(), u2s(u'A string with <a href="mailto:cmeerw@e
xample.com">cmeerw@example.com</a> *embedded* \u00df'))
r'''
class HTMLPermissions: class HTMLPermissions:
def is_edit_ok(self): def is_edit_ok(self):
def is_view_ok(self): def is_view_ok(self):
def is_only_view_ok(self): def is_only_view_ok(self):
def view_check(self): def view_check(self):
def edit_check(self): def edit_check(self):
def input_html4(**attrs): def input_html4(**attrs):
def input_xhtml(**attrs): def input_xhtml(**attrs):
class HTMLInputMixin: class HTMLInputMixin:
def __init__(self): def __init__(self):
class HTMLClass(HTMLInputMixin, HTMLPermissions): class HTMLClass(HTMLInputMixin, HTMLPermissions):
def __init__(self, client, classname, anonymous=0): def __init__(self, client, classname, anonymous=0):
def __repr__(self): def __repr__(self):
def __getitem__(self, item): def __getitem__(self, item):
def __getattr__(self, attr): def __getattr__(self, attr):
def designator(self): def designator(self):
def getItem(self, itemid, num_re=re.compile('-?\d+')): def getItem(self, itemid, num_re=re.compile(r'-?\d+')):
def properties(self, sort=1, cansearch=True): def properties(self, sort=1, cansearch=True):
def list(self, sort_on=None): def list(self, sort_on=None):
def csv(self): def csv(self):
def propnames(self): def propnames(self):
def filter(self, request=None, filterspec={}, sort=(None,None), def filter(self, request=None, filterspec={}, sort=(None,None),
def classhelp(self, properties=None, label='(list)', width='500', def classhelp(self, properties=None, label='(list)', width='500',
def submit(self, label="Submit New Entry"): def submit(self, label="Submit New Entry"):
def history(self): def history(self):
def renderWith(self, name, **kwargs): def renderWith(self, name, **kwargs):
skipping to change at line 355 skipping to change at line 597
class HTMLUserClass(HTMLUserPermission, HTMLClass): class HTMLUserClass(HTMLUserPermission, HTMLClass):
class HTMLUser(HTMLUserPermission, HTMLItem): class HTMLUser(HTMLUserPermission, HTMLItem):
def __init__(self, client, classname, nodeid, anonymous=0): def __init__(self, client, classname, nodeid, anonymous=0):
def hasPermission(self, permission, classname=_marker): def hasPermission(self, permission, classname=_marker):
class HTMLProperty(HTMLInputMixin, HTMLPermissions): class HTMLProperty(HTMLInputMixin, HTMLPermissions):
def __init__(self, client, classname, nodeid, prop, name, value, def __init__(self, client, classname, nodeid, prop, name, value,
def __repr__(self): def __repr__(self):
def __str__(self): def __str__(self):
def __cmp__(self, other): def __lt__(self, other):
def __le__(self, other):
def __eq__(self, other):
def __ne__(self, other):
def __gt__(self, other):
def __ge__(self, other):
def is_edit_ok(self): def is_edit_ok(self):
def is_view_ok(self): def is_view_ok(self):
class StringHTMLProperty(HTMLProperty): class StringHTMLProperty(HTMLProperty):
def _hyper_repl(self, match): def _hyper_repl(self, match):
def hyperlinked(self): def hyperlinked(self):
def plain(self, escape=0, hyperlink=0): def plain(self, escape=0, hyperlink=0):
def stext(self, escape=0): def stext(self, escape=0):
def field(self, size = 30): def field(self, size = 30):
def multiline(self, escape=0, rows=5, cols=40): def multiline(self, escape=0, rows=5, cols=40):
skipping to change at line 415 skipping to change at line 662
def field(self, showid=0, size=None): def field(self, showid=0, size=None):
def menu(self, size=None, height=None, showid=0, additional=[], def menu(self, size=None, height=None, showid=0, additional=[],
class MultilinkHTMLProperty(HTMLProperty): class MultilinkHTMLProperty(HTMLProperty):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
def __len__(self): def __len__(self):
def __getattr__(self, attr): def __getattr__(self, attr):
def __getitem__(self, num): def __getitem__(self, num):
def __contains__(self, value): def __contains__(self, value):
def reverse(self): def reverse(self):
def sorted(self, property, reverse=False):
def plain(self, escape=0): def plain(self, escape=0):
def field(self, size=30, showid=0): def field(self, size=30, showid=0):
def menu(self, size=None, height=None, showid=0, additional=[], def menu(self, size=None, height=None, showid=0, additional=[],
def make_sort_function(db, classname, sort_on=None): def make_key_function(db, classname, sort_on=None):
def sortfunc(a, b): def keyfunc(a):
def find_sort_key(linkcl): def find_sort_key(linkcl):
def handleListCGIValue(value): def handleListCGIValue(value):
class ShowDict: class ShowDict:
def __init__(self, columns): def __init__(self, columns):
def __getitem__(self, name): def __getitem__(self, name):
class HTMLRequest(HTMLInputMixin): class HTMLRequest(HTMLInputMixin):
 End of changes. 33 change blocks. 
36 lines changed or deleted 320 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)