root / snf-django-lib / snf_django / utils / testing.py @ d2b8ec7b
History | View | Annotate | Download (6.2 kB)
1 | f09da76e | Kostas Papadimitriou | # Copyright 2011-2013 GRNET S.A. All rights reserved.
|
---|---|---|---|
2 | f09da76e | Kostas Papadimitriou | #
|
3 | f09da76e | Kostas Papadimitriou | # Redistribution and use in source and binary forms, with or
|
4 | f09da76e | Kostas Papadimitriou | # without modification, are permitted provided that the following
|
5 | f09da76e | Kostas Papadimitriou | # conditions are met:
|
6 | f09da76e | Kostas Papadimitriou | #
|
7 | f09da76e | Kostas Papadimitriou | # 1. Redistributions of source code must retain the above
|
8 | f09da76e | Kostas Papadimitriou | # copyright notice, this list of conditions and the following
|
9 | f09da76e | Kostas Papadimitriou | # disclaimer.
|
10 | f09da76e | Kostas Papadimitriou | #
|
11 | f09da76e | Kostas Papadimitriou | # 2. Redistributions in binary form must reproduce the above
|
12 | f09da76e | Kostas Papadimitriou | # copyright notice, this list of conditions and the following
|
13 | f09da76e | Kostas Papadimitriou | # disclaimer in the documentation and/or other materials
|
14 | f09da76e | Kostas Papadimitriou | # provided with the distribution.
|
15 | f09da76e | Kostas Papadimitriou | #
|
16 | f09da76e | Kostas Papadimitriou | # THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
|
17 | f09da76e | Kostas Papadimitriou | # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
18 | f09da76e | Kostas Papadimitriou | # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
19 | f09da76e | Kostas Papadimitriou | # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
|
20 | f09da76e | Kostas Papadimitriou | # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
21 | f09da76e | Kostas Papadimitriou | # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
22 | f09da76e | Kostas Papadimitriou | # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
23 | f09da76e | Kostas Papadimitriou | # USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
24 | f09da76e | Kostas Papadimitriou | # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
25 | f09da76e | Kostas Papadimitriou | # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
26 | f09da76e | Kostas Papadimitriou | # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
27 | f09da76e | Kostas Papadimitriou | # POSSIBILITY OF SUCH DAMAGE.
|
28 | f09da76e | Kostas Papadimitriou | #
|
29 | f09da76e | Kostas Papadimitriou | # The views and conclusions contained in the software and
|
30 | f09da76e | Kostas Papadimitriou | # documentation are those of the authors and should not be
|
31 | f09da76e | Kostas Papadimitriou | # interpreted as representing official policies, either expressed
|
32 | f09da76e | Kostas Papadimitriou | # or implied, of GRNET S.A.
|
33 | f09da76e | Kostas Papadimitriou | |
34 | f09da76e | Kostas Papadimitriou | |
35 | f09da76e | Kostas Papadimitriou | from contextlib import contextmanager |
36 | d2b8ec7b | Christos Stavrakakis | from django.test import TestCase |
37 | d2b8ec7b | Christos Stavrakakis | from django.utils import simplejson as json |
38 | d2b8ec7b | Christos Stavrakakis | from mock import patch |
39 | f09da76e | Kostas Papadimitriou | |
40 | f09da76e | Kostas Papadimitriou | |
41 | f09da76e | Kostas Papadimitriou | @contextmanager
|
42 | f09da76e | Kostas Papadimitriou | def override_settings(settings, **kwargs): |
43 | f09da76e | Kostas Papadimitriou | """
|
44 | f09da76e | Kostas Papadimitriou | Helper context manager to override django settings within the provided
|
45 | f09da76e | Kostas Papadimitriou | context.
|
46 | f09da76e | Kostas Papadimitriou |
|
47 | f09da76e | Kostas Papadimitriou | All keyword arguments provided are set to the django settings object and
|
48 | f09da76e | Kostas Papadimitriou | get reverted/removed when the manager exits.
|
49 | f09da76e | Kostas Papadimitriou |
|
50 | f09da76e | Kostas Papadimitriou | >>> from synnefo.util.testing import override_settings
|
51 | f09da76e | Kostas Papadimitriou | >>> from django.conf import settings
|
52 | f09da76e | Kostas Papadimitriou | >>> with override_settings(settings, DEBUG=True):
|
53 | f09da76e | Kostas Papadimitriou | >>> assert settings.DEBUG == True
|
54 | f09da76e | Kostas Papadimitriou |
|
55 | f09da76e | Kostas Papadimitriou | The special arguemnt ``prefix`` can be set to prefix all setting keys with
|
56 | f09da76e | Kostas Papadimitriou | the provided value.
|
57 | f09da76e | Kostas Papadimitriou |
|
58 | f09da76e | Kostas Papadimitriou | >>> from django.conf import settings
|
59 | f09da76e | Kostas Papadimitriou | >>> from django.core import mail
|
60 | f09da76e | Kostas Papadimitriou | >>> with override_settings(settings, CONTACT_EMAILS=['kpap@grnet.gr'],
|
61 | f09da76e | Kostas Papadimitriou | >>> prefix='MYAPP_'):
|
62 | f09da76e | Kostas Papadimitriou | >>> from django.core.mail import send_mail
|
63 | f09da76e | Kostas Papadimitriou | >>> send_mail("hello", "I love you kpap", settings.DEFAULT_FROM_EMAIL,
|
64 | f09da76e | Kostas Papadimitriou | >>> settings.MYAPP_CONTACT_EMAILS)
|
65 | f09da76e | Kostas Papadimitriou | >>> assert 'kpap@grnet.gr' in mail.mailbox[0].recipients()
|
66 | f09da76e | Kostas Papadimitriou |
|
67 | f09da76e | Kostas Papadimitriou | If you plan to reuse it
|
68 | f09da76e | Kostas Papadimitriou |
|
69 | f09da76e | Kostas Papadimitriou | >>> import functools
|
70 | f09da76e | Kostas Papadimitriou | >>> from synnefo.util.testing import override_settings
|
71 | f09da76e | Kostas Papadimitriou | >>> from django.conf import settings
|
72 | f09da76e | Kostas Papadimitriou | >>> myapp_settings = functools.partial(override_settings, prefix='MYAPP_')
|
73 | f09da76e | Kostas Papadimitriou | >>> with myapp_settings(CONTACT_EMAILS=['kpap@grnet.gr'])
|
74 | f09da76e | Kostas Papadimitriou | >>> assert settings.MYAPP_CONTACT_EMAILS == ['kpap@grnet.gr']
|
75 | f09da76e | Kostas Papadimitriou |
|
76 | f09da76e | Kostas Papadimitriou | """
|
77 | f09da76e | Kostas Papadimitriou | |
78 | f09da76e | Kostas Papadimitriou | _prefix = kwargs.get('prefix', '') |
79 | f09da76e | Kostas Papadimitriou | prefix = lambda key: '%s%s' % (_prefix, key) |
80 | f09da76e | Kostas Papadimitriou | |
81 | f09da76e | Kostas Papadimitriou | oldkeys = [k for k in dir(settings) if k.upper() == k] |
82 | f09da76e | Kostas Papadimitriou | oldsettings = dict([(k, getattr(settings, k)) for k in oldkeys]) |
83 | f09da76e | Kostas Papadimitriou | |
84 | f09da76e | Kostas Papadimitriou | toremove = [] |
85 | f09da76e | Kostas Papadimitriou | for key, value in kwargs.iteritems(): |
86 | f09da76e | Kostas Papadimitriou | key = prefix(key) |
87 | f09da76e | Kostas Papadimitriou | if not hasattr(settings, key): |
88 | f09da76e | Kostas Papadimitriou | toremove.append(key) |
89 | f09da76e | Kostas Papadimitriou | setattr(settings, key, value)
|
90 | f09da76e | Kostas Papadimitriou | |
91 | f09da76e | Kostas Papadimitriou | yield
|
92 | f09da76e | Kostas Papadimitriou | |
93 | f09da76e | Kostas Papadimitriou | # Remove keys that didn't exist
|
94 | f09da76e | Kostas Papadimitriou | for key in toremove: |
95 | f09da76e | Kostas Papadimitriou | delattr(settings, key)
|
96 | f09da76e | Kostas Papadimitriou | |
97 | f09da76e | Kostas Papadimitriou | # Remove keys that added during the execution of the context
|
98 | f09da76e | Kostas Papadimitriou | if kwargs.get('reset_changes', True): |
99 | f09da76e | Kostas Papadimitriou | newkeys = [k for k in dir(settings) if k.upper() == k] |
100 | f09da76e | Kostas Papadimitriou | for key in newkeys: |
101 | f09da76e | Kostas Papadimitriou | if not key in oldkeys: |
102 | f09da76e | Kostas Papadimitriou | delattr(settings, key)
|
103 | f09da76e | Kostas Papadimitriou | |
104 | f09da76e | Kostas Papadimitriou | # Revert old keys
|
105 | f09da76e | Kostas Papadimitriou | for key in oldkeys: |
106 | f09da76e | Kostas Papadimitriou | if key == key.upper():
|
107 | f09da76e | Kostas Papadimitriou | setattr(settings, key, oldsettings.get(key))
|
108 | f09da76e | Kostas Papadimitriou | |
109 | f09da76e | Kostas Papadimitriou | |
110 | f09da76e | Kostas Papadimitriou | def with_settings(settings, prefix='', **override): |
111 | f09da76e | Kostas Papadimitriou | def wrapper(func): |
112 | f09da76e | Kostas Papadimitriou | def inner(*args, **kwargs): |
113 | f09da76e | Kostas Papadimitriou | with override_settings(settings, prefix=prefix, **override):
|
114 | f09da76e | Kostas Papadimitriou | ret = func(*args, **kwargs) |
115 | f09da76e | Kostas Papadimitriou | return ret
|
116 | f09da76e | Kostas Papadimitriou | return inner
|
117 | f09da76e | Kostas Papadimitriou | return wrapper
|
118 | d2b8ec7b | Christos Stavrakakis | |
119 | d2b8ec7b | Christos Stavrakakis | |
120 | d2b8ec7b | Christos Stavrakakis | @contextmanager
|
121 | d2b8ec7b | Christos Stavrakakis | def astakos_user(user): |
122 | d2b8ec7b | Christos Stavrakakis | """
|
123 | d2b8ec7b | Christos Stavrakakis | Context manager to mock astakos response.
|
124 | d2b8ec7b | Christos Stavrakakis |
|
125 | d2b8ec7b | Christos Stavrakakis | usage:
|
126 | d2b8ec7b | Christos Stavrakakis | with astakos_user("user@user.com"):
|
127 | d2b8ec7b | Christos Stavrakakis | .... make api calls ....
|
128 | d2b8ec7b | Christos Stavrakakis |
|
129 | d2b8ec7b | Christos Stavrakakis | """
|
130 | d2b8ec7b | Christos Stavrakakis | with patch("snf_django.lib.api.get_token") as get_token: |
131 | d2b8ec7b | Christos Stavrakakis | get_token.return_value = "DummyToken"
|
132 | d2b8ec7b | Christos Stavrakakis | with patch('astakosclient.AstakosClient.get_user_info') as m: |
133 | d2b8ec7b | Christos Stavrakakis | m.return_value = {"uuid": user}
|
134 | d2b8ec7b | Christos Stavrakakis | yield
|
135 | d2b8ec7b | Christos Stavrakakis | |
136 | d2b8ec7b | Christos Stavrakakis | |
137 | d2b8ec7b | Christos Stavrakakis | class BaseAPITest(TestCase): |
138 | d2b8ec7b | Christos Stavrakakis | def get(self, url, user='user', *args, **kwargs): |
139 | d2b8ec7b | Christos Stavrakakis | with astakos_user(user):
|
140 | d2b8ec7b | Christos Stavrakakis | response = self.client.get(url, *args, **kwargs)
|
141 | d2b8ec7b | Christos Stavrakakis | return response
|
142 | d2b8ec7b | Christos Stavrakakis | |
143 | d2b8ec7b | Christos Stavrakakis | def delete(self, url, user='user'): |
144 | d2b8ec7b | Christos Stavrakakis | with astakos_user(user):
|
145 | d2b8ec7b | Christos Stavrakakis | response = self.client.delete(url)
|
146 | d2b8ec7b | Christos Stavrakakis | return response
|
147 | d2b8ec7b | Christos Stavrakakis | |
148 | d2b8ec7b | Christos Stavrakakis | def post(self, url, user='user', params={}, ctype='json', *args, **kwargs): |
149 | d2b8ec7b | Christos Stavrakakis | if ctype == 'json': |
150 | d2b8ec7b | Christos Stavrakakis | content_type = 'application/json'
|
151 | d2b8ec7b | Christos Stavrakakis | with astakos_user(user):
|
152 | d2b8ec7b | Christos Stavrakakis | response = self.client.post(url, params, content_type=content_type,
|
153 | d2b8ec7b | Christos Stavrakakis | *args, **kwargs) |
154 | d2b8ec7b | Christos Stavrakakis | return response
|
155 | d2b8ec7b | Christos Stavrakakis | |
156 | d2b8ec7b | Christos Stavrakakis | def put(self, url, user='user', params={}, ctype='json', *args, **kwargs): |
157 | d2b8ec7b | Christos Stavrakakis | if ctype == 'json': |
158 | d2b8ec7b | Christos Stavrakakis | content_type = 'application/json'
|
159 | d2b8ec7b | Christos Stavrakakis | with astakos_user(user):
|
160 | d2b8ec7b | Christos Stavrakakis | response = self.client.put(url, params, content_type=content_type,
|
161 | d2b8ec7b | Christos Stavrakakis | *args, **kwargs) |
162 | d2b8ec7b | Christos Stavrakakis | return response
|
163 | d2b8ec7b | Christos Stavrakakis | |
164 | d2b8ec7b | Christos Stavrakakis | def assertSuccess(self, response): |
165 | d2b8ec7b | Christos Stavrakakis | self.assertTrue(response.status_code in [200, 203, 204]) |
166 | d2b8ec7b | Christos Stavrakakis | |
167 | d2b8ec7b | Christos Stavrakakis | def assertFault(self, response, status_code, name): |
168 | d2b8ec7b | Christos Stavrakakis | self.assertEqual(response.status_code, status_code)
|
169 | d2b8ec7b | Christos Stavrakakis | fault = json.loads(response.content) |
170 | d2b8ec7b | Christos Stavrakakis | self.assertEqual(fault.keys(), [name])
|
171 | d2b8ec7b | Christos Stavrakakis | |
172 | d2b8ec7b | Christos Stavrakakis | def assertBadRequest(self, response): |
173 | d2b8ec7b | Christos Stavrakakis | self.assertFault(response, 400, 'badRequest') |
174 | d2b8ec7b | Christos Stavrakakis | |
175 | d2b8ec7b | Christos Stavrakakis | def assertItemNotFound(self, response): |
176 | d2b8ec7b | Christos Stavrakakis | self.assertFault(response, 404, 'itemNotFound') |