Skip to content

Commit dbcd1ba

Browse files
committed
Merge pull request #47 from avojnovicDk/signals
Added signals for user creation, update and delete.
2 parents 9312ae9 + 4203d86 commit dbcd1ba

File tree

5 files changed

+165
-0
lines changed

5 files changed

+165
-0
lines changed

flask_stormpath/models.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,19 @@
33

44
from flask import current_app
55
from six import text_type
6+
7+
from blinker import Namespace
8+
69
from stormpath.resources.account import Account
710
from stormpath.resources.provider import Provider
811

912

13+
stormpath_signals = Namespace()
14+
user_created = stormpath_signals.signal('user-created')
15+
user_updated = stormpath_signals.signal('user-updated')
16+
user_deleted = stormpath_signals.signal('user-deleted')
17+
18+
1019
class User(Account):
1120
"""
1221
The base User object.
@@ -44,6 +53,22 @@ def is_authenticated(self):
4453
"""
4554
return True
4655

56+
def save(self):
57+
"""
58+
Send signal after user is updated.
59+
"""
60+
return_value = super(User, self).save()
61+
user_updated.send(self, user=self)
62+
return return_value
63+
64+
def delete(self):
65+
"""
66+
Send signal after user is deleted.
67+
"""
68+
return_value = super(User, self).delete()
69+
user_deleted.send(self, user=self)
70+
return return_value
71+
4772
@classmethod
4873
def create(self, email, password, given_name, surname, username=None, middle_name=None, custom_data=None, status='ENABLED'):
4974
"""
@@ -84,6 +109,7 @@ def create(self, email, password, given_name, surname, username=None, middle_nam
84109
'status': status,
85110
})
86111
_user.__class__ = User
112+
user_created.send(self, user=_user)
87113

88114
return _user
89115

requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
Sphinx>=1.2.1
22
pytest>=2.5.2
33
pytest-xdist>=1.10
4+
blinker==1.3

setup.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ def run(self):
5757
'facebook-sdk==0.4.0',
5858
'oauth2client==1.2',
5959
'stormpath==2.0.7',
60+
'blinker==1.3'
6061
],
6162
dependency_links=[
6263
'git+git://github.com/pythonforfacebook/facebook-sdk.git@e65d06158e48388b3932563f1483ca77065951b3#egg=facebook-sdk-1.0.0-alpha',

tests/helpers.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,15 @@ def tearDown(self):
4343
directory.delete()
4444

4545

46+
class SignalReceiver(object):
47+
received_signals = None
48+
49+
def signal_user_receiver_function(self, sender, user):
50+
if self.received_signals is None:
51+
self.received_signals = []
52+
self.received_signals.append((sender, user))
53+
54+
4655
def bootstrap_client():
4756
"""
4857
Create a new Stormpath Client from environment variables.

tests/test_signals.py

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
"""Run tests for signals."""
2+
3+
from flask.ext.login import user_logged_in
4+
from flask.ext.stormpath.models import (
5+
User,
6+
user_created,
7+
user_deleted,
8+
user_updated
9+
)
10+
11+
from .helpers import StormpathTestCase, SignalReceiver
12+
13+
14+
class TestSignals(StormpathTestCase):
15+
"""Test signals."""
16+
17+
def test_user_created_signal(self):
18+
# Subscribe to signals for user creation
19+
signal_receiver = SignalReceiver()
20+
user_created.connect(signal_receiver.signal_user_receiver_function)
21+
22+
# Register new account
23+
with self.app.test_client() as c:
24+
resp = c.post('/register', data={
25+
'given_name': 'Randall',
26+
'middle_name': 'Clark',
27+
'surname': 'Degges',
28+
'email': '[email protected]',
29+
'password': 'woot1LoveCookies!',
30+
})
31+
self.assertEqual(resp.status_code, 302)
32+
33+
# Check that signal for user creation is received
34+
self.assertEqual(len(signal_receiver.received_signals), 1)
35+
received_signal = signal_receiver.received_signals[0]
36+
# User instance is received
37+
self.assertIsInstance(received_signal[1], User)
38+
# Correct user instance is received
39+
created_user = received_signal[1]
40+
self.assertEqual(created_user.email, '[email protected]')
41+
self.assertEqual(created_user.surname, 'Degges')
42+
43+
def test_user_logged_in_signal(self):
44+
# Subscribe to signals for user login
45+
signal_receiver = SignalReceiver()
46+
user_logged_in.connect(signal_receiver.signal_user_receiver_function)
47+
48+
# Create a user.
49+
with self.app.app_context():
50+
User.create(
51+
username = 'rdegges',
52+
given_name = 'Randall',
53+
surname = 'Degges',
54+
email = '[email protected]',
55+
password = 'woot1LoveCookies!',
56+
)
57+
58+
# Attempt a login using username and password.
59+
with self.app.test_client() as c:
60+
resp = c.post('/login', data={
61+
'login': 'rdegges',
62+
'password': 'woot1LoveCookies!',
63+
})
64+
self.assertEqual(resp.status_code, 302)
65+
66+
# Check that signal for user login is received
67+
self.assertEqual(len(signal_receiver.received_signals), 1)
68+
received_signal = signal_receiver.received_signals[0]
69+
# User instance is received
70+
self.assertIsInstance(received_signal[1], User)
71+
# Correct user instance is received
72+
logged_in_user = received_signal[1]
73+
self.assertEqual(logged_in_user.email, '[email protected]')
74+
self.assertEqual(logged_in_user.surname, 'Degges')
75+
76+
def test_user_is_updated_signal(self):
77+
# Subscribe to signals for user update
78+
signal_receiver = SignalReceiver()
79+
user_updated.connect(signal_receiver.signal_user_receiver_function)
80+
81+
with self.app.app_context():
82+
83+
# Ensure all requied fields are properly set.
84+
user = User.create(
85+
email = '[email protected]',
86+
password = 'woot1LoveCookies!',
87+
given_name = 'Randall',
88+
surname = 'Degges',
89+
)
90+
91+
user.middle_name = 'Clark'
92+
user.save()
93+
94+
# Check that signal for user update is received
95+
self.assertEqual(len(signal_receiver.received_signals), 1)
96+
received_signal = signal_receiver.received_signals[0]
97+
# User instance is received
98+
self.assertIsInstance(received_signal[1], User)
99+
# Correct user instance is received
100+
updated_user = received_signal[1]
101+
self.assertEqual(updated_user.email, '[email protected]')
102+
self.assertEqual(updated_user.middle_name, 'Clark')
103+
104+
def test_user_is_deleted_signal(self):
105+
# Subscribe to signals for user delete
106+
signal_receiver = SignalReceiver()
107+
user_deleted.connect(signal_receiver.signal_user_receiver_function)
108+
109+
with self.app.app_context():
110+
111+
# Ensure all requied fields are properly set.
112+
user = User.create(
113+
email = '[email protected]',
114+
password = 'woot1LoveCookies!',
115+
given_name = 'Randall',
116+
surname = 'Degges',
117+
)
118+
119+
user.delete()
120+
121+
# Check that signal for user deletion is received
122+
self.assertEqual(len(signal_receiver.received_signals), 1)
123+
received_signal = signal_receiver.received_signals[0]
124+
# User instance is received
125+
self.assertIsInstance(received_signal[1], User)
126+
# Correct user instance is received
127+
deleted_user = received_signal[1]
128+
self.assertEqual(deleted_user.email, '[email protected]')

0 commit comments

Comments
 (0)