Merge lp:~alecu/ubuntuone-client/removable-signals into lp:ubuntuone-client

Proposed by Alejandro J. Cura
Status: Merged
Approved by: Natalia Bidart
Approved revision: 1039
Merged at revision: 1040
Proposed branch: lp:~alecu/ubuntuone-client/removable-signals
Merge into: lp:ubuntuone-client
Diff against target: 206 lines (+132/-13)
2 files modified
tests/platform/windows/test_credentials.py (+98/-1)
ubuntuone/platform/windows/credentials.py (+34/-12)
To merge this branch: bzr merge lp:~alecu/ubuntuone-client/removable-signals
Reviewer Review Type Date Requested Status
Natalia Bidart (community) Approve
Roberto Alsina (community) Approve
Review via email: mp+66807@code.launchpad.net

Commit message

Make signals removable, so the pb proxy looks a bit more like dbus. (LP: #805471)

Description of the change

Make signals removable, so the pb proxy looks a bit more like dbus. (LP: #805471)

To post a comment you must log in.
Revision history for this message
Roberto Alsina (ralsina) wrote :

+1

review: Approve
Revision history for this message
Natalia Bidart (nataliabidart) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'tests/platform/windows/test_credentials.py'
2--- tests/platform/windows/test_credentials.py 2011-06-24 05:30:34 +0000
3+++ tests/platform/windows/test_credentials.py 2011-07-04 15:23:09 +0000
4@@ -23,7 +23,7 @@
5 from ubuntuone.platform.windows import credentials
6
7 TEST_APP_NAME = "test application"
8-
9+TEST_ERROR_DICT = {}
10 TEST_CREDENTIALS = {
11 "token": "1234token",
12 }
13@@ -32,11 +32,67 @@
14 class FakeSSOProxy(object):
15 """A fake SSOProxy."""
16
17+ def __init__(self):
18+ """Initialize this fake."""
19+ signals = [
20+ "credentials_stored",
21+ "credentials_cleared",
22+ "credentials_found",
23+ "credentials_not_found",
24+ "authorization_denied",
25+ "credentials_error",
26+ ]
27+ for s in signals:
28+ handler_name = "on_%s" % s
29+ callback_name = "on_%s_cb" % s
30+
31+ def make_handler(callback_name):
32+ """Create a handler for a given callback_name."""
33+
34+ def handler(*args):
35+ """A signal was called."""
36+ callback = getattr(self, callback_name, None)
37+ if callback is not None:
38+ callback(*args)
39+
40+ return handler
41+
42+ setattr(self, handler_name, make_handler(callback_name))
43+ setattr(self, callback_name, None)
44+
45+
46 def find_credentials(self, app_name, options, **kwargs):
47 """Ask the U1 credentials."""
48 return defer.succeed(TEST_CREDENTIALS)
49
50
51+class RemovableSignalTestCase(TestCase):
52+ """Tests for RemovableSignal."""
53+
54+ def setUp(self):
55+ """Initialize this fake instance."""
56+ self.proxy = FakeSSOProxy()
57+
58+ def test_dunder_callable(self):
59+ """__call__ works as expected."""
60+ sample_store = []
61+ test_cb = lambda app_name, creds: sample_store.append(creds)
62+ rs = credentials.RemovableSignal(self.proxy, "on_credentials_found_cb",
63+ test_cb)
64+ rs(TEST_APP_NAME, TEST_CREDENTIALS)
65+ self.assertEqual(sample_store[0], TEST_CREDENTIALS)
66+
67+ def test_remove(self):
68+ """The signal has a .remove that removes the callback."""
69+ sample_store = []
70+ test_cb = lambda app_name, creds: sample_store.append(creds)
71+ rs = credentials.RemovableSignal(self.proxy, "on_credentials_found_cb",
72+ test_cb)
73+ rs.remove()
74+ rs(TEST_APP_NAME, TEST_CREDENTIALS)
75+ self.assertEqual(len(sample_store), 0)
76+
77+
78 class CredentialsManagementTestCase(TestCase):
79 """Tests for CredentialsManagement."""
80
81@@ -66,3 +122,44 @@
82 cb = lambda: None
83 other_cb = self.cm.register_to_credentials_not_found(cb)
84 other_cb(TEST_APP_NAME)
85+
86+ def _verify_not_called_twice(self, signal_name, *args):
87+ """Test that the callback is not called twice."""
88+ d = defer.Deferred()
89+
90+ def signal_handler(*args):
91+ """Fake the behaviour of CredentialsManagementToolRoot."""
92+ d.callback(args[0] if len(args) > 0 else None)
93+
94+ register = getattr(self.cm, "register_to_" + signal_name)
95+ signal = register(signal_handler)
96+ proxy_cb = getattr(self.proxy, "on_" + signal_name)
97+ proxy_cb(*args)
98+ if getattr(signal, "remove", False):
99+ signal.remove()
100+ proxy_cb(*args)
101+
102+ def test_not_called_twice_credentials_stored(self):
103+ """Test that on_credentials_stored is not called twice."""
104+ self._verify_not_called_twice("credentials_stored")
105+
106+ def test_not_called_twice_credentials_cleared(self):
107+ """Test that on_credentials_cleared is not called twice."""
108+ self._verify_not_called_twice("credentials_cleared")
109+
110+ def test_not_called_twice_credentials_found(self):
111+ """Test that on_credentials_found is not called twice."""
112+ self._verify_not_called_twice("credentials_found", TEST_APP_NAME,
113+ TEST_CREDENTIALS)
114+
115+ def test_not_called_twice_credentials_not_found(self):
116+ """Test that on_credentials_not_found is not called twice."""
117+ self._verify_not_called_twice("credentials_not_found")
118+
119+ def test_not_called_twice_authorization_denied(self):
120+ """Test that on_authorization_denied is not called twice."""
121+ self._verify_not_called_twice("authorization_denied")
122+
123+ def test_not_called_twice_credentials_error(self):
124+ """Test that on_credentials_error is not called twice."""
125+ self._verify_not_called_twice("credentials_error", TEST_ERROR_DICT)
126
127=== modified file 'ubuntuone/platform/windows/credentials.py'
128--- ubuntuone/platform/windows/credentials.py 2011-06-24 05:30:34 +0000
129+++ ubuntuone/platform/windows/credentials.py 2011-07-04 15:23:09 +0000
130@@ -40,6 +40,28 @@
131 CredentialsError = CredentialsErrorRoot
132
133
134+class RemovableSignal(object):
135+ """A signal that can be removed."""
136+
137+ def __init__(self, proxy, signal_name, callback):
138+ """Initialize this instance."""
139+ self.proxy = proxy
140+ self.signal_name = signal_name
141+ self.callback = callback
142+ setattr(self.proxy, signal_name, callback)
143+
144+ def __call__(self, *args, **kwargs):
145+ """Call this instance."""
146+ func = getattr(self.proxy, self.signal_name, None)
147+ if func is not None:
148+ return func(*args, **kwargs)
149+
150+ def remove(self):
151+ """Remove this signal."""
152+ if getattr(self.proxy, self.signal_name, False):
153+ setattr(self.proxy, self.signal_name, None)
154+
155+
156 class CredentialsManagement(object):
157 """Object that manages Ubuntu One credentials."""
158
159@@ -81,35 +103,35 @@
160
161 def register_to_credentials_stored(self, callback):
162 """Register to the CredentialsStored dbus signal."""
163- self.sso_proxy.on_credentials_stored_cb = callback
164- return self.sso_proxy.on_credentials_stored_cb
165+ return RemovableSignal(self.sso_proxy, "on_credentials_stored_cb",
166+ callback)
167
168 def register_to_credentials_cleared(self, callback):
169 """Register to the CredentialsCleared dbus signal."""
170- self.sso_proxy.on_credentials_cleared_cb = callback
171- return self.sso_proxy.on_credentials_cleared_cb
172+ return RemovableSignal(self.sso_proxy, "on_credentials_cleared_cb",
173+ callback)
174
175 def register_to_credentials_found(self, callback):
176 """Register to the CredentialsFound dbus signal."""
177 pass_credentials = lambda app_name, creds: callback(creds)
178- self.sso_proxy.on_credentials_found_cb = pass_credentials
179- return self.sso_proxy.on_credentials_found_cb
180+ return RemovableSignal(self.sso_proxy, "on_credentials_found_cb",
181+ pass_credentials)
182
183 def register_to_credentials_not_found(self, callback):
184 """Register to the CredentialsFound dbus signal."""
185 pass_empty = lambda *args: callback()
186- self.sso_proxy.on_credentials_not_found_cb = pass_empty
187- return self.sso_proxy.on_credentials_not_found_cb
188+ return RemovableSignal(self.sso_proxy, "on_credentials_not_found_cb",
189+ pass_empty)
190
191 def register_to_authorization_denied(self, callback):
192 """Register to the AuthorizationDenied dbus signal."""
193- self.sso_proxy.on_authorization_denied_cb = callback
194- return self.sso_proxy.on_authorization_denied_cb
195+ return RemovableSignal(self.sso_proxy, "on_authorization_denied_cb",
196+ callback)
197
198 def register_to_credentials_error(self, callback):
199 """Register to the CredentialsError dbus signal."""
200- self.sso_proxy.on_credentials_error_cb = callback
201- return self.sso_proxy.on_credentials_error_cb
202+ return RemovableSignal(self.sso_proxy, "on_credentials_error_cb",
203+ callback)
204
205
206 @defer.inlineCallbacks

Subscribers

People subscribed via source and target branches