[Checkins] SVN: grokapps/gbepastebin/ rest apis must be hypertext driven
Michael Haubenwallner
michael at d2m.at
Sun Oct 26 04:27:48 EDT 2008
Log message for revision 92578:
rest apis must be hypertext driven
Changed:
A grokapps/gbepastebin/CHANGES.txt
U grokapps/gbepastebin/setup.py
U grokapps/gbepastebin/src/gbepastebin/app.py
U grokapps/gbepastebin/src/gbepastebin/app.txt
U grokapps/gbepastebin/src/gbepastebin/rest.py
A grokapps/gbepastebin/src/gbepastebin/rest.txt
-=-
Added: grokapps/gbepastebin/CHANGES.txt
===================================================================
--- grokapps/gbepastebin/CHANGES.txt (rev 0)
+++ grokapps/gbepastebin/CHANGES.txt 2008-10-26 08:27:46 UTC (rev 92578)
@@ -0,0 +1,9 @@
+CHANGES
+-------
+
+0.1.1 split tests (app.txt, rest.txt)
+ switch to absolute urls for pasteids (rest)
+ see: http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven
+ remove the delete_pastes method from the rest module
+
+0.1 initial release
\ No newline at end of file
Modified: grokapps/gbepastebin/setup.py
===================================================================
--- grokapps/gbepastebin/setup.py 2008-10-26 05:59:00 UTC (rev 92577)
+++ grokapps/gbepastebin/setup.py 2008-10-26 08:27:46 UTC (rev 92578)
@@ -1,6 +1,6 @@
from setuptools import setup, find_packages
-version = '0.1'
+version = '0.1.1'
setup(name='gbepastebin',
version=version,
Modified: grokapps/gbepastebin/src/gbepastebin/app.py
===================================================================
--- grokapps/gbepastebin/src/gbepastebin/app.py 2008-10-26 05:59:00 UTC (rev 92577)
+++ grokapps/gbepastebin/src/gbepastebin/app.py 2008-10-26 08:27:46 UTC (rev 92578)
@@ -7,40 +7,40 @@
class Application(grok.Application, grok.Container):
display_limit=10
- version=0.1
+ version='0.1.1'
def next_id(self):
keys=[0]
- keylist=self.store.keys()
+ keylist=self['store'].keys()
if keylist:
keys=[int(key) for key in keylist]
keys.sort()
return str(int(keys[-1])+1)
def get_paste(self, pasteid):
- return self.store.get(pasteid)
+ return self['store'].get(pasteid)
def add_paste(self, paste):
pasteid=self.next_id()
paste.pasteid=pasteid
- self.store[pasteid]=paste
+ self['store'][pasteid]=paste
return pasteid
def delete_paste(self, pasteid):
if self.get_paste(pasteid):
- del self.store[pasteid]
+ del self['store'][pasteid]
return True
return False
def list_pastes(self, max=display_limit):
- keylist=self.store.keys()
+ keylist=self['store'].keys()
keys=[int(key) for key in keylist]
keys.sort()
keys.reverse()
return [self.get_paste(str(key)) for key in keys[:max]]
def list_pasteids(self):
- return list(self.store.keys())
+ return list(self['store'].keys())
def delete_pastes(self, pastelist):
success=True
@@ -51,5 +51,5 @@
@grok.subscribe(Application, grok.IObjectAddedEvent)
def handle(obj, event):
- #obj.store=volatile_pastebin()
- obj.store=pastebin()
+ #obj['store']=volatile_pastebin()
+ obj['store']=pastebin()
Modified: grokapps/gbepastebin/src/gbepastebin/app.txt
===================================================================
--- grokapps/gbepastebin/src/gbepastebin/app.txt 2008-10-26 05:59:00 UTC (rev 92577)
+++ grokapps/gbepastebin/src/gbepastebin/app.txt 2008-10-26 08:27:46 UTC (rev 92578)
@@ -91,55 +91,3 @@
True
>>> show_pastebin()
[]
-
-
-
-Test the REST views
--------------------
-
-Add a few pastes and list the Pastebin contents:
-
- >>> import simplejson
- >>> for paste in range(3):
- ... browser.open('http://localhost/++rest++json/app/', 'author_name=name&paste=text&language=python')
- >>> browser.open('http://localhost/++rest++json/app/')
- >>> simplejson.loads(browser.contents)
- [u'1', u'2', u'3']
-
-Delete Paste #2 (Deletions must be authenticated):
-
- >>> from grok.ftests.test_grok_functional import http_call
- >>> response = http_call('DELETE', 'http://localhost/++rest++json/app/2')
- Traceback (most recent call last):
- ...
- Unauthorized: (<grok.meta.JSONPaste ...>, '__call__', 'gbepastebin.manage')
- >>> response = http_call('DELETE', 'http://localhost/++rest++json/app/2',Authorization='Basic mgr:mgrpw')
- >>> simplejson.loads(response.getBody())
- True
-
-Delete it again:
-
- >>> response = http_call('DELETE', 'http://localhost/++rest++json/app/2',Authorization='Basic mgr:mgrpw')
- Traceback (most recent call last):
- ...
- NotFound: Object: <gbepastebin.app.Application object at ...>, name: u'2'
-
-Delete all Pastes:
-
- >>> response = http_call('DELETE', 'http://localhost/++rest++json/app/',Authorization='Basic mgr:mgrpw')
- >>> simplejson.loads(response.getBody())
- True
-
-Show the Pastebin contents.
-
- >>> browser.open('http://localhost/++rest++json/app/')
- >>> simplejson.loads(browser.contents)
- []
-
-Test the 'languages' command:
-
- >>> browser.open('http://localhost/++rest++json/app/languages')
- >>> ['python', 'Python'] in simplejson.loads(browser.contents)
- True
-
-
\ No newline at end of file
Modified: grokapps/gbepastebin/src/gbepastebin/rest.py
===================================================================
--- grokapps/gbepastebin/src/gbepastebin/rest.py 2008-10-26 05:59:00 UTC (rev 92577)
+++ grokapps/gbepastebin/src/gbepastebin/rest.py 2008-10-26 08:27:46 UTC (rev 92578)
@@ -14,7 +14,6 @@
----------- ------- ----------------------- ------------------------ ---------
/ GET list all pastes ['pasteid', ...] Anonymous
/ POST add new paste 'pasteid' Anonymous
-/ DELETE delete all pastes Boolean Manager
/<id> GET return paste (id) Paste Anonymous
/<id> DELETE delete paste (id) Boolean Manager
/languages GET list languages [('alias', 'name'), ...] Anonymous
@@ -31,7 +30,10 @@
class BaseApplication(object):
def list_pastes(self):
- return self.context.list_pasteids()
+ pasteids=self.context.list_pasteids()
+ site=grok.getSite()
+ site_url=grok.url(self.request,site)
+ return ['%s/%s' % (site_url, pasteid) for pasteid in pasteids]
def add_paste(self):
author_name=self.request.get('author_name')
@@ -41,7 +43,7 @@
return self.context.add_paste(paste_obj)
def delete_pastes(self):
- pastelist=self.list_pastes()
+ pastelist=self.list_pasts()
return self.context.delete_pastes(pastelist)
class JSONApplication(grok.REST, BaseApplication):
@@ -54,10 +56,6 @@
def POST(self):
return simplejson.dumps(self.add_paste())
- @grok.require('gbepastebin.manage')
- def DELETE(self):
- return simplejson.dumps(self.delete_pastes())
-
class Utils(grok.Model):
def list_languages(self):
Added: grokapps/gbepastebin/src/gbepastebin/rest.txt
===================================================================
--- grokapps/gbepastebin/src/gbepastebin/rest.txt (rev 0)
+++ grokapps/gbepastebin/src/gbepastebin/rest.txt 2008-10-26 08:27:46 UTC (rev 92578)
@@ -0,0 +1,73 @@
+Do a functional doctest test on the app.
+========================================
+
+:Test-Layer: functional
+
+
+Test the REST views
+-------------------
+
+Let's first create an instance of gbepastebin at the top level:
+
+ >>> from gbepastebin.app import Application
+ >>> from gbepastebin.paste import Paste
+ >>> root = getRootFolder()
+ >>> root['app'] = app = Application()
+
+Create a browser and visit the instance you just created:
+
+ >>> from zope.testbrowser.testing import Browser
+ >>> browser = Browser()
+
+
+Add a few pastes and list the Pastebin contents:
+
+ >>> import simplejson
+ >>> for paste in range(3):
+ ... browser.open('http://localhost/++rest++json/app/', 'author_name=name&paste=text&language=python')
+ >>> browser.open('http://localhost/++rest++json/app/')
+ >>> sorted(simplejson.loads(browser.contents))
+ [u'http://localhost/++rest++json/app/1', u'http://localhost/++rest++json/app/2', u'http://localhost/++rest++json/app/3']
+
+Delete Paste #2 (Deletions must be authenticated):
+
+ >>> from grok.ftests.test_grok_functional import http_call
+ >>> response = http_call('DELETE', 'http://localhost/++rest++json/app/2')
+ Traceback (most recent call last):
+ ...
+ Unauthorized: (<grok.meta.JSONPaste ...>, '__call__', 'gbepastebin.manage')
+ >>> response = http_call('DELETE', 'http://localhost/++rest++json/app/2',Authorization='Basic mgr:mgrpw')
+ >>> simplejson.loads(response.getBody())
+ True
+
+Delete it again:
+
+ >>> response = http_call('DELETE', 'http://localhost/++rest++json/app/2',Authorization='Basic mgr:mgrpw')
+ Traceback (most recent call last):
+ ...
+ NotFound: Object: <gbepastebin.app.Application object at ...>, name: u'2'
+
+Delete all Pastes:
+
+ >>> browser.open('http://localhost/++rest++json/app/')
+ >>> pastes = simplejson.loads(browser.contents)
+ >>> response = True
+ >>> for paste in pastes:
+ ... res = http_call('DELETE', paste, Authorization='Basic mgr:mgrpw')
+ ... response = response and simplejson.loads(res.getBody())
+ >>> response
+ True
+
+Show the Pastebin contents.
+
+ >>> browser.open('http://localhost/++rest++json/app/')
+ >>> simplejson.loads(browser.contents)
+ []
+
+Test the 'languages' command:
+
+ >>> browser.open('http://localhost/++rest++json/app/languages')
+ >>> ['python', 'Python'] in simplejson.loads(browser.contents)
+ True
+
+
\ No newline at end of file
More information about the Checkins
mailing list