1 | #!/bin/python |
---|
2 | # -*- coding: utf-8 -*- |
---|
3 | |
---|
4 | """ |
---|
5 | Unit tests for gluon.tools |
---|
6 | """ |
---|
7 | import os |
---|
8 | import sys |
---|
9 | import shutil |
---|
10 | import tempfile |
---|
11 | import smtplib |
---|
12 | import datetime |
---|
13 | import unittest |
---|
14 | |
---|
15 | DEFAULT_URI = os.getenv('DB', 'sqlite:memory') |
---|
16 | |
---|
17 | from gluon.dal import DAL, Field |
---|
18 | from pydal.objects import Table |
---|
19 | from gluon import tools |
---|
20 | from gluon.tools import Auth, Mail, Recaptcha2, prettydate, Expose |
---|
21 | from gluon._compat import PY2, to_bytes |
---|
22 | from gluon.globals import Request, Response, Session |
---|
23 | from gluon.storage import Storage |
---|
24 | from gluon.languages import TranslatorFactory |
---|
25 | from gluon.http import HTTP |
---|
26 | from gluon import SPAN, H3, TABLE, TR, TD, A, URL, current |
---|
27 | |
---|
28 | IS_IMAP = "imap" in DEFAULT_URI |
---|
29 | |
---|
30 | |
---|
31 | class TestMail(unittest.TestCase): |
---|
32 | """ |
---|
33 | Test the Mail class. |
---|
34 | """ |
---|
35 | |
---|
36 | class Message(object): |
---|
37 | |
---|
38 | def __init__(self, sender, to, payload): |
---|
39 | self.sender = sender |
---|
40 | self.to = to |
---|
41 | self.payload = payload |
---|
42 | self._parsed_payload = None |
---|
43 | |
---|
44 | @property |
---|
45 | def parsed_payload(self): |
---|
46 | if self._parsed_payload is None: |
---|
47 | import email |
---|
48 | self._parsed_payload = email.message_from_string(self.payload) |
---|
49 | return self._parsed_payload |
---|
50 | |
---|
51 | class DummySMTP(object): |
---|
52 | """ |
---|
53 | Dummy smtp server |
---|
54 | |
---|
55 | NOTE: Test methods should take care of always leaving inbox and users empty when they finish. |
---|
56 | """ |
---|
57 | inbox = [] |
---|
58 | users = {} |
---|
59 | |
---|
60 | def __init__(self, address, port, **kwargs): |
---|
61 | self.address = address |
---|
62 | self.port = port |
---|
63 | self.has_quit = False |
---|
64 | self.tls = False |
---|
65 | |
---|
66 | def login(self, username, password): |
---|
67 | if username not in self.users or self.users[username] != password: |
---|
68 | raise smtplib.SMTPAuthenticationError |
---|
69 | self.username = username |
---|
70 | self.password = password |
---|
71 | |
---|
72 | def sendmail(self, sender, to, payload): |
---|
73 | self.inbox.append(TestMail.Message(sender, to, payload)) |
---|
74 | |
---|
75 | def quit(self): |
---|
76 | self.has_quit = True |
---|
77 | |
---|
78 | def ehlo(self, hostname=None): |
---|
79 | pass |
---|
80 | |
---|
81 | def starttls(self): |
---|
82 | self.tls = True |
---|
83 | |
---|
84 | def setUp(self): |
---|
85 | self.original_SMTP = smtplib.SMTP |
---|
86 | self.original_SMTP_SSL = smtplib.SMTP_SSL |
---|
87 | smtplib.SMTP = TestMail.DummySMTP |
---|
88 | smtplib.SMTP_SSL = TestMail.DummySMTP |
---|
89 | |
---|
90 | def tearDown(self): |
---|
91 | smtplib.SMTP = self.original_SMTP |
---|
92 | smtplib.SMTP_SSL = self.original_SMTP_SSL |
---|
93 | |
---|
94 | def test_hello_world(self): |
---|
95 | mail = Mail() |
---|
96 | mail.settings.server = 'smtp.example.com:25' |
---|
97 | mail.settings.sender = 'you@example.com' |
---|
98 | self.assertTrue(mail.send(to=['somebody@example.com'], |
---|
99 | subject='hello', |
---|
100 | # If reply_to is omitted, then mail.settings.sender is used |
---|
101 | reply_to='us@example.com', |
---|
102 | message='world')) |
---|
103 | message = TestMail.DummySMTP.inbox.pop() |
---|
104 | self.assertEqual(message.sender, mail.settings.sender) |
---|
105 | self.assertEqual(message.to, ['somebody@example.com']) |
---|
106 | header = "To: somebody@example.com\nReply-To: us@example.com\nSubject: hello\n" |
---|
107 | self.assertTrue(header in message.payload) |
---|
108 | self.assertTrue(message.payload.endswith('world')) |
---|
109 | |
---|
110 | def test_failed_login(self): |
---|
111 | mail = Mail() |
---|
112 | mail.settings.server = 'smtp.example.com:25' |
---|
113 | mail.settings.sender = 'you@example.com' |
---|
114 | mail.settings.login = 'username:password' |
---|
115 | self.assertFalse(mail.send(to=['somebody@example.com'], |
---|
116 | subject='hello', |
---|
117 | # If reply_to is omitted, then mail.settings.sender is used |
---|
118 | reply_to='us@example.com', |
---|
119 | message='world')) |
---|
120 | |
---|
121 | def test_login(self): |
---|
122 | TestMail.DummySMTP.users['username'] = 'password' |
---|
123 | mail = Mail() |
---|
124 | mail.settings.server = 'smtp.example.com:25' |
---|
125 | mail.settings.sender = 'you@example.com' |
---|
126 | mail.settings.login = 'username:password' |
---|
127 | self.assertTrue(mail.send(to=['somebody@example.com'], |
---|
128 | subject='hello', |
---|
129 | # If reply_to is omitted, then mail.settings.sender is used |
---|
130 | reply_to='us@example.com', |
---|
131 | message='world')) |
---|
132 | del TestMail.DummySMTP.users['username'] |
---|
133 | TestMail.DummySMTP.inbox.pop() |
---|
134 | |
---|
135 | def test_html(self): |
---|
136 | mail = Mail() |
---|
137 | mail.settings.server = 'smtp.example.com:25' |
---|
138 | mail.settings.sender = 'you@example.com' |
---|
139 | self.assertTrue(mail.send(to=['somebody@example.com'], |
---|
140 | subject='hello', |
---|
141 | # If reply_to is omitted, then mail.settings.sender is used |
---|
142 | reply_to='us@example.com', |
---|
143 | message='<html><head></head><body></body></html>')) |
---|
144 | message = TestMail.DummySMTP.inbox.pop() |
---|
145 | self.assertTrue('Content-Type: text/html' in message.payload) |
---|
146 | |
---|
147 | def test_alternative(self): |
---|
148 | mail = Mail() |
---|
149 | mail.settings.server = 'smtp.example.com:25' |
---|
150 | mail.settings.sender = 'you@example.com' |
---|
151 | self.assertTrue(mail.send(to=['somebody@example.com'], |
---|
152 | message=('Text only', '<html><pre>HTML Only</pre></html>'))) |
---|
153 | message = TestMail.DummySMTP.inbox.pop() |
---|
154 | self.assertTrue(message.parsed_payload.is_multipart()) |
---|
155 | self.assertTrue(message.parsed_payload.get_content_type() == 'multipart/alternative') |
---|
156 | parts = message.parsed_payload.get_payload() |
---|
157 | self.assertTrue('Text only' in parts[0].as_string()) |
---|
158 | self.assertTrue('<html><pre>HTML Only</pre></html>' in parts[1].as_string()) |
---|
159 | |
---|
160 | def test_ssl(self): |
---|
161 | mail = Mail() |
---|
162 | mail.settings.server = 'smtp.example.com:25' |
---|
163 | mail.settings.sender = 'you@example.com' |
---|
164 | mail.settings.ssl = True |
---|
165 | self.assertTrue(mail.send(to=['somebody@example.com'], |
---|
166 | subject='hello', |
---|
167 | # If reply_to is omitted, then mail.settings.sender is used |
---|
168 | reply_to='us@example.com', |
---|
169 | message='world')) |
---|
170 | TestMail.DummySMTP.inbox.pop() |
---|
171 | |
---|
172 | def test_tls(self): |
---|
173 | mail = Mail() |
---|
174 | mail.settings.server = 'smtp.example.com:25' |
---|
175 | mail.settings.sender = 'you@example.com' |
---|
176 | mail.settings.tls = True |
---|
177 | self.assertTrue(mail.send(to=['somebody@example.com'], |
---|
178 | subject='hello', |
---|
179 | # If reply_to is omitted, then mail.settings.sender is used |
---|
180 | reply_to='us@example.com', |
---|
181 | message='world')) |
---|
182 | TestMail.DummySMTP.inbox.pop() |
---|
183 | |
---|
184 | def test_attachment(self): |
---|
185 | module_file = os.path.abspath(__file__) |
---|
186 | mail = Mail() |
---|
187 | mail.settings.server = 'smtp.example.com:25' |
---|
188 | mail.settings.sender = 'you@example.com' |
---|
189 | self.assertTrue(mail.send(to=['somebody@example.com'], |
---|
190 | subject='hello', |
---|
191 | message='world', |
---|
192 | attachments=Mail.Attachment(module_file))) |
---|
193 | message = TestMail.DummySMTP.inbox.pop() |
---|
194 | attachment = message.parsed_payload.get_payload(1).get_payload(decode=True) |
---|
195 | with open(module_file, 'rb') as mf: |
---|
196 | self.assertEqual(to_bytes(attachment), to_bytes(mf.read())) |
---|
197 | # Test missing attachment name error |
---|
198 | stream = open(module_file) |
---|
199 | self.assertRaises(Exception, lambda *args, **kwargs: Mail.Attachment(*args, **kwargs), stream) |
---|
200 | stream.close() |
---|
201 | # Test you can define content-id and content type |
---|
202 | self.assertTrue(mail.send(to=['somebody@example.com'], |
---|
203 | subject='hello', |
---|
204 | message='world', |
---|
205 | attachments=Mail.Attachment(module_file, content_id='trololo', content_type='tra/lala'))) |
---|
206 | message = TestMail.DummySMTP.inbox.pop() |
---|
207 | self.assertTrue('Content-Type: tra/lala' in message.payload) |
---|
208 | self.assertTrue('Content-Id: <trololo>' in message.payload) |
---|
209 | |
---|
210 | |
---|
211 | # TODO: class TestAuthJWT(unittest.TestCase): |
---|
212 | class TestAuthJWT(unittest.TestCase): |
---|
213 | def setUp(self): |
---|
214 | from gluon.tools import AuthJWT |
---|
215 | |
---|
216 | from gluon import current |
---|
217 | |
---|
218 | self.request = Request(env={}) |
---|
219 | self.request.application = 'a' |
---|
220 | self.request.controller = 'c' |
---|
221 | self.request.function = 'f' |
---|
222 | self.request.folder = 'applications/admin' |
---|
223 | self.current = current |
---|
224 | self.current.request = self.request |
---|
225 | |
---|
226 | self.db = DAL(DEFAULT_URI, check_reserved=['all']) |
---|
227 | self.auth = Auth(self.db) |
---|
228 | self.auth.define_tables(username=True, signature=False) |
---|
229 | self.user_data = dict(username='jwtuser', password='jwtuser123') |
---|
230 | self.db.auth_user.insert(username=self.user_data['username'], |
---|
231 | password=str( |
---|
232 | self.db.auth_user.password.requires[0]( |
---|
233 | self.user_data['password'])[0])) |
---|
234 | self.jwtauth = AuthJWT(self.auth, secret_key='secret', verify_expiration=True) |
---|
235 | |
---|
236 | def test_jwt_token_manager(self): |
---|
237 | import gluon.serializers |
---|
238 | self.request.vars.update(self.user_data) |
---|
239 | self.token = self.jwtauth.jwt_token_manager() |
---|
240 | self.assertIsNotNone(self.token) |
---|
241 | del self.request.vars['username'] |
---|
242 | del self.request.vars['password'] |
---|
243 | self.request.vars._token = gluon.serializers.json_parser.loads(self.token)['token'] |
---|
244 | self.token = self.jwtauth.jwt_token_manager() |
---|
245 | self.assertIsNotNone(self.token) |
---|
246 | |
---|
247 | def test_allows_jwt(self): |
---|
248 | import gluon.serializers |
---|
249 | self.request.vars.update(self.user_data) |
---|
250 | self.token = self.jwtauth.jwt_token_manager() |
---|
251 | self.assertIsNotNone(self.token) |
---|
252 | del self.request.vars['username'] |
---|
253 | del self.request.vars['password'] |
---|
254 | self.token = self.jwtauth.jwt_token_manager() |
---|
255 | self.request.vars._token = gluon.serializers.json_parser.loads(self.token)['token'] |
---|
256 | |
---|
257 | @self.jwtauth.allows_jwt() |
---|
258 | def optional_auth(): |
---|
259 | self.assertEqual(self.user_data['username'], self.auth.user.username) |
---|
260 | optional_auth() |
---|
261 | |
---|
262 | |
---|
263 | @unittest.skipIf(IS_IMAP, "TODO: Imap raises 'Connection refused'") |
---|
264 | # class TestAuth(unittest.TestCase): |
---|
265 | # |
---|
266 | # def setUp(self): |
---|
267 | # request = Request(env={}) |
---|
268 | # request.application = 'a' |
---|
269 | # request.controller = 'c' |
---|
270 | # request.function = 'f' |
---|
271 | # request.folder = 'applications/admin' |
---|
272 | # response = Response() |
---|
273 | # session = Session() |
---|
274 | # T = TranslatorFactory('', 'en') |
---|
275 | # session.connect(request, response) |
---|
276 | # from gluon.globals import current |
---|
277 | # current.request = request |
---|
278 | # current.response = response |
---|
279 | # current.session = session |
---|
280 | # current.T = T |
---|
281 | # self.db = DAL(DEFAULT_URI, check_reserved=['all']) |
---|
282 | # self.auth = Auth(self.db) |
---|
283 | # self.auth.define_tables(username=True, signature=False) |
---|
284 | # self.db.define_table('t0', Field('tt'), self.auth.signature) |
---|
285 | # self.auth.enable_record_versioning(self.db) |
---|
286 | # # Create a user |
---|
287 | # self.auth.get_or_create_user(dict(first_name='Bart', |
---|
288 | # last_name='Simpson', |
---|
289 | # username='bart', |
---|
290 | # email='bart@simpson.com', |
---|
291 | # password='bart_password', |
---|
292 | # registration_key='bart', |
---|
293 | # registration_id='' |
---|
294 | # )) |
---|
295 | # # self.auth.settings.registration_requires_verification = False |
---|
296 | # # self.auth.settings.registration_requires_approval = False |
---|
297 | # |
---|
298 | # def test_assert_setup(self): |
---|
299 | # self.assertEqual(self.db(self.db.auth_user.username == 'bart').select().first()['username'], 'bart') |
---|
300 | # self.assertTrue('auth_user' in self.db) |
---|
301 | # self.assertTrue('auth_group' in self.db) |
---|
302 | # self.assertTrue('auth_membership' in self.db) |
---|
303 | # self.assertTrue('auth_permission' in self.db) |
---|
304 | # self.assertTrue('auth_event' in self.db) |
---|
305 | # |
---|
306 | # def test_enable_record_versioning(self): |
---|
307 | # self.assertTrue('t0_archive' in self.db) |
---|
308 | # |
---|
309 | # def test_basic_blank_forms(self): |
---|
310 | # for f in ['login', 'retrieve_password', |
---|
311 | # 'retrieve_username', |
---|
312 | # # 'register' # register complain about : client_side=self.settings.client_side |
---|
313 | # ]: |
---|
314 | # html_form = getattr(self.auth, f)().xml() |
---|
315 | # self.assertTrue('name="_formkey"' in html_form) |
---|
316 | # |
---|
317 | # # NOTE: Not sure it is the proper way to logout_bare() as there is not methods for that and auth.logout() failed |
---|
318 | # self.auth.logout_bare() |
---|
319 | # # self.assertTrue(self.auth.is_logged_in()) |
---|
320 | # |
---|
321 | # for f in ['logout', 'verify_email', 'reset_password', |
---|
322 | # 'change_password', 'profile', 'groups']: |
---|
323 | # self.assertRaisesRegexp(HTTP, "303*", getattr(self.auth, f)) |
---|
324 | # |
---|
325 | # self.assertRaisesRegexp(HTTP, "401*", self.auth.impersonate) |
---|
326 | # |
---|
327 | # try: |
---|
328 | # for t in ['t0_archive', 't0', 'auth_cas', 'auth_event', |
---|
329 | # 'auth_membership', 'auth_permission', 'auth_group', |
---|
330 | # 'auth_user']: |
---|
331 | # self.db[t].drop() |
---|
332 | # except SyntaxError as e: |
---|
333 | # # GAE doesn't support drop |
---|
334 | # pass |
---|
335 | # return |
---|
336 | # |
---|
337 | # def test_get_or_create_user(self): |
---|
338 | # self.db.auth_user.insert(email='user1@test.com', username='user1', password='password_123') |
---|
339 | # self.db.commit() |
---|
340 | # # True case |
---|
341 | # self.assertEqual(self.auth.get_or_create_user({'email': 'user1@test.com', |
---|
342 | # 'username': 'user1', |
---|
343 | # 'password': 'password_123' |
---|
344 | # })['username'], 'user1') |
---|
345 | # # user2 doesn't exist yet and get created |
---|
346 | # self.assertEqual(self.auth.get_or_create_user({'email': 'user2@test.com', |
---|
347 | # 'username': 'user2'})['username'], 'user2') |
---|
348 | # # user3 for corner case |
---|
349 | # self.assertEqual(self.auth.get_or_create_user({'first_name': 'Omer', |
---|
350 | # 'last_name': 'Simpson', |
---|
351 | # 'email': 'user3@test.com', |
---|
352 | # 'registration_id': 'user3', |
---|
353 | # 'username': 'user3'})['username'], 'user3') |
---|
354 | # # False case |
---|
355 | # self.assertEqual(self.auth.get_or_create_user({'email': ''}), None) |
---|
356 | # self.db.auth_user.truncate() |
---|
357 | # self.db.commit() |
---|
358 | # |
---|
359 | # def test_login_bare(self): |
---|
360 | # # The following test case should succeed but failed as I never received the user record but False |
---|
361 | # self.auth.login_bare(username='bart@simpson.com', password='bart_password') |
---|
362 | # self.assertTrue(self.auth.is_logged_in()) |
---|
363 | # # Failing login because bad_password |
---|
364 | # self.assertEqual(self.auth.login_bare(username='bart', password='wrong_password'), False) |
---|
365 | # self.db.auth_user.truncate() |
---|
366 | # |
---|
367 | # def test_register_bare(self): |
---|
368 | # # corner case empty register call register_bare without args |
---|
369 | # self.assertRaises(ValueError, self.auth.register_bare) |
---|
370 | # # failing register_bare user already exist |
---|
371 | # self.assertEqual(self.auth.register_bare(username='bart', password='wrong_password'), False) |
---|
372 | # # successful register_bare |
---|
373 | # self.assertEqual(self.auth.register_bare(username='user2', |
---|
374 | # email='user2@test.com', |
---|
375 | # password='password_123')['username'], 'user2') |
---|
376 | # # raise ValueError |
---|
377 | # self.assertRaises(ValueError, self.auth.register_bare, |
---|
378 | # **dict(wrong_field_name='user3', password='password_123')) |
---|
379 | # # raise ValueError wrong email |
---|
380 | # self.assertRaises(ValueError, self.auth.register_bare, |
---|
381 | # **dict(email='user4@', password='password_123')) |
---|
382 | # self.db.auth_user.truncate() |
---|
383 | # self.db.commit() |
---|
384 | # |
---|
385 | # def test_bulk_register(self): |
---|
386 | # self.auth.login_bare(username='bart', password='bart_password') |
---|
387 | # self.auth.settings.bulk_register_enabled = True |
---|
388 | # bulk_register_form = self.auth.bulk_register(max_emails=10).xml() |
---|
389 | # self.assertTrue('name="_formkey"' in bulk_register_form) |
---|
390 | # |
---|
391 | # def test_change_password(self): |
---|
392 | # self.auth.login_bare(username='bart', password='bart_password') |
---|
393 | # change_password_form = getattr(self.auth, 'change_password')().xml() |
---|
394 | # self.assertTrue('name="_formkey"' in change_password_form) |
---|
395 | # |
---|
396 | # def test_profile(self): |
---|
397 | # self.auth.login_bare(username='bart', password='bart_password') |
---|
398 | # profile_form = getattr(self.auth, 'profile')().xml() |
---|
399 | # self.assertTrue('name="_formkey"' in profile_form) |
---|
400 | # |
---|
401 | # # def test_impersonate(self): |
---|
402 | # # # Create a user to be impersonated |
---|
403 | # # self.auth.get_or_create_user(dict(first_name='Omer', |
---|
404 | # # last_name='Simpson', |
---|
405 | # # username='omer', |
---|
406 | # # email='omer@test.com', |
---|
407 | # # password='password_omer', |
---|
408 | # # registration_key='', |
---|
409 | # # registration_id='')) |
---|
410 | # # # Create impersonate group, assign bart to impersonate group and add impersonate permission over auth_user |
---|
411 | # # self.auth.add_group('impersonate') |
---|
412 | # # self.auth.add_membership(user_id=1, |
---|
413 | # # group_id=self.db(self.db.auth_user.username == 'bart' |
---|
414 | # # ).select(self.db.auth_user.id).first().id) |
---|
415 | # # self.auth.add_permission(group_id=self.db(self.db.auth_group.role == 'impersonate' |
---|
416 | # # ).select(self.db.auth_group.id).first().id, |
---|
417 | # # name='impersonate', |
---|
418 | # # table_name='auth_user', |
---|
419 | # # record_id=0) |
---|
420 | # # # Bart login |
---|
421 | # # self.auth.login_bare(username='bart', password='bart_password') |
---|
422 | # # self.assertTrue(self.auth.is_logged_in()) |
---|
423 | # # # Bart impersonate Omer |
---|
424 | # # omer_id = self.db(self.db.auth_user.username == 'omer').select(self.db.auth_user.id).first().id |
---|
425 | # # impersonate_form = self.auth.impersonate(user_id=omer_id) |
---|
426 | # # self.assertTrue(self.auth.is_impersonating()) |
---|
427 | # # self.assertEqual(impersonate_form, 'test') |
---|
428 | # |
---|
429 | # # def test_impersonate(self): |
---|
430 | # # request = Request(env={}) |
---|
431 | # # request.application = 'a' |
---|
432 | # # request.controller = 'c' |
---|
433 | # # request.function = 'f' |
---|
434 | # # request.folder = 'applications/admin' |
---|
435 | # # response = Response() |
---|
436 | # # session = Session() |
---|
437 | # # T = TranslatorFactory('', 'en') |
---|
438 | # # session.connect(request, response) |
---|
439 | # # from gluon.globals import current |
---|
440 | # # current.request = request |
---|
441 | # # current.response = response |
---|
442 | # # current.session = session |
---|
443 | # # current.T = T |
---|
444 | # # db = DAL(DEFAULT_URI, check_reserved=['all']) |
---|
445 | # # auth = Auth(db) |
---|
446 | # # auth.define_tables(username=True, signature=False) |
---|
447 | # # db.define_table('t0', Field('tt'), auth.signature) |
---|
448 | # # auth.enable_record_versioning(db) |
---|
449 | # # # Create a user |
---|
450 | # # auth.get_or_create_user(dict(first_name='Bart', |
---|
451 | # # last_name='Simpson', |
---|
452 | # # username='bart', |
---|
453 | # # email='bart@simpson.com', |
---|
454 | # # password='bart_password', |
---|
455 | # # registration_key='bart', |
---|
456 | # # registration_id='' |
---|
457 | # # )) |
---|
458 | # # # Create a user to be impersonated |
---|
459 | # # auth.get_or_create_user(dict(first_name='Omer', |
---|
460 | # # last_name='Simpson', |
---|
461 | # # username='omer', |
---|
462 | # # email='omer@test.com', |
---|
463 | # # password='password_omer', |
---|
464 | # # registration_key='', |
---|
465 | # # registration_id='')) |
---|
466 | # # # Create impersonate group, assign bart to impersonate group and add impersonate permission over auth_user |
---|
467 | # # auth.add_group('impersonate') |
---|
468 | # # auth.add_membership(user_id=1, |
---|
469 | # # group_id=db(db.auth_user.username == 'bart' |
---|
470 | # # ).select(db.auth_user.id).first().id) |
---|
471 | # # auth.add_permission(group_id=db(db.auth_group.role == 'impersonate' |
---|
472 | # # ).select(db.auth_group.id).first().id, |
---|
473 | # # name='impersonate', |
---|
474 | # # table_name='auth_user', |
---|
475 | # # record_id=0) |
---|
476 | # # # Bart login |
---|
477 | # # auth.login_bare(username='bart', password='bart_password') |
---|
478 | # # # Bart impersonate Omer |
---|
479 | # # omer_id = db(db.auth_user.username == 'omer').select(db.auth_user.id).first().id |
---|
480 | # # impersonate_form = auth.impersonate(user_id=omer_id) |
---|
481 | # # self.assertTrue(auth.is_impersonating()) |
---|
482 | # # self.assertEqual(impersonate_form, 'test') |
---|
483 | class TestAuth(unittest.TestCase): |
---|
484 | |
---|
485 | def myassertRaisesRegex(self, *args, **kwargs): |
---|
486 | if PY2: |
---|
487 | return getattr(self, 'assertRaisesRegexp')(*args, **kwargs) |
---|
488 | return getattr(self, 'assertRaisesRegex')(*args, **kwargs) |
---|
489 | |
---|
490 | def setUp(self): |
---|
491 | self.request = Request(env={}) |
---|
492 | self.request.application = 'a' |
---|
493 | self.request.controller = 'c' |
---|
494 | self.request.function = 'f' |
---|
495 | self.request.folder = 'applications/admin' |
---|
496 | self.response = Response() |
---|
497 | self.session = Session() |
---|
498 | T = TranslatorFactory('', 'en') |
---|
499 | self.session.connect(self.request, self.response) |
---|
500 | from gluon.globals import current |
---|
501 | self.current = current |
---|
502 | self.current.request = self.request |
---|
503 | self.current.response = self.response |
---|
504 | self.current.session = self.session |
---|
505 | self.current.T = T |
---|
506 | self.db = DAL(DEFAULT_URI, check_reserved=['all']) |
---|
507 | self.auth = Auth(self.db) |
---|
508 | self.auth.define_tables(username=True, signature=False) |
---|
509 | self.db.define_table('t0', Field('tt'), self.auth.signature) |
---|
510 | self.auth.enable_record_versioning(self.db) |
---|
511 | self.auth.settings.registration_requires_verification = False |
---|
512 | self.auth.settings.registration_requires_approval = False |
---|
513 | # Create a user |
---|
514 | # Note: get_or_create_user() doesn't seems to create user properly it better to use register_bare() and |
---|
515 | # prevent login_bare() test from succeed. db insert the user manually not properly work either. |
---|
516 | # Not working |
---|
517 | # self.auth.get_or_create_user(dict(first_name='Bart', |
---|
518 | # last_name='Simpson', |
---|
519 | # username='bart', |
---|
520 | # email='bart@simpson.com', |
---|
521 | # password='bart_password', |
---|
522 | # # registration_key=None, |
---|
523 | # #registration_id='bart@simpson.com' |
---|
524 | # ), |
---|
525 | # login=False) |
---|
526 | # Not working |
---|
527 | # self.db.auth_user.insert(first_name='Bart', |
---|
528 | # last_name='Simpson', |
---|
529 | # username='bart', |
---|
530 | # email='bart@simpson.com', |
---|
531 | # password='bart_password') |
---|
532 | # self.db.commit() |
---|
533 | self.auth.register_bare(first_name='Bart', |
---|
534 | last_name='Simpson', |
---|
535 | username='bart', |
---|
536 | email='bart@simpson.com', |
---|
537 | password='bart_password') |
---|
538 | |
---|
539 | def test_assert_setup(self): |
---|
540 | self.assertTrue('auth_user' in self.db) |
---|
541 | self.assertTrue('auth_group' in self.db) |
---|
542 | self.assertTrue('auth_membership' in self.db) |
---|
543 | self.assertTrue('auth_permission' in self.db) |
---|
544 | self.assertTrue('auth_event' in self.db) |
---|
545 | bart_record = self.db(self.db.auth_user.username == 'bart').select().first() |
---|
546 | self.assertEqual(bart_record['username'], 'bart') |
---|
547 | self.assertEqual(bart_record['registration_key'], '') |
---|
548 | bart_id = self.db(self.db.auth_user.username == 'bart').select().first().id |
---|
549 | bart_group_id = self.db(self.db.auth_group.role == 'user_{0}'.format(bart_id)).select().first().id |
---|
550 | self.assertTrue(self.db((self.db.auth_membership.group_id == bart_group_id) & |
---|
551 | (self.db.auth_membership.user_id == bart_id)).select().first()) |
---|
552 | |
---|
553 | # Just calling many form functions |
---|
554 | def test_basic_blank_forms(self): |
---|
555 | for f in ['login', 'retrieve_password', 'retrieve_username', 'register']: |
---|
556 | html_form = getattr(self.auth, f)().xml() |
---|
557 | self.assertTrue(b'name="_formkey"' in html_form) |
---|
558 | |
---|
559 | for f in ['logout', 'verify_email', 'reset_password', 'change_password', 'profile', 'groups']: |
---|
560 | self.myassertRaisesRegex(HTTP, "303*", getattr(self.auth, f)) |
---|
561 | |
---|
562 | self.myassertRaisesRegex(HTTP, "401*", self.auth.impersonate) |
---|
563 | |
---|
564 | try: |
---|
565 | for t in ['t0_archive', 't0', 'auth_cas', 'auth_event', |
---|
566 | 'auth_membership', 'auth_permission', 'auth_group', |
---|
567 | 'auth_user']: |
---|
568 | self.db[t].drop() |
---|
569 | except SyntaxError as e: |
---|
570 | # GAE doesn't support drop |
---|
571 | pass |
---|
572 | return |
---|
573 | |
---|
574 | def test_get_vars_next(self): |
---|
575 | self.current.request.vars._next = 'next_test' |
---|
576 | self.assertEqual(self.auth.get_vars_next(), 'next_test') |
---|
577 | |
---|
578 | # TODO: def test_navbar(self): |
---|
579 | # TODO: def test___get_migrate(self): |
---|
580 | |
---|
581 | def test_enable_record_versioning(self): |
---|
582 | self.assertTrue('t0_archive' in self.db) |
---|
583 | |
---|
584 | # TODO: def test_define_signature(self): |
---|
585 | # TODO: def test_define_signature(self): |
---|
586 | # TODO: def test_define_table(self): |
---|
587 | |
---|
588 | def test_log_event(self): |
---|
589 | self.auth.login_user(self.db(self.db.auth_user.username == 'bart').select().first()) # bypass login_bare() |
---|
590 | bart_id = self.db(self.db.auth_user.username == 'bart').select(self.db.auth_user.id).first().id |
---|
591 | # user logged in |
---|
592 | self.auth.log_event(description='some_log_event_description_%(var1)s', |
---|
593 | vars={"var1": "var1"}, |
---|
594 | origin='log_event_test_1') |
---|
595 | rtn = self.db(self.db.auth_event.origin == 'log_event_test_1' |
---|
596 | ).select(*[self.db.auth_event[f] |
---|
597 | for f in self.db.auth_event.fields if f not in ('id', 'time_stamp')]).first().as_dict() |
---|
598 | self.assertEqual(set(rtn.items()), set({'origin': 'log_event_test_1', |
---|
599 | 'client_ip': None, |
---|
600 | 'user_id': bart_id, |
---|
601 | 'description': 'some_log_event_description_var1'}.items())) |
---|
602 | # user not logged |
---|
603 | self.auth.logout_bare() |
---|
604 | self.auth.log_event(description='some_log_event_description_%(var2)s', |
---|
605 | vars={"var2": "var2"}, |
---|
606 | origin='log_event_test_2') |
---|
607 | rtn = self.db(self.db.auth_event.origin == 'log_event_test_2' |
---|
608 | ).select(*[self.db.auth_event[f] |
---|
609 | for f in self.db.auth_event.fields if f not in ('id', 'time_stamp')]).first().as_dict() |
---|
610 | self.assertEqual(set(rtn.items()), set({'origin': 'log_event_test_2', |
---|
611 | 'client_ip': None, |
---|
612 | 'user_id': None, |
---|
613 | 'description': 'some_log_event_description_var2'}.items())) |
---|
614 | # no logging tests |
---|
615 | self.auth.settings.logging_enabled = False |
---|
616 | count_log_event_test_before = self.db(self.db.auth_event.id > 0).count() |
---|
617 | self.auth.log_event(description='some_log_event_description_%(var3)s', |
---|
618 | vars={"var3": "var3"}, |
---|
619 | origin='log_event_test_3') |
---|
620 | count_log_event_test_after = self.db(self.db.auth_event.id > 0).count() |
---|
621 | self.assertEqual(count_log_event_test_after, count_log_event_test_before) |
---|
622 | self.auth.settings.logging_enabled = True |
---|
623 | count_log_event_test_before = self.db(self.db.auth_event.id > 0).count() |
---|
624 | self.auth.log_event(description=None, |
---|
625 | vars={"var4": "var4"}, |
---|
626 | origin='log_event_test_4') |
---|
627 | count_log_event_test_after = self.db(self.db.auth_event.id > 0).count() |
---|
628 | self.assertEqual(count_log_event_test_after, count_log_event_test_before) |
---|
629 | # TODO: Corner case translated description... |
---|
630 | |
---|
631 | def test_get_or_create_user(self): |
---|
632 | self.db.auth_user.insert(email='user1@test.com', username='user1', password='password_123') |
---|
633 | self.db.commit() |
---|
634 | # True case |
---|
635 | self.assertEqual(self.auth.get_or_create_user({'email': 'user1@test.com', |
---|
636 | 'username': 'user1', |
---|
637 | 'password': 'password_123' |
---|
638 | })['username'], 'user1') |
---|
639 | # user2 doesn't exist yet and get created |
---|
640 | self.assertEqual(self.auth.get_or_create_user({'email': 'user2@test.com', |
---|
641 | 'username': 'user2'})['username'], 'user2') |
---|
642 | # user3 for corner case |
---|
643 | self.assertEqual(self.auth.get_or_create_user({'first_name': 'Omer', |
---|
644 | 'last_name': 'Simpson', |
---|
645 | 'email': 'user3@test.com', |
---|
646 | 'registration_id': 'user3', |
---|
647 | 'username': 'user3'})['username'], 'user3') |
---|
648 | # False case |
---|
649 | self.assertEqual(self.auth.get_or_create_user({'email': ''}), None) |
---|
650 | self.db.auth_user.truncate() |
---|
651 | self.db.commit() |
---|
652 | |
---|
653 | # TODO: def test_basic(self): |
---|
654 | # TODO: def test_login_user(self): |
---|
655 | # TODO: def test__get_login_settings(self): |
---|
656 | |
---|
657 | def test_login_bare(self): |
---|
658 | self.auth.login_bare(username='bart', password='bart_password') |
---|
659 | self.assertTrue(self.auth.is_logged_in()) |
---|
660 | self.auth.logout_bare() |
---|
661 | # Failing login because wrong_password |
---|
662 | self.assertFalse(self.auth.login_bare(username='bart', password='wrong_password')) |
---|
663 | # NOTE : The following failed for some reason, but I can't find out why |
---|
664 | # self.auth = Auth(self.db) |
---|
665 | # self.auth.define_tables(username=False, signature=False) |
---|
666 | # self.auth.settings.registration_requires_verification = False |
---|
667 | # self.auth.settings.registration_requires_approval = False |
---|
668 | # self.auth.register_bare(first_name='Omer', |
---|
669 | # last_name='Simpson', |
---|
670 | # # no username field passed, failed with : |
---|
671 | # # ValueError('register_bare: userfield not provided or invalid') |
---|
672 | # # Or |
---|
673 | # # username='omer', |
---|
674 | # # Or |
---|
675 | # # username='omer@simpson.com', |
---|
676 | # # In either previous cases, it failed with : |
---|
677 | # # self.assertTrue(self.auth.is_logged_in()) AssertionError: False is not true |
---|
678 | # email='omer@simpson.com', |
---|
679 | # password='omer_password') |
---|
680 | # self.auth.login_bare(username='omer@sympson.com', password='omer_password') |
---|
681 | # self.assertTrue(self.auth.is_logged_in()) |
---|
682 | |
---|
683 | def test_register_bare(self): |
---|
684 | # corner case empty register call register_bare without args |
---|
685 | self.assertRaises(ValueError, self.auth.register_bare) |
---|
686 | # failing register_bare user already exist |
---|
687 | self.assertEqual(self.auth.register_bare(username='bart', password='wrong_password'), False) |
---|
688 | # successful register_bare |
---|
689 | self.assertEqual(self.auth.register_bare(username='user2', |
---|
690 | email='user2@test.com', |
---|
691 | password='password_123')['username'], 'user2') |
---|
692 | # raise ValueError |
---|
693 | self.assertRaises(ValueError, self.auth.register_bare, |
---|
694 | **dict(wrong_field_name='user3', password='password_123')) |
---|
695 | # raise ValueError wrong email |
---|
696 | self.assertRaises(ValueError, self.auth.register_bare, |
---|
697 | **dict(email='user4@', password='password_123')) |
---|
698 | self.db.auth_user.truncate() |
---|
699 | self.db.commit() |
---|
700 | |
---|
701 | # TODO: def test_cas_login(self): |
---|
702 | # TODO: def test_cas_validate(self): |
---|
703 | # TODO: def test__reset_two_factor_auth(self): |
---|
704 | # TODO: def test_when_is_logged_in_bypass_next_in_url(self): |
---|
705 | # TODO: def test_login(self): |
---|
706 | # TODO: def test_logout(self): |
---|
707 | |
---|
708 | def test_logout_bare(self): |
---|
709 | self.auth.login_user(self.db(self.db.auth_user.username == 'bart').select().first()) # bypass login_bare() |
---|
710 | self.assertTrue(self.auth.is_logged_in()) |
---|
711 | self.auth.logout_bare() |
---|
712 | self.assertFalse(self.auth.is_logged_in()) |
---|
713 | |
---|
714 | # TODO: def test_register(self): |
---|
715 | |
---|
716 | def test_is_logged_in(self): |
---|
717 | self.auth.user = 'logged_in' |
---|
718 | self.assertTrue(self.auth.is_logged_in()) |
---|
719 | self.auth.user = None |
---|
720 | self.assertFalse(self.auth.is_logged_in()) |
---|
721 | |
---|
722 | # TODO: def test_verify_email(self): |
---|
723 | # TODO: def test_retrieve_username(self): |
---|
724 | |
---|
725 | def test_random_password(self): |
---|
726 | # let just check that the function is callable |
---|
727 | self.assertTrue(self.auth.random_password()) |
---|
728 | |
---|
729 | # TODO: def test_reset_password_deprecated(self): |
---|
730 | # TODO: def test_confirm_registration(self): |
---|
731 | # TODO: def test_email_registration(self): |
---|
732 | |
---|
733 | def test_bulk_register(self): |
---|
734 | self.auth.login_user(self.db(self.db.auth_user.username == 'bart').select().first()) # bypass login_bare() |
---|
735 | self.auth.settings.bulk_register_enabled = True |
---|
736 | bulk_register_form = self.auth.bulk_register(max_emails=10).xml() |
---|
737 | self.assertTrue(b'name="_formkey"' in bulk_register_form) |
---|
738 | |
---|
739 | # TODO: def test_manage_tokens(self): |
---|
740 | # TODO: def test_reset_password(self): |
---|
741 | # TODO: def test_request_reset_password(self): |
---|
742 | # TODO: def test_email_reset_password(self): |
---|
743 | # TODO: def test_retrieve_password(self): |
---|
744 | |
---|
745 | def test_change_password(self): |
---|
746 | self.auth.login_user(self.db(self.db.auth_user.username == 'bart').select().first()) # bypass login_bare() |
---|
747 | change_password_form = getattr(self.auth, 'change_password')().xml() |
---|
748 | self.assertTrue(b'name="_formkey"' in change_password_form) |
---|
749 | |
---|
750 | def test_profile(self): |
---|
751 | self.auth.login_user(self.db(self.db.auth_user.username == 'bart').select().first()) # bypass login_bare() |
---|
752 | profile_form = getattr(self.auth, 'profile')().xml() |
---|
753 | self.assertTrue(b'name="_formkey"' in profile_form) |
---|
754 | |
---|
755 | # TODO: def test_run_login_onaccept(self): |
---|
756 | # TODO: def test_jwt(self): |
---|
757 | # TODO: def test_is_impersonating(self): |
---|
758 | |
---|
759 | def test_impersonate(self): |
---|
760 | # Create a user to be impersonated |
---|
761 | self.auth.get_or_create_user(dict(first_name='Omer', |
---|
762 | last_name='Simpson', |
---|
763 | username='omer', |
---|
764 | email='omer@test.com', |
---|
765 | password='password_omer', |
---|
766 | registration_key='', |
---|
767 | registration_id=''), |
---|
768 | login=False) |
---|
769 | self.db.commit() |
---|
770 | self.assertFalse(self.auth.is_logged_in()) |
---|
771 | # Create impersonate group, assign bart to impersonate group and add impersonate permission over auth_user |
---|
772 | group_id = self.auth.add_group('impersonate') |
---|
773 | self.auth.add_membership(user_id=self.db(self.db.auth_user.username == 'bart' |
---|
774 | ).select(self.db.auth_user.id).first().id, |
---|
775 | group_id=group_id) |
---|
776 | self.auth.add_permission(group_id=group_id, |
---|
777 | name='impersonate', |
---|
778 | table_name='auth_user', |
---|
779 | record_id=0) |
---|
780 | # Bart login |
---|
781 | # self.auth.login_bare(username='bart', password='bart_password') |
---|
782 | self.auth.login_user(self.db(self.db.auth_user.username == 'bart').select().first()) # bypass login_bare() |
---|
783 | self.assertTrue(self.auth.is_logged_in()) |
---|
784 | bart_id = self.db(self.db.auth_user.username == 'bart').select(self.db.auth_user.id).first().id |
---|
785 | self.assertEqual(self.auth.user_id, bart_id) |
---|
786 | # self.session.auth = self.auth |
---|
787 | # self.assertTrue(self.session.auth) |
---|
788 | |
---|
789 | # basic impersonate() test that return a read form |
---|
790 | self.assertEqual(self.auth.impersonate().xml(), |
---|
791 | b'<form action="#" enctype="multipart/form-data" method="post"><table><tr id="no_table_user_id__row"><td class="w2p_fl"><label class="" for="no_table_user_id" id="no_table_user_id__label">User Id: </label></td><td class="w2p_fw"><input class="integer" id="no_table_user_id" name="user_id" type="text" value="" /></td><td class="w2p_fc"></td></tr><tr id="submit_record__row"><td class="w2p_fl"></td><td class="w2p_fw"><input type="submit" value="Submit" /></td><td class="w2p_fc"></td></tr></table></form>') |
---|
792 | # bart impersonate itself |
---|
793 | self.assertEqual(self.auth.impersonate(bart_id), None) |
---|
794 | self.assertFalse(self.auth.is_impersonating()) # User shouldn't impersonate itself? |
---|
795 | # Bart impersonate Omer |
---|
796 | omer_id = self.db(self.db.auth_user.username == 'omer').select(self.db.auth_user.id).first().id |
---|
797 | impersonate_form = self.auth.impersonate(user_id=omer_id) |
---|
798 | self.assertTrue(self.auth.is_impersonating()) |
---|
799 | self.assertEqual(self.auth.user_id, omer_id) # we make it really sure |
---|
800 | self.assertEqual(impersonate_form.xml(), |
---|
801 | b'<form action="#" enctype="multipart/form-data" method="post"><table><tr id="auth_user_id__row"><td class="w2p_fl"><label class="readonly" for="auth_user_id" id="auth_user_id__label">Id: </label></td><td class="w2p_fw"><span id="auth_user_id">2</span></td><td class="w2p_fc"></td></tr><tr id="auth_user_first_name__row"><td class="w2p_fl"><label class="readonly" for="auth_user_first_name" id="auth_user_first_name__label">First name: </label></td><td class="w2p_fw">Omer</td><td class="w2p_fc"></td></tr><tr id="auth_user_last_name__row"><td class="w2p_fl"><label class="readonly" for="auth_user_last_name" id="auth_user_last_name__label">Last name: </label></td><td class="w2p_fw">Simpson</td><td class="w2p_fc"></td></tr><tr id="auth_user_email__row"><td class="w2p_fl"><label class="readonly" for="auth_user_email" id="auth_user_email__label">E-mail: </label></td><td class="w2p_fw">omer@test.com</td><td class="w2p_fc"></td></tr><tr id="auth_user_username__row"><td class="w2p_fl"><label class="readonly" for="auth_user_username" id="auth_user_username__label">Username: </label></td><td class="w2p_fw">omer</td><td class="w2p_fc"></td></tr></table><div style="display:none;"><input name="id" type="hidden" value="2" /></div></form>') |
---|
802 | self.auth.logout_bare() |
---|
803 | # Failing impersonation |
---|
804 | # User lacking impersonate membership |
---|
805 | self.auth.login_user(self.db(self.db.auth_user.username == 'omer').select().first()) # bypass login_bare() |
---|
806 | # self.assertTrue(self.auth.is_logged_in()) # For developing test |
---|
807 | # self.assertFalse(self.auth.is_impersonating()) # For developing test |
---|
808 | self.myassertRaisesRegex(HTTP, "403*", self.auth.impersonate, bart_id) |
---|
809 | self.auth.logout_bare() |
---|
810 | # Try impersonate a non existing user |
---|
811 | self.auth.login_user(self.db(self.db.auth_user.username == 'bart').select().first()) # bypass login_bare() |
---|
812 | # self.assertTrue(self.auth.is_logged_in()) # For developing test |
---|
813 | # self.assertFalse(self.auth.is_impersonating()) # For developing test |
---|
814 | self.myassertRaisesRegex(HTTP, "401*", self.auth.impersonate, 1000) # user with id 1000 shouldn't exist |
---|
815 | # Try impersonate user with id = 0 or '0' when bart impersonating omer |
---|
816 | self.auth.impersonate(user_id=omer_id) |
---|
817 | self.assertTrue(self.auth.is_impersonating()) |
---|
818 | self.assertEqual(self.auth.impersonate(user_id=0), None) |
---|
819 | |
---|
820 | # TODO: def test_update_groups(self): |
---|
821 | |
---|
822 | def test_groups(self): |
---|
823 | self.auth.login_user(self.db(self.db.auth_user.username == 'bart').select().first()) # bypass login_bare() |
---|
824 | self.assertEqual(self.auth.groups().xml(), |
---|
825 | b'<table><tr><td><h3>user_1(1)</h3></td></tr><tr><td><p></p></td></tr></table>') |
---|
826 | |
---|
827 | def test_not_authorized(self): |
---|
828 | self.current.request.ajax = 'facke_ajax_request' |
---|
829 | self.myassertRaisesRegex(HTTP, "403*", self.auth.not_authorized) |
---|
830 | self.current.request.ajax = None |
---|
831 | self.assertEqual(self.auth.not_authorized(), self.auth.messages.access_denied) |
---|
832 | |
---|
833 | def test_allows_jwt(self): |
---|
834 | self.myassertRaisesRegex(HTTP, "400*", self.auth.allows_jwt) |
---|
835 | |
---|
836 | # TODO: def test_requires(self): |
---|
837 | |
---|
838 | # def test_login(self): |
---|
839 | # Basic testing above in "test_basic_blank_forms()" could be refined here |
---|
840 | |
---|
841 | # TODO: def test_requires_login_or_token(self): |
---|
842 | # TODO: def test_requires_membership(self): |
---|
843 | # TODO: def test_requires_permission(self): |
---|
844 | # TODO: def test_requires_signature(self): |
---|
845 | |
---|
846 | def test_add_group(self): |
---|
847 | self.assertEqual(self.auth.add_group(role='a_group', description='a_group_role_description'), |
---|
848 | self.db(self.db.auth_group.role == 'a_group').select(self.db.auth_group.id).first().id) |
---|
849 | |
---|
850 | def test_del_group(self): |
---|
851 | bart_group_id = 1 # Should be group 1, 'user_1' |
---|
852 | self.assertEqual(self.auth.del_group(group_id=bart_group_id), None) |
---|
853 | |
---|
854 | def test_id_group(self): |
---|
855 | self.assertEqual(self.auth.id_group(role='user_1'), 1) |
---|
856 | # If role don't exist it return None |
---|
857 | self.assertEqual(self.auth.id_group(role='non_existing_role_name'), None) |
---|
858 | |
---|
859 | def test_user_group(self): |
---|
860 | self.assertEqual(self.auth.user_group(user_id=1), 1) |
---|
861 | # Bart should be user 1 and it unique group should be 1, 'user_1' |
---|
862 | |
---|
863 | def test_user_group_role(self): |
---|
864 | self.auth.login_user(self.db(self.db.auth_user.username == 'bart').select().first()) # bypass login_bare() |
---|
865 | user_group_role = 'user_%s' % self.db(self.db.auth_user.username == 'bart' |
---|
866 | ).select(self.db.auth_user.id).first().id |
---|
867 | self.assertEqual(self.auth.user_group_role(), user_group_role) |
---|
868 | self.auth.logout_bare() |
---|
869 | # with user_id args |
---|
870 | self.assertEqual(self.auth.user_group_role(user_id=1), 'user_1') |
---|
871 | # test None |
---|
872 | self.auth.settings.create_user_groups = None |
---|
873 | self.assertEqual(self.auth.user_group_role(user_id=1), None) |
---|
874 | |
---|
875 | def test_has_membership(self): |
---|
876 | self.auth.login_user(self.db(self.db.auth_user.username == 'bart').select().first()) # bypass login_bare() |
---|
877 | self.assertTrue(self.auth.has_membership('user_1')) |
---|
878 | self.assertFalse(self.auth.has_membership('user_555')) |
---|
879 | self.assertTrue(self.auth.has_membership(group_id=1)) |
---|
880 | self.auth.logout_bare() |
---|
881 | self.assertTrue(self.auth.has_membership(role='user_1', user_id=1)) |
---|
882 | self.assertTrue(self.auth.has_membership(group_id=1, user_id=1)) |
---|
883 | # check that event is logged |
---|
884 | count_log_event_test_before = self.db(self.db.auth_event.id > 0).count() |
---|
885 | self.assertTrue(self.auth.has_membership(group_id=1, user_id=1)) |
---|
886 | count_log_event_test_after = self.db(self.db.auth_event.id > 0).count() |
---|
887 | self.assertEqual(count_log_event_test_after, count_log_event_test_before) |
---|
888 | |
---|
889 | def test_add_membership(self): |
---|
890 | user = self.db(self.db.auth_user.username == 'bart').select().first() # bypass login_bare() |
---|
891 | user_id = user.id |
---|
892 | role_name = 'test_add_membership_group' |
---|
893 | group_id = self.auth.add_group(role_name) |
---|
894 | self.assertFalse(self.auth.has_membership(role_name)) |
---|
895 | |
---|
896 | self.auth.add_membership(group_id=group_id, user_id=user_id) |
---|
897 | self.assertTrue(self.auth.has_membership(group_id, user_id=user_id)) |
---|
898 | self.auth.del_membership(group_id=group_id, user_id=user_id) |
---|
899 | self.assertFalse(self.auth.has_membership(group_id, user_id=user_id)) |
---|
900 | |
---|
901 | self.auth.add_membership(role=role_name, user_id=user_id) |
---|
902 | self.assertTrue(self.auth.has_membership(group_id, user_id=user_id)) |
---|
903 | self.auth.del_membership(group_id=group_id, user_id=user_id) |
---|
904 | self.assertFalse(self.auth.has_membership(group_id, user_id=user_id)) |
---|
905 | |
---|
906 | with self.myassertRaisesRegex(ValueError, '^group_id not provided or invalid$'): |
---|
907 | self.auth.add_membership(group_id='not_existing_group_name', user_id=user_id) |
---|
908 | with self.myassertRaisesRegex(ValueError, '^group_id not provided or invalid$'): |
---|
909 | self.auth.add_membership(role='not_existing_role_name', user_id=user_id) |
---|
910 | with self.myassertRaisesRegex(ValueError, '^user_id not provided or invalid$'): |
---|
911 | self.auth.add_membership(group_id=group_id, user_id=None) |
---|
912 | with self.myassertRaisesRegex(ValueError, '^user_id not provided or invalid$'): |
---|
913 | self.auth.add_membership(role=role_name, user_id=None) |
---|
914 | |
---|
915 | self.auth.login_user(user) |
---|
916 | |
---|
917 | self.auth.add_membership(group_id=group_id) |
---|
918 | self.assertTrue(self.auth.has_membership(group_id)) |
---|
919 | self.auth.del_membership(group_id=group_id) |
---|
920 | self.assertFalse(self.auth.has_membership(group_id)) |
---|
921 | |
---|
922 | self.auth.add_membership(role=role_name) |
---|
923 | self.assertTrue(self.auth.has_membership(group_id)) |
---|
924 | self.auth.del_membership(group_id=group_id) |
---|
925 | self.assertFalse(self.auth.has_membership(group_id)) |
---|
926 | |
---|
927 | # default usage (group_id=role_name) |
---|
928 | self.auth.add_membership(role_name) |
---|
929 | self.assertTrue(self.auth.has_membership(group_id)) |
---|
930 | self.auth.del_membership(group_id=group_id) |
---|
931 | self.assertFalse(self.auth.has_membership(group_id)) |
---|
932 | |
---|
933 | # re-adding a membership should return the existing membership |
---|
934 | record0_id = self.auth.add_membership(group_id) |
---|
935 | self.assertTrue(self.auth.has_membership(group_id)) |
---|
936 | record1_id = self.auth.add_membership(group_id) |
---|
937 | self.assertEqual(record0_id, record1_id) |
---|
938 | self.auth.del_membership(group_id=group_id) |
---|
939 | self.assertFalse(self.auth.has_membership(group_id)) |
---|
940 | |
---|
941 | with self.myassertRaisesRegex(ValueError, '^group_id not provided or invalid$'): |
---|
942 | self.auth.add_membership(group_id='not_existing_group_name') |
---|
943 | with self.myassertRaisesRegex(ValueError, '^group_id not provided or invalid$'): |
---|
944 | self.auth.add_membership(role='not_existing_role_name') |
---|
945 | |
---|
946 | def test_del_membership(self): |
---|
947 | self.auth.login_user(self.db(self.db.auth_user.username == 'bart').select().first()) # bypass login_bare() |
---|
948 | count_log_event_test_before = self.db(self.db.auth_event.id > 0).count() |
---|
949 | user_1_role_id = self.db(self.db.auth_membership.group_id == self.auth.id_group('user_1') |
---|
950 | ).select(self.db.auth_membership.id).first().id |
---|
951 | self.assertEqual(self.auth.del_membership('user_1'), user_1_role_id) |
---|
952 | count_log_event_test_after = self.db(self.db.auth_event.id > 0).count() |
---|
953 | # check that event is logged |
---|
954 | self.assertEqual(count_log_event_test_after, count_log_event_test_before) |
---|
955 | # not logged in test case |
---|
956 | group_id = self.auth.add_group('some_test_group') |
---|
957 | membership_id = self.auth.add_membership('some_test_group') |
---|
958 | self.assertEqual(self.auth.user_groups[group_id], 'some_test_group') |
---|
959 | self.auth.logout_bare() |
---|
960 | # not deleted |
---|
961 | self.assertFalse(self.auth.del_membership('some_test_group')) |
---|
962 | self.assertEqual(set(self.db.auth_membership(membership_id).as_dict().items()), |
---|
963 | set({'group_id': 2, 'user_id': 1, 'id': 2}.items())) # is not deleted |
---|
964 | # deleted |
---|
965 | bart_id = self.db(self.db.auth_user.username == 'bart').select(self.db.auth_user.id).first().id |
---|
966 | self.assertTrue(self.auth.del_membership('some_test_group', user_id=bart_id)) |
---|
967 | self.assertEqual(self.db.auth_membership(membership_id), None) # is really deleted |
---|
968 | |
---|
969 | def test_has_permission(self): |
---|
970 | self.auth.login_user(self.db(self.db.auth_user.username == 'bart').select().first()) # bypass login_bare() |
---|
971 | bart_id = self.db(self.db.auth_user.username == 'bart').select(self.db.auth_user.id).first().id |
---|
972 | self.auth.add_permission(group_id=self.auth.id_group('user_1'), |
---|
973 | name='some_permission', |
---|
974 | table_name='auth_user', |
---|
975 | record_id=0, |
---|
976 | ) |
---|
977 | # True case |
---|
978 | self.assertTrue(self.auth.has_permission(name='some_permission', |
---|
979 | table_name='auth_user', |
---|
980 | record_id=0, |
---|
981 | user_id=bart_id, |
---|
982 | group_id=self.auth.id_group('user_1'))) |
---|
983 | # False case |
---|
984 | self.assertFalse(self.auth.has_permission(name='some_other_permission', |
---|
985 | table_name='auth_user', |
---|
986 | record_id=0, |
---|
987 | user_id=bart_id, |
---|
988 | group_id=self.auth.id_group('user_1'))) |
---|
989 | |
---|
990 | def test_add_permission(self): |
---|
991 | count_log_event_test_before = self.db(self.db.auth_event.id > 0).count() |
---|
992 | permission_id = \ |
---|
993 | self.auth.add_permission(group_id=self.auth.id_group('user_1'), |
---|
994 | name='some_permission', |
---|
995 | table_name='auth_user', |
---|
996 | record_id=0, |
---|
997 | ) |
---|
998 | count_log_event_test_after = self.db(self.db.auth_event.id > 0).count() |
---|
999 | # check that event is logged |
---|
1000 | self.assertEqual(count_log_event_test_after, count_log_event_test_before) |
---|
1001 | # True case |
---|
1002 | permission_count = \ |
---|
1003 | self.db(self.db.auth_permission.id == permission_id).count() |
---|
1004 | self.assertTrue(permission_count) |
---|
1005 | # False case |
---|
1006 | permission_count = \ |
---|
1007 | self.db((self.db.auth_permission.group_id == self.auth.id_group('user_1')) & |
---|
1008 | (self.db.auth_permission.name == 'no_permission') & |
---|
1009 | (self.db.auth_permission.table_name == 'no_table') & |
---|
1010 | (self.db.auth_permission.record_id == 0)).count() |
---|
1011 | self.assertFalse(permission_count) |
---|
1012 | # corner case |
---|
1013 | self.auth.login_user(self.db(self.db.auth_user.username == 'bart').select().first()) # bypass login_bare() |
---|
1014 | permission_id = \ |
---|
1015 | self.auth.add_permission(group_id=0, |
---|
1016 | name='user_1_permission', |
---|
1017 | table_name='auth_user', |
---|
1018 | record_id=0, |
---|
1019 | ) |
---|
1020 | permission_name = \ |
---|
1021 | self.db(self.db.auth_permission.id == permission_id).select(self.db.auth_permission.name).first().name |
---|
1022 | self.assertEqual(permission_name, 'user_1_permission') |
---|
1023 | # add an existing permission |
---|
1024 | permission_id =\ |
---|
1025 | self.auth.add_permission(group_id=0, |
---|
1026 | name='user_1_permission', |
---|
1027 | table_name='auth_user', |
---|
1028 | record_id=0, |
---|
1029 | ) |
---|
1030 | self.assertTrue(permission_id) |
---|
1031 | |
---|
1032 | def test_del_permission(self): |
---|
1033 | permission_id = \ |
---|
1034 | self.auth.add_permission(group_id=self.auth.id_group('user_1'), |
---|
1035 | name='del_permission_test', |
---|
1036 | table_name='auth_user', |
---|
1037 | record_id=0, |
---|
1038 | ) |
---|
1039 | count_log_event_test_before = self.db(self.db.auth_event.id > 0).count() |
---|
1040 | self.assertTrue(self.auth.del_permission(group_id=self.auth.id_group('user_1'), |
---|
1041 | name='del_permission_test', |
---|
1042 | table_name='auth_user', |
---|
1043 | record_id=0,)) |
---|
1044 | count_log_event_test_after = self.db(self.db.auth_event.id > 0).count() |
---|
1045 | # check that event is logged |
---|
1046 | self.assertEqual(count_log_event_test_after, count_log_event_test_before) |
---|
1047 | # really deleted |
---|
1048 | permission_count = \ |
---|
1049 | self.db(self.db.auth_permission.id == permission_id).count() |
---|
1050 | self.assertFalse(permission_count) |
---|
1051 | |
---|
1052 | # TODO: def test_accessible_query(self): |
---|
1053 | # TODO: def test_archive(self): |
---|
1054 | # TODO: def test_wiki(self): |
---|
1055 | # TODO: def test_wikimenu(self): |
---|
1056 | # End Auth test |
---|
1057 | |
---|
1058 | |
---|
1059 | # TODO: class TestCrud(unittest.TestCase): |
---|
1060 | # It deprecated so far from a priority |
---|
1061 | |
---|
1062 | |
---|
1063 | # TODO: class TestService(unittest.TestCase): |
---|
1064 | |
---|
1065 | |
---|
1066 | # TODO: class TestPluginManager(unittest.TestCase): |
---|
1067 | |
---|
1068 | |
---|
1069 | # TODO: class TestWiki(unittest.TestCase): |
---|
1070 | |
---|
1071 | |
---|
1072 | # TODO: class TestConfig(unittest.TestCase): |
---|
1073 | |
---|
1074 | |
---|
1075 | class TestToolsFunctions(unittest.TestCase): |
---|
1076 | """ |
---|
1077 | Test suite for all the tools.py functions |
---|
1078 | """ |
---|
1079 | def test_prettydate(self): |
---|
1080 | # plain |
---|
1081 | now = datetime.datetime.now() |
---|
1082 | self.assertEqual(prettydate(d=now), 'now') |
---|
1083 | one_second = now - datetime.timedelta(seconds=1) |
---|
1084 | self.assertEqual(prettydate(d=one_second), '1 second ago') |
---|
1085 | more_than_one_second = now - datetime.timedelta(seconds=2) |
---|
1086 | self.assertEqual(prettydate(d=more_than_one_second), '2 seconds ago') |
---|
1087 | one_minute = now - datetime.timedelta(seconds=60) |
---|
1088 | self.assertEqual(prettydate(d=one_minute), '1 minute ago') |
---|
1089 | more_than_one_minute = now - datetime.timedelta(seconds=61) |
---|
1090 | self.assertEqual(prettydate(d=more_than_one_minute), '1 minute ago') |
---|
1091 | two_minutes = now - datetime.timedelta(seconds=120) |
---|
1092 | self.assertEqual(prettydate(d=two_minutes), '2 minutes ago') |
---|
1093 | more_than_two_minutes = now - datetime.timedelta(seconds=121) |
---|
1094 | self.assertEqual(prettydate(d=more_than_two_minutes), '2 minutes ago') |
---|
1095 | one_hour = now - datetime.timedelta(seconds=60 * 60) |
---|
1096 | self.assertEqual(prettydate(d=one_hour), '1 hour ago') |
---|
1097 | more_than_one_hour = now - datetime.timedelta(seconds=3601) |
---|
1098 | self.assertEqual(prettydate(d=more_than_one_hour), '1 hour ago') |
---|
1099 | two_hours = now - datetime.timedelta(seconds=2 * 60 * 60) |
---|
1100 | self.assertEqual(prettydate(d=two_hours), '2 hours ago') |
---|
1101 | more_than_two_hours = now - datetime.timedelta(seconds=2 * 60 * 60 + 1) |
---|
1102 | self.assertEqual(prettydate(d=more_than_two_hours), '2 hours ago') |
---|
1103 | one_day = now - datetime.timedelta(days=1) |
---|
1104 | self.assertEqual(prettydate(d=one_day), '1 day ago') |
---|
1105 | more_than_one_day = now - datetime.timedelta(days=2) |
---|
1106 | self.assertEqual(prettydate(d=more_than_one_day), '2 days ago') |
---|
1107 | one_week = now - datetime.timedelta(days=7) |
---|
1108 | self.assertEqual(prettydate(d=one_week), '1 week ago') |
---|
1109 | more_than_one_week = now - datetime.timedelta(days=8) |
---|
1110 | self.assertEqual(prettydate(d=more_than_one_week), '1 week ago') |
---|
1111 | two_weeks = now - datetime.timedelta(days=14) |
---|
1112 | self.assertEqual(prettydate(d=two_weeks), '2 weeks ago') |
---|
1113 | more_than_two_weeks = now - datetime.timedelta(days=15) |
---|
1114 | self.assertEqual(prettydate(d=more_than_two_weeks), '2 weeks ago') |
---|
1115 | three_weeks = now - datetime.timedelta(days=21) |
---|
1116 | self.assertEqual(prettydate(d=three_weeks), '3 weeks ago') |
---|
1117 | one_month = now - datetime.timedelta(days=27) |
---|
1118 | self.assertEqual(prettydate(d=one_month), '1 month ago') |
---|
1119 | more_than_one_month = now - datetime.timedelta(days=28) |
---|
1120 | self.assertEqual(prettydate(d=more_than_one_month), '1 month ago') |
---|
1121 | two_months = now - datetime.timedelta(days=60) |
---|
1122 | self.assertEqual(prettydate(d=two_months), '2 months ago') |
---|
1123 | three_months = now - datetime.timedelta(days=90) |
---|
1124 | self.assertEqual(prettydate(d=three_months), '3 months ago') |
---|
1125 | one_year = now - datetime.timedelta(days=365) |
---|
1126 | self.assertEqual(prettydate(d=one_year), '1 year ago') |
---|
1127 | more_than_one_year = now - datetime.timedelta(days=366) |
---|
1128 | self.assertEqual(prettydate(d=more_than_one_year), '1 year ago') |
---|
1129 | two_years = now - datetime.timedelta(days=2 * 365) |
---|
1130 | self.assertEqual(prettydate(d=two_years), '2 years ago') |
---|
1131 | more_than_two_years = now - datetime.timedelta(days=2 * 365 + 1) |
---|
1132 | self.assertEqual(prettydate(d=more_than_two_years), '2 years ago') |
---|
1133 | # date() |
---|
1134 | d = now.date() |
---|
1135 | self.assertEqual(prettydate(d=d), 'now') |
---|
1136 | one_day = now.date() - datetime.timedelta(days=1) |
---|
1137 | self.assertEqual(prettydate(d=one_day), '1 day ago') |
---|
1138 | tow_days = now.date() - datetime.timedelta(days=2) |
---|
1139 | self.assertEqual(prettydate(d=tow_days), '2 days ago') |
---|
1140 | # from now |
---|
1141 | # from now is picky depending of the execution time, so we can't use sharp value like 1 second or 1 day |
---|
1142 | in_one_minute = now - datetime.timedelta(seconds=-65) |
---|
1143 | self.assertEqual(prettydate(d=in_one_minute), '1 minute from now') |
---|
1144 | in_twenty_three_hours = now - datetime.timedelta(hours=-23.5) |
---|
1145 | self.assertEqual(prettydate(d=in_twenty_three_hours), '23 hours from now') |
---|
1146 | in_one_year = now - datetime.timedelta(days=-366) |
---|
1147 | self.assertEqual(prettydate(d=in_one_year), '1 year from now') |
---|
1148 | # utc=True |
---|
1149 | now = datetime.datetime.utcnow() |
---|
1150 | self.assertEqual(prettydate(d=now, utc=True), 'now') |
---|
1151 | one_second = now - datetime.timedelta(seconds=1) |
---|
1152 | self.assertEqual(prettydate(d=one_second, utc=True), '1 second ago') |
---|
1153 | # not d or invalid date |
---|
1154 | self.assertEqual(prettydate(d=None), '') |
---|
1155 | self.assertEqual(prettydate(d='invalid_date'), '[invalid date]') |
---|
1156 | |
---|
1157 | |
---|
1158 | pjoin = os.path.join |
---|
1159 | |
---|
1160 | |
---|
1161 | def have_symlinks(): |
---|
1162 | return os.name == 'posix' |
---|
1163 | |
---|
1164 | |
---|
1165 | class Test_Expose__in_base(unittest.TestCase): |
---|
1166 | |
---|
1167 | def test_in_base(self): |
---|
1168 | are_under = [ |
---|
1169 | # (sub, base) |
---|
1170 | ('/foo/bar', '/foo'), |
---|
1171 | ('/foo', '/foo'), |
---|
1172 | ('/foo', '/'), |
---|
1173 | ('/', '/'), |
---|
1174 | ] |
---|
1175 | for sub, base in are_under: |
---|
1176 | self.assertTrue(Expose._Expose__in_base(subdir=sub, basedir=base, sep='/'), |
---|
1177 | '%s is not under %s' % (sub, base)) |
---|
1178 | |
---|
1179 | def test_not_in_base(self): |
---|
1180 | are_not_under = [ |
---|
1181 | # (sub, base) |
---|
1182 | ('/foobar', '/foo'), |
---|
1183 | ('/foo', '/foo/bar'), |
---|
1184 | ('/bar', '/foo'), |
---|
1185 | ('/foo/bar', '/bar'), |
---|
1186 | ('/', '/x'), |
---|
1187 | ] |
---|
1188 | for sub, base in are_not_under: |
---|
1189 | self.assertFalse(Expose._Expose__in_base(subdir=sub, basedir=base, sep='/'), |
---|
1190 | '%s should not be under %s' % (sub, base)) |
---|
1191 | |
---|
1192 | |
---|
1193 | class TestExpose(unittest.TestCase): |
---|
1194 | |
---|
1195 | def setUp(self): |
---|
1196 | self.base_dir = tempfile.mkdtemp() |
---|
1197 | |
---|
1198 | self.make_dirs() |
---|
1199 | self.touch_files() |
---|
1200 | self.make_readme() |
---|
1201 | if have_symlinks(): |
---|
1202 | self.make_symlinks() |
---|
1203 | |
---|
1204 | # $BASE/ |
---|
1205 | # |-- inside/ |
---|
1206 | # | |-- dir1/ |
---|
1207 | # | | |-- file1 |
---|
1208 | # | | `-- file2 |
---|
1209 | # | |-- dir2/ |
---|
1210 | # | | |-- link_to_dir1/@ -> $BASE/inside/dir1/ |
---|
1211 | # | | `-- link_to_file1@ -> $BASE/inside/dir1/file1 |
---|
1212 | # | |-- link_to_outside/@ -> $BASE/outside/ |
---|
1213 | # | |-- link_to_file3@ -> $BASE/outside/file3 |
---|
1214 | # | `-- README |
---|
1215 | # `-- outside/ |
---|
1216 | # `-- file3 |
---|
1217 | |
---|
1218 | self.set_expectations() |
---|
1219 | tools.URL = lambda args: URL(a='a', c='c', f='f', args=args) |
---|
1220 | |
---|
1221 | def tearDown(self): |
---|
1222 | tools.URL = URL |
---|
1223 | shutil.rmtree(self.base_dir) |
---|
1224 | |
---|
1225 | def make_dirs(self): |
---|
1226 | """setup directory structure""" |
---|
1227 | for d in (['inside'], |
---|
1228 | ['inside', 'dir1'], |
---|
1229 | ['inside', 'dir2'], |
---|
1230 | ['outside']): |
---|
1231 | os.mkdir(pjoin(self.base_dir, *d)) |
---|
1232 | |
---|
1233 | def touch_files(self): |
---|
1234 | """create some files""" |
---|
1235 | for f in (['inside', 'dir1', 'file1'], |
---|
1236 | ['inside', 'dir1', 'file2'], |
---|
1237 | ['outside', 'file3']): |
---|
1238 | with open(pjoin(self.base_dir, *f), 'a'): |
---|
1239 | pass |
---|
1240 | |
---|
1241 | def make_readme(self): |
---|
1242 | with open(pjoin(self.base_dir, 'inside', 'README'), 'w') as f: |
---|
1243 | f.write('README content') |
---|
1244 | |
---|
1245 | def make_symlinks(self): |
---|
1246 | """setup extension for posix systems""" |
---|
1247 | # inside links |
---|
1248 | os.symlink( |
---|
1249 | pjoin(self.base_dir, 'inside', 'dir1'), |
---|
1250 | pjoin(self.base_dir, 'inside', 'dir2', 'link_to_dir1')) |
---|
1251 | os.symlink( |
---|
1252 | pjoin(self.base_dir, 'inside', 'dir1', 'file1'), |
---|
1253 | pjoin(self.base_dir, 'inside', 'dir2', 'link_to_file1')) |
---|
1254 | # outside links |
---|
1255 | os.symlink( |
---|
1256 | pjoin(self.base_dir, 'outside'), |
---|
1257 | pjoin(self.base_dir, 'inside', 'link_to_outside')) |
---|
1258 | os.symlink( |
---|
1259 | pjoin(self.base_dir, 'outside', 'file3'), |
---|
1260 | pjoin(self.base_dir, 'inside', 'link_to_file3')) |
---|
1261 | |
---|
1262 | def set_expectations(self): |
---|
1263 | url = lambda args: URL('a', 'c', 'f', args=args) |
---|
1264 | |
---|
1265 | self.expected_folders = {} |
---|
1266 | self.expected_folders['inside'] = SPAN(H3('Folders'), TABLE( |
---|
1267 | TR(TD(A('dir1', _href=url(args=['dir1'])))), |
---|
1268 | TR(TD(A('dir2', _href=url(args=['dir2'])))), |
---|
1269 | _class='table', |
---|
1270 | )) |
---|
1271 | self.expected_folders[pjoin('inside', 'dir1')] = '' |
---|
1272 | if have_symlinks(): |
---|
1273 | self.expected_folders[pjoin('inside', 'dir2')] = SPAN(H3('Folders'), TABLE( |
---|
1274 | TR(TD(A('link_to_dir1', _href=url(args=['dir2', 'link_to_dir1'])))), |
---|
1275 | _class='table', |
---|
1276 | )) |
---|
1277 | else: |
---|
1278 | self.expected_folders[pjoin('inside', 'dir2')] = '' |
---|
1279 | |
---|
1280 | self.expected_files = {} |
---|
1281 | self.expected_files['inside'] = SPAN(H3('Files'), TABLE( |
---|
1282 | TR(TD(A('README', _href=url(args=['README']))), TD('')), |
---|
1283 | _class='table', |
---|
1284 | )) |
---|
1285 | self.expected_files[pjoin('inside', 'dir1')] = SPAN(H3('Files'), TABLE( |
---|
1286 | TR(TD(A('file1', _href=url(args=['dir1', 'file1']))), TD('')), |
---|
1287 | TR(TD(A('file2', _href=url(args=['dir1', 'file2']))), TD('')), |
---|
1288 | _class='table', |
---|
1289 | )) |
---|
1290 | if have_symlinks(): |
---|
1291 | self.expected_files[pjoin('inside', 'dir2')] = SPAN(H3('Files'), TABLE( |
---|
1292 | TR(TD(A('link_to_file1', _href=url(args=['dir2', 'link_to_file1']))), TD('')), |
---|
1293 | _class='table', |
---|
1294 | )) |
---|
1295 | else: |
---|
1296 | self.expected_files[pjoin('inside', 'dir2')] = '' |
---|
1297 | |
---|
1298 | def make_expose(self, base, show='', follow_symlink_out=False): |
---|
1299 | current.request = Request(env={}) |
---|
1300 | current.request.raw_args = show |
---|
1301 | current.request.args = show.split('/') |
---|
1302 | return Expose(base=pjoin(self.base_dir, base), |
---|
1303 | basename=base, |
---|
1304 | follow_symlink_out=follow_symlink_out) |
---|
1305 | |
---|
1306 | def test_expose_inside_state(self): |
---|
1307 | expose = self.make_expose(base='inside', show='') |
---|
1308 | self.assertEqual(expose.args, []) |
---|
1309 | self.assertEqual(expose.folders, ['dir1', 'dir2']) |
---|
1310 | self.assertEqual(expose.filenames, ['README']) |
---|
1311 | |
---|
1312 | @unittest.skipUnless(have_symlinks(), 'requires symlinks') |
---|
1313 | def test_expose_inside_state_floow_symlink_out(self): |
---|
1314 | expose = self.make_expose(base='inside', show='', |
---|
1315 | follow_symlink_out=True) |
---|
1316 | self.assertEqual(expose.args, []) |
---|
1317 | self.assertEqual(expose.folders, ['dir1', 'dir2', 'link_to_outside']) |
---|
1318 | self.assertEqual(expose.filenames, ['README', 'link_to_file3']) |
---|
1319 | |
---|
1320 | def test_expose_inside_dir1_state(self): |
---|
1321 | expose = self.make_expose(base='inside', show='dir1') |
---|
1322 | self.assertEqual(expose.args, ['dir1']) |
---|
1323 | self.assertEqual(expose.folders, []) |
---|
1324 | self.assertEqual(expose.filenames, ['file1', 'file2']) |
---|
1325 | |
---|
1326 | def test_expose_inside_dir2_state(self): |
---|
1327 | expose = self.make_expose(base='inside', show='dir2') |
---|
1328 | self.assertEqual(expose.args, ['dir2']) |
---|
1329 | if have_symlinks(): |
---|
1330 | self.assertEqual(expose.folders, ['link_to_dir1']) |
---|
1331 | self.assertEqual(expose.filenames, ['link_to_file1']) |
---|
1332 | else: |
---|
1333 | self.assertEqual(expose.folders, []) |
---|
1334 | self.assertEqual(expose.filenames, []) |
---|
1335 | |
---|
1336 | def test_expose_base_inside_state(self): |
---|
1337 | expose = self.make_expose(base='', show='inside') |
---|
1338 | self.assertEqual(expose.args, ['inside']) |
---|
1339 | if have_symlinks(): |
---|
1340 | self.assertEqual(expose.folders, ['dir1', 'dir2', 'link_to_outside']) |
---|
1341 | self.assertEqual(expose.filenames, ['README', 'link_to_file3']) |
---|
1342 | else: |
---|
1343 | self.assertEqual(expose.folders, ['dir1', 'dir2']) |
---|
1344 | self.assertEqual(expose.filenames, ['README']) |
---|
1345 | |
---|
1346 | def test_expose_base_inside_dir2_state(self): |
---|
1347 | expose = self.make_expose(base='', show='inside/dir2') |
---|
1348 | self.assertEqual(expose.args, ['inside', 'dir2']) |
---|
1349 | if have_symlinks(): |
---|
1350 | self.assertEqual(expose.folders, ['link_to_dir1']) |
---|
1351 | self.assertEqual(expose.filenames, ['link_to_file1']) |
---|
1352 | else: |
---|
1353 | self.assertEqual(expose.folders, []) |
---|
1354 | self.assertEqual(expose.filenames, []) |
---|
1355 | |
---|
1356 | def assertSameXML(self, a, b): |
---|
1357 | self.assertEqual(a if isinstance(a, str) else a.xml(), |
---|
1358 | b if isinstance(b, str) else b.xml()) |
---|
1359 | |
---|
1360 | def run_test_xml_for(self, base, show): |
---|
1361 | expose = self.make_expose(base, show) |
---|
1362 | path = pjoin(base, show).rstrip(os.path.sep) |
---|
1363 | request = Request(env={}) |
---|
1364 | self.assertSameXML(expose.table_files(), self.expected_files[path]) |
---|
1365 | self.assertSameXML(expose.table_folders(), self.expected_folders[path]) |
---|
1366 | |
---|
1367 | def test_xml_inside(self): |
---|
1368 | self.run_test_xml_for(base='inside', show='') |
---|
1369 | |
---|
1370 | def test_xml_dir1(self): |
---|
1371 | self.run_test_xml_for(base='inside', show='dir1') |
---|
1372 | |
---|
1373 | def test_xml_dir2(self): |
---|
1374 | self.run_test_xml_for(base='inside', show='dir2') |
---|
1375 | |
---|
1376 | def test_file_not_found(self): |
---|
1377 | with self.assertRaises(HTTP): |
---|
1378 | self.make_expose(base='inside', show='dir1/file_not_found') |
---|
1379 | |
---|
1380 | def test_not_authorized(self): |
---|
1381 | with self.assertRaises(HTTP): |
---|
1382 | self.make_expose(base='inside', show='link_to_file3') |
---|