def testServiceConfigThrottling(self): c = ServiceConfig(type='api', minVersion="4.2", untilVersion="5.0", path='/main') configServices = CONFIG_SERVICES() configServices['config']['api.frontend']['throttling'] = { '/path': {'max_connections_per_ip' : 10, 'max_connections': 100}, '/other': {'max_connections_per_ip' : 30, 'max_connections': 150} } consume(c.updateConfig(**configServices)) self.assertEquals([ 'limit_conn_zone $binary_remote_addr zone=api-other-byip:10m;', 'limit_conn_zone $server_name zone=api-other-total:10m;', 'limit_conn_zone $binary_remote_addr zone=api-path-byip:10m;', 'limit_conn_zone $server_name zone=api-path-total:10m;' ], asString(c.zones()).split('\n')) self.assertEquals([ ' location /main {', ' proxy_pass http://__var_af9b2fd9f1c7f17413223dc3c26aeee4_api;', ' }', ' location /other {', ' proxy_pass http://__var_af9b2fd9f1c7f17413223dc3c26aeee4_api;', ' limit_conn api-other-byip 30;', ' limit_conn api-other-total 150;', ' }', ' location /path {', ' proxy_pass http://__var_af9b2fd9f1c7f17413223dc3c26aeee4_api;', ' limit_conn api-path-byip 10;', ' limit_conn api-path-total 100;', ' }', ], asString(c.locations()).split('\n'))
def testServiceConfig(self): c = ServiceConfig(type='api', minVersion="4.2", untilVersion="5.0") consume(c.updateConfig(**CONFIG_SERVICES())) self.assertEquals(['api.front.example.org', 'alias1', 'alias2'], asList(c.servernames())) self.assertEquals('', asString(c.zones())) self.assertEquals(' location / {\n proxy_pass http://__var_af9b2fd9f1c7f17413223dc3c26aeee4_api;\n }', asString(c.locations())) self.assertEquals(' listen 0.0.0.0:80;\n', asString(c.listenLines()))
def testLoggedPathsNewStyle(self): log = CallTrace('log') def handleRequest(**kwargs): yield okPlainText yield 'result' index = CallTrace('index', methods={'handleRequest':handleRequest}) observable = be((Observable(), (LogCollector(), (QueryLogWriter(log=log, scopeNames=('global', 'yesPath')),), (LogCollectorScope('global'), (HandleRequestLog(), (PathFilter('/yes'), (LogCollectorScope('yesPath'), (index,), ) ), (PathFilter('/no'), (index,), ) ) ) ) )) result = asString(observable.all.handleRequest(Client=('11.22.33.44', 1234), path='/yes')) self.assertEquals(okPlainText+'result', result) result = asString(observable.all.handleRequest(Client=('22.33.44.55', 2345), path='/no')) self.assertEquals(okPlainText+'result', result) result = asString(observable.all.handleRequest(Client=('33.44.55.66', 3456), path='/yes')) self.assertEquals(okPlainText+'result', result) self.assertEquals(['log', 'log'], log.calledMethodNames()) self.assertEquals(['/yes', '/yes'], [m.kwargs['path'] for m in log.calledMethods])
def testUpdateUser(self): action = UserActions(dataDir=self.tempdir) dna = be( (Observable(), (action, ), )) users = action.listUsers() users.append(User(username="******")) action.saveUsers(users) self.assertEqual(2, len(action.listUsers())) self.assertEqual("", action.getUser("johan").organization) response = asString(dna.call.handleRequest( Method="POST", path="/user.action/update", Body=urlencode(dict( redirectUri="/go_here_now", username="******", organization="Seecr")))) self.assertEqual(2, len(action.listUsers())) self.assertEqual("Seecr", action.getUser("johan").organization) self.assertTrue("Location: /go_here_now?identifier=johan" in response, response) response = asString(dna.call.handleRequest( Method="POST", path="/user.action/update", Body=urlencode(dict( redirectUri="/go_here_now", username="******", organization="")))) self.assertEqual("", action.getUser("johan").organization)
def testShowUserList(self): pf = PasswordFile(join(self.tempdir, 'passwd')) self.form.addObserver(pf) pf.addUser('one', 'password') pf.addUser('two', 'password') pf.addUser('three', 'password') def enrichUser(user): user.title = lambda: user.name.title() o = CallTrace(onlySpecifiedMethods=True, methods=dict(enrichUser=enrichUser)) self.form.addObserver(o) session = {'user': self.form.loginAsUser('two')} session['user'].canEdit = lambda username=None: username not in ['two', 'admin'] result = asString(self.form.userList(session=session, path='/show/login')) self.assertEqualsWS("""<div id="login-user-list"> <script type="text/javascript"> function deleteUser(username) { if (confirm("Are you sure?")) { document.removeUser.username.value = username; document.removeUser.submit(); } } </script> <form name="removeUser" method="POST" action="/action/remove"> <input type="hidden" name="formUrl" value="/show/login"/> <input type="hidden" name="username"/> </form> <ul> <li>Admin</li> <li>One <a href="javascript:deleteUser('one');">delete</a></li> <li>Three <a href="javascript:deleteUser('three');">delete</a></li> <li>Two</li> </ul> </div>""", result) result = asString(self.form.userList(session=session, path='/show/login', userLink='/user')) self.assertEqualsWS("""<div id="login-user-list"> <script type="text/javascript"> function deleteUser(username) { if (confirm("Are you sure?")) { document.removeUser.username.value = username; document.removeUser.submit(); } } </script> <form name="removeUser" method="POST" action="/action/remove"> <input type="hidden" name="formUrl" value="/show/login"/> <input type="hidden" name="username"/> </form> <ul> <li><a href="/user?user=admin">Admin</a></li> <li><a href="/user?user=one">One</a> <a href="javascript:deleteUser('one');">delete</a></li> <li><a href="/user?user=three">Three</a> <a href="javascript:deleteUser('three');">delete</a></li> <li><a href="/user?user=two">Two</a></li> </ul> </div>""", result)
def testTransparentForAll(self): def someMessage(*args, **kwargs): yield 'text' self.observer.methods['someMessage'] = someMessage result = asString(self.dna.all.someMessage('arg', kwarg='kwarg')) self.assertEquals('text', result) result = asString(self.dna.all.someMessage('arg', kwarg='kwarg')) self.assertEquals('text', result) self.assertEquals(['someMessage', 'someMessage'], self.observer.calledMethodNames())
def testDebugFlagIsRememberedWithCookie(self): consume(self.flagCheck.updateConfig(this_service={'readable': True, 'state':{'readable':False}})) header, body = asString(self.server.all.handleRequest(ignored='ignored', arguments=dict(debug=['True']), Headers={}, Client=('host', 1234))).split('\r\n\r\n') self.assertEquals('RESULT', body) headers = parseHeaders(header) self.assertTrue('Set-Cookie' in headers,headers) self.assertTrue('Expires=' in headers['Set-Cookie']) header, body = asString(self.server.all.handleRequest(ignored='ignored', arguments={}, Headers={'Cookie': ';'.join([headers['Set-Cookie'], 'other=cookie'])}, Client=('host', 1234))).split('\r\n\r\n') self.assertEquals('RESULT', body) self.assertEquals(['handleRequest', 'handleRequest'], self.observer.calledMethodNames())
def testBroadcastAddUserToAllObservers(self): values = [] dna = be( (Observable(), (BasicHtmlLoginForm(action="/action", loginPath="/"), (CallTrace(methods={'addUser': lambda *args, **kwargs: values.append(("1st", args, kwargs))}),), (CallTrace(methods={'addUser': lambda *args, **kwargs: values.append(("2nd", args, kwargs))}),), (CallTrace(methods={'addUser': lambda *args, **kwargs: values.append(("3rd", args, kwargs))}),), ) ) ) asString(dna.all.handleNewUser(session={'user': BasicHtmlLoginForm.User('admin')}, Body=urlencode(dict(password="******", retypedPassword="******", username='******')))) self.assertEquals(3, len(values))
def testSetInfo(self): result = asString(self.top.all.handleRequest(path='/info/json/set', arguments=dict(set=['set1']))) header, body = result.split('\r\n\r\n') lastStamp = self.jazz.getLastStampId(setSpec='set1', prefix=None) self.assertTrue(lastStamp != None) self.assertEquals(dict(setSpec='set1', name='set1', nrOfRecords=dict(total=3, deletes=1), lastStamp=lastStamp), loads(body)) result = asString(self.top.all.handleRequest(path='/info/json/set', arguments=dict(set=['set2']))) header, body = result.split('\r\n\r\n') set2LastStamp = self.jazz.getLastStampId(setSpec='set2', prefix=None) self.assertTrue(lastStamp == set2LastStamp) self.assertEquals(dict(setSpec='set2', name='set name 2', nrOfRecords=dict(total=1, deletes=1), lastStamp=set2LastStamp), loads(body))
def testListMetadataFormats(self): self.init() response = self.listMetadataFormats.listMetadataFormats(arguments=dict( verb=['ListMetadataFormats'], ), **self.httpkwargs) _, body = asString(response).split("\r\n\r\n") self.assertEquals(['oai_dc', 'rdf'], xpath(XML(body), '/oai:OAI-PMH/oai:ListMetadataFormats/oai:metadataFormat/oai:metadataPrefix/text()')) response = self.listMetadataFormats.listMetadataFormats(arguments=dict( verb=['ListMetadataFormats'], identifier=['id0'], ), **self.httpkwargs) _, body = asString(response).split("\r\n\r\n") self.assertEquals(['oai_dc'], xpath(XML(body), '/oai:OAI-PMH/oai:ListMetadataFormats/oai:metadataFormat/oai:metadataPrefix/text()'))
def testFirstOneWins(self): with open(join(self.directory, 'someFile'), 'w') as f: f.write("Some Contents") with open(join(self.directory2, 'someFile'), 'w') as f: f.write("Different Contents") fileServer = FileServer(documentRoot=[self.directory, self.directory2]) response = asString(fileServer.handleRequest(port=80, Client=('localhost', 9000), path="/someFile", Method="GET", Headers={})) self.assertTrue("Some Contents" in response) self.assertFalse("Different Contents" in response) fileServer = FileServer(documentRoot=[self.directory2, self.directory]) response = asString(fileServer.handleRequest(port=80, Client=('localhost', 9000), path="/someFile", Method="GET", Headers={})) self.assertTrue("Different Contents" in response) self.assertFalse("Some Contents" in response)
def testGroupsUserFormAdminSelf(self): kwargs = { 'path': '/path/to/form', 'arguments': {'key': ['value']}, } self.assertEqualsWS("""<div id="usergroups-groups-user-form"> <form name="groups" method="POST" action="/action/updateGroupsForUser"> <input type="hidden" name="username" value="bob"/> <input type="hidden" name="formUrl" value="/path/to/form?key=value"/> <ul> <li><label><input type="checkbox" name="groupname" value="admin" checked="checked" disabled="disabled"/>admin</label></li> <li><label><input type="checkbox" name="groupname" value="management" />management</label></li> <li><label><input type="checkbox" name="groupname" value="special" />special</label></li> <li><label><input type="checkbox" name="groupname" value="users" checked="checked" />users</label></li> </ul> <input type="submit" value="Aanpassen"/> </form> </div>""", asString(self.userGroups.groupsUserForm(user=self.adminUser, **kwargs))) self.assertEquals([ dict(checked=True, description='', disabled=True, groupname='admin'), dict(checked=False, description='', disabled=False, groupname='management'), dict(checked=False, description='', disabled=False, groupname='special'), dict(checked=True, description='', disabled=False, groupname='users'), ], self.userGroups._groupsForForm(user=self.adminUser, forUsername=self.adminUser.name)) self.assertTrue(self.userGroups.canEditGroups(user=self.adminUser, forUsername=self.adminUser.name))
def testInsertHeaderNone(self): def handleRequest(*args, **kwargs): yield "HTTP/1.0 200 OK\r\n" yield "Header: value\r\n\r\n" yield '<ht' yield 'ml/>' self.assertEqual('HTTP/1.0 200 OK\r\nHeader: value\r\n\r\n<html/>', asString(utils.insertHeader(handleRequest(), None)))
def testGroupsUserFormUser(self): kwargs = { 'path': '/path/to/form', 'arguments': {'key': ['value']}, } self.assertEquals('', asString(self.userGroups.groupsUserForm(user=self.normalUser, **kwargs))) self.assertFalse(self.userGroups.canEditGroups(user=self.normalUser, forUsername=self.normalUser.name))
def testGetMultipleDataWithOtherBatchSize(self): self._addRecords(['id%s' % i for i in xrange(99)]) self.oaiList = OaiList(batchSize=10, dataBatchSize=2, repository=OaiRepository()) self.oaiList.addObserver(self.observer) def getMultipleData(identifiers, **kwargs): return [(id, '<data id="%s"/>' % id) for id in identifiers] self.observer.methods['getMultipleData'] = getMultipleData def oaiRecord(record, metadataPrefix, fetchedRecords=None): yield fetchedRecords[record.identifier] self.observer.methods['oaiRecord'] = oaiRecord body = asString(self.oaiList.listRecords(arguments=dict(verb=['ListRecords'], metadataPrefix=['oai_dc']), **self.httpkwargs)).split(CRLF*2,1)[-1] oai = parse(StringIO(body)) self.assertEquals(['id0', 'id1', 'id2', 'id3', 'id4', 'id5', 'id6', 'id7', 'id8', 'id9'], xpath(oai, '//oai:ListRecords/oai:data/@id')) self.assertEquals(['getAllPrefixes', 'oaiSelect', 'oaiWatermark', 'getMultipleData', 'oaiRecord', 'oaiRecord', 'getMultipleData', 'oaiRecord', 'oaiRecord', 'getMultipleData', 'oaiRecord', 'oaiRecord', 'getMultipleData', 'oaiRecord', 'oaiRecord', 'getMultipleData', 'oaiRecord', 'oaiRecord' ], self.observer.calledMethodNames())
def testChangePasswordMismatch(self): Body = urlencode(dict(username='******', oldPassword='******', newPassword="******", retypedPassword="******", formUrl='/show/changepasswordform')) session = {'user': BasicHtmlLoginForm.User('user')} result = asString(self.form.handleRequest(path='/login/changepassword', Client=('127.0.0.1', 3451), Method='POST', Body=Body, session=session)) self.assertEquals({'username':'******', 'errorMessage': 'New passwords do not match'}, session['BasicHtmlLoginForm.formValues']) self.assertEqualsWS("""HTTP/1.0 302 Found\r\nLocation: /show/changepasswordform\r\n\r\n""", result)
def testShowChangePasswordFormErrorWithoutUser(self): session = {} result = asString(self.form.changePasswordForm(session=session, path='/show/changepasswordform', arguments={})) self.assertEqualsWS("""<div id="login-change-password-form"> <p class="error">Please login to change password.</p> </div>""", result)
def testCreateSession(self): called = [] class MyObserver(Observable): def handleRequest(self, *args, **kwargs): session = self.ctx.session called.append({'args':args, 'kwargs':kwargs, 'session': session}) yield utils.okHtml yield '<ht' yield 'ml/>' self.handler.addObserver(MyObserver()) result = asString(self.handler.handleRequest(RequestURI='/path', Client=('127.0.0.1', 12345), Headers={'a':'b'})) self.assertEquals(1, len(called)) self.assertEqual({}, called[0]['session']) session = called[0]['kwargs']['session'] self.assertEqual({}, session) self.assertEquals({'a':'b'}, called[0]['kwargs']['Headers']) self.assertTrue(('127.0.0.1', 12345), called[0]['kwargs']['Client']) header, body = result.split(utils.CRLF*2,1) self.assertEquals('<html/>', body) self.assertTrue('Set-Cookie' in header, header) headerParts = header.split(utils.CRLF) self.assertEquals("HTTP/1.0 200 OK", headerParts[0]) sessionCookie = [p for p in headerParts[1:] if 'Set-Cookie' in p][0] self.assertTrue(sessionCookie.startswith('Set-Cookie: session'))
def testOneResult(self): observer = CallTrace( returnValues={ 'getRecord': '<item><title>Test Title</title><link>Test Identifier</link><description>Test Description</description></item>', }, ignoredAttributes=['unknown', 'extraResponseData', 'echoedExtraRequestData']) def executeQuery(**kwargs): raise StopIteration(Response(total=1, hits=[Hit(1)])) yield observer.methods['executeQuery'] = executeQuery rss = Rss( title = 'Test title', description = 'Test description', link = 'http://www.example.org', sortKeys = 'date,,1', maximumRecords = '15', ) rss.addObserver(observer) result = asString(rss.handleRequest(RequestURI='/?query=aQuery')) self.assertEqualsWS(RSS % """<item> <title>Test Title</title> <link>Test Identifier</link> <description>Test Description</description> </item>""", result)
def getMultipleData(self, name, identifiers, **kwargs): identifiers = list(identifiers) erfgeoEnrichments = self.call.getMultipleData(identifiers=identifiers, name='erfGeoEnrichment', **kwargs) if name == ERFGEO_ENRICHMENT_PROFILE.prefix: return erfgeoEnrichments elif name != COMBINED_METADATA_PREFIX: raise ValueError('unsupported name %s' % name) summaryIdentifiers = [ SUMMARY_PROFILE.uriFor(ERFGEO_ENRICHMENT_PROFILE.targetUriFrom(identifier)) for identifier in identifiers ] summaries = dict(self.call.getMultipleData(identifiers=summaryIdentifiers, name=SUMMARY_PROFILE.prefix, **kwargs)) return ( ( erfGeoEnrichmentUri, asString( self._combine( erfgeoEnrichmentData, summaries[SUMMARY_PROFILE.uriFor(ERFGEO_ENRICHMENT_PROFILE.targetUriFrom(erfGeoEnrichmentUri))] ) ) ) for erfGeoEnrichmentUri, erfgeoEnrichmentData in erfgeoEnrichments )
def testQuery(self): def executeQuery(**kwargs): raise StopIteration(Response(total=42)) yield index = CallTrace('index', emptyGeneratorMethods=['echoedExtraRequestData', 'extraResponseData'], methods=dict(executeQuery=executeQuery)) observable = be((Observable(), (LogCollector(), (self.handleRequestLog, (SruParser(), (SruHandler(enableCollectLog=True), (index,) ) ) ), (self.queryLogWriter,), ) )) result = asString(observable.all.handleRequest( Method='GET', Client=('127.0.0.1', 1234), arguments={ 'version': ['1.2'], 'operation': ['searchRetrieve'], 'query': ['query'], 'maximumRecords': ['0'], }, path='/path/sru', otherKwarg='value')) self.assertTrue('<srw:numberOfRecords>42</srw:numberOfRecords>' in result, result) self.assertTrue(isfile(join(self.tempdir, '2009-11-02-query.log'))) self.assertEquals('2009-11-02T11:25:37Z 127.0.0.1 0.7K 1.000s 42hits /path/sru maximumRecords=0&operation=searchRetrieve&query=query&recordPacking=xml&recordSchema=dc&startRecord=1&version=1.2\n', open(join(self.tempdir, '2009-11-02-query.log')).read())
def testFileNotFound2(self): with open(join(self.tempdir, 'a.sf'), 'w') as f: f.write('def main(pipe, **kwargs):\n yield pipe') d = DynamicHtml([self.tempdir], reactor=CallTrace('Reactor')) result = asString(d.handleRequest(scheme='http', netloc='host.nl', path='/a/path', query='?query=something', fragments='#fragments', arguments={'query': 'something'})) self.assertTrue(result.startswith('HTTP/1.0 404 Not Found'), result) self.assertTrue('File "path" does not exist.' in result, result)
def testAutocompleteCSS(self): result = asString(self.auto.handleRequest( path='/path/autocomplete.css', arguments={})) header,body = result.split('\r\n'*2) self.assertTrue('jqac-' in body, body[:300]) self.assertTrue('Content-Type: text/css' in header, header)
def testCreateUser(self): observer = CallTrace() action = UserActions(dataDir=self.tempdir) session = {} dna = be( (Observable(), (action, (observer, ) ), )) self.assertEqual(1, len(action.listUsers())) response = asString(dna.call.handleRequest( Method="POST", path="/user.action/create", session=session, Body=urlencode(dict( redirectUri="/go_here_now", username="******", domain="domein", password1="password", password2="password")))) self.assertEqual(2, len(action.listUsers())) self.assertTrue("Location: /go_here_now?identifier=johan" in response, response) self.assertEqual(1, len(observer.calledMethods)) self.assertEqual({}, session)
def testOpenSearchWithoutHtmlAndPort80(self): queryTemplate = '/sru?version=1.1&operation=searchRetrieve&query={searchTerms}' self.auto = be((Autocomplete( host='localhost', port=80, path='/some/path', templateQuery=queryTemplate, shortname="Web Search", description="Use this web search to search something", defaultLimit=50, defaultField='lom', ), (self.observer,), )) result = asString(self.auto.handleRequest( path='/path/opensearchdescription.xml', arguments={})) header,body = result.split('\r\n'*2) self.assertTrue("Content-Type: text/xml" in header, header) self.assertEqualsWS("""<?xml version="1.0" encoding="UTF-8"?> <OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/"> <ShortName>Web Search</ShortName> <Description>Use this web search to search something</Description> <Url type="text/xml" method="get" template="http://localhost/sru?version=1.1&operation=searchRetrieve&query={searchTerms}"/> <Url type="application/x-suggestions+json" template="http://localhost/some/path?prefix={searchTerms}"/> </OpenSearchDescription>""", body)
def testMinimumLength(self): self._setUpAuto(prefixBasedSearchKwargs=dict(minimumLength=5)) header, body = asString(self.auto.handleRequest(path='/path', arguments={'prefix':['test']})).split('\r\n'*2) self.assertTrue("Content-Type: application/x-suggestions+json" in header, header) self.assertEquals("""["test", []]""", body) self.assertEquals([], [m.name for m in self.observer.calledMethods])
def testPrefixInfo(self): result = asString(self.top.all.handleRequest(path='/info/json/prefix', arguments=dict(prefix=['prefix1']))) header, body = result.split('\r\n\r\n') lastStamp = self.jazz.getLastStampId(prefix='prefix1') self.assertTrue(lastStamp != None) self.assertEquals(dict(prefix='prefix1', schema='', namespace='', nrOfRecords=dict(total=3, deletes=1), lastStamp=lastStamp), loads(body)) result = asString(self.top.all.handleRequest(path='/info/json/prefix', arguments=dict(prefix=['oai']))) header, body = result.split('\r\n\r\n') oaiLastStamp = self.jazz.getLastStampId(prefix='oai') self.assertTrue(oaiLastStamp != None) self.assertTrue(lastStamp != oaiLastStamp) self.assertEquals(dict(prefix='oai', schema='oai-schema', namespace='oai-namespace', nrOfRecords=dict(total=1, deletes=0), lastStamp=oaiLastStamp), loads(body))
def testProvenance(self): observable = Observable() provenance = OaiProvenance( nsMap = {'oai_dc': "http://www.openarchives.org/OAI/2.0/"}, baseURL = ('meta', '/meta/repository/baseurl/text()'), harvestDate = ('meta', '/meta/repository/harvestDate/text()'), metadataNamespace = ('meta', '/meta/repository/metadataNamespace/text()'), identifier = ('header','/oai_dc:header/oai_dc:identifier/text()'), datestamp = ('header', '/oai_dc:header/oai_dc:datestamp/text()') ) observable.addObserver(provenance) observer = MockStorage() provenance.addObserver(observer) result = asString(observable.any.provenance("recordId")) self.assertEqualsWS("""<provenance xmlns="http://www.openarchives.org/OAI/2.0/provenance" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/provenance http://www.openarchives.org/OAI/2.0/provenance.xsd"> <originDescription harvestDate="HARVESTDATE" altered="true"> <baseURL>BASEURL</baseURL> <identifier>recordId</identifier> <datestamp>DATESTAMP</datestamp> <metadataNamespace>METADATANAMESPACE</metadataNamespace> </originDescription> </provenance>""", result)
def testFilters(self): self.response = dumps([ {"suggestion": "harry", "type": "uri:track", "creator": None, "score": 1.0}, ]) header, body = asString(self.sic.handleRequest(path='/suggestion', arguments={"value": ["ha"], "concepts": "True", "minScore": ["0"], "filter": ["type=uri:track"]})).split(CRLF*2) self.assertEqual('["ha", ["harry"], [["harry", "uri:track", null]]]', body) self.assertEqual(1, len(self.post)) self.assertEqual({'data': '{"keySetName": null, "trigram": false, "limit": null, "filters": ["type=uri:track"], "value": "ha"}', 'path': '/suggest'}, self.post[0])
def testGroupsUserFormManagementAdmin(self): kwargs = { 'path': '/path/to/form', 'arguments': {'key': ['value']}, } self.assertEquals('', asString(self.userGroups.groupsUserForm(user=self.managementUser, forUsername=self.adminUser.name, **kwargs))) self.assertFalse(self.userGroups.canEditGroups(user=self.managementUser, forUsername=self.adminUser.name)) self.assertEquals([], self.userGroups._groupsForForm(user=self.managementUser, forUsername=self.adminUser.name))
def testLoginWithPOSTsucceedsRedirectsToOriginalPath(self): observer = CallTrace(onlySpecifiedMethods=True, returnValues={'hasUser': True}) self.form.addObserver(observer) observer.returnValues['validateUser'] = True Body = urlencode(dict(username='******', password='******')) session = {ORIGINAL_PATH:'/please/go/here'} result = asString(self.form.handleRequest(path='/login', Client=('127.0.0.1', 3451), Method='POST', Body=Body, session=session)) self.assertEquals('user', session['user'].name) header, body = result.split(CRLF*2) self.assertTrue('302' in header) self.assertTrue('Location: /please/go/here' in header) user = session['user'] self.assertFalse(user.isAdmin()) self.assertEquals(['validateUser', 'hasUser'], [m.name for m in observer.calledMethods]) self.assertEquals({'username': '******', 'password':'******'}, observer.calledMethods[0].kwargs)
def testTransparentWontLogIfNothingPresentAll(self): observer = createObserver() observable = be((Observable(), (LogCollector(), (observer,) ) )) result = asString(observable.all.allMessage('arg', kwarg='kwarg')) self.assertEquals('allresult', result) result = retval(observable.any.anyMessage('arg', kwarg='kwarg')) self.assertEquals('anyresult', result) observable.do.doMessage('arg', kwarg='kwarg') result = observable.call.callMessage('arg', kwarg='kwarg') self.assertEquals('callresult', result) self.assertEquals(['allMessage', 'anyMessage', 'doMessage', 'callMessage'], observer.calledMethodNames()) for m in observer.calledMethods: self.assertEquals(('arg',), m.args) self.assertEquals(dict(kwarg='kwarg'), m.kwargs)
def testHandleUpdateGroupsForManagementUser(self): Body = urlencode( { 'username': [self.managementUser.name], 'groupname': ['special'], 'formUrl': ['/useraccount'] }, doseq=True) session = {'user': self.managementUser} result = asString( self.userGroups.handleRequest(Method='POST', path='/action/updateGroupsForUser', session=session, Body=Body)) self.assertEquals( 'HTTP/1.0 302 Found\r\nLocation: /useraccount\r\n\r\n', result) self.assertEquals(set(['management', 'special']), self.managementUser.groups())
def testNewUserWithPOSTFails(self): pf = PasswordFile(join(self.tempdir, 'passwd')) self.form.addObserver(pf) pf.addUser('existing', 'password') pf.addUser('newuser', 'oldpassword') Body = urlencode(dict(username='******', password='******', retypedPassword='******', formUrl='/page/newUser', returnUrl='/return')) session = {'user': BasicHtmlLoginForm.User('admin')} result = asString(self.form.handleRequest(path='/action/newUser', Client=('127.0.0.1', 3451), Method='POST', Body=Body, session=session)) header, body = result.split(CRLF*2) self.assertTrue('302' in header) self.assertTrue('Location: /page/newUser' in header) self.assertEquals(set(['existing', 'newuser', 'admin']), set(pf.listUsernames())) self.assertTrue(pf.validateUser('newuser', 'oldpassword')) self.assertFalse(pf.validateUser('newuser', 'newpassword')) self.assertEquals({'errorMessage':'User already exists.', 'username':'******'}, session['BasicHtmlLoginForm.newUserFormValues'])
def testLoginFormDutch(self): result = asString(self.form.loginForm(session={}, path='/page/login2', lang='nl')) self.assertEqualsWS("""<div id="login-form"> <form method="POST" name="login" action="/action"> <input type="hidden" name="formUrl" value="/page/login2"/> <dl> <dt>Gebruikersnaam</dt> <dd><input type="text" name="username" value=""/></dd> <dt>Wachtwoord</dt> <dd><input type="password" name="password"/></dd> <dd class="submit"><input type="submit" id="submitLogin" value="Inloggen"/></dd> </dl> </form> <script type="text/javascript"> document.getElementById("submitLogin").focus() </script> </div>""", result)
def testLoginWithPOSTsucceeds(self): observer = CallTrace(onlySpecifiedMethods=True, returnValues={'hasUser': True}) self.form = BasicHtmlLoginForm(action='/action', loginPath='/login', home='/home') self.form.addObserver(observer) observer.returnValues['validateUser'] = True Body = urlencode(dict(username='******', password='******')) session = {} result = asString(self.form.handleRequest(path='/login', Client=('127.0.0.1', 3451), Method='POST', Body=Body, session=session)) self.assertEquals('admin', session['user'].name) self.assertEquals(True, session['user'].isAdmin()) header, body = result.split(CRLF*2) self.assertTrue('302' in header) self.assertTrue('Location: /home' in header) self.assertEquals(['validateUser', 'hasUser'], [m.name for m in observer.calledMethods]) self.assertEquals({'username': '******', 'password':'******'}, observer.calledMethods[0].kwargs)
def testError(self): observer = CallTrace( ignoredAttributes=['unknown', 'extraResponseData', 'echoedExtraRequestData']) def executeQuery(**kwargs): return Response(total=0, hits=[]) yield observer.methods['executeQuery'] = executeQuery rss = Rss( title = 'Test title', description = 'Test description', link = 'http://www.example.org', ) rss.addObserver(observer) result = asString(rss.handleRequest(RequestURI='/?query=aQuery%29')) #%29 == ')' xml = parse(StringIO(result[result.index("<rss"):])) self.assertEqual(['Test title'], xml.xpath('/rss/channel/title/text()')) self.assertEqual(['Test description'], xml.xpath('/rss/channel/description/text()'))
def testAlmostNoData(self): # No data due to HandleRequestLog is not used. requestHandler = CallTrace('handler', ignoredAttributes=['writeLog', 'do_unknown']) def handleRequest(**kwarg): collectLog(dict(key='value')) yield okXml yield '<sru></sru>' requestHandler.methods['handleRequest'] = handleRequest observable = be((Observable(), (LogCollector(), (requestHandler,), (self.queryLogWriter,), ) )) result = asString(observable.all.handleRequest(Method='GET', Client=('127.0.0.1', 1234), arguments={}, path='/path/sru', otherKwarg='value')) self.assertEqual(okXml+'<sru></sru>', result) self.assertEqual(0, len(listdir(self.tempdir)))
def testForm(self): result = asString( self.form.userInfoForm(self.normalUser, forUsername=self.normalUser.name, path='/path/to/form', arguments={'key': ['value']})) self.assertEqualsWS( '''<div id="userinfoform-change-user-info"> <form name="userinfo" method="POST" action="/action/updateInfoForUser"> <input type="hidden" name="username" value="normal"/> <input type="hidden" name="formUrl" value="/path/to/form?key=value"/> <dl> <dt>Volledige naam</dt> <dd><input type="text" name="fullname" value="Full Username"/></dd> <dt></dt> <dd><input type="submit" value="Aanpassen"/></dd> </dl> </form> </div>''', result)
def testNoResults(self): observer = CallTrace( ignoredAttributes=['unknown', 'extraResponseData', 'echoedExtraRequestData']) def executeQuery(**kwargs): raise StopIteration(Response(total=0, hits=[])) yield observer.methods['executeQuery'] = executeQuery rss = Rss( title = 'Test title', description = 'Test description', link = 'http://www.example.org', sortKeys = 'date,,1', maximumRecords = '15', ) rss.addObserver(observer) result = asString(rss.handleRequest(RequestURI='/?query=aQuery')) self.assertEqualsWS(RSS % '', result)
def testChangePassword_withEmptySession(self): # A.k.a. not logged-in. pf = PasswordFile(join(self.tempdir, 'passwd')) self.form.addObserver(pf) pf.addUser('existing', 'password') Body = urlencode(dict(username='******', oldPassword='******', newPassword='******', retypedPassword='******', formUrl='/page/newUser', returnUrl='/return')) session = {} result = asString(self.form.handleRequest(path='/action/changepassword', Client=('127.0.0.1', 3451), Method='POST', Body=Body, session=session)) header, body = result.split(CRLF*2) self.assertTrue('302' in header) self.assertTrue('Location: /page/newUser' in header) self.assertEquals(set(['existing', 'admin']), set(pf.listUsernames())) self.assertTrue(pf.validateUser('existing', 'password')) self.assertEquals( {'errorMessage': 'Login required for "change password".', 'username': '******'}, session['BasicHtmlLoginForm.formValues'])
def testHandleRequestWithDebug(self): self.response = dumps([ {"suggestion": "hallo", "type": "uri:book", "creator": 'by:me', "score": 0.80111}, {"suggestion": "harry", "type": "uri:book", "creator": "rowling", "score": 0.80111} ]) header, body = asString(self.sic.handleRequest(path='/suggestion', arguments={"value": ["ha"], "x-debug": ["true"], "minScore": ["0"]})).split(CRLF*2) self.assertEquals("""HTTP/1.0 200 OK\r Content-Type: application/x-suggestions+json\r Access-Control-Allow-Origin: *\r Access-Control-Allow-Headers: X-Requested-With\r Access-Control-Allow-Methods: GET, POST, OPTIONS\r Access-Control-Max-Age: 86400""", header) json = loads(body) self.assertEquals('ha', json['value']) self.assertTrue("time" in json, json) suggestions = [(s[0], dict((k,round(v, 3)) for k,v in s[3].items())) for s in json['suggestions']] self.assertEquals(sorted([ ("hallo", {"distanceScore": 0.653, "score": 0.801, "sortScore": 0.839, "matchScore": 1.0}), ("harry", {"distanceScore": 0.653, "score": 0.801, "sortScore": 0.839, "matchScore": 1.0}), ]), sorted(suggestions))
def testCookie(self): session = {} Headers = dict(Cookie="CID=THIS IS THE REMEMBER ME COOKIE") response = asString( self.dna.all.handleRequest(path='/some_page', Headers=Headers, session=session)) self.assertEqual("RESPONSE", response) self.assertEqual(['/some_page'], self.paths) self.assertTrue('user' in session, session) self.assertEqual(['cookieName', 'validateCookie', 'handleRequest'], self.observer.calledMethodNames()) self.assertEquals( { 'path': '/some_page', 'session': { 'user': '******' }, 'Headers': Headers }, self.observer.calledMethods[-1].kwargs)
def testGroupsUserFormManagementAdmin(self): kwargs = { 'path': '/path/to/form', 'arguments': { 'key': ['value'] }, } self.assertEquals( '', asString( self.userGroups.groupsUserForm(user=self.managementUser, forUsername=self.adminUser.name, **kwargs))) self.assertFalse( self.userGroups.canEditGroups(user=self.managementUser, forUsername=self.adminUser.name)) self.assertEquals([], self.userGroups._groupsForForm( user=self.managementUser, forUsername=self.adminUser.name))
def testSetRememberMeCookie(self): observer = CallTrace( methods={ 'validateUser': lambda username, password: True, 'createCookie': lambda user: dict( cookie='THIS IS THE COOKIE VALUE', header='Set-Cookie: somevalue', ) }, onlySpecifiedMethods=True, returnValues={'hasUser': True}) basicHtmlLoginForm = BasicHtmlLoginForm( action="/action", loginPath="/", home="/index", rememberMeCookie=True) basicHtmlLoginForm._now = lambda: 3600 dna = be( (Observable(), (basicHtmlLoginForm, (observer, ) ) ) ) session = {} header, _ = asString(dna.all.handleRequest( Method="POST", path="/", session=session, Body=urlencode(dict(username="******", password="******", rememberMe="on")) )).split('\r\n\r\n', 1) self.assertTrue('user' in session, session) headers = headerToDict(header) self.assertEquals("/index", headers['Location']) self.assertTrue('Set-Cookie' in headers, headers) self.assertEquals("somevalue", headers['Set-Cookie'])
def testManagementCannotChangeAdminUser(self): self.assertEquals(set(['admin', 'users']), self.adminUser.groups()) self.assertEquals(set(['management']), self.managementUser.groups()) Body = urlencode( { 'username': [self.adminUser.name], 'groupname': ['special', 'users'], 'formUrl': ['/useraccount'] }, doseq=True) session = {'user': self.managementUser} result = asString( self.userGroups.handleRequest(Method='POST', path='/action/updateGroupsForUser', session=session, Body=Body)) self.assertEquals('HTTP/1.0 401 Unauthorized', result.split('\r\n')[0]) self.assertEquals(set(['management']), self.managementUser.groups()) self.assertEquals(set(['admin', 'users']), self.adminUser.groups())
def testLoginFormWithError(self): session = {} session['BasicHtmlLoginForm.formValues']={'username': '******', 'errorMessage': 'Invalid <username> or "password"'} result = asString(self.form.loginForm(session=session, path='/show/login')) self.assertEqualsWS("""<div id="login-form"> <p class="error">Invalid <username> or "password"</p> <form method="POST" name="login" action="/action"> <input type="hidden" name="formUrl" value="/show/login"/> <dl> <dt>Username</dt> <dd><input type="text" name="username" value='<us"er>'/></dd> <dt>Password</dt> <dd><input type="password" name="password"/></dd> <dd class="submit"><input type="submit" id="submitLogin" value="Login"/></dd> </dl> </form> <script type="text/javascript"> document.getElementById("submitLogin").focus() </script> </div>""", result)
def testAdminCanChangeOtherAdmins(self): otherAdminUser = BasicHtmlLoginForm.User('johan') self.groupsFile.enrichUser(otherAdminUser) Body = urlencode( { 'username': [otherAdminUser.name], 'groupname': ['special'], 'formUrl': ['/useraccount'] }, doseq=True) session = {'user': self.adminUser} result = asString( self.userGroups.handleRequest(Method='POST', path='/action/updateGroupsForUser', session=session, Body=Body)) self.assertEquals( 'HTTP/1.0 302 Found\r\nLocation: /useraccount\r\n\r\n', result) self.assertEquals(set(['special']), otherAdminUser.groups())
def testNewUserWithPOSTsucceeds(self): pf = PasswordFile(join(self.tempdir, 'passwd')) self.form.addObserver(pf) observer = CallTrace() self.form.addObserver(observer) pf.addUser('existing', 'password') Body = urlencode(dict(username='******', password='******', retypedPassword='******', formUrl='/page/newUser', returnUrl='/return')) session = {'user': BasicHtmlLoginForm.User('admin')} result = asString(self.form.handleRequest(path='/action/newUser', Client=('127.0.0.1', 3451), Method='POST', Body=Body, session=session)) header, body = result.split(CRLF*2) self.assertTrue('302' in header) self.assertTrue('Location: /return' in header) self.assertEquals(set(['existing', 'newuser', 'admin']), set(pf.listUsernames())) self.assertTrue(pf.validateUser('newuser', 'secret')) self.assertEquals('Added user "newuser"', session['BasicHtmlLoginForm.newUserFormValues']['successMessage']) self.assertEqual(['addUser', 'handleNewUser'], observer.calledMethodNames()) self.assertEqual({'username': '******', 'password': '******'}, observer.calledMethods[0].kwargs) self.assertEqual({'Body': 'username=newuser&formUrl=%2Fpage%2FnewUser&password=secret&returnUrl=%2Freturn&retypedPassword=secret', 'username': '******'}, observer.calledMethods[1].kwargs)
def testGetRecordWithMultiSequentialStorage(self): oaijazz = OaiJazz(self.tempdir + '/jazz') oaijazz.updateMetadataFormat(prefix="oai_dc", schema="", namespace="") storage = MultiSequentialStorage(self.tempdir + "/seq-store") oairecord = OaiRecord() oaigetrecord = be( (OaiGetRecord(repository=OaiRepository()), (oaijazz, ), (oairecord, (RetrieveToGetDataAdapter(), (storage, ))))) oaijazz.addOaiRecord(identifier="id0", metadataPrefixes=['oai_dc']) storage.addData(identifier="id0", name="oai_dc", data=b"data01") response = oaigetrecord.getRecord(arguments=dict( verb=['GetRecord'], metadataPrefix=['oai_dc'], identifier=['id0'], ), **self.httpkwargs) _, body = asString(response).split("\r\n\r\n") self.assertEqual( "data01", xpath(parse(BytesIO(body.encode())), '//oai:metadata')[0].text)
def testRedirectWithPostedRedirectPathButWithoutIdentifier(self): def validate(**kwargs): raise ValueError('oops') registry = ObjectRegistry(self.tempdir, name='name', redirectPath='/redirect', validate=validate) registry.registerKeys(keys=['key1', 'key2'], booleanKeys=['enabled1', 'enabled2']) data = urlencode([('key1', 'value1'), ('enabled1', 'on'), ('redirectPath', '/object?id={}')]) header, _ = asString( registry.handleRequest(Method='POST', path='/objects/add', Body=data, session={})).split(CRLF * 2) redirectLocation = parseHeaders(header + CRLF)['Location'] path, objectid = redirectLocation.split('#') self.assertEquals('/redirect', path) self.assertEqual('', objectid) self.assertEquals({}, registry.listObjects())
def testShowChangePasswordFormForSpecifiedUser(self): session = { 'user': BasicHtmlLoginForm.User('username'), 'BasicHtmlLoginForm.formValues': {'errorMessage': 'BAD BOY'}, } result = asString(self.form.changePasswordForm(session=session, path='/show/changepasswordform', lang="nl", arguments=dict(user=['myuser']), user='******', onlyNewPassword=True)) self.assertEqualsWS("""<div id="login-change-password-form"> <p class="error">BAD BOY</p> <form method="POST" name="changePassword" action="/action/changepassword"> <input type="hidden" name="formUrl" value="/show/changepasswordform?user=myuser"/> <input type="hidden" name="returnUrl" value="/show/changepasswordform"/> <input type="hidden" name="username" value="myuser"/> <dl> <dt>Nieuw wachtwoord</dt> <dd><input type="password" name="newPassword"/></dd> <dt>Herhaal nieuw wachtwoord</dt> <dd><input type="password" name="retypedPassword"/></dd> <dd class="submit"><input type="submit" value="Aanpassen"/></dd> </dl> </form> </div>""", result)
def testNewUserFormEN(self): session = { 'user': BasicHtmlLoginForm.User('username'), 'BasicHtmlLoginForm.newUserFormValues': {'errorMessage': 'BAD BOY'}, } result = asString(self.form.newUserForm(session=session, path='/page/login2', returnUrl='/return')) self.assertEqualsWS("""<div id="login-new-user-form"> <p class="error">BAD BOY</p> <form method="POST" name="newUser" action="/action/newUser"> <input type="hidden" name="formUrl" value="/page/login2"/> <input type="hidden" name="returnUrl" value="/return"/> <dl> <dt>Username</dt> <dd><input type="text" name="username" value=""/></dd> <dt>Password</dt> <dd><input type="password" name="password"/></dd> <dt>Retype password</dt> <dd><input type="password" name="retypedPassword"/></dd> <dd class="submit"><input type="submit" value="Create"/></dd> </dl> </form> </div>""", result)
def testNoKeySendDoesNotChangeOldValue(self): registry = ObjectRegistry(self.tempdir, name='name', redirectPath='/redirect') registry.registerKeys(keys=['key2', 'key1'], booleanKeys=['enabled1', 'enabled2']) object1id = registry.addObject(key1=["object1"], key2=["value2"], enabled1=['on']) self.assertEquals( { 'key1': 'object1', 'key2': 'value2', 'enabled1': True, 'enabled2': False, }, registry.listObjects()[object1id]) data = urlencode([ ('identifier', object1id), ('key1', 'value1'), ('enabled2', 'on'), ]) header, _ = asString( registry.handleRequest(Method='POST', path='/objects/update', Body=data, session={})).split(CRLF * 2) redirectLocation = parseHeaders(header + CRLF)['Location'] path, objectid = redirectLocation.split('#') self.assertEquals(object1id, objectid) self.assertEquals( { 'key1': 'value1', 'key2': 'value2', 'enabled1': False, 'enabled2': True, }, registry.listObjects()[object1id])
def testServeFileWithCorrectContentType(self): for extension, expectedType in [('.js', 'application/javascript'), ('.xhtml', 'application/xhtml+xml'), ('.png', 'image/png'), ('.css', 'text/css')]: filename = 'someFile' + extension f = open(join(self.directory, filename), 'w') f.write("Some Contents") f.close() fileServer = FileServer(self.directory) response = asString( fileServer.handleRequest(port=80, Client=('localhost', 9000), path="/%s" % filename, Method="GET", Headers={})) headersList = response.split('\r\n\r\n', 1)[0].split('\r\n') self.assertTrue("HTTP/1.0 200 OK" in response) self.assertTrue("Some Contents" in response) self.assertTrue('Content-Type: %s' % expectedType in headersList, headersList)
def testLoginForWithRememberMe(self): form = BasicHtmlLoginForm( action='/action', loginPath='/login', home='/home', rememberMeCookie=True) result = asString(form.loginForm(session={}, path='/page/login2')) self.assertEqualsWS("""<div id="login-form"> <form method="POST" name="login" action="/action"> <input type="hidden" name="formUrl" value="/page/login2"/> <dl> <dt>Username</dt> <dd><input type="text" name="username" value=""/></dd> <dt>Password</dt> <dd><input type="password" name="password"/></dd> <dt> </dt><dd class="rememberMe"><input type="checkbox" name="rememberMe" id="rememberMe" /><label for="rememberMe">Remember me</label></dd> <dd class="submit"><input type="submit" id="submitLogin" value="Login"/></dd> </dl> </form> <script type="text/javascript"> document.getElementById("submitLogin").focus() </script> </div>""", result)
def testCacheControlStuff(self): with open(join(self.directory, 'someFile'), 'w') as f: f.write("Some Contents") fileServer = FileServer(self.directory) response = asString( fileServer.handleRequest(port=80, Client=('localhost', 9000), path="/someFile", Method="GET", Headers={})) headers, body = response.split("\r\n\r\n") self.assertTrue("Date: " in headers) self.assertTrue("Last-Modified: " in headers) self.assertTrue("Expires: " in headers) headerValues = dict( tuple(a.strip() for a in line.split(':', 1)) for line in headers.split('\r\n') if ':' in line) date = timegm(parsedate(headerValues['Date'])) expires = timegm(parsedate(headerValues['Expires'])) self.assertTrue(1 > time() - date > 0, time() - date) self.assertTrue(61 * 60 > expires - date > 59 * 60, expires - date)
def testShowChangePasswordFormEn(self): session = { 'user': BasicHtmlLoginForm.User('username'), 'BasicHtmlLoginForm.formValues': {'errorMessage': 'BAD BOY'}, } result = asString(self.form.changePasswordForm(session=session, path='/show/changepasswordform', arguments={})) self.assertEqualsWS("""<div id="login-change-password-form"> <p class="error">BAD BOY</p> <form method="POST" name="changePassword" action="/action/changepassword"> <input type="hidden" name="formUrl" value="/show/changepasswordform"/> <input type="hidden" name="returnUrl" value="/show/changepasswordform"/> <input type="hidden" name="username" value="username"/> <dl> <dt>Old password</dt> <dd><input type="password" name="oldPassword"/></dd> <dt>New password</dt> <dd><input type="password" name="newPassword"/></dd> <dt>Retype new password</dt> <dd><input type="password" name="retypedPassword"/></dd> <dd class="submit"><input type="submit" value="Change"/></dd> </dl> </form> </div>""", result)
def testHandleRequestWithEmptyValue(self): self.response = dumps([]) header, body = asString(self.sic.handleRequest(path='/suggestion', arguments={})).split(CRLF*2) self.assertEquals('[]', body)
def doRequest(dataRetrieve, path=None, **arguments): result = asString( dataRetrieve.handleRequest(path=path, arguments=arguments)) header, body = result.split(CRLF * 2, 1) return header, body