/
testing.py
174 lines (133 loc) · 5.35 KB
/
testing.py
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
import os
from collections import defaultdict
try:
import unittest2 as unittest
except ImportError: # pragma: no cover
import unittest # NOQA
import mock
import webtest
from cornice import errors as cornice_errors
from enum import Enum
from pyramid.url import parse_url_overrides
from kinto.core import DEFAULT_SETTINGS
from kinto.core.storage import generators
from kinto.core.utils import sqlalchemy, follow_subrequest, encode64
skip_if_travis = unittest.skipIf('TRAVIS' in os.environ, "travis")
skip_if_no_postgresql = unittest.skipIf(sqlalchemy is None,
"postgresql is not installed.")
class DummyRequest(mock.MagicMock):
"""Fully mocked request.
"""
def __init__(self, *args, **kwargs):
super(DummyRequest, self).__init__(*args, **kwargs)
self.upath_info = '/v0/'
self.registry = mock.MagicMock(settings=DEFAULT_SETTINGS.copy())
self.registry.id_generators = defaultdict(generators.UUID4)
self.GET = {}
self.headers = {}
self.errors = cornice_errors.Errors(request=self)
self.authenticated_userid = 'bob'
self.authn_type = 'basicauth'
self.prefixed_userid = 'basicauth:bob'
self.json = {}
self.validated = {}
self.matchdict = {}
self.response = mock.MagicMock(headers={})
def route_url(*a, **kw):
# XXX: refactor DummyRequest to take advantage of `pyramid.testing`
parts = parse_url_overrides(kw)
return ''.join([p for p in parts if p])
self.route_url = route_url
follow_subrequest = follow_subrequest
def get_request_class(prefix):
class PrefixedRequestClass(webtest.app.TestRequest):
@classmethod
def blank(cls, path, *args, **kwargs):
if prefix:
path = '/%s%s' % (prefix, path)
return webtest.app.TestRequest.blank(path, *args, **kwargs)
return PrefixedRequestClass
class FormattedErrorMixin(object):
"""Test mixin in order to perform advanced error responses assertions.
"""
def assertFormattedError(self, response, code, errno, error,
message=None, info=None):
if isinstance(errno, Enum):
errno = errno.value
self.assertEqual(response.headers['Content-Type'],
'application/json; charset=UTF-8')
self.assertEqual(response.json['code'], code)
self.assertEqual(response.json['errno'], errno)
self.assertEqual(response.json['error'], error)
if message is not None:
self.assertIn(message, response.json['message'])
else: # pragma: no cover
self.assertNotIn('message', response.json)
if info is not None:
self.assertIn(info, response.json['info'])
else: # pragma: no cover
self.assertNotIn('info', response.json)
def get_user_headers(user):
"""Helper to obtain a Basic Auth authorization headers from the specified
`user` (e.g. ``"user:pass"``)
:rtype: dict
"""
credentials = "%s:secret" % user
authorization = 'Basic {0}'.format(encode64(credentials))
return {
'Authorization': authorization
}
class BaseWebTest(object):
"""Base Web Test to test your kinto.core service.
It setups the database before each test and delete it after.
"""
api_prefix = "v0"
"""URL version prefix"""
entry_point = None
"""Main application entry"""
def __init__(self, *args, **kwargs):
super(BaseWebTest, self).__init__(*args, **kwargs)
self.app = self.make_app()
self.storage = self.app.app.registry.storage
self.cache = self.app.app.registry.cache
self.permission = self.app.app.registry.permission
self.storage.initialize_schema()
self.permission.initialize_schema()
self.cache.initialize_schema()
self.headers = {
'Content-Type': 'application/json'
}
def make_app(self, settings=None, config=None):
"""Instantiate the application and setup requests to use the api
prefix.
:param dict settings: extra settings values
:param pyramid.config.Configurator config: already initialized config
:returns: webtest application instance
"""
settings = self.get_app_settings(extras=settings)
try:
main = self.entry_point.__func__
except AttributeError: # pragma: no cover
main = self.entry_point.im_func
wsgi_app = main({}, config=config, **settings)
app = webtest.TestApp(wsgi_app)
app.RequestClass = get_request_class(self.api_prefix)
return app
def get_app_settings(self, extras=None):
"""Application settings to be used. Override to tweak default settings
for the tests.
:param dict extras: extra settings values
:rtype: dict
"""
settings = DEFAULT_SETTINGS.copy()
settings['storage_backend'] = 'kinto.core.storage.memory'
settings['cache_backend'] = 'kinto.core.cache.memory'
settings['permission_backend'] = 'kinto.core.permission.memory'
if extras is not None:
settings.update(extras)
return settings
def tearDown(self):
super(BaseWebTest, self).tearDown()
self.storage.flush()
self.cache.flush()
self.permission.flush()