File: tests.py

package info (click to toggle)
python-django-piston 0.2.3-2
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd, stretch
  • size: 540 kB
  • ctags: 883
  • sloc: python: 3,013; xml: 33; sh: 23; makefile: 6
file content (200 lines) | stat: -rw-r--r-- 7,124 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
# Django imports
import django
from django.core import mail
from django.contrib.auth.models import User
from django.conf import settings
from django.template import loader, TemplateDoesNotExist
from django.http import HttpRequest, HttpResponse
from django.utils import simplejson

# Piston imports
from test import TestCase
from models import Consumer
from handler import BaseHandler
from utils import rc
from resource import Resource

class ConsumerTest(TestCase):
    fixtures = ['models.json']

    def setUp(self):
        self.consumer = Consumer()
        self.consumer.name = "Piston Test Consumer"
        self.consumer.description = "A test consumer for Piston."
        self.consumer.user = User.objects.get(pk=3)
        self.consumer.generate_random_codes()

    def _pre_test_email(self):
        template = "piston/mails/consumer_%s.txt" % self.consumer.status
        try:
            loader.render_to_string(template, {
                'consumer': self.consumer,
                'user': self.consumer.user
            })
            return True
        except TemplateDoesNotExist:
            """
            They haven't set up the templates, which means they might not want
            these emails sent.
            """
            return False

    def test_create_pending(self):
        """ Ensure creating a pending Consumer sends proper emails """
        # Verify if the emails can be sent
        if not self._pre_test_email():
            return

        # If it's pending we should have two messages in the outbox; one
        # to the consumer and one to the site admins.
        if len(settings.ADMINS):
            self.assertEquals(len(mail.outbox), 2)
        else:
            self.assertEquals(len(mail.outbox), 1)

        expected = "Your API Consumer for example.com is awaiting approval."
        self.assertEquals(mail.outbox[0].subject, expected)

    def test_delete_consumer(self):
        """ Ensure deleting a Consumer sends a cancel email """

        # Clear out the outbox before we test for the cancel email.
        mail.outbox = []

        # Delete the consumer, which should fire off the cancel email.
        self.consumer.delete()

        # Verify if the emails can be sent
        if not self._pre_test_email():
            return

        self.assertEquals(len(mail.outbox), 1)
        expected = "Your API Consumer for example.com has been canceled."
        self.assertEquals(mail.outbox[0].subject, expected)


class CustomResponseWithStatusCodeTest(TestCase):
     """
     Test returning content to be formatted and a custom response code from a 
     handler method. In this case we're returning 201 (created) and a dictionary 
     of data. This data will be formatted as json. 
     """

     def test_reponse_with_data_and_status_code(self):
         response_data = dict(complex_response=dict(something='good', 
             something_else='great'))

         class MyHandler(BaseHandler):
             """
             Handler which returns a response w/ both data and a status code (201)
             """
             allowed_methods = ('POST', )

             def create(self, request):
                 resp = rc.CREATED
                 resp.content = response_data
                 return resp

         resource = Resource(MyHandler)
         request = HttpRequest()
         request.method = 'POST'
         response = resource(request, emitter_format='json')

         self.assertEquals(201, response.status_code)
         is_string = (not response._base_content_is_iter) if django.VERSION >= (1,4) else response._is_string
         self.assert_(is_string, "Expected response content to be a string")

         # compare the original data dict with the json response 
         # converted to a dict
         self.assertEquals(response_data, simplejson.loads(response.content))


class ErrorHandlerTest(TestCase):
    def test_customized_error_handler(self):
        """
        Throw a custom error from a handler method and catch (and format) it 
        in an overridden error_handler method on the associated Resource object
        """
        class GoAwayError(Exception):
            def __init__(self, name, reason):
                self.name = name
                self.reason = reason

        class MyHandler(BaseHandler):
            """
            Handler which raises a custom exception 
            """
            allowed_methods = ('GET',)

            def read(self, request):
                raise GoAwayError('Jerome', 'No one likes you')

        class MyResource(Resource):
            def error_handler(self, error, request, meth, em_format):
                # if the exception is our exeption then generate a 
                # custom response with embedded content that will be 
                # formatted as json 
                if isinstance(error, GoAwayError):
                    response = rc.FORBIDDEN
                    response.content = dict(error=dict(
                        name=error.name, 
                        message="Get out of here and dont come back", 
                        reason=error.reason
                    ))    

                    return response

                return super(MyResource, self).error_handler(error, request, meth)

        resource = MyResource(MyHandler)

        request = HttpRequest()
        request.method = 'GET'
        response = resource(request, emitter_format='json')

        self.assertEquals(401, response.status_code)

        # verify the content we got back can be converted back to json 
        # and examine the dictionary keys all exist as expected
        response_data = simplejson.loads(response.content)
        self.assertTrue('error' in response_data)
        self.assertTrue('name' in response_data['error'])
        self.assertTrue('message' in response_data['error'])
        self.assertTrue('reason' in response_data['error'])

    def test_type_error(self):
        """
        Verify that type errors thrown from a handler method result in a valid 
        HttpResonse object being returned from the error_handler method
        """
        class MyHandler(BaseHandler):
            def read(self, request):
                raise TypeError()

        request = HttpRequest()
        request.method = 'GET'
        response = Resource(MyHandler)(request)

        self.assertTrue(isinstance(response, HttpResponse), "Expected a response, not: %s" 
            % response)


    def test_other_error(self):
        """
        Verify that other exceptions thrown from a handler method result in a valid
        HttpResponse object being returned from the error_handler method
        """
        class MyHandler(BaseHandler):
            def read(self, request):
                raise Exception()

        resource = Resource(MyHandler)
        resource.display_errors = True
        resource.email_errors = False

        request = HttpRequest()
        request.method = 'GET'
        response = resource(request)

        self.assertTrue(isinstance(response, HttpResponse), "Expected a response, not: %s" 
            % response)