david / django-roa (http://welldev.org/)

Turn your models into remote resources that you can access through Django's ORM. ROA stands for Resource Oriented Architecture.

Clone this repository (size: 560.7 KB): HTTPS / SSH
$ hg clone http://code.welldev.org/django-roa

Changed (Δ5.9 KB):

raw changeset »

piston/fixtures/models.json (46 lines added, 0 lines removed)

piston/fixtures/oauth.json (27 lines added, 0 lines removed)

piston/signals.py (14 lines added, 0 lines removed)

piston/test.py (62 lines added, 0 lines removed)

piston/tests.py (44 lines added, 0 lines removed)

Up to file-list piston/fixtures/models.json:

1
[
2
    {
3
        "pk": 2, 
4
        "model": "auth.user", 
5
        "fields": {
6
            "username": "pistontestuser", 
7
            "first_name": "Piston", 
8
            "last_name": "User", 
9
            "is_active": true, 
10
            "is_superuser": false, 
11
            "is_staff": false, 
12
            "last_login": "2009-08-03 13:11:53", 
13
            "groups": [], 
14
            "user_permissions": [], 
15
            "password": "sha1$b6c1f$83d5879f3854f6e9d27f393e3bcb4b8db05cf671", 
16
            "email": "pistontestuser@example.com", 
17
            "date_joined": "2009-08-03 13:11:53"
18
        }
19
    },
20
    {
21
        "pk": 3, 
22
        "model": "auth.user", 
23
        "fields": {
24
            "username": "pistontestconsumer", 
25
            "first_name": "Piston", 
26
            "last_name": "Consumer", 
27
            "is_active": true, 
28
            "is_superuser": false, 
29
            "is_staff": false, 
30
            "last_login": "2009-08-03 13:11:53", 
31
            "groups": [], 
32
            "user_permissions": [], 
33
            "password": "sha1$b6c1f$83d5879f3854f6e9d27f393e3bcb4b8db05cf671", 
34
            "email": "pistontestconsumer@example.com", 
35
            "date_joined": "2009-08-03 13:11:53"
36
        }
37
    },
38
    {
39
        "pk": 1, 
40
        "model": "sites.site", 
41
        "fields": {
42
            "domain": "example.com", 
43
            "name": "example.com"
44
        }
45
    }
46
]

Up to file-list piston/fixtures/oauth.json:

1
[
2
    {
3
        "pk": 1, 
4
        "model": "piston.consumer", 
5
        "fields": {
6
            "status": "accepted", 
7
            "name": "Piston Test Consumer", 
8
            "secret": "T5XkNMkcjffDpC9mNQJbyQnJXGsenYbz", 
9
            "user": 2, 
10
            "key": "8aZSFj3W54h8J8sCpx", 
11
            "description": "A test consumer record for Piston unit tests."
12
        }
13
    },
14
    {
15
        "pk": 1, 
16
        "model": "piston.token", 
17
        "fields": {
18
            "is_approved": true, 
19
            "timestamp": 1249347414, 
20
            "token_type": 2, 
21
            "secret": "qSWZq36t7yvkBquetYBkd8JxnuCu9jKk", 
22
            "user": 2, 
23
            "key": "Y7358vL5hDBbeP3HHL", 
24
            "consumer": 1
25
        }
26
    }
27
]

Up to file-list piston/signals.py:

1
# Django imports
2
import django.dispatch 
3
4
# Piston imports
5
from utils import send_consumer_mail
6
7
def consumer_post_save(sender, instance, created, **kwargs):
8
    send_consumer_mail(instance)
9
10
def consumer_post_delete(sender, instance, **kwargs):
11
    instance.status = 'canceled'
12
    send_consumer_mail(instance)
13
14

Up to file-list piston/test.py:

1
# Django imports
2
import django.test.client as client
3
import django.test as test
4
from django.utils.http import urlencode
5
6
# Piston imports
7
from piston import oauth
8
from piston.models import Consumer, Token
9
10
# 3rd/Python party imports
11
import httplib2, urllib, cgi
12
13
URLENCODED_FORM_CONTENT = 'application/x-www-form-urlencoded'
14
15
class OAuthClient(client.Client):
16
    def __init__(self, consumer, token):
17
        self.token = oauth.OAuthToken(token.key, token.secret)
18
        self.consumer = oauth.OAuthConsumer(consumer.key, consumer.secret)
19
        self.signature = oauth.OAuthSignatureMethod_HMAC_SHA1()
20
21
        super(OAuthClient, self).__init__()
22
23
    def request(self, **request):
24
        # Figure out parameters from request['QUERY_STRING'] and FakePayload
25
        params = {}
26
        if request['REQUEST_METHOD'] in ('POST', 'PUT'):
27
            if request['CONTENT_TYPE'] == URLENCODED_FORM_CONTENT:
28
                payload = request['wsgi.input'].read()
29
                request['wsgi.input'] = client.FakePayload(payload)
30
                params = cgi.parse_qs(payload)
31
32
        url = "http://testserver" + request['PATH_INFO']
33
34
        req = oauth.OAuthRequest.from_consumer_and_token(
35
            self.consumer, token=self.token, 
36
            http_method=request['REQUEST_METHOD'], http_url=url, 
37
            parameters=params
38
        )
39
40
        req.sign_request(self.signature, self.consumer, self.token)
41
        headers = req.to_header()
42
        request['HTTP_AUTHORIZATION'] = headers['Authorization']
43
44
        return super(OAuthClient, self).request(**request)
45
46
    def post(self, path, data={}, content_type=None, follow=False, **extra):
47
        if content_type is None:
48
            content_type = URLENCODED_FORM_CONTENT
49
50
        if isinstance(data, dict):
51
            data = urlencode(data)
52
        
53
        return super(OAuthClient, self).post(path, data, content_type, follow, **extra)
54
55
class TestCase(test.TestCase):
56
    pass
57
58
class OAuthTestCase(TestCase):
59
    @property
60
    def oauth(self):
61
        return OAuthClient(self.consumer, self.token)
62

Up to file-list piston/tests.py:

1
# Django imports
2
from django.core import mail
3
from django.contrib.auth.models import User
4
from django.conf import settings
5
6
# Piston imports
7
from test import TestCase
8
from models import Consumer
9
10
class ConsumerTest(TestCase):
11
    fixtures = ['models.json']
12
13
    def setUp(self):
14
        self.consumer = Consumer()
15
        self.consumer.name = "Piston Test Consumer"
16
        self.consumer.description = "A test consumer for Piston."
17
        self.consumer.user = User.objects.get(pk=3)
18
        self.consumer.generate_random_codes()
19
20
    def test_create_pending(self):
21
        """ Ensure creating a pending Consumer sends proper emails """
22
        # If it's pending we should have two messages in the outbox; one 
23
        # to the consumer and one to the site admins.
24
        if len(settings.ADMINS):
25
            self.assertEquals(len(mail.outbox), 2)
26
        else:
27
            self.assertEquals(len(mail.outbox), 1)
28
29
        expected = "Your API Consumer for example.com is awaiting approval."
30
        self.assertEquals(mail.outbox[0].subject, expected)
31
32
    def test_delete_consumer(self):
33
        """ Ensure deleting a Consumer sends a cancel email """
34
35
        # Clear out the outbox before we test for the cancel email.
36
        mail.outbox = []
37
38
        # Delete the consumer, which should fire off the cancel email.
39
        self.consumer.delete() 
40
        
41
        self.assertEquals(len(mail.outbox), 1)
42
        expected = "Your API Consumer for example.com has been canceled."
43
        self.assertEquals(mail.outbox[0].subject, expected)
44