diff options
| author | tom christie tom@tomchristie.com | 2011-01-23 23:08:44 +0000 |
|---|---|---|
| committer | tom christie tom@tomchristie.com | 2011-01-23 23:08:44 +0000 |
| commit | e95198a1c0b206bd3b565bb62d167ada71595099 (patch) | |
| tree | 65dc7f469b28f09783b732862ab9822b8528f10d /src/testapp | |
| parent | 4100242fa2395bef8db0c5ffbab6f5d0cf95301d (diff) | |
| download | django-rest-framework-e95198a1c0b206bd3b565bb62d167ada71595099.tar.bz2 | |
Sphinx docs, examples, lots of refactoring
Diffstat (limited to 'src/testapp')
| -rw-r--r-- | src/testapp/__init__.py | 0 | ||||
| -rw-r--r-- | src/testapp/forms.py | 7 | ||||
| -rw-r--r-- | src/testapp/models.py | 94 | ||||
| -rw-r--r-- | src/testapp/tests.py | 162 | ||||
| -rw-r--r-- | src/testapp/urls.py | 19 | ||||
| -rw-r--r-- | src/testapp/views.py | 118 |
6 files changed, 0 insertions, 400 deletions
diff --git a/src/testapp/__init__.py b/src/testapp/__init__.py deleted file mode 100644 index e69de29b..00000000 --- a/src/testapp/__init__.py +++ /dev/null diff --git a/src/testapp/forms.py b/src/testapp/forms.py deleted file mode 100644 index b86d8a5f..00000000 --- a/src/testapp/forms.py +++ /dev/null @@ -1,7 +0,0 @@ -from django import forms - -class ExampleForm(forms.Form): - title = forms.CharField(max_length=100) - message = forms.CharField() - sender = forms.EmailField() - valid = forms.BooleanField(required=False) diff --git a/src/testapp/models.py b/src/testapp/models.py deleted file mode 100644 index 909788a3..00000000 --- a/src/testapp/models.py +++ /dev/null @@ -1,94 +0,0 @@ -from django.db import models -from django.template.defaultfilters import slugify -import uuid - -def uuid_str(): - return str(uuid.uuid1()) - -#class ExampleModel(models.Model): -# num = models.IntegerField(default=2, choices=((1,'one'), (2, 'two'))) -# hidden_num = models.IntegerField(verbose_name='Something', help_text='HELP') -# text = models.TextField(blank=False) -# another = models.CharField(max_length=10) - - -#class ExampleContainer(models.Model): -# """Container. Has a key, a name, and some internal data, and contains a set of items.""" -# key = models.CharField(primary_key=True, default=uuid_str, max_length=36, editable=False) -# name = models.CharField(max_length=256) -# internal = models.IntegerField(default=0) - -# @models.permalink -# def get_absolute_url(self): -# return ('testapp.views.ContainerInstance', [self.key]) - - -#class ExampleItem(models.Model): -# """Item. Belongs to a container and has an index number and a note. -# Items are uniquely identified by their container and index number.""" -# container = models.ForeignKey(ExampleContainer, related_name='items') -# index = models.IntegerField() -# note = models.CharField(max_length=1024) -# unique_together = (container, index) - - -RATING_CHOICES = ((0, 'Awful'), - (1, 'Poor'), - (2, 'OK'), - (3, 'Good'), - (4, 'Excellent')) - -class BlogPost(models.Model): - key = models.CharField(primary_key=True, max_length=64, default=uuid_str, editable=False) - title = models.CharField(max_length=128) - content = models.TextField() - created = models.DateTimeField(auto_now_add=True) - slug = models.SlugField(editable=False, default='') - - class Meta: - ordering = ('created',) - - @models.permalink - def get_absolute_url(self): - return ('testapp.views.BlogPostInstance', (self.key,)) - - @property - @models.permalink - def comments_url(self): - """Link to a resource which lists all comments for this blog post.""" - return ('testapp.views.CommentList', (self.key,)) - - @property - @models.permalink - def comment_url(self): - """Link to a resource which can create a comment for this blog post.""" - return ('testapp.views.CommentCreator', (self.key,)) - - def __unicode__(self): - return self.title - - def save(self, *args, **kwargs): - self.slug = slugify(self.title) - super(self.__class__, self).save(*args, **kwargs) - - -class Comment(models.Model): - blogpost = models.ForeignKey(BlogPost, editable=False, related_name='comments') - username = models.CharField(max_length=128) - comment = models.TextField() - rating = models.IntegerField(blank=True, null=True, choices=RATING_CHOICES, help_text='How did you rate this post?') - created = models.DateTimeField(auto_now_add=True) - - class Meta: - ordering = ('created',) - - @models.permalink - def get_absolute_url(self): - return ('testapp.views.CommentInstance', (self.blogpost.key, self.id)) - - @property - @models.permalink - def blogpost_url(self): - """Link to the blog post resource which this comment corresponds to.""" - return ('testapp.views.BlogPostInstance', (self.blogpost.key,)) - diff --git a/src/testapp/tests.py b/src/testapp/tests.py deleted file mode 100644 index 3fcfc9e1..00000000 --- a/src/testapp/tests.py +++ /dev/null @@ -1,162 +0,0 @@ -"""Test a range of REST API usage of the example application. -""" - -from django.test import TestCase -from django.core.urlresolvers import reverse -from testapp import views -#import json -#from rest.utils import xml2dict, dict2xml - - -class AcceptHeaderTests(TestCase): - """Test correct behaviour of the Accept header as specified by RFC 2616: - - http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.1""" - - def assert_accept_mimetype(self, mimetype, expect=None): - """Assert that a request with given mimetype in the accept header, - gives a response with the appropriate content-type.""" - if expect is None: - expect = mimetype - - resp = self.client.get(reverse(views.RootResource), HTTP_ACCEPT=mimetype) - - self.assertEquals(resp['content-type'], expect) - - - def test_accept_json(self): - """Ensure server responds with Content-Type of JSON when requested.""" - self.assert_accept_mimetype('application/json') - - def test_accept_xml(self): - """Ensure server responds with Content-Type of XML when requested.""" - self.assert_accept_mimetype('application/xml') - - def test_accept_json_when_prefered_to_xml(self): - """Ensure server responds with Content-Type of JSON when it is the client's prefered choice.""" - self.assert_accept_mimetype('application/json,q=0.9;application/xml,q=0.1', expect='application/json') - - def test_accept_xml_when_prefered_to_json(self): - """Ensure server responds with Content-Type of XML when it is the client's prefered choice.""" - self.assert_accept_mimetype('application/xml,q=0.9;application/json,q=0.1', expect='application/xml') - - def test_default_json_prefered(self): - """Ensure server responds with JSON in preference to XML.""" - self.assert_accept_mimetype('application/json;application/xml', expect='application/json') - - def test_accept_generic_subtype_format(self): - """Ensure server responds with an appropriate type, when the subtype is left generic.""" - self.assert_accept_mimetype('text/*', expect='text/html') - - def test_accept_generic_type_format(self): - """Ensure server responds with an appropriate type, when the type and subtype are left generic.""" - self.assert_accept_mimetype('*/*', expect='application/json') - - def test_invalid_accept_header_returns_406(self): - """Ensure server returns a 406 (not acceptable) response if we set the Accept header to junk.""" - resp = self.client.get(reverse(views.RootResource), HTTP_ACCEPT='invalid/invalid') - self.assertNotEquals(resp['content-type'], 'invalid/invalid') - self.assertEquals(resp.status_code, 406) - - def test_prefer_specific_over_generic(self): # This test is broken right now - """More specific accept types have precedence over less specific types.""" - self.assert_accept_mimetype('application/xml;*/*', expect='application/xml') - - -class AllowedMethodsTests(TestCase): - """Basic tests to check that only allowed operations may be performed on a Resource""" - - def test_reading_a_read_only_resource_is_allowed(self): - """GET requests on a read only resource should default to a 200 (OK) response""" - resp = self.client.get(reverse(views.RootResource)) - self.assertEquals(resp.status_code, 200) - - def test_writing_to_read_only_resource_is_not_allowed(self): - """PUT requests on a read only resource should default to a 405 (method not allowed) response""" - resp = self.client.put(reverse(views.RootResource), {}) - self.assertEquals(resp.status_code, 405) -# -# def test_reading_write_only_not_allowed(self): -# resp = self.client.get(reverse(views.WriteOnlyResource)) -# self.assertEquals(resp.status_code, 405) -# -# def test_writing_write_only_allowed(self): -# resp = self.client.put(reverse(views.WriteOnlyResource), {}) -# self.assertEquals(resp.status_code, 200) -# -# -#class EncodeDecodeTests(TestCase): -# def setUp(self): -# super(self.__class__, self).setUp() -# self.input = {'a': 1, 'b': 'example'} -# -# def test_encode_form_decode_json(self): -# content = self.input -# resp = self.client.put(reverse(views.WriteOnlyResource), content) -# output = json.loads(resp.content) -# self.assertEquals(self.input, output) -# -# def test_encode_json_decode_json(self): -# content = json.dumps(self.input) -# resp = self.client.put(reverse(views.WriteOnlyResource), content, 'application/json') -# output = json.loads(resp.content) -# self.assertEquals(self.input, output) -# -# #def test_encode_xml_decode_json(self): -# # content = dict2xml(self.input) -# # resp = self.client.put(reverse(views.WriteOnlyResource), content, 'application/json', HTTP_ACCEPT='application/json') -# # output = json.loads(resp.content) -# # self.assertEquals(self.input, output) -# -# #def test_encode_form_decode_xml(self): -# # content = self.input -# # resp = self.client.put(reverse(views.WriteOnlyResource), content, HTTP_ACCEPT='application/xml') -# # output = xml2dict(resp.content) -# # self.assertEquals(self.input, output) -# -# #def test_encode_json_decode_xml(self): -# # content = json.dumps(self.input) -# # resp = self.client.put(reverse(views.WriteOnlyResource), content, 'application/json', HTTP_ACCEPT='application/xml') -# # output = xml2dict(resp.content) -# # self.assertEquals(self.input, output) -# -# #def test_encode_xml_decode_xml(self): -# # content = dict2xml(self.input) -# # resp = self.client.put(reverse(views.WriteOnlyResource), content, 'application/json', HTTP_ACCEPT='application/xml') -# # output = xml2dict(resp.content) -# # self.assertEquals(self.input, output) -# -#class ModelTests(TestCase): -# def test_create_container(self): -# content = json.dumps({'name': 'example'}) -# resp = self.client.post(reverse(views.ContainerFactory), content, 'application/json') -# output = json.loads(resp.content) -# self.assertEquals(resp.status_code, 201) -# self.assertEquals(output['name'], 'example') -# self.assertEquals(set(output.keys()), set(('absolute_uri', 'name', 'key'))) -# -#class CreatedModelTests(TestCase): -# def setUp(self): -# content = json.dumps({'name': 'example'}) -# resp = self.client.post(reverse(views.ContainerFactory), content, 'application/json', HTTP_ACCEPT='application/json') -# self.container = json.loads(resp.content) -# -# def test_read_container(self): -# resp = self.client.get(self.container["absolute_uri"]) -# self.assertEquals(resp.status_code, 200) -# container = json.loads(resp.content) -# self.assertEquals(container, self.container) -# -# def test_delete_container(self): -# resp = self.client.delete(self.container["absolute_uri"]) -# self.assertEquals(resp.status_code, 204) -# self.assertEquals(resp.content, '') -# -# def test_update_container(self): -# self.container['name'] = 'new' -# content = json.dumps(self.container) -# resp = self.client.put(self.container["absolute_uri"], content, 'application/json') -# self.assertEquals(resp.status_code, 200) -# container = json.loads(resp.content) -# self.assertEquals(container, self.container) - diff --git a/src/testapp/urls.py b/src/testapp/urls.py deleted file mode 100644 index 16ea9a2f..00000000 --- a/src/testapp/urls.py +++ /dev/null @@ -1,19 +0,0 @@ -from django.conf.urls.defaults import patterns - -urlpatterns = patterns('testapp.views', - (r'^$', 'RootResource'), - #(r'^read-only$', 'ReadOnlyResource'), - #(r'^write-only$', 'WriteOnlyResource'), - #(r'^read-write$', 'ReadWriteResource'), - #(r'^model$', 'ModelFormResource'), - #(r'^container$', 'ContainerFactory'), - #(r'^container/((?P<key>[^/]+))$', 'ContainerInstance'), - - (r'^blog-posts/$', 'BlogPostList'), - (r'^blog-post/$', 'BlogPostCreator'), - (r'^blog-post/(?P<key>[^/]+)/$', 'BlogPostInstance'), - - (r'^blog-post/(?P<blogpost_id>[^/]+)/comments/$', 'CommentList'), - (r'^blog-post/(?P<blogpost_id>[^/]+)/comment/$', 'CommentCreator'), - (r'^blog-post/(?P<blogpost>[^/]+)/comments/(?P<id>[^/]+)/$', 'CommentInstance'), -) diff --git a/src/testapp/views.py b/src/testapp/views.py deleted file mode 100644 index 82539435..00000000 --- a/src/testapp/views.py +++ /dev/null @@ -1,118 +0,0 @@ -from rest.resource import Resource -from rest.modelresource import ModelResource, QueryModelResource -from testapp.models import BlogPost, Comment - -##### Root Resource ##### - -class RootResource(Resource): - """This is the top level resource for the API. - All the sub-resources are discoverable from here.""" - allowed_operations = ('read',) - - def read(self, headers={}, *args, **kwargs): - return (200, {'blog-posts': self.reverse(BlogPostList), - 'blog-post': self.reverse(BlogPostCreator)}, {}) - - -##### Blog Post Resources ##### - -BLOG_POST_FIELDS = ('created', 'title', 'slug', 'content', 'absolute_url', 'comment_url', 'comments_url') - -class BlogPostList(QueryModelResource): - """A resource which lists all existing blog posts.""" - allowed_operations = ('read', ) - model = BlogPost - fields = BLOG_POST_FIELDS - -class BlogPostCreator(ModelResource): - """A resource with which blog posts may be created.""" - allowed_operations = ('create',) - model = BlogPost - fields = BLOG_POST_FIELDS - -class BlogPostInstance(ModelResource): - """A resource which represents a single blog post.""" - allowed_operations = ('read', 'update', 'delete') - model = BlogPost - fields = BLOG_POST_FIELDS - - -##### Comment Resources ##### - -COMMENT_FIELDS = ('username', 'comment', 'created', 'rating', 'absolute_url', 'blogpost_url') - -class CommentList(QueryModelResource): - """A resource which lists all existing comments for a given blog post.""" - allowed_operations = ('read', ) - model = Comment - fields = COMMENT_FIELDS - -class CommentCreator(ModelResource): - """A resource with which blog comments may be created for a given blog post.""" - allowed_operations = ('create',) - model = Comment - fields = COMMENT_FIELDS - -class CommentInstance(ModelResource): - """A resource which represents a single comment.""" - allowed_operations = ('read', 'update', 'delete') - model = Comment - fields = COMMENT_FIELDS - - - -# -#'read-only-api': self.reverse(ReadOnlyResource), -# 'write-only-api': self.reverse(WriteOnlyResource), -# 'read-write-api': self.reverse(ReadWriteResource), -# 'model-api': self.reverse(ModelFormResource), -# 'create-container': self.reverse(ContainerFactory), -# -#class ReadOnlyResource(Resource): -# """This is my docstring -# """ -# allowed_operations = ('read',) -# -# def read(self, headers={}, *args, **kwargs): -# return (200, {'ExampleString': 'Example', -# 'ExampleInt': 1, -# 'ExampleDecimal': 1.0}, {}) -# -# -#class WriteOnlyResource(Resource): -# """This is my docstring -# """ -# allowed_operations = ('update',) -# -# def update(self, data, headers={}, *args, **kwargs): -# return (200, data, {}) -# -# -#class ReadWriteResource(Resource): -# allowed_operations = ('read', 'update', 'delete') -# create_form = ExampleForm -# update_form = ExampleForm -# -# -#class ModelFormResource(ModelResource): -# allowed_operations = ('read', 'update', 'delete') -# model = ExampleModel -# -## Nice things: form validation is applied to any input type -## html forms for output -## output always serialized nicely -#class ContainerFactory(ModelResource): -# allowed_operations = ('create',) -# model = ExampleContainer -# fields = ('absolute_uri', 'name', 'key') -# form_fields = ('name',) -# -# -#class ContainerInstance(ModelResource): -# allowed_operations = ('read', 'update', 'delete') -# model = ExampleContainer -# fields = ('absolute_uri', 'name', 'key') -# form_fields = ('name',) - -####################### - |
