""".strip ())
def testCsrfProtection(self):
# need to set SENDMAILDEBUG to prevent
# downstream issue when email is sent on successful
# issue creation. Also delete the file afterwards
# just tomake sure that someother test looking for
# SENDMAILDEBUG won't trip over ours.
if not os.environ.has_key('SENDMAILDEBUG'):
os.environ['SENDMAILDEBUG'] = 'mail-test1.log'
SENDMAILDEBUG = os.environ['SENDMAILDEBUG']
page_template = """
""".strip ()
self.db.keyword.create (name = 'key1')
self.db.keyword.create (name = 'key2')
nodeid = self.db.issue.create (title = 'Title', priority = '1',
status = '1', nosy = ['1'], keyword = ['1'])
self.db.commit ()
form = {':note': 'msg-content', 'title': 'New title',
'priority': '2', 'status': '2', 'nosy': '1,2', 'keyword': '',
':action': 'edit'}
cl = self.setupClient(form, 'issue', '1')
pt = RoundupPageTemplate()
pt.pt_edit(page_template, 'text/html')
out = []
def wh(s):
out.append(s)
cl.write_html = wh
# Enable the following if we get a templating error:
#def send_error (*args, **kw):
# import pdb; pdb.set_trace()
#cl.send_error_to_admin = send_error
# Need to rollback the database on error -- this usually happens
# in web-interface (and for other databases) anyway, need it for
# testing that the form values are really used, not the database!
# We do this together with the setup of the easy template above
def load_template(x):
cl.db.rollback()
return pt
cl.instance.templates.load = load_template
cl.selectTemplate = MockNull()
cl.determine_context = MockNull ()
def hasPermission(s, p, classname=None, d=None, e=None, **kw):
return True
actions.Action.hasPermission = hasPermission
e1 = _HTMLItem.is_edit_ok
_HTMLItem.is_edit_ok = lambda x : True
e2 = HTMLProperty.is_edit_ok
HTMLProperty.is_edit_ok = lambda x : True
# test with no headers and config by default requires 1
cl.inner_main()
match_at=out[0].find('Unable to verify sufficient headers')
self.assertNotEqual(match_at, -1)
del(out[0])
# all the rest of these allow at least one header to pass
# and the edit happens with a redirect back to issue 1
cl.env['HTTP_REFERER'] = 'http://whoami.com/path/'
cl.inner_main()
match_at=out[0].find('Redirecting to hello world RaNdOmJunk
'))
# make sure we can find issue 1 title foo in the output
self.assertNotEqual(-1,
self.output[0].index('foo'))
# make sure we can find the last SHA1 sum line at the end of the
# page
self.assertNotEqual(-1,
self.output[0].index(''))
def testrenderContext(self):
# set up the client;
# run determine_context to set the required client attributes
# run renderContext(); check result for proper page
# this will generate the default home page like
# testrenderFrontPage
self.client.form=makeForm({})
self.client.path = ''
self.client.determine_context()
self.assertEqual((self.client.classname, self.client.template, self.client.nodeid), (None, '', None))
self.assertEqual(self.client._ok_message, [])
result = self.client.renderContext()
self.assertNotEqual(-1,
result.index(''))
# now look at the user index page
self.client.form=makeForm({ "@ok_message": "ok message", "@template": "index"})
self.client.path = 'user'
self.client.determine_context()
self.assertEqual((self.client.classname, self.client.template, self.client.nodeid), ('user', 'index', None))
self.assertEqual(self.client._ok_message, ['ok message'])
result = self.client.renderContext()
self.assertNotEqual(-1, result.index('User listing - Roundup issue tracker'))
self.assertNotEqual(-1, result.index('ok message'))
# print result
def testRenderAltTemplates(self):
# check that right page is returned when rendering
# @template=oktempl|errortmpl
# set up the client;
# run determine_context to set the required client attributes
# run renderContext(); check result for proper page
# Test ok state template that uses user.forgotten.html
self.client.form=makeForm({"@template": "forgotten|item"})
self.client.path = 'user'
self.client.determine_context()
self.client.session_api = MockNull(_sid="1234567890")
self.assertEqual((self.client.classname, self.client.template, self.client.nodeid), ('user', 'forgotten|item', None))
self.assertEqual(self.client._ok_message, [])
result = self.client.renderContext()
print result
self.assertNotEqual(-1,
result.index(''))
# now set an error in the form to get error template user.item.html
self.client.form=makeForm({"@template": "forgotten|item",
"@error_message": "this is an error"})
self.client.path = 'user'
self.client.determine_context()
self.assertEqual((self.client.classname, self.client.template, self.client.nodeid), ('user', 'forgotten|item', None))
self.assertEqual(self.client._ok_message, [])
self.assertEqual(self.client._error_message, ["this is an error"])
result = self.client.renderContext()
print result
self.assertNotEqual(-1,
result.index(''))
def testexamine_url(self):
''' test the examine_url function '''
def te(url, exception, raises=ValueError):
with self.assertRaises(raises) as cm:
examine_url(url)
self.assertEqual(cm.exception.message, exception)
action = actions.Action(self.client)
examine_url = action.examine_url
# Christmas tree url: test of every component that passes
self.assertEqual(
examine_url("http://tracker.example/cgi-bin/roundup.cgi/bugs/user3;parm=bar?@template=foo&parm=(zot)#issue"),
'http://tracker.example/cgi-bin/roundup.cgi/bugs/user3;parm=bar?@template=foo&parm=(zot)#issue')
# allow replacing http with https if base is http
self.assertEqual(
examine_url("https://tracker.example/cgi-bin/roundup.cgi/bugs/user3;parm=bar?@template=foo&parm=(zot)#issue"),
'https://tracker.example/cgi-bin/roundup.cgi/bugs/user3;parm=bar?@template=foo&parm=(zot)#issue')
# change base to use https and make sure we don't redirect to http
saved_base = action.base
action.base = "https://tracker.example/cgi-bin/roundup.cgi/bugs/"
te("http://tracker.example/cgi-bin/roundup.cgi/bugs/user3;parm=bar?@template=foo&parm=(zot)#issue",
'Base url https://tracker.example/cgi-bin/roundup.cgi/bugs/ requires https. Redirect url http://tracker.example/cgi-bin/roundup.cgi/bugs/user3;parm=bar?@template=foo&parm=(zot)#issue uses http.')
action.base = saved_base
# url doesn't have to be valid to roundup, just has to be contained
# inside of roundup. No zoik class is defined
self.assertEqual(examine_url("http://tracker.example/cgi-bin/roundup.cgi/bugs/zoik7;parm=bar?@template=foo&parm=(zot)#issue"), "http://tracker.example/cgi-bin/roundup.cgi/bugs/zoik7;parm=bar?@template=foo&parm=(zot)#issue")
# test with wonky schemes
te("email://tracker.example/cgi-bin/roundup.cgi/bugs/user3;parm=bar?@template=foo&parm=(zot)#issue",
'Unrecognized scheme in email://tracker.example/cgi-bin/roundup.cgi/bugs/user3;parm=bar?@template=foo&parm=(zot)#issue')
te("http%3a//tracker.example/cgi-bin/roundup.cgi/bugs/user3;parm=bar?@template=foo&parm=(zot)#issue", 'Unrecognized scheme in http%3a//tracker.example/cgi-bin/roundup.cgi/bugs/user3;parm=bar?@template=foo&parm=(zot)#issue')
# test different netloc/path prefix
# assert port
te("http://tracker.example:1025/cgi-bin/roundup.cgi/bugs/user3;parm=bar?@template=foo&parm=(zot)#issue",'Net location in http://tracker.example:1025/cgi-bin/roundup.cgi/bugs/user3;parm=bar?@template=foo&parm=(zot)#issue does not match base: tracker.example')
#assert user
te("http://user@tracker.example/cgi-bin/roundup.cgi/bugs/user3;parm=bar?@template=foo&parm=(zot)#issue", 'Net location in http://user@tracker.example/cgi-bin/roundup.cgi/bugs/user3;parm=bar?@template=foo&parm=(zot)#issue does not match base: tracker.example')
#assert user:password
te("http://user:pass@tracker.example/cgi-bin/roundup.cgi/bugs/user3;parm=bar?@template=foo&parm=(zot)#issue", 'Net location in http://user:pass@tracker.example/cgi-bin/roundup.cgi/bugs/user3;parm=bar?@template=foo&parm=(zot)#issue does not match base: tracker.example')
# try localhost http scheme
te("http://localhost/cgi-bin/roundup.cgi/bugs/user3", 'Net location in http://localhost/cgi-bin/roundup.cgi/bugs/user3 does not match base: tracker.example')
# try localhost https scheme
te("https://localhost/cgi-bin/roundup.cgi/bugs/user3", 'Net location in https://localhost/cgi-bin/roundup.cgi/bugs/user3 does not match base: tracker.example')
# try different host
te("http://bad.guys.are.us/cgi-bin/roundup.cgi/bugs/user3;parm=bar?@template=foo&parm=(zot)#issue", 'Net location in http://bad.guys.are.us/cgi-bin/roundup.cgi/bugs/user3;parm=bar?@template=foo&parm=(zot)#issue does not match base: tracker.example')
# change the base path to .../bug from .../bugs
te("http://tracker.example/cgi-bin/roundup.cgi/bug/user3;parm=bar?@template=foo&parm=(zot)#issue", 'Base path /cgi-bin/roundup.cgi/bugs/ is not a prefix for url http://tracker.example/cgi-bin/roundup.cgi/bug/user3;parm=bar?@template=foo&parm=(zot)#issue')
# change the base path eliminate - in cgi-bin
te("http://tracker.example/cgibin/roundup.cgi/bug/user3;parm=bar?@template=foo&parm=(zot)#issue",'Base path /cgi-bin/roundup.cgi/bugs/ is not a prefix for url http://tracker.example/cgibin/roundup.cgi/bug/user3;parm=bar?@template=foo&parm=(zot)#issue')
# scan for unencoded characters
# we skip schema and net location since unencoded character
# are allowed only by an explicit match to a reference.
#
# break components with unescaped character '<'
# path component
te("http://tracker.example/cgi-bin/roundup.cgi/bugs/&parm=(zot)#issue", 'Query component (@template=&parm=(zot)) in http://tracker.example/cgi-bin/roundup.cgi/bugs/user3;parm=bar?@template=&parm=(zot)#issue is not properly escaped')
# fragment component
te("http://tracker.example/cgi-bin/roundup.cgi/bugs/user3;parm=bar?@template=foo&parm=(zot)#iss