',
"PDF zum Termin", # rendering of event with attachment
]).addCallback(self._removeAttachment)
def testUploadLimit(self):
SERVER.conn.stconf.uploadLimit = 10000
return self.assertPOSTHasStrings("/edit/8", {
"__nevow_form__": "attach",
"upload": ("input", io.BytesIO(b"%PDF"*3000))
}, [
"Zusätze dürfen nicht länger als 10000 Bytes sein",])
def testEditGhostEvent(self):
return self.assertGETHasStrings("/edit/ronzo", {},
["Nicht gefunden
"])
def testCloneGhostEvent(self):
return self.assertGETHasStrings("/edit/ronzo/clone", {},
["Nicht gefunden
"])
class TagsEntryTest(PagesTest):
"""entering and deleting tags.
"""
def assertTagResult(self, moreKeys, test):
args = {"bdate": "1", "teaser": "a",
"__nevow_form__": "termedit"}
args.update(moreKeys)
return self.runQuery(SERVER, "POST", "/edit/1111", args,
).addCallback(test)
def testSetNoTag(self):
def test(postResult):
return self.assertGETLacksStrings("/edit/1111", {}, ["checked"])
return self.assertTagResult({}, test)
def testSetOneTag(self):
def assertChecked(result):
tree = getXMLTree(result[0])
self.assertEqual(
tree.xpath("//input[@value='Frauen']")[0].get("checked"),
"checked")
def test(postResult):
return self.assertGETHasStrings("/edit/1111", {},
['1111']
).addCallback(assertChecked)
return self.assertTagResult({"tags": "Frauen"}, test)
def testSetTwoTags(self):
def assertChecked(result):
tree = getXMLTree(result[0])
self.assertEqual(tree.xpath("//input[@value='Frauen']")[0].get("checked"),
"checked")
self.assertEqual(
tree.xpath("//input[@value='AKF']")[0].get("checked"),
"checked")
def test(postResult):
return self.assertGETHasStrings("/edit/1111", {},
['1111']
).addCallback(assertChecked)
return self.assertTagResult({"tags": ["Frauen", "AKF"]}, test)
def testCustomTagsShow(self):
def test(ignored):
return self.assertGETHasStrings("/edit/1111", {}, []
).addCallback(self.assertXpath,
"//input[@value='customTag1']",
{"name": "tags", "checked": "checked"}
).addCallback(self.assertXpath,
"//input[@value='customTag2']",
{"name": "tags", "checked": "checked"})
return self.assertTagResult({"tags": ["customTag1",
"customTag2"]}, test)
def testExtraTag(self):
def cleanup(ignored):
SERVER.conn.stconf.rmKey(self.sponsor+"::tag")
SERVER.conn.stconf.addKeyValue(self.sponsor+"::tag", "krawall")
return self.assertGETHasStrings("/edit/1111", {},
['value="krawall"']
).addBoth(cleanup)
def testNoExtraTag(self):
return self.assertGETLacksStrings("/edit/1111", {},
['value="krawall"'])
class ErrorsTest(PagesTest):
"""See if error pages are delivered as expected.
"""
def testPlain404(self):
return self.assertGETHasStrings("/nonexistingresource", {},
["Nicht gefunden", "No such resource"])
def testNoneIsNotFound(self):
return self.assertGETHasStrings("/edit/bar/foo", {},
["Nicht gefunden", "No such resource"])
def testNoEvent(self):
return self.assertStatus("/edit/1112", 404)
def testRedirect(self):
return self.assertStatus("/errors/re", 302)
def testForbiddenCode(self):
return self.assertStatus("/errors/fb", 403)
def testForbiddenMsg(self):
return self.assertGETHasStrings("/errors/fb", {},
["kann nur machen", "statt klicken"])
def testBrokenCode(self):
return self.assertGETHasStrings("/errors/murks", {},
["passieren sollen", "unspecified"])
def testBadDate(self):
return self.assertPOSTHasStrings("/edit/1111", {
"teaser":"a", "bdate": "glugger", "__nevow_form__": "termedit"},
["Kein Datum zu erkennen"])
def testBadTime(self):
return self.assertPOSTHasStrings("/edit/1111", {
"teaser":"a", "bdate": "1", "__nevow_form__": "termedit", "btime": "32"},
["Zeit aus den Fugen", "0..23"])
def testRSTErrorEncoding(self):
return self.assertPOSTHasStrings("/edit/1111", {
"teaser":"a", "bdate": "1", "__nevow_form__": "termedit",
"fulltext": '`knülle`_'},
['Line 1: Unknown target name: "knülle".'])
def testChildless(self):
return self.assertGETHasStrings("/config/rotten", {},
["Nicht gefunden", "/config hat keine Unterseiten"])
class NoSponsorTest(PagesTest):
"""tests for behaviour for non-sponsors.
"""
sponsor = None
def testRootAdapts(self):
return self.assertGETLacksStrings("/list", {}, ["[Neuer Termin]"])
def testStyleRemains(self):
return self.assertGETHasStrings("/list", {}, ["default.css"])
def testEditDenied(self):
return self.assertStatus("/edit", 403)
def testEditArticleDenied(self):
return self.assertPOSTHasStrings("/edit/1", {"teaser": "x"},
["Darfst du nicht", "Hingehen"])
def testNoDelete(self):
return self.assertResultHasStrings("DELETE", "/event/1111",
{}, ["Nix gibts"])
def testNoTagedit(self):
def assertion(res):
return self.assertStringsIn(res,
["Diese Funktion hier kann nur machen,"])
return self.runQuery(SERVER, "GET", "/tagedit", {},
).addCallback(assertion)
def testCal(self):
return self.assertGETLacksStrings("/cal", {},
["Neuen Termin für diesen Tag", "/edit"])
class EventListTest(PagesTest):
"""tests dealing with event lists.
"""
def testMainPage(self):
return self.assertGETHasStrings("/list", {}, [
"Neuer Termin", "default.css",
"Mittwoch, 17.02.",
'11.55 Uhr',
'Super-VA',
'teaser">Denkw',
'20.00 Uhr',
'class="icon place">Autonomes Zentrum',
'Wir'])
def testEndDate(self):
def _checkNoLateEvent(res):
self.assertFalse(b"Wir gedenken" in res[0])
return res
return self.assertGETHasStrings("/list", {"endDate": "2010-02-17"}, [
"17.02"]).addCallback(_checkNoLateEvent)
def testBadStartDate(self):
return self.assertGETHasStrings("/list", {"startDate": "foobar"}, [
" Bad ISO date/time: 'foobar'",
"Ups..."])
def testOneTagCatches(self):
return self.assertGETHasStrings("/list", {'tag': 'a'}, [
"Super-VA", ">Denkw"])
def testOneTagLacks(self):
return self.assertGETLacksStrings("/list", {'tag': 'a'}, [
"event/3",
"Aktionswoche", # see that long-terms are excluded as well
"Im Gange...", # and that the header gets swallowed
])
def testOneTagLongterm(self):
return self.assertGETHasStrings("/list", {'tag': 'c'}, [
"Aktionswoche",
"Im Gange...",
"Super-VA"])
def testDefaultList(self):
return self.assertGETHasStrings("/list", {}, [
'11.55 Uhr',
'Denkw'])
class ArchiveTest(PagesTest):
def testArchiveList(self):
return self.assertGETHasStrings("/archive", {}, [
'span class="teaser">Vergangenes'])
def testArchiveNoEdit(self):
return self.assertGETLacksStrings("/archive", {}, [
'Edit'])
def testArchiveYear(self):
return self.assertGETHasStrings("/archive/2010", {}, [
'span class="teaser">Vergangenes'])
def testArchiveYearSelects(self):
return self.assertGETLacksStrings("/archive/2009", {}, [
'span class="teaser">Vergangenes'])
def testArchiveMonth(self):
return self.assertGETHasStrings("/archive/2010/02", {}, [
'span class="teaser">Vergangenes'])
def testArchiveMonthSelects(self):
return self.assertGETLacksStrings("/archive/2010/01", {}, [
'span class="teaser">Vergangenes'])
def testArchiveBadChild(self):
return self.assertGETHasStrings("/archive/badyear", {},
["Servermaschinerie: This doesn't lead to any archive."])
def testArchiveNextYear(self):
return self.assertGETHasStrings("/archive/2009/12", {}, [
"Dezember 2009",])
# We also ought to test if the end date really is 2010-01-01 here,
# but I'm too lazy.
def testArchiveOverrideDates(self):
return self.assertGETHasStrings("/archive",
{"startDate": "1980-01-01", "endDate": "2013-02-01"}, [
"Termin-Archiv zwischen 1. Januar 1980 und 1. Februar 2013"])
def testArchiveOverrideDays(self):
return self.assertGETHasStrings("/archive",
{"endDate": "2008-06-04", "nDays": "365"}, [
"Termin-Archiv zwischen 5. Juni 2007 und 4. Juni 2008"])
def testYearBeforeStops(self):
return self.assertGETLacksStrings("/archive/2001", {},
["archive/2000", ">1999"])
def testForwardLinks(self):
return self.assertGETHasStrings("/archive/2006", {},
["2007", "2008", "2009"])
def testYearAfterStops(self):
return self.assertGETLacksStrings("/archive/2010", {},
["2011", "2012", "2013"])
def testArchivedCal(self):
return self.assertGETHasStrings("/cal/2006/10", {},
["Ewig her"])
class FullevTest(PagesTest):
"""tests for working full event/full text display.
"""
def testSimple(self):
return self.assertGETHasStrings("/event/1", {}, [
'default.css',
'Termin für 2010-02-17',
'Super-VA '])
def testFulltextEdit(self):
def testOriginalUnchanged(ignored):
return self.assertGETLacksStrings("/event/1", {}, [
'einmal'])
def removeChange(ignored):
return self.assertPOSTHasStrings("/edit/1111", {"fulltext":
"Hurgel", "__nevow_form__": "termedit", "teaser": "a", "bdate": "1"},
["Hurgel"]).addCallback(testOriginalUnchanged)
def testChanged(ignored):
return self.assertGETHasStrings("/event/1111", {}, [
'einmal']
).addCallback(removeChange)
return self.assertPOSTHasStrings("/edit/1111", {
"teaser": "a", "bdate": "1",
"fulltext": "* einmal\n* zweimal", "__nevow_form__": "termedit"}, []
).addCallback(testChanged)
def testBadRSTRejected(self):
return self.assertPOSTHasStrings("/edit/1111", {
"teaser": "a", "bdate": "1",
"fulltext": "* einmal\nzweimal", "__nevow_form__": "termedit"}, [
'Langtext : ',
'Bullet list ends without'])
def testArchivedEventFound(self):
return self.assertGETHasStrings("/event/4", {},
["Ist jetzt schon was her."])
def testNaked(self):
return self.assertGETHasStrings("/event/n/4", {},
['full-description">Ist jetzt']
).addCallback(
self.assertXpath, "//p[@class='ednote']/a", {"href": "/"})
class StaticTest(PagesTest):
"""tests for delivering static resources.
"""
def testNonExisting(self):
return self.assertStatus("/static/etc/passwd", 404)
def testNoParent(self):
return self.assertStatus("/static/../model.py", 403)
def testCSSDelivery(self):
def test(res):
self.assertEqual(res[1].getResponseHeader("Content-Type"), "text/css")
self.assertEqual(res[1].code, 200)
self.assertTrue(b"body" in res[0], "CSS content seems broken")
return self.runQuery(SERVER, "GET", "/static/default.css", {}
).addCallback(test)
def testCSSRootAlias(self):
def test(res):
self.assertEqual(res[1].getResponseHeader("Content-Type"), "text/css")
self.assertEqual(res[1].code, 200)
return self.assertGETHasStrings("/default.css", {},
["body"]
).addCallback(test)
def testNonExistingTemplatePage(self):
return self.assertStatus("/dyn/missionstatement", 404)
def testDynRoot(self):
return self.assertStatus("/dyn", 404)
def testValidDyn(self):
return self.assertGETHasStrings("/dyn/mitmachen", {}, ["fortschritt"])
def _makeStaticDir():
# a helper resource for ExternalStaticTest, cleaned up using atexit
staticDir = os.path.join(os.environ["HOME"], "static")
os.makedirs(staticDir, exist_ok=True)
dir = tempfile.TemporaryDirectory(dir=staticDir)
with open(os.path.join(dir.name, "index.html"), "w") as f:
f.write('\n')
with open(os.path.join(dir.name, "other.txt"), "w") as f:
f.write("A, B, C\n")
def cleanup():
dir.cleanup()
try:
os.rmdir(staticDir)
except IOError:
pass
atexit.register(cleanup)
return dir.name.split("/")[-1]
_STATIC_DIR = _makeStaticDir()
class ExternalStaticTest(PagesTest):
def testCustomStaticRetrieval(self):
return self.assertGETHasStrings("/static/"+_STATIC_DIR, {}, [
''])
def testCustomStaticRetrievalWithSlash(self):
return self.assertGETHasStrings("/static/"+_STATIC_DIR+"/", {}, [
''])
def testCustomStaticRetrievalOther(self):
return self.assertGETHasStrings("/static/"+_STATIC_DIR+"/other.txt", {}, [
'A, B, C'])
def testNoTraversal(self):
return self.assertGETHasStrings("/static/"+_STATIC_DIR+"../../.ssh", {}, [
"You're not serious, are you?
"])
class RenderTest(PagesTest):
"""tests for some aspects of rendering events in HTML.
"""
def testPlaceExpansionLiteral(self):
def testExpanded(ignored):
return self.assertGETHasStrings("/event/1111", {},
["Cherry Lane,", '