Merge lp:~dobey/ubuntu-sso-client/update-4-0 into lp:ubuntu-sso-client/stable-4-0
- update-4-0
- Merge into stable-4-0
Status: | Merged |
---|---|
Approved by: | dobey |
Approved revision: | no longer in the source branch. |
Merged at revision: | 960 |
Proposed branch: | lp:~dobey/ubuntu-sso-client/update-4-0 |
Merge into: | lp:ubuntu-sso-client/stable-4-0 |
Diff against target: |
1801 lines (+311/-618) 50 files modified
bin/ubuntu-sso-login (+1/-1) setup.py (+2/-4) ubuntu_sso/account.py (+5/-5) ubuntu_sso/gtk/gui.py (+23/-5) ubuntu_sso/gtk/tests/test_gui.py (+14/-5) ubuntu_sso/keyring/tests/test_linux.py (+1/-1) ubuntu_sso/logger.py (+2/-2) ubuntu_sso/main/__init__.py (+1/-1) ubuntu_sso/main/linux.py (+6/-1) ubuntu_sso/main/tests/test_linux.py (+59/-0) ubuntu_sso/networkstate/darwin.py (+2/-2) ubuntu_sso/networkstate/linux.py (+3/-3) ubuntu_sso/networkstate/windows.py (+1/-1) ubuntu_sso/qt/__init__.py (+1/-1) ubuntu_sso/qt/current_user_sign_in_page.py (+1/-3) ubuntu_sso/qt/main/__init__.py (+2/-0) ubuntu_sso/qt/main/tests/test_main.py (+1/-0) ubuntu_sso/qt/proxy_dialog.py (+1/-1) ubuntu_sso/qt/setup_account_page.py (+2/-3) ubuntu_sso/qt/sso_wizard_page.py (+2/-2) ubuntu_sso/qt/tests/test_arrow.py (+1/-1) ubuntu_sso/qt/tests/test_common.py (+3/-3) ubuntu_sso/qt/tests/test_current_user_sign_in_page.py (+1/-1) ubuntu_sso/qt/tests/test_setup_account.py (+1/-2) ubuntu_sso/tests/test_account.py (+1/-1) ubuntu_sso/tests/test_credentials.py (+2/-1) ubuntu_sso/utils/__init__.py (+1/-1) ubuntu_sso/utils/ipc.py (+3/-3) ubuntu_sso/utils/runner/glib.py (+1/-1) ubuntu_sso/utils/runner/tests/test_glib.py (+1/-1) ubuntu_sso/utils/runner/tests/test_qt.py (+2/-2) ubuntu_sso/utils/runner/tx.py (+2/-2) ubuntu_sso/utils/tcpactivation.py (+5/-1) ubuntu_sso/utils/tests/test_common.py (+1/-0) ubuntu_sso/utils/tests/test_tcpactivation.py (+49/-50) ubuntu_sso/utils/txsecrets.py (+1/-1) ubuntu_sso/utils/webclient/common.py (+2/-2) ubuntu_sso/utils/webclient/gsettings.py (+9/-2) ubuntu_sso/utils/webclient/libsoup.py (+1/-1) ubuntu_sso/utils/webclient/qtnetwork.py (+3/-3) ubuntu_sso/utils/webclient/restful.py (+12/-1) ubuntu_sso/utils/webclient/tests/test_gsettings.py (+32/-0) ubuntu_sso/utils/webclient/tests/test_restful.py (+44/-0) ubuntu_sso/utils/webclient/tests/test_webclient.py (+2/-2) ubuntu_sso/utils/webclient/timestamp.py (+1/-1) ubuntu_sso/xdg_base_directory/__init__.py (+0/-104) ubuntu_sso/xdg_base_directory/tests/__init__.py (+0/-29) ubuntu_sso/xdg_base_directory/tests/test_common.py (+0/-91) ubuntu_sso/xdg_base_directory/tests/test_windows.py (+0/-157) ubuntu_sso/xdg_base_directory/windows.py (+0/-113) |
To merge this branch: | bzr merge lp:~dobey/ubuntu-sso-client/update-4-0 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Alejandro J. Cura (community) | Approve | ||
Roberto Alsina (community) | Approve | ||
Review via email:
|
Commit message
[Mike McCracken]
- Delay importing twisted.
- Correctly bring main sso client window to the front on OS X. (LP: #1012837)
- Fixes bug with loading incorrect plug-ins caused by ignoring qt.conf. (LP: #1010102)
[Alejandro Cura]
- Account for g_variant_print type annotations (LP: #1007109).
[Brian Curtin]
- Move from iteritems/
- Use Python 3 style exception handling syntax.
[Rodney Dawes]
- Remove the xdg_base_directory module as it duplicates dirspec now.
- Disable the color validation for warning labels due to new GTK+ breaking it.
- Ensure we are using strict ssl with the system ca-certificates.crt file.
- Trap DBusException when getting the SessionBus, and add a test case for it.
[Manuel de la Pena]
- Changed tests so that they use u1-dev-tools better and do not get blocked in the clean up (LP: #1009071).
[Natalia Bidart]
- Added a little more logging to the webclient when doing REST calls.
[Roberto Alsina]
- Remove back buttons in signin/signup pages (Fixes LP: #1009107).
Description of the change
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Ubuntu One Auto Pilot (otto-pilot) wrote : | # |
Voting does not meet specified criteria. Required: Approve >= 1, Disapprove == 0, Needs Fixing == 0, Needs Information == 0, Resubmit == 0, Pending == 0. Got: 1 Approve, 1 Pending.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Alejandro J. Cura (alecu) wrote : | # |
+1 looks just like trunk
- 960. By Brian Curtin
-
[Mike McCracken]
- Delay importing twisted.
internet. reactor to avoid creating default reactor when we need qt4reactor. (LP: #1017672)
- Correctly bring main sso client window to the front on OS X. (LP: #1012837)
- Fixes bug with loading incorrect plug-ins caused by ignoring qt.conf. (LP: #1010102)[Alejandro Cura]
- Account for g_variant_print type annotations (LP: #1007109).
[Brian Curtin]
- Move from iteritems/
itervalues to items/values for Python 3 support.
- Use Python 3 style exception handling syntax.[Rodney Dawes]
- Remove the xdg_base_directory module as it duplicates dirspec now.
- Disable the color validation for warning labels due to new GTK+ breaking it.
- Ensure we are using strict ssl with the system ca-certificates.crt file.
- Trap DBusException when getting the SessionBus, and add a test case for it.[Manuel de la Pena]
- Changed tests so that they use u1-dev-tools better and do not get blocked in the clean up (LP: #1009071).
[Natalia Bidart]
- Added a little more logging to the webclient when doing REST calls.
[Roberto Alsina]
- Remove back buttons in signin/signup pages (Fixes LP: #1009107).
Preview Diff
1 | === modified file 'bin/ubuntu-sso-login' | |||
2 | --- bin/ubuntu-sso-login 2012-05-18 14:25:49 +0000 | |||
3 | +++ bin/ubuntu-sso-login 2012-06-27 15:30:29 +0000 | |||
4 | @@ -57,7 +57,7 @@ | |||
5 | 57 | # need to create the QApplication before installing the reactor | 57 | # need to create the QApplication before installing the reactor |
6 | 58 | if os.environ.get('TESTABILITY', False): | 58 | if os.environ.get('TESTABILITY', False): |
7 | 59 | sys.argv.append('-testability') | 59 | sys.argv.append('-testability') |
9 | 60 | QtGui.QApplication(sys.argv) | 60 | app = QtGui.QApplication(sys.argv) |
10 | 61 | 61 | ||
11 | 62 | # pylint: disable=F0401 | 62 | # pylint: disable=F0401 |
12 | 63 | import qt4reactor | 63 | import qt4reactor |
13 | 64 | 64 | ||
14 | === modified file 'setup.py' | |||
15 | --- setup.py 2012-06-05 19:55:04 +0000 | |||
16 | +++ setup.py 2012-06-27 15:30:29 +0000 | |||
17 | @@ -301,8 +301,8 @@ | |||
18 | 301 | author='Natalia Bidart', | 301 | author='Natalia Bidart', |
19 | 302 | author_email='natalia.bidart@canonical.com', | 302 | author_email='natalia.bidart@canonical.com', |
20 | 303 | description='Ubuntu Single Sign-On client', | 303 | description='Ubuntu Single Sign-On client', |
23 | 304 | long_description='Desktop service to allow applications to sign in' \ | 304 | long_description=('Desktop service to allow applications to sign in' |
24 | 305 | 'to Ubuntu services via SSO', | 305 | 'to Ubuntu services via SSO'), |
25 | 306 | url='https://launchpad.net/ubuntu-sso-client', | 306 | url='https://launchpad.net/ubuntu-sso-client', |
26 | 307 | extra_path='ubuntu-sso-client', | 307 | extra_path='ubuntu-sso-client', |
27 | 308 | data_files=data_files, | 308 | data_files=data_files, |
28 | @@ -325,8 +325,6 @@ | |||
29 | 325 | 'ubuntu_sso.utils.runner.tests', | 325 | 'ubuntu_sso.utils.runner.tests', |
30 | 326 | 'ubuntu_sso.utils.webclient', | 326 | 'ubuntu_sso.utils.webclient', |
31 | 327 | 'ubuntu_sso.utils.webclient.tests', | 327 | 'ubuntu_sso.utils.webclient.tests', |
32 | 328 | 'ubuntu_sso.xdg_base_directory', | ||
33 | 329 | 'ubuntu_sso.xdg_base_directory.tests', | ||
34 | 330 | ], | 328 | ], |
35 | 331 | cmdclass=cmdclass, | 329 | cmdclass=cmdclass, |
36 | 332 | **extra) | 330 | **extra) |
37 | 333 | 331 | ||
38 | === modified file 'ubuntu_sso/account.py' | |||
39 | --- ubuntu_sso/account.py 2012-05-29 16:56:45 +0000 | |||
40 | +++ ubuntu_sso/account.py 2012-06-27 15:30:29 +0000 | |||
41 | @@ -110,7 +110,7 @@ | |||
42 | 110 | def _format_webservice_errors(self, errdict): | 110 | def _format_webservice_errors(self, errdict): |
43 | 111 | """Turn each list of strings in the errdict into a LF separated str.""" | 111 | """Turn each list of strings in the errdict into a LF separated str.""" |
44 | 112 | result = {} | 112 | result = {} |
46 | 113 | for key, val in errdict.iteritems(): | 113 | for key, val in errdict.items(): |
47 | 114 | # workaround until bug #624955 is solved | 114 | # workaround until bug #624955 is solved |
48 | 115 | if isinstance(val, basestring): | 115 | if isinstance(val, basestring): |
49 | 116 | result[key] = val | 116 | result[key] = val |
50 | @@ -197,7 +197,7 @@ | |||
51 | 197 | finally: | 197 | finally: |
52 | 198 | restful_client.shutdown() | 198 | restful_client.shutdown() |
53 | 199 | 199 | ||
55 | 200 | logger.debug('login: authentication successful! consumer_key: %r, ' \ | 200 | logger.debug('login: authentication successful! consumer_key: %r, ' |
56 | 201 | 'token_name: %r', credentials['consumer_key'], token_name) | 201 | 'token_name: %r', credentials['consumer_key'], token_name) |
57 | 202 | defer.returnValue(credentials) | 202 | defer.returnValue(credentials) |
58 | 203 | 203 | ||
59 | @@ -212,7 +212,7 @@ | |||
60 | 212 | finally: | 212 | finally: |
61 | 213 | restful_client.shutdown() | 213 | restful_client.shutdown() |
62 | 214 | key = 'preferred_email' | 214 | key = 'preferred_email' |
64 | 215 | result = key in me_info and me_info[key] != None | 215 | result = key in me_info and me_info[key] is not None |
65 | 216 | 216 | ||
66 | 217 | logger.info('is_validated: consumer_key: %r, result: %r.', | 217 | logger.info('is_validated: consumer_key: %r, result: %r.', |
67 | 218 | token['consumer_key'], result) | 218 | token['consumer_key'], result) |
68 | @@ -249,7 +249,7 @@ | |||
69 | 249 | try: | 249 | try: |
70 | 250 | operation = u"registration.request_password_reset_token" | 250 | operation = u"registration.request_password_reset_token" |
71 | 251 | result = yield restful_client.restcall(operation, email=email) | 251 | result = yield restful_client.restcall(operation, email=email) |
73 | 252 | except WebClientError, e: | 252 | except WebClientError as e: |
74 | 253 | logger.exception('request_password_reset_token failed with:') | 253 | logger.exception('request_password_reset_token failed with:') |
75 | 254 | raise ResetPasswordTokenError(e[1].split('\n')[0]) | 254 | raise ResetPasswordTokenError(e[1].split('\n')[0]) |
76 | 255 | finally: | 255 | finally: |
77 | @@ -275,7 +275,7 @@ | |||
78 | 275 | u"registration.set_new_password", | 275 | u"registration.set_new_password", |
79 | 276 | email=email, token=token, | 276 | email=email, token=token, |
80 | 277 | new_password=new_password) | 277 | new_password=new_password) |
82 | 278 | except WebClientError, e: | 278 | except WebClientError as e: |
83 | 279 | logger.exception('set_new_password failed with:') | 279 | logger.exception('set_new_password failed with:') |
84 | 280 | raise NewPasswordError(e[1].split('\n')[0]) | 280 | raise NewPasswordError(e[1].split('\n')[0]) |
85 | 281 | finally: | 281 | finally: |
86 | 282 | 282 | ||
87 | === modified file 'ubuntu_sso/gtk/gui.py' | |||
88 | --- ubuntu_sso/gtk/gui.py 2012-04-11 16:38:28 +0000 | |||
89 | +++ ubuntu_sso/gtk/gui.py 2012-06-27 15:30:29 +0000 | |||
90 | @@ -109,6 +109,12 @@ | |||
91 | 109 | LARGE_MARKUP = u'<span size="x-large">%s</span>' | 109 | LARGE_MARKUP = u'<span size="x-large">%s</span>' |
92 | 110 | 110 | ||
93 | 111 | 111 | ||
94 | 112 | # SSL properties and certs location | ||
95 | 113 | STRICT_SSL_PROP = 'ssl-strict' | ||
96 | 114 | CERTS_FILE_PROP = 'ssl-ca-file' | ||
97 | 115 | CA_CERT_FILE = '/etc/ssl/certs/ca-certificates.crt' | ||
98 | 116 | |||
99 | 117 | |||
100 | 112 | def log_call(f): | 118 | def log_call(f): |
101 | 113 | """Decorator to log call funtions.""" | 119 | """Decorator to log call funtions.""" |
102 | 114 | 120 | ||
103 | @@ -356,7 +362,7 @@ | |||
104 | 356 | if app_name == self.app_name: | 362 | if app_name == self.app_name: |
105 | 357 | result = f(app_name, *args, **kwargs) | 363 | result = f(app_name, *args, **kwargs) |
106 | 358 | else: | 364 | else: |
108 | 359 | logger.info('%s: ignoring call since received app_name '\ | 365 | logger.info('%s: ignoring call since received app_name ' |
109 | 360 | '%r (expected %r)', | 366 | '%r (expected %r)', |
110 | 361 | f.__name__, app_name, self.app_name) | 367 | f.__name__, app_name, self.app_name) |
111 | 362 | return result | 368 | return result |
112 | @@ -365,7 +371,7 @@ | |||
113 | 365 | 371 | ||
114 | 366 | def _setup_signals(self): | 372 | def _setup_signals(self): |
115 | 367 | """Bind signals to callbacks to be able to test the pages.""" | 373 | """Bind signals to callbacks to be able to test the pages.""" |
117 | 368 | for signal, method in self._signals.iteritems(): | 374 | for signal, method in self._signals.items(): |
118 | 369 | actual = self._signals_receivers.get(signal) | 375 | actual = self._signals_receivers.get(signal) |
119 | 370 | if actual is not None: | 376 | if actual is not None: |
120 | 371 | msg = 'Signal %r is already connected with %r.' | 377 | msg = 'Signal %r is already connected with %r.' |
121 | @@ -703,7 +709,7 @@ | |||
122 | 703 | if os.path.exists(self._captcha_filename): | 709 | if os.path.exists(self._captcha_filename): |
123 | 704 | os.remove(self._captcha_filename) | 710 | os.remove(self._captcha_filename) |
124 | 705 | 711 | ||
126 | 706 | for signal, match in self._signals_receivers.iteritems(): | 712 | for signal, match in self._signals_receivers.items(): |
127 | 707 | self.backend.disconnect_from_signal(signal, match) | 713 | self.backend.disconnect_from_signal(signal, match) |
128 | 708 | 714 | ||
129 | 709 | # hide the main window | 715 | # hide the main window |
130 | @@ -790,7 +796,7 @@ | |||
131 | 790 | self.user_email = email1 | 796 | self.user_email = email1 |
132 | 791 | self.user_password = password1 | 797 | self.user_password = password1 |
133 | 792 | 798 | ||
135 | 793 | logger.info('Calling register_user with email %r, password <hidden>,' \ | 799 | logger.info('Calling register_user with email %r, password <hidden>,' |
136 | 794 | ' name %r, captcha_id %r and captcha_solution %r.', email1, | 800 | ' name %r, captcha_id %r and captcha_solution %r.', email1, |
137 | 795 | name, self._captcha_id, captcha_solution) | 801 | name, self._captcha_id, captcha_solution) |
138 | 796 | 802 | ||
139 | @@ -943,7 +949,7 @@ | |||
140 | 943 | return | 949 | return |
141 | 944 | 950 | ||
142 | 945 | email = self.reset_email_entry.get_text() | 951 | email = self.reset_email_entry.get_text() |
144 | 946 | logger.info('Calling set_new_password with email %r, token %r and ' \ | 952 | logger.info('Calling set_new_password with email %r, token %r and ' |
145 | 947 | 'new password: <hidden>.', email, token) | 953 | 'new password: <hidden>.', email, token) |
146 | 948 | f = self.backend.set_new_password | 954 | f = self.backend.set_new_password |
147 | 949 | error_handler = partial(self._handle_error, f, | 955 | error_handler = partial(self._handle_error, f, |
148 | @@ -953,11 +959,23 @@ | |||
149 | 953 | 959 | ||
150 | 954 | self._set_current_page(self.processing_vbox) | 960 | self._set_current_page(self.processing_vbox) |
151 | 955 | 961 | ||
152 | 962 | def _webkit_init_ssl(self): | ||
153 | 963 | """Set the WebKit ssl strictness.""" | ||
154 | 964 | # delay the import of webkit to be able to build without it | ||
155 | 965 | from gi.repository import WebKit # pylint: disable=E0611 | ||
156 | 966 | |||
157 | 967 | # Set the Soup session to be strict and use system CA certs | ||
158 | 968 | session = WebKit.get_default_session() | ||
159 | 969 | session.set_property(STRICT_SSL_PROP, True) | ||
160 | 970 | session.set_property(CERTS_FILE_PROP, CA_CERT_FILE) | ||
161 | 971 | |||
162 | 956 | def _add_webkit_browser(self): | 972 | def _add_webkit_browser(self): |
163 | 957 | """Add the webkit browser for the t&c.""" | 973 | """Add the webkit browser for the t&c.""" |
164 | 958 | # delay the import of webkit to be able to build without it | 974 | # delay the import of webkit to be able to build without it |
165 | 959 | from gi.repository import WebKit # pylint: disable=E0611 | 975 | from gi.repository import WebKit # pylint: disable=E0611 |
166 | 960 | 976 | ||
167 | 977 | self._webkit_init_ssl() | ||
168 | 978 | |||
169 | 961 | browser = WebKit.WebView() | 979 | browser = WebKit.WebView() |
170 | 962 | 980 | ||
171 | 963 | browser.connect('notify::load-status', | 981 | browser.connect('notify::load-status', |
172 | 964 | 982 | ||
173 | === modified file 'ubuntu_sso/gtk/tests/test_gui.py' | |||
174 | --- ubuntu_sso/gtk/tests/test_gui.py 2012-04-11 16:38:28 +0000 | |||
175 | +++ ubuntu_sso/gtk/tests/test_gui.py 2012-06-27 15:30:29 +0000 | |||
176 | @@ -168,6 +168,7 @@ | |||
177 | 168 | self.memento = MementoHandler() | 168 | self.memento = MementoHandler() |
178 | 169 | self.memento.setLevel(logging.DEBUG) | 169 | self.memento.setLevel(logging.DEBUG) |
179 | 170 | gui.logger.addHandler(self.memento) | 170 | gui.logger.addHandler(self.memento) |
180 | 171 | self.addCleanup(gui.logger.removeHandler, self.memento) | ||
181 | 171 | 172 | ||
182 | 172 | def _set_called(self, *args, **kwargs): | 173 | def _set_called(self, *args, **kwargs): |
183 | 173 | """Set _called to True.""" | 174 | """Set _called to True.""" |
184 | @@ -446,9 +447,10 @@ | |||
185 | 446 | self.assertEqual(actual, message) | 447 | self.assertEqual(actual, message) |
186 | 447 | 448 | ||
187 | 448 | # content color is correct | 449 | # content color is correct |
191 | 449 | expected = gui.WARNING_TEXT_COLOR | 450 | # FIXME - New GTK+ 3.5 breaks this check - see bug #1014772 |
192 | 450 | actual = label.get_style().fg[Gtk.StateFlags.NORMAL] | 451 | # expected = gui.WARNING_TEXT_COLOR |
193 | 451 | self.assert_color_equal(expected, actual) | 452 | # actual = label.get_style().fg[Gtk.StateFlags.NORMAL] |
194 | 453 | # self.assert_color_equal(expected, actual) | ||
195 | 452 | 454 | ||
196 | 453 | def assert_correct_entry_warning(self, entry, message): | 455 | def assert_correct_entry_warning(self, entry, message): |
197 | 454 | """Check that a warning is shown displaying 'message'.""" | 456 | """Check that a warning is shown displaying 'message'.""" |
198 | @@ -911,6 +913,7 @@ | |||
199 | 911 | def setUp(self): | 913 | def setUp(self): |
200 | 912 | yield super(TermsAndConditionsBrowserTestCase, self).setUp() | 914 | yield super(TermsAndConditionsBrowserTestCase, self).setUp() |
201 | 913 | self.patch(WebKit, 'WebView', FakedEmbeddedBrowser) | 915 | self.patch(WebKit, 'WebView', FakedEmbeddedBrowser) |
202 | 916 | self.patch(self.ui, '_webkit_init_ssl', self._set_called) | ||
203 | 914 | 917 | ||
204 | 915 | self.ui.tc_button.clicked() | 918 | self.ui.tc_button.clicked() |
205 | 916 | self.addCleanup(self.ui.tc_browser_vbox.hide) | 919 | self.addCleanup(self.ui.tc_browser_vbox.hide) |
206 | @@ -919,6 +922,12 @@ | |||
207 | 919 | assert len(children) == 1 | 922 | assert len(children) == 1 |
208 | 920 | self.browser = children[0] | 923 | self.browser = children[0] |
209 | 921 | 924 | ||
210 | 925 | def test_ssl_validation(self): | ||
211 | 926 | """The browser is set to validate SSL.""" | ||
212 | 927 | self.assertEqual(self._called, ((), {}), | ||
213 | 928 | '_webkit_init_ssl should be called when creating a ' | ||
214 | 929 | 'webkit browser.') | ||
215 | 930 | |||
216 | 922 | def test_tc_browser_is_created_when_tc_page_is_shown(self): | 931 | def test_tc_browser_is_created_when_tc_page_is_shown(self): |
217 | 923 | """The browser is created when the TC button is clicked.""" | 932 | """The browser is created when the TC button is clicked.""" |
218 | 924 | self.ui.on_tc_browser_notify_load_status(self.browser) | 933 | self.ui.on_tc_browser_notify_load_status(self.browser) |
219 | @@ -1983,7 +1992,7 @@ | |||
220 | 1983 | """Callbacks are connected to signals of interest.""" | 1992 | """Callbacks are connected to signals of interest.""" |
221 | 1984 | msg1 = 'callback %r for signal %r must be added to the backend.' | 1993 | msg1 = 'callback %r for signal %r must be added to the backend.' |
222 | 1985 | msg2 = 'callback %r for signal %r must be added to the ui log.' | 1994 | msg2 = 'callback %r for signal %r must be added to the ui log.' |
224 | 1986 | for signal, method in self.ui._signals.iteritems(): | 1995 | for signal, method in self.ui._signals.items(): |
225 | 1987 | actual = self.ui.backend.callbacks.get(signal) | 1996 | actual = self.ui.backend.callbacks.get(signal) |
226 | 1988 | self.assertEqual([method], actual, msg1 % (method, signal)) | 1997 | self.assertEqual([method], actual, msg1 % (method, signal)) |
227 | 1989 | actual = self.ui._signals_receivers.get(signal) | 1998 | actual = self.ui._signals_receivers.get(signal) |
228 | @@ -1992,7 +2001,7 @@ | |||
229 | 1992 | def test_callbacks_only_log_when_app_name_doesnt_match(self): | 2001 | def test_callbacks_only_log_when_app_name_doesnt_match(self): |
230 | 1993 | """Callbacks do nothing but logging when app_name doesn't match.""" | 2002 | """Callbacks do nothing but logging when app_name doesn't match.""" |
231 | 1994 | mismatch_app_name = self.ui.app_name * 2 | 2003 | mismatch_app_name = self.ui.app_name * 2 |
233 | 1995 | for method in self.ui._signals.itervalues(): | 2004 | for method in self.ui._signals.values(): |
234 | 1996 | msgs = ('ignoring', method.__name__, repr(mismatch_app_name)) | 2005 | msgs = ('ignoring', method.__name__, repr(mismatch_app_name)) |
235 | 1997 | method(mismatch_app_name, 'dummy') | 2006 | method(mismatch_app_name, 'dummy') |
236 | 1998 | self.assertTrue(self.memento.check(logging.INFO, *msgs)) | 2007 | self.assertTrue(self.memento.check(logging.INFO, *msgs)) |
237 | 1999 | 2008 | ||
238 | === modified file 'ubuntu_sso/keyring/tests/test_linux.py' | |||
239 | --- ubuntu_sso/keyring/tests/test_linux.py 2012-04-09 17:38:24 +0000 | |||
240 | +++ ubuntu_sso/keyring/tests/test_linux.py 2012-06-27 15:30:29 +0000 | |||
241 | @@ -137,7 +137,7 @@ | |||
242 | 137 | 137 | ||
243 | 138 | def get_mock_service(self): | 138 | def get_mock_service(self): |
244 | 139 | """Create only one instance of the mock service per test.""" | 139 | """Create only one instance of the mock service per test.""" |
246 | 140 | if self.mock_service == None: | 140 | if self.mock_service is None: |
247 | 141 | self.mock_service = MockSecretService() | 141 | self.mock_service = MockSecretService() |
248 | 142 | return self.mock_service | 142 | return self.mock_service |
249 | 143 | 143 | ||
250 | 144 | 144 | ||
251 | === modified file 'ubuntu_sso/logger.py' | |||
252 | --- ubuntu_sso/logger.py 2012-04-09 17:38:24 +0000 | |||
253 | +++ ubuntu_sso/logger.py 2012-06-27 15:30:29 +0000 | |||
254 | @@ -37,11 +37,11 @@ | |||
255 | 37 | import os | 37 | import os |
256 | 38 | import sys | 38 | import sys |
257 | 39 | 39 | ||
258 | 40 | from dirspec.basedir import xdg_cache_home | ||
259 | 41 | from dirspec.utils import unicode_path | ||
260 | 40 | from functools import wraps | 42 | from functools import wraps |
261 | 41 | from logging.handlers import RotatingFileHandler | 43 | from logging.handlers import RotatingFileHandler |
262 | 42 | 44 | ||
263 | 43 | from ubuntu_sso.xdg_base_directory import unicode_path, xdg_cache_home | ||
264 | 44 | |||
265 | 45 | LOGFOLDER = os.path.join(xdg_cache_home, 'sso') | 45 | LOGFOLDER = os.path.join(xdg_cache_home, 'sso') |
266 | 46 | # create log folder if it doesn't exists | 46 | # create log folder if it doesn't exists |
267 | 47 | if not os.path.exists(unicode_path(LOGFOLDER)): | 47 | if not os.path.exists(unicode_path(LOGFOLDER)): |
268 | 48 | 48 | ||
269 | === modified file 'ubuntu_sso/main/__init__.py' | |||
270 | --- ubuntu_sso/main/__init__.py 2012-05-21 14:28:14 +0000 | |||
271 | +++ ubuntu_sso/main/__init__.py 2012-06-27 15:30:29 +0000 | |||
272 | @@ -348,7 +348,7 @@ | |||
273 | 348 | 348 | ||
274 | 349 | def _parse_args(self, args): | 349 | def _parse_args(self, args): |
275 | 350 | """Retrieve values from the generic param 'args'.""" | 350 | """Retrieve values from the generic param 'args'.""" |
277 | 351 | result = dict(i for i in args.iteritems() if i[0] in self.valid_keys) | 351 | result = dict(i for i in args.items() if i[0] in self.valid_keys) |
278 | 352 | result[WINDOW_ID_KEY] = int(args.get(WINDOW_ID_KEY, 0)) | 352 | result[WINDOW_ID_KEY] = int(args.get(WINDOW_ID_KEY, 0)) |
279 | 353 | return result | 353 | return result |
280 | 354 | 354 | ||
281 | 355 | 355 | ||
282 | === modified file 'ubuntu_sso/main/linux.py' | |||
283 | --- ubuntu_sso/main/linux.py 2012-04-10 10:43:48 +0000 | |||
284 | +++ ubuntu_sso/main/linux.py 2012-06-27 15:30:29 +0000 | |||
285 | @@ -342,10 +342,15 @@ | |||
286 | 342 | 342 | ||
287 | 343 | def __init__(self, root): | 343 | def __init__(self, root): |
288 | 344 | self.root = root | 344 | self.root = root |
289 | 345 | self.bus = dbus.SessionBus() | ||
290 | 346 | self.sso_login = None | 345 | self.sso_login = None |
291 | 347 | self.cred_manager = None | 346 | self.cred_manager = None |
292 | 348 | 347 | ||
293 | 348 | try: | ||
294 | 349 | self.bus = dbus.SessionBus() | ||
295 | 350 | except dbus.service.DBusException as e: | ||
296 | 351 | logger.exception(e) | ||
297 | 352 | shutdown_func() | ||
298 | 353 | |||
299 | 349 | def start(self): | 354 | def start(self): |
300 | 350 | """Start listening, nothing async to be done in this platform.""" | 355 | """Start listening, nothing async to be done in this platform.""" |
301 | 351 | # Register DBus service for making sure we run only one instance | 356 | # Register DBus service for making sure we run only one instance |
302 | 352 | 357 | ||
303 | === added file 'ubuntu_sso/main/tests/test_linux.py' | |||
304 | --- ubuntu_sso/main/tests/test_linux.py 1970-01-01 00:00:00 +0000 | |||
305 | +++ ubuntu_sso/main/tests/test_linux.py 2012-06-27 15:30:29 +0000 | |||
306 | @@ -0,0 +1,59 @@ | |||
307 | 1 | # -*- coding: utf-8 -*- | ||
308 | 2 | # | ||
309 | 3 | # Copyright 2012 Canonical Ltd. | ||
310 | 4 | # | ||
311 | 5 | # This program is free software: you can redistribute it and/or modify it | ||
312 | 6 | # under the terms of the GNU General Public License version 3, as published | ||
313 | 7 | # by the Free Software Foundation. | ||
314 | 8 | # | ||
315 | 9 | # This program is distributed in the hope that it will be useful, but | ||
316 | 10 | # WITHOUT ANY WARRANTY; without even the implied warranties of | ||
317 | 11 | # MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR | ||
318 | 12 | # PURPOSE. See the GNU General Public License for more details. | ||
319 | 13 | # | ||
320 | 14 | # You should have received a copy of the GNU General Public License along | ||
321 | 15 | # with this program. If not, see <http://www.gnu.org/licenses/>. | ||
322 | 16 | # | ||
323 | 17 | # In addition, as a special exception, the copyright holders give | ||
324 | 18 | # permission to link the code of portions of this program with the | ||
325 | 19 | # OpenSSL library under certain conditions as described in each | ||
326 | 20 | # individual source file, and distribute linked combinations | ||
327 | 21 | # including the two. | ||
328 | 22 | # You must obey the GNU General Public License in all respects | ||
329 | 23 | # for all of the code used other than OpenSSL. If you modify | ||
330 | 24 | # file(s) with this exception, you may extend this exception to your | ||
331 | 25 | # version of the file(s), but you are not obligated to do so. If you | ||
332 | 26 | # do not wish to do so, delete this exception statement from your | ||
333 | 27 | # version. If you delete this exception statement from all source | ||
334 | 28 | # files in the program, then also delete it here. | ||
335 | 29 | """Tests for the main SSO Linux client code.""" | ||
336 | 30 | |||
337 | 31 | # pylint: disable=C0103 | ||
338 | 32 | do_tests = False | ||
339 | 33 | try: | ||
340 | 34 | import dbus | ||
341 | 35 | import dbus.service | ||
342 | 36 | from ubuntu_sso.main import linux as main | ||
343 | 37 | do_tests = True | ||
344 | 38 | except ImportError: | ||
345 | 39 | do_tests = False | ||
346 | 40 | # pylint enable=C0103 | ||
347 | 41 | |||
348 | 42 | from ubuntuone.devtools.testcases import BaseTestCase, skipIf | ||
349 | 43 | |||
350 | 44 | |||
351 | 45 | @skipIf(not do_tests, 'Tests only work with DBus and linux imports.') | ||
352 | 46 | class LinuxProxyTestCase(BaseTestCase): | ||
353 | 47 | """Test some Linux specific cases.""" | ||
354 | 48 | |||
355 | 49 | def test_dbus_missing_exists_clean(self): | ||
356 | 50 | """Test that dbus-daemon not being available gives us a clean exit.""" | ||
357 | 51 | def patched(*args, **kwargs): | ||
358 | 52 | """Method to patch in for testing.""" | ||
359 | 53 | raise dbus.service.DBusException( | ||
360 | 54 | 'org.freedesktop.DBus.Error.NoServer') | ||
361 | 55 | |||
362 | 56 | self.patch(dbus, "SessionBus", patched) | ||
363 | 57 | self.patch(main, "shutdown_func", patched) | ||
364 | 58 | self.assertRaises(dbus.service.DBusException, | ||
365 | 59 | main.UbuntuSSOProxy, None) | ||
366 | 0 | 60 | ||
367 | === modified file 'ubuntu_sso/networkstate/darwin.py' | |||
368 | --- ubuntu_sso/networkstate/darwin.py 2012-05-21 14:48:25 +0000 | |||
369 | +++ ubuntu_sso/networkstate/darwin.py 2012-06-27 15:30:29 +0000 | |||
370 | @@ -126,7 +126,7 @@ | |||
371 | 126 | CFRelease(target) | 126 | CFRelease(target) |
372 | 127 | 127 | ||
373 | 128 | if not ok: | 128 | if not ok: |
375 | 129 | logger.error("Error getting reachability status of '%s'" % \ | 129 | logger.error("Error getting reachability status of '%s'" % |
376 | 130 | HOSTNAME_TO_CHECK) | 130 | HOSTNAME_TO_CHECK) |
377 | 131 | raise NetworkFailException() | 131 | raise NetworkFailException() |
378 | 132 | 132 | ||
379 | @@ -298,6 +298,6 @@ | |||
380 | 298 | """ | 298 | """ |
381 | 299 | try: | 299 | try: |
382 | 300 | return defer.succeed(check_connected_state()) | 300 | return defer.succeed(check_connected_state()) |
384 | 301 | except Exception, e: # pylint: disable=W0703 | 301 | except Exception as e: # pylint: disable=W0703 |
385 | 302 | logger.exception("Exception calling check_connected_state:") | 302 | logger.exception("Exception calling check_connected_state:") |
386 | 303 | return defer.fail(NetworkFailException(e)) | 303 | return defer.fail(NetworkFailException(e)) |
387 | 304 | 304 | ||
388 | === modified file 'ubuntu_sso/networkstate/linux.py' | |||
389 | --- ubuntu_sso/networkstate/linux.py 2012-05-24 04:20:08 +0000 | |||
390 | +++ ubuntu_sso/networkstate/linux.py 2012-06-27 15:30:29 +0000 | |||
391 | @@ -79,7 +79,7 @@ | |||
392 | 79 | # the user has connected in some other way | 79 | # the user has connected in some other way |
393 | 80 | self.call_result_cb(ONLINE) | 80 | self.call_result_cb(ONLINE) |
394 | 81 | else: | 81 | else: |
396 | 82 | logger.error("Error contacting NetworkManager: %s" % \ | 82 | logger.error("Error contacting NetworkManager: %s" % |
397 | 83 | str(error)) | 83 | str(error)) |
398 | 84 | self.call_result_cb(UNKNOWN) | 84 | self.call_result_cb(UNKNOWN) |
399 | 85 | 85 | ||
400 | @@ -107,7 +107,7 @@ | |||
401 | 107 | nm_proxy.Get(NM_DBUS_INTERFACE, "State", | 107 | nm_proxy.Get(NM_DBUS_INTERFACE, "State", |
402 | 108 | reply_handler=self.got_state, | 108 | reply_handler=self.got_state, |
403 | 109 | error_handler=self.got_error) | 109 | error_handler=self.got_error) |
405 | 110 | except Exception, e: # pylint: disable=W0703 | 110 | except Exception as e: # pylint: disable=W0703 |
406 | 111 | self.got_error(e) | 111 | self.got_error(e) |
407 | 112 | 112 | ||
408 | 113 | 113 | ||
409 | @@ -127,7 +127,7 @@ | |||
410 | 127 | try: | 127 | try: |
411 | 128 | network = NetworkManagerState(got_state) | 128 | network = NetworkManagerState(got_state) |
412 | 129 | network.find_online_state() | 129 | network.find_online_state() |
414 | 130 | except Exception, e: | 130 | except Exception as e: |
415 | 131 | logger.exception('is_machine_connected failed with:') | 131 | logger.exception('is_machine_connected failed with:') |
416 | 132 | d.errback(NetworkFailException(e)) | 132 | d.errback(NetworkFailException(e)) |
417 | 133 | # pylint: enable=W0702, W0703 | 133 | # pylint: enable=W0702, W0703 |
418 | 134 | 134 | ||
419 | === modified file 'ubuntu_sso/networkstate/windows.py' | |||
420 | --- ubuntu_sso/networkstate/windows.py 2012-04-09 17:38:24 +0000 | |||
421 | +++ ubuntu_sso/networkstate/windows.py 2012-06-27 15:30:29 +0000 | |||
422 | @@ -184,7 +184,7 @@ | |||
423 | 184 | flags = DWORD() | 184 | flags = DWORD() |
424 | 185 | connected = wininet.InternetGetConnectedState(byref(flags), None) | 185 | connected = wininet.InternetGetConnectedState(byref(flags), None) |
425 | 186 | return defer.succeed(connected == 1) | 186 | return defer.succeed(connected == 1) |
427 | 187 | except Exception, e: | 187 | except Exception as e: |
428 | 188 | logger.exception('is_machine_connected failed with:') | 188 | logger.exception('is_machine_connected failed with:') |
429 | 189 | return defer.fail(NetworkFailException(e)) | 189 | return defer.fail(NetworkFailException(e)) |
430 | 190 | # pylint: enable=W0703, W0702 | 190 | # pylint: enable=W0703, W0702 |
431 | 191 | 191 | ||
432 | === modified file 'ubuntu_sso/qt/__init__.py' | |||
433 | --- ubuntu_sso/qt/__init__.py 2012-04-23 13:32:52 +0000 | |||
434 | +++ ubuntu_sso/qt/__init__.py 2012-06-27 15:30:29 +0000 | |||
435 | @@ -75,7 +75,7 @@ | |||
436 | 75 | if 'errtype' in errordict: | 75 | if 'errtype' in errordict: |
437 | 76 | del errordict['errtype'] | 76 | del errordict['errtype'] |
438 | 77 | result = '\n'.join( | 77 | result = '\n'.join( |
440 | 78 | [('%s: %s' % (k, v)) for k, v in errordict.iteritems()]) | 78 | [('%s: %s' % (k, v)) for k, v in errordict.items()]) |
441 | 79 | else: | 79 | else: |
442 | 80 | result = GENERIC_BACKEND_ERROR | 80 | result = GENERIC_BACKEND_ERROR |
443 | 81 | logger.error('build_general_error_message with unknown error: %r', | 81 | logger.error('build_general_error_message with unknown error: %r', |
444 | 82 | 82 | ||
445 | === modified file 'ubuntu_sso/qt/current_user_sign_in_page.py' | |||
446 | --- ubuntu_sso/qt/current_user_sign_in_page.py 2012-04-09 17:38:24 +0000 | |||
447 | +++ ubuntu_sso/qt/current_user_sign_in_page.py 2012-06-27 15:30:29 +0000 | |||
448 | @@ -97,9 +97,7 @@ | |||
449 | 97 | self.setButtonText(QtGui.QWizard.CancelButton, CANCEL_BUTTON) | 97 | self.setButtonText(QtGui.QWizard.CancelButton, CANCEL_BUTTON) |
450 | 98 | # Layout without custom button 1, | 98 | # Layout without custom button 1, |
451 | 99 | # without finish button | 99 | # without finish button |
455 | 100 | self.wizard().setButtonLayout([ | 100 | self.wizard().setButtonLayout([]) |
453 | 101 | QtGui.QWizard.BackButton, | ||
454 | 102 | QtGui.QWizard.Stretch]) | ||
456 | 103 | 101 | ||
457 | 104 | # Set sign_in_button as default when the page is shown. | 102 | # Set sign_in_button as default when the page is shown. |
458 | 105 | self.ui.sign_in_button.setDefault(True) | 103 | self.ui.sign_in_button.setDefault(True) |
459 | 106 | 104 | ||
460 | === modified file 'ubuntu_sso/qt/main/__init__.py' | |||
461 | --- ubuntu_sso/qt/main/__init__.py 2012-05-09 18:00:22 +0000 | |||
462 | +++ ubuntu_sso/qt/main/__init__.py 2012-06-27 15:30:29 +0000 | |||
463 | @@ -80,5 +80,7 @@ | |||
464 | 80 | ui.size(), app.desktop().availableGeometry()) | 80 | ui.size(), app.desktop().availableGeometry()) |
465 | 81 | ui.setGeometry(style) | 81 | ui.setGeometry(style) |
466 | 82 | ui.show() | 82 | ui.show() |
467 | 83 | if sys.platform == 'darwin': | ||
468 | 84 | ui.raise_() | ||
469 | 83 | 85 | ||
470 | 84 | source.main_start(app) | 86 | source.main_start(app) |
471 | 85 | 87 | ||
472 | === modified file 'ubuntu_sso/qt/main/tests/test_main.py' | |||
473 | --- ubuntu_sso/qt/main/tests/test_main.py 2012-05-09 17:48:32 +0000 | |||
474 | +++ ubuntu_sso/qt/main/tests/test_main.py 2012-06-27 15:30:29 +0000 | |||
475 | @@ -53,6 +53,7 @@ | |||
476 | 53 | """Fake setGeometry.""" | 53 | """Fake setGeometry.""" |
477 | 54 | 54 | ||
478 | 55 | show = setGeometry | 55 | show = setGeometry |
479 | 56 | raise_ = lambda self: None | ||
480 | 56 | 57 | ||
481 | 57 | 58 | ||
482 | 58 | class FakeDesktop(object): | 59 | class FakeDesktop(object): |
483 | 59 | 60 | ||
484 | === modified file 'ubuntu_sso/qt/proxy_dialog.py' | |||
485 | --- ubuntu_sso/qt/proxy_dialog.py 2012-04-09 17:38:24 +0000 | |||
486 | +++ ubuntu_sso/qt/proxy_dialog.py 2012-06-27 15:30:29 +0000 | |||
487 | @@ -116,7 +116,7 @@ | |||
488 | 116 | try: | 116 | try: |
489 | 117 | logger.debug('Save credentials as for domain %s.', self.domain) | 117 | logger.debug('Save credentials as for domain %s.', self.domain) |
490 | 118 | yield self.keyring.set_credentials(self.domain, creds) | 118 | yield self.keyring.set_credentials(self.domain, creds) |
492 | 119 | except Exception, e: | 119 | except Exception as e: |
493 | 120 | logger.exception('Could not set credentials:') | 120 | logger.exception('Could not set credentials:') |
494 | 121 | self.done(EXCEPTION_RAISED) | 121 | self.done(EXCEPTION_RAISED) |
495 | 122 | logger.debug('Stored creds') | 122 | logger.debug('Stored creds') |
496 | 123 | 123 | ||
497 | === modified file 'ubuntu_sso/qt/setup_account_page.py' | |||
498 | --- ubuntu_sso/qt/setup_account_page.py 2012-05-01 12:48:42 +0000 | |||
499 | +++ ubuntu_sso/qt/setup_account_page.py 2012-06-27 15:30:29 +0000 | |||
500 | @@ -154,7 +154,6 @@ | |||
501 | 154 | 154 | ||
502 | 155 | # Button setup | 155 | # Button setup |
503 | 156 | self.wizard().setButtonLayout([ | 156 | self.wizard().setButtonLayout([ |
504 | 157 | QtGui.QWizard.BackButton, | ||
505 | 158 | QtGui.QWizard.Stretch, | 157 | QtGui.QWizard.Stretch, |
506 | 159 | QtGui.QWizard.CustomButton3]) | 158 | QtGui.QWizard.CustomButton3]) |
507 | 160 | 159 | ||
508 | @@ -246,8 +245,8 @@ | |||
509 | 246 | common.NORMAL)) | 245 | common.NORMAL)) |
510 | 247 | 246 | ||
511 | 248 | self.ui.refresh_label.linkActivated.connect(self.hide_error) | 247 | self.ui.refresh_label.linkActivated.connect(self.hide_error) |
514 | 249 | self.ui.refresh_label.linkActivated.connect(lambda url: \ | 248 | self.ui.refresh_label.linkActivated.connect( |
515 | 250 | self._refresh_captcha()) | 249 | lambda url: self._refresh_captcha()) |
516 | 251 | # We need to check if we enable the button on many signals | 250 | # We need to check if we enable the button on many signals |
517 | 252 | self.ui.name_edit.textEdited.connect(self._enable_setup_button) | 251 | self.ui.name_edit.textEdited.connect(self._enable_setup_button) |
518 | 253 | self.ui.email_edit.textEdited.connect(self._enable_setup_button) | 252 | self.ui.email_edit.textEdited.connect(self._enable_setup_button) |
519 | 254 | 253 | ||
520 | === modified file 'ubuntu_sso/qt/sso_wizard_page.py' | |||
521 | --- ubuntu_sso/qt/sso_wizard_page.py 2012-04-09 17:38:24 +0000 | |||
522 | +++ ubuntu_sso/qt/sso_wizard_page.py 2012-06-27 15:30:29 +0000 | |||
523 | @@ -253,7 +253,7 @@ | |||
524 | 253 | if app_name == self.app_name: | 253 | if app_name == self.app_name: |
525 | 254 | result = f(app_name, *args, **kwargs) | 254 | result = f(app_name, *args, **kwargs) |
526 | 255 | else: | 255 | else: |
528 | 256 | logger.info('%s: ignoring call since received app_name '\ | 256 | logger.info('%s: ignoring call since received app_name ' |
529 | 257 | '"%s" (expected "%s")', | 257 | '"%s" (expected "%s")', |
530 | 258 | f.__name__, app_name, self.app_name) | 258 | f.__name__, app_name, self.app_name) |
531 | 259 | return result | 259 | return result |
532 | @@ -262,7 +262,7 @@ | |||
533 | 262 | 262 | ||
534 | 263 | def _setup_signals(self): | 263 | def _setup_signals(self): |
535 | 264 | """Bind signals to callbacks to be able to test the pages.""" | 264 | """Bind signals to callbacks to be able to test the pages.""" |
537 | 265 | for signal, method in self._signals.iteritems(): | 265 | for signal, method in self._signals.items(): |
538 | 266 | actual = self._signals_receivers.get(signal) | 266 | actual = self._signals_receivers.get(signal) |
539 | 267 | if actual is not None: | 267 | if actual is not None: |
540 | 268 | msg = 'Signal %r is already connected with %r.' | 268 | msg = 'Signal %r is already connected with %r.' |
541 | 269 | 269 | ||
542 | === modified file 'ubuntu_sso/qt/tests/test_arrow.py' | |||
543 | --- ubuntu_sso/qt/tests/test_arrow.py 2012-04-09 17:38:24 +0000 | |||
544 | +++ ubuntu_sso/qt/tests/test_arrow.py 2012-06-27 15:30:29 +0000 | |||
545 | @@ -96,7 +96,7 @@ | |||
546 | 96 | arrow = QArrow(QArrow.RIGHT) | 96 | arrow = QArrow(QArrow.RIGHT) |
547 | 97 | self.patch(arrow, 'style', self.style) | 97 | self.patch(arrow, 'style', self.style) |
548 | 98 | 98 | ||
550 | 99 | for key, value in directions_map.iteritems(): | 99 | for key, value in directions_map.items(): |
551 | 100 | self.style.called = [] | 100 | self.style.called = [] |
552 | 101 | arrow.direction = key | 101 | arrow.direction = key |
553 | 102 | arrow.paintEvent(None) | 102 | arrow.paintEvent(None) |
554 | 103 | 103 | ||
555 | === modified file 'ubuntu_sso/qt/tests/test_common.py' | |||
556 | --- ubuntu_sso/qt/tests/test_common.py 2012-04-09 17:38:24 +0000 | |||
557 | +++ ubuntu_sso/qt/tests/test_common.py 2012-06-27 15:30:29 +0000 | |||
558 | @@ -350,7 +350,7 @@ | |||
559 | 350 | result = build_general_error_message(err_dict) | 350 | result = build_general_error_message(err_dict) |
560 | 351 | 351 | ||
561 | 352 | expected = '\n'.join( | 352 | expected = '\n'.join( |
563 | 353 | [('%s: %s' % (k, v)) for k, v in err_dict.iteritems()]) | 353 | [('%s: %s' % (k, v)) for k, v in err_dict.items()]) |
564 | 354 | self.assertEqual(result, expected) | 354 | self.assertEqual(result, expected) |
565 | 355 | 355 | ||
566 | 356 | def test_with_random_keys_with_errtype(self): | 356 | def test_with_random_keys_with_errtype(self): |
567 | @@ -362,8 +362,8 @@ | |||
568 | 362 | result = build_general_error_message(err_dict) | 362 | result = build_general_error_message(err_dict) |
569 | 363 | 363 | ||
570 | 364 | expected = '\n'.join( | 364 | expected = '\n'.join( |
573 | 365 | [('%s: %s' % (k, v)) \ | 365 | [('%s: %s' % (k, v)) |
574 | 366 | for k, v in {'my_bad': error, 'odd_error': error2}.iteritems()]) | 366 | for k, v in {'my_bad': error, 'odd_error': error2}.items()]) |
575 | 367 | self.assertEqual(result, expected) | 367 | self.assertEqual(result, expected) |
576 | 368 | 368 | ||
577 | 369 | def test_with_not_dict(self): | 369 | def test_with_not_dict(self): |
578 | 370 | 370 | ||
579 | === modified file 'ubuntu_sso/qt/tests/test_current_user_sign_in_page.py' | |||
580 | --- ubuntu_sso/qt/tests/test_current_user_sign_in_page.py 2012-04-09 17:38:24 +0000 | |||
581 | +++ ubuntu_sso/qt/tests/test_current_user_sign_in_page.py 2012-06-27 15:30:29 +0000 | |||
582 | @@ -59,7 +59,7 @@ | |||
583 | 59 | self.assertEqual(wizard.buttons_text[QtGui.QWizard.CancelButton], | 59 | self.assertEqual(wizard.buttons_text[QtGui.QWizard.CancelButton], |
584 | 60 | "Cancel") | 60 | "Cancel") |
585 | 61 | self.assertIn(('setButtonLayout', | 61 | self.assertIn(('setButtonLayout', |
587 | 62 | (([QtGui.QWizard.BackButton, QtGui.QWizard.Stretch],), {})), | 62 | (([],), {})), |
588 | 63 | wizard.called) | 63 | wizard.called) |
589 | 64 | self.assertTrue(button.properties['default']) | 64 | self.assertTrue(button.properties['default']) |
590 | 65 | self.assertFalse(button.isEnabled()) | 65 | self.assertFalse(button.isEnabled()) |
591 | 66 | 66 | ||
592 | === modified file 'ubuntu_sso/qt/tests/test_setup_account.py' | |||
593 | --- ubuntu_sso/qt/tests/test_setup_account.py 2012-04-09 17:38:24 +0000 | |||
594 | +++ ubuntu_sso/qt/tests/test_setup_account.py 2012-06-27 15:30:29 +0000 | |||
595 | @@ -207,8 +207,7 @@ | |||
596 | 207 | self.ui.initializePage() | 207 | self.ui.initializePage() |
597 | 208 | 208 | ||
598 | 209 | # set up account button | 209 | # set up account button |
601 | 210 | expected = [QtGui.QWizard.BackButton, QtGui.QWizard.Stretch, | 210 | expected = [QtGui.QWizard.Stretch, QtGui.QWizard.CustomButton3] |
600 | 211 | QtGui.QWizard.CustomButton3] | ||
602 | 212 | self.assertIn(('setButtonLayout', ((expected,), {})), | 211 | self.assertIn(('setButtonLayout', ((expected,), {})), |
603 | 213 | self.ui.wizard().called) | 212 | self.ui.wizard().called) |
604 | 214 | self.assertEqual(gui.SET_UP_ACCOUNT_BUTTON, | 213 | self.assertEqual(gui.SET_UP_ACCOUNT_BUTTON, |
605 | 215 | 214 | ||
606 | === modified file 'ubuntu_sso/tests/test_account.py' | |||
607 | --- ubuntu_sso/tests/test_account.py 2012-05-29 16:58:30 +0000 | |||
608 | +++ ubuntu_sso/tests/test_account.py 2012-06-27 15:30:29 +0000 | |||
609 | @@ -230,7 +230,7 @@ | |||
610 | 230 | 230 | ||
611 | 231 | def verify_frc_shutdown(self): | 231 | def verify_frc_shutdown(self): |
612 | 232 | """Verify that the FakeRestfulClient was stopped.""" | 232 | """Verify that the FakeRestfulClient was stopped.""" |
614 | 233 | assert self.frc.started == False, "Restfulclient must be shut down." | 233 | assert self.frc.started is False, "Restfulclient must be shut down." |
615 | 234 | 234 | ||
616 | 235 | @defer.inlineCallbacks | 235 | @defer.inlineCallbacks |
617 | 236 | def test_generate_captcha(self): | 236 | def test_generate_captcha(self): |
618 | 237 | 237 | ||
619 | === modified file 'ubuntu_sso/tests/test_credentials.py' | |||
620 | --- ubuntu_sso/tests/test_credentials.py 2012-05-04 18:48:54 +0000 | |||
621 | +++ ubuntu_sso/tests/test_credentials.py 2012-06-27 15:30:29 +0000 | |||
622 | @@ -122,6 +122,7 @@ | |||
623 | 122 | self.memento = MementoHandler() | 122 | self.memento = MementoHandler() |
624 | 123 | self.memento.setLevel(logging.DEBUG) | 123 | self.memento.setLevel(logging.DEBUG) |
625 | 124 | credentials.logger.addHandler(self.memento) | 124 | credentials.logger.addHandler(self.memento) |
626 | 125 | self.addCleanup(credentials.logger.removeHandler, self.memento) | ||
627 | 125 | 126 | ||
628 | 126 | self.patch(credentials, 'get_bin_dir', lambda: self.bin_dir) | 127 | self.patch(credentials, 'get_bin_dir', lambda: self.bin_dir) |
629 | 127 | 128 | ||
630 | @@ -147,7 +148,7 @@ | |||
631 | 147 | 148 | ||
632 | 148 | def test_creation_parameters_are_stored(self): | 149 | def test_creation_parameters_are_stored(self): |
633 | 149 | """Creation parameters are stored.""" | 150 | """Creation parameters are stored.""" |
635 | 150 | for key, value in KWARGS.iteritems(): | 151 | for key, value in KWARGS.items(): |
636 | 151 | self.assertEqual(getattr(self.obj, key), value) | 152 | self.assertEqual(getattr(self.obj, key), value) |
637 | 152 | 153 | ||
638 | 153 | def test_tc_url_defaults_to_none(self): | 154 | def test_tc_url_defaults_to_none(self): |
639 | 154 | 155 | ||
640 | === modified file 'ubuntu_sso/utils/__init__.py' | |||
641 | --- ubuntu_sso/utils/__init__.py 2012-04-25 14:17:16 +0000 | |||
642 | +++ ubuntu_sso/utils/__init__.py 2012-06-27 15:30:29 +0000 | |||
643 | @@ -165,7 +165,7 @@ | |||
644 | 165 | logger.debug("Calculated server-local time skew: %r", | 165 | logger.debug("Calculated server-local time skew: %r", |
645 | 166 | self.skew) | 166 | self.skew) |
646 | 167 | #pylint: disable=W0703 | 167 | #pylint: disable=W0703 |
648 | 168 | except Exception, server_error: | 168 | except Exception as server_error: |
649 | 169 | logger.debug("Error while verifying the server time skew: %r", | 169 | logger.debug("Error while verifying the server time skew: %r", |
650 | 170 | server_error) | 170 | server_error) |
651 | 171 | self.next_check = local_time + self.ERROR_INTERVAL | 171 | self.next_check = local_time + self.ERROR_INTERVAL |
652 | 172 | 172 | ||
653 | === modified file 'ubuntu_sso/utils/ipc.py' | |||
654 | --- ubuntu_sso/utils/ipc.py 2012-05-16 09:48:55 +0000 | |||
655 | +++ ubuntu_sso/utils/ipc.py 2012-06-27 15:30:29 +0000 | |||
656 | @@ -132,7 +132,7 @@ | |||
657 | 132 | 132 | ||
658 | 133 | def remote_unregister_to_signals(self, client): | 133 | def remote_unregister_to_signals(self, client): |
659 | 134 | """Allow a client to unregister from the signal.""" | 134 | """Allow a client to unregister from the signal.""" |
661 | 135 | for connected_clients in self.clients_per_signal.itervalues(): | 135 | for connected_clients in self.clients_per_signal.values(): |
662 | 136 | if client in connected_clients: | 136 | if client in connected_clients: |
663 | 137 | connected_clients.remove(client) | 137 | connected_clients.remove(client) |
664 | 138 | 138 | ||
665 | @@ -198,7 +198,7 @@ | |||
666 | 198 | super(BaseService, self).__init__() | 198 | super(BaseService, self).__init__() |
667 | 199 | self.factory = None | 199 | self.factory = None |
668 | 200 | self.listener = None | 200 | self.listener = None |
670 | 201 | for name, service_class in self.services.iteritems(): | 201 | for name, service_class in self.services.items(): |
671 | 202 | service = service_class(*a, **kw) | 202 | service = service_class(*a, **kw) |
672 | 203 | setattr(self, name, service) | 203 | setattr(self, name, service) |
673 | 204 | setattr(self, 'remote_get_%s' % name, | 204 | setattr(self, 'remote_get_%s' % name, |
674 | @@ -344,7 +344,7 @@ | |||
675 | 344 | """Request all the diff remote objects used for the communication.""" | 344 | """Request all the diff remote objects used for the communication.""" |
676 | 345 | logger.debug('Requesting remote objects (%r) for %s', | 345 | logger.debug('Requesting remote objects (%r) for %s', |
677 | 346 | self.clients.keys(), self.__class__.__name__) | 346 | self.clients.keys(), self.__class__.__name__) |
679 | 347 | for name, client_class in self.clients.iteritems(): | 347 | for name, client_class in self.clients.items(): |
680 | 348 | remote = yield root.callRemote('get_%s' % name) | 348 | remote = yield root.callRemote('get_%s' % name) |
681 | 349 | setattr(self, name, client_class(remote)) | 349 | setattr(self, name, client_class(remote)) |
682 | 350 | 350 | ||
683 | 351 | 351 | ||
684 | === modified file 'ubuntu_sso/utils/runner/glib.py' | |||
685 | --- ubuntu_sso/utils/runner/glib.py 2012-04-09 17:38:24 +0000 | |||
686 | +++ ubuntu_sso/utils/runner/glib.py 2012-06-27 15:30:29 +0000 | |||
687 | @@ -89,7 +89,7 @@ | |||
688 | 89 | 89 | ||
689 | 90 | try: | 90 | try: |
690 | 91 | pid, _, _, _ = GLib.spawn_async(argv=bytes_args, flags=flags) | 91 | pid, _, _, _ = GLib.spawn_async(argv=bytes_args, flags=flags) |
692 | 92 | except GLib.GError, e: | 92 | except GLib.GError as e: |
693 | 93 | handle_error(e) | 93 | handle_error(e) |
694 | 94 | else: | 94 | else: |
695 | 95 | logger.debug('Spawning the program %r with the glib mainloop ' | 95 | logger.debug('Spawning the program %r with the glib mainloop ' |
696 | 96 | 96 | ||
697 | === modified file 'ubuntu_sso/utils/runner/tests/test_glib.py' | |||
698 | --- ubuntu_sso/utils/runner/tests/test_glib.py 2012-04-09 17:38:24 +0000 | |||
699 | +++ ubuntu_sso/utils/runner/tests/test_glib.py 2012-06-27 15:30:29 +0000 | |||
700 | @@ -87,7 +87,7 @@ | |||
701 | 87 | 87 | ||
702 | 88 | try: | 88 | try: |
703 | 89 | subprocess.call(argv) | 89 | subprocess.call(argv) |
705 | 90 | except Exception, e: | 90 | except Exception as e: |
706 | 91 | exc = GLib.GError() | 91 | exc = GLib.GError() |
707 | 92 | exc.message = str(e) | 92 | exc.message = str(e) |
708 | 93 | exc.code = 42 | 93 | exc.code = 42 |
709 | 94 | 94 | ||
710 | === modified file 'ubuntu_sso/utils/runner/tests/test_qt.py' | |||
711 | --- ubuntu_sso/utils/runner/tests/test_qt.py 2012-04-09 17:38:24 +0000 | |||
712 | +++ ubuntu_sso/utils/runner/tests/test_qt.py 2012-06-27 15:30:29 +0000 | |||
713 | @@ -86,12 +86,12 @@ | |||
714 | 86 | 86 | ||
715 | 87 | try: | 87 | try: |
716 | 88 | subprocess.call(bytes_args) | 88 | subprocess.call(bytes_args) |
718 | 89 | except OSError, e: | 89 | except OSError as e: |
719 | 90 | if e.errno == 2: | 90 | if e.errno == 2: |
720 | 91 | self.error.emit(self.FailedToStart) | 91 | self.error.emit(self.FailedToStart) |
721 | 92 | else: | 92 | else: |
722 | 93 | self.error.emit(e) | 93 | self.error.emit(e) |
724 | 94 | except Exception, e: | 94 | except Exception as e: |
725 | 95 | self.error.emit(e) | 95 | self.error.emit(e) |
726 | 96 | else: | 96 | else: |
727 | 97 | self.finished.emit(self._status_code) | 97 | self.finished.emit(self._status_code) |
728 | 98 | 98 | ||
729 | === modified file 'ubuntu_sso/utils/runner/tx.py' | |||
730 | --- ubuntu_sso/utils/runner/tx.py 2012-04-09 17:38:24 +0000 | |||
731 | +++ ubuntu_sso/utils/runner/tx.py 2012-06-27 15:30:29 +0000 | |||
732 | @@ -102,9 +102,9 @@ | |||
733 | 102 | 102 | ||
734 | 103 | try: | 103 | try: |
735 | 104 | d = utils.getProcessOutputAndValue(program, bytes_args, env=os.environ) | 104 | d = utils.getProcessOutputAndValue(program, bytes_args, env=os.environ) |
737 | 105 | except OSError, e: | 105 | except OSError as e: |
738 | 106 | error_handler(msg=e, failed_to_start=True) | 106 | error_handler(msg=e, failed_to_start=True) |
740 | 107 | except Exception, e: | 107 | except Exception as e: |
741 | 108 | error_handler(msg=e, failed_to_start=False) | 108 | error_handler(msg=e, failed_to_start=False) |
742 | 109 | else: | 109 | else: |
743 | 110 | logger.debug('Spawning the program %r with the twisted reactor ' | 110 | logger.debug('Spawning the program %r with the twisted reactor ' |
744 | 111 | 111 | ||
745 | === modified file 'ubuntu_sso/utils/tcpactivation.py' | |||
746 | --- ubuntu_sso/utils/tcpactivation.py 2012-05-03 11:42:55 +0000 | |||
747 | +++ ubuntu_sso/utils/tcpactivation.py 2012-06-27 15:30:29 +0000 | |||
748 | @@ -30,7 +30,7 @@ | |||
749 | 30 | 30 | ||
750 | 31 | import subprocess | 31 | import subprocess |
751 | 32 | 32 | ||
753 | 33 | from twisted.internet import defer, error, protocol, reactor | 33 | from twisted.internet import defer, error, protocol |
754 | 34 | from twisted.internet.endpoints import clientFromString | 34 | from twisted.internet.endpoints import clientFromString |
755 | 35 | 35 | ||
756 | 36 | LOCALHOST = "127.0.0.1" | 36 | LOCALHOST = "127.0.0.1" |
757 | @@ -43,6 +43,7 @@ | |||
758 | 43 | 43 | ||
759 | 44 | def async_sleep(delay): | 44 | def async_sleep(delay): |
760 | 45 | """Fire the returned deferred after some specified delay.""" | 45 | """Fire the returned deferred after some specified delay.""" |
761 | 46 | from twisted.internet import reactor | ||
762 | 46 | d = defer.Deferred() | 47 | d = defer.Deferred() |
763 | 47 | # pylint: disable=E1101 | 48 | # pylint: disable=E1101 |
764 | 48 | reactor.callLater(delay, d.callback, None) | 49 | reactor.callLater(delay, d.callback, None) |
765 | @@ -87,11 +88,13 @@ | |||
766 | 87 | 88 | ||
767 | 88 | def clientConnectionLost(self, connector, reason): | 89 | def clientConnectionLost(self, connector, reason): |
768 | 89 | """The connection was lost.""" | 90 | """The connection was lost.""" |
769 | 91 | protocol.ClientFactory.clientConnectionLost(self, connector, reason) | ||
770 | 90 | if not self.d.called: | 92 | if not self.d.called: |
771 | 91 | self.d.callback(False) | 93 | self.d.callback(False) |
772 | 92 | 94 | ||
773 | 93 | def clientConnectionFailed(self, connector, reason): | 95 | def clientConnectionFailed(self, connector, reason): |
774 | 94 | """The connection failed.""" | 96 | """The connection failed.""" |
775 | 97 | protocol.ClientFactory.clientConnectionFailed(self, connector, reason) | ||
776 | 95 | if not self.d.called: | 98 | if not self.d.called: |
777 | 96 | self.d.callback(False) | 99 | self.d.callback(False) |
778 | 97 | 100 | ||
779 | @@ -116,6 +119,7 @@ | |||
780 | 116 | @defer.inlineCallbacks | 119 | @defer.inlineCallbacks |
781 | 117 | def is_already_running(self): | 120 | def is_already_running(self): |
782 | 118 | """Check if the instance is already running.""" | 121 | """Check if the instance is already running.""" |
783 | 122 | from twisted.internet import reactor | ||
784 | 119 | factory = PortDetectFactory() | 123 | factory = PortDetectFactory() |
785 | 120 | client = clientFromString(reactor, self.config.description.client) | 124 | client = clientFromString(reactor, self.config.description.client) |
786 | 121 | try: | 125 | try: |
787 | 122 | 126 | ||
788 | === modified file 'ubuntu_sso/utils/tests/test_common.py' | |||
789 | --- ubuntu_sso/utils/tests/test_common.py 2012-04-17 20:27:21 +0000 | |||
790 | +++ ubuntu_sso/utils/tests/test_common.py 2012-06-27 15:30:29 +0000 | |||
791 | @@ -106,6 +106,7 @@ | |||
792 | 106 | self.memento = MementoHandler() | 106 | self.memento = MementoHandler() |
793 | 107 | self.memento.setLevel(logging.DEBUG) | 107 | self.memento.setLevel(logging.DEBUG) |
794 | 108 | utils.logger.addHandler(self.memento) | 108 | utils.logger.addHandler(self.memento) |
795 | 109 | self.addCleanup(utils.logger.removeHandler, self.memento) | ||
796 | 109 | 110 | ||
797 | 110 | self.get_dir = getattr(utils, self.DIR_GETTER) | 111 | self.get_dir = getattr(utils, self.DIR_GETTER) |
798 | 111 | 112 | ||
799 | 112 | 113 | ||
800 | === modified file 'ubuntu_sso/utils/tests/test_tcpactivation.py' | |||
801 | --- ubuntu_sso/utils/tests/test_tcpactivation.py 2012-05-03 12:36:08 +0000 | |||
802 | +++ ubuntu_sso/utils/tests/test_tcpactivation.py 2012-06-27 15:30:29 +0000 | |||
803 | @@ -35,7 +35,8 @@ | |||
804 | 35 | # this test module access a few protected members (starting with _) | 35 | # this test module access a few protected members (starting with _) |
805 | 36 | # pylint: disable=W0212 | 36 | # pylint: disable=W0212 |
806 | 37 | 37 | ||
808 | 38 | from twisted.internet import defer, protocol, reactor, task | 38 | import twisted.internet |
809 | 39 | from twisted.internet import defer, protocol, task | ||
810 | 39 | from twisted.trial.unittest import TestCase | 40 | from twisted.trial.unittest import TestCase |
811 | 40 | 41 | ||
812 | 41 | # pylint: disable=W0611 | 42 | # pylint: disable=W0611 |
813 | @@ -72,7 +73,7 @@ | |||
814 | 72 | self.transport.write(data) | 73 | self.transport.write(data) |
815 | 73 | 74 | ||
816 | 74 | 75 | ||
818 | 75 | class FakeServerFactory(protocol.Factory): | 76 | class FakeServerFactory(protocol.ServerFactory): |
819 | 76 | """A factory for the test server.""" | 77 | """A factory for the test server.""" |
820 | 77 | 78 | ||
821 | 78 | protocol = FakeServerProtocol | 79 | protocol = FakeServerProtocol |
822 | @@ -97,37 +98,6 @@ | |||
823 | 97 | self.client = client_description | 98 | self.client = client_description |
824 | 98 | 99 | ||
825 | 99 | 100 | ||
826 | 100 | class FakeConnectedClient(object): | ||
827 | 101 | """Fake class use to patch connections.""" | ||
828 | 102 | |||
829 | 103 | def __init__(self, testcase, inner): | ||
830 | 104 | """Create a new instance.""" | ||
831 | 105 | self.testcase = testcase | ||
832 | 106 | self.inner = inner | ||
833 | 107 | |||
834 | 108 | @defer.inlineCallbacks | ||
835 | 109 | def connect(self, factory): | ||
836 | 110 | """Connect using the given factory.""" | ||
837 | 111 | # we need to get the class of the factory and patch it | ||
838 | 112 | yield self.testcase.connect_client(PortDetectFactory) | ||
839 | 113 | self.inner.factory = self.testcase.client_factory | ||
840 | 114 | defer.returnValue(self.testcase.connector) | ||
841 | 115 | |||
842 | 116 | |||
843 | 117 | class WrapperFactory(object): | ||
844 | 118 | """Wrapps a factory so that it can be replaced in a test.""" | ||
845 | 119 | |||
846 | 120 | def __init__(self, factory): | ||
847 | 121 | self.factory = None | ||
848 | 122 | |||
849 | 123 | def __call__(self, *args, **kwargs): | ||
850 | 124 | return self | ||
851 | 125 | |||
852 | 126 | def is_listening(self): | ||
853 | 127 | """Return if the service is listening.""" | ||
854 | 128 | return self.factory.is_listening() | ||
855 | 129 | |||
856 | 130 | |||
857 | 131 | class AsyncSleepTestCase(TestCase): | 101 | class AsyncSleepTestCase(TestCase): |
858 | 132 | """Tests for the async_sleep function.""" | 102 | """Tests for the async_sleep function.""" |
859 | 133 | 103 | ||
860 | @@ -137,7 +107,7 @@ | |||
861 | 137 | yield super(AsyncSleepTestCase, self).setUp() | 107 | yield super(AsyncSleepTestCase, self).setUp() |
862 | 138 | self.test_timeout = 5.0 | 108 | self.test_timeout = 5.0 |
863 | 139 | self.clock = task.Clock() | 109 | self.clock = task.Clock() |
865 | 140 | self.patch(tcpactivation, "reactor", self.clock) | 110 | self.patch(twisted.internet, "reactor", self.clock) |
866 | 141 | self.d = tcpactivation.async_sleep(self.test_timeout) | 111 | self.d = tcpactivation.async_sleep(self.test_timeout) |
867 | 142 | 112 | ||
868 | 143 | def test_async_sleep_not_fired_immediately(self): | 113 | def test_async_sleep_not_fired_immediately(self): |
869 | @@ -231,7 +201,7 @@ | |||
870 | 231 | self.assertEqual(config.description, SAMPLE_CLIENT_DESCRIPTION) | 201 | self.assertEqual(config.description, SAMPLE_CLIENT_DESCRIPTION) |
871 | 232 | 202 | ||
872 | 233 | 203 | ||
874 | 234 | class ActivationDetectorTestCase(ServerTestCase): | 204 | class ActivationDetectorTestCase(TestCase): |
875 | 235 | """Tests for the ActivationDetector class.""" | 205 | """Tests for the ActivationDetector class.""" |
876 | 236 | 206 | ||
877 | 237 | timeoue = 3 | 207 | timeoue = 3 |
878 | @@ -270,15 +240,29 @@ | |||
879 | 270 | @defer.inlineCallbacks | 240 | @defer.inlineCallbacks |
880 | 271 | def test_is_already_running(self): | 241 | def test_is_already_running(self): |
881 | 272 | """The is_already_running method returns True if already started.""" | 242 | """The is_already_running method returns True if already started.""" |
886 | 273 | inner = WrapperFactory(None) | 243 | server = self.get_server() |
887 | 274 | 244 | self.addCleanup(server.clean_up) | |
888 | 275 | self.patch(tcpactivation, 'PortDetectFactory', inner) | 245 | |
889 | 276 | client = FakeConnectedClient(self, inner) | 246 | class TestConnect(object): |
890 | 247 | """A fake connection object.""" | ||
891 | 248 | |||
892 | 249 | # pylint: disable=E0213 | ||
893 | 250 | @defer.inlineCallbacks | ||
894 | 251 | def connect(my_self, factory): | ||
895 | 252 | """A fake connection.""" | ||
896 | 253 | |||
897 | 254 | connected_factory = yield server.connect_client( | ||
898 | 255 | PortDetectFactory) | ||
899 | 256 | self.patch(factory, 'is_listening', | ||
900 | 257 | connected_factory.is_listening) | ||
901 | 258 | defer.returnValue(connected_factory) | ||
902 | 259 | # pylint: enable=E0213 | ||
903 | 277 | 260 | ||
904 | 278 | self.patch(tcpactivation, 'clientFromString', | 261 | self.patch(tcpactivation, 'clientFromString', |
908 | 279 | lambda *args: client) | 262 | lambda *args: TestConnect()) |
909 | 280 | 263 | ||
910 | 281 | yield self.listen_server(FakeServerFactory) | 264 | yield server.listen_server(protocol.ServerFactory) |
911 | 265 | |||
912 | 282 | # pylint: disable=E1101 | 266 | # pylint: disable=E1101 |
913 | 283 | ad = ActivationDetector(self.config) | 267 | ad = ActivationDetector(self.config) |
914 | 284 | result = yield ad.is_already_running() | 268 | result = yield ad.is_already_running() |
915 | @@ -347,7 +331,7 @@ | |||
916 | 347 | """Test the _wait_server_active method.""" | 331 | """Test the _wait_server_active method.""" |
917 | 348 | ac = ActivationClient(self.config) | 332 | ac = ActivationClient(self.config) |
918 | 349 | clock = task.Clock() | 333 | clock = task.Clock() |
920 | 350 | self.patch(tcpactivation, "reactor", clock) | 334 | self.patch(twisted.internet, "reactor", clock) |
921 | 351 | self.patch(ac, "is_already_running", lambda: defer.succeed(False)) | 335 | self.patch(ac, "is_already_running", lambda: defer.succeed(False)) |
922 | 352 | 336 | ||
923 | 353 | d = ac._wait_server_active() | 337 | d = ac._wait_server_active() |
924 | @@ -363,7 +347,7 @@ | |||
925 | 363 | """If the server takes too long to start then timeout.""" | 347 | """If the server takes too long to start then timeout.""" |
926 | 364 | ac = ActivationClient(self.config) | 348 | ac = ActivationClient(self.config) |
927 | 365 | clock = task.Clock() | 349 | clock = task.Clock() |
929 | 366 | self.patch(tcpactivation, "reactor", clock) | 350 | self.patch(twisted.internet, "reactor", clock) |
930 | 367 | self.patch(ac, "is_already_running", lambda: defer.succeed(False)) | 351 | self.patch(ac, "is_already_running", lambda: defer.succeed(False)) |
931 | 368 | d = ac._wait_server_active() | 352 | d = ac._wait_server_active() |
932 | 369 | clock.pump([tcpactivation.DELAY_BETWEEN_CHECKS] * | 353 | clock.pump([tcpactivation.DELAY_BETWEEN_CHECKS] * |
933 | @@ -420,15 +404,28 @@ | |||
934 | 420 | @defer.inlineCallbacks | 404 | @defer.inlineCallbacks |
935 | 421 | def test_get_description_fails_if_service_already_started(self): | 405 | def test_get_description_fails_if_service_already_started(self): |
936 | 422 | """The get_description method fails if service already started.""" | 406 | """The get_description method fails if service already started.""" |
941 | 423 | inner = WrapperFactory(None) | 407 | server = self.get_server() |
942 | 424 | 408 | self.addCleanup(server.clean_up) | |
943 | 425 | self.patch(tcpactivation, 'PortDetectFactory', inner) | 409 | |
944 | 426 | client = FakeConnectedClient(self, inner) | 410 | class TestConnect(object): |
945 | 411 | """A fake connection object.""" | ||
946 | 412 | |||
947 | 413 | # pylint: disable=E0213 | ||
948 | 414 | @defer.inlineCallbacks | ||
949 | 415 | def connect(my_self, factory): | ||
950 | 416 | """A fake connection.""" | ||
951 | 417 | |||
952 | 418 | connected_factory = yield server.connect_client( | ||
953 | 419 | PortDetectFactory) | ||
954 | 420 | self.patch(factory, 'is_listening', | ||
955 | 421 | connected_factory.is_listening) | ||
956 | 422 | defer.returnValue(connected_factory) | ||
957 | 423 | # pylint: enable=E0213 | ||
958 | 427 | 424 | ||
959 | 428 | self.patch(tcpactivation, 'clientFromString', | 425 | self.patch(tcpactivation, 'clientFromString', |
961 | 429 | lambda *args: client) | 426 | lambda *args: TestConnect()) |
962 | 430 | 427 | ||
964 | 431 | yield self.listen_server(FakeServerFactory) | 428 | yield server.listen_server(protocol.ServerFactory) |
965 | 432 | 429 | ||
966 | 433 | ai = ActivationInstance(self.config) | 430 | ai = ActivationInstance(self.config) |
967 | 434 | yield self.assertFailure(ai.get_server_description(), | 431 | yield self.assertFailure(ai.get_server_description(), |
968 | @@ -438,6 +435,7 @@ | |||
969 | 438 | 435 | ||
970 | 439 | def server_test(config): | 436 | def server_test(config): |
971 | 440 | """An IRL test of the server.""" | 437 | """An IRL test of the server.""" |
972 | 438 | from twisted.internet import reactor | ||
973 | 441 | 439 | ||
974 | 442 | def got_description(description): | 440 | def got_description(description): |
975 | 443 | """The description was found.""" | 441 | """The description was found.""" |
976 | @@ -472,6 +470,7 @@ | |||
977 | 472 | 470 | ||
978 | 473 | def client_test(config): | 471 | def client_test(config): |
979 | 474 | """An IRL test of the client.""" | 472 | """An IRL test of the client.""" |
980 | 473 | from twisted.internet import reactor | ||
981 | 475 | print "starting the client." | 474 | print "starting the client." |
982 | 476 | ac = ActivationClient(config) | 475 | ac = ActivationClient(config) |
983 | 477 | d = ac.get_active_client_description() | 476 | d = ac.get_active_client_description() |
984 | 478 | 477 | ||
985 | === modified file 'ubuntu_sso/utils/txsecrets.py' | |||
986 | --- ubuntu_sso/utils/txsecrets.py 2012-04-09 17:38:24 +0000 | |||
987 | +++ ubuntu_sso/utils/txsecrets.py 2012-06-27 15:30:29 +0000 | |||
988 | @@ -100,7 +100,7 @@ | |||
989 | 100 | self.service.OpenSession(ALGORITHM, parameters, | 100 | self.service.OpenSession(ALGORITHM, parameters, |
990 | 101 | reply_handler=session_opened, | 101 | reply_handler=session_opened, |
991 | 102 | error_handler=d.errback) | 102 | error_handler=d.errback) |
993 | 103 | except dbus.exceptions.DBusException, e: | 103 | except dbus.exceptions.DBusException as e: |
994 | 104 | d.errback(e) | 104 | d.errback(e) |
995 | 105 | return d | 105 | return d |
996 | 106 | 106 | ||
997 | 107 | 107 | ||
998 | === modified file 'ubuntu_sso/utils/webclient/common.py' | |||
999 | --- ubuntu_sso/utils/webclient/common.py 2012-04-12 12:07:46 +0000 | |||
1000 | +++ ubuntu_sso/utils/webclient/common.py 2012-06-27 15:30:29 +0000 | |||
1001 | @@ -206,7 +206,7 @@ | |||
1002 | 206 | try: | 206 | try: |
1003 | 207 | creds = yield keyring.get_credentials(str(domain)) | 207 | creds = yield keyring.get_credentials(str(domain)) |
1004 | 208 | logger.debug('Got credentials from keyring.') | 208 | logger.debug('Got credentials from keyring.') |
1006 | 209 | except Exception, e: | 209 | except Exception as e: |
1007 | 210 | logger.error('Error when retrieving the creds.') | 210 | logger.error('Error when retrieving the creds.') |
1008 | 211 | raise WebClientError('Error when retrieving the creds.', e) | 211 | raise WebClientError('Error when retrieving the creds.', e) |
1009 | 212 | if creds is not None: | 212 | if creds is not None: |
1010 | @@ -249,7 +249,7 @@ | |||
1011 | 249 | 249 | ||
1012 | 250 | try: | 250 | try: |
1013 | 251 | return_code = yield self._launch_proxy_creds_dialog(domain, retry) | 251 | return_code = yield self._launch_proxy_creds_dialog(domain, retry) |
1015 | 252 | except Exception, e: | 252 | except Exception as e: |
1016 | 253 | logger.error('Error when running external ui process.') | 253 | logger.error('Error when running external ui process.') |
1017 | 254 | raise WebClientError('Error when running external ui process.', e) | 254 | raise WebClientError('Error when running external ui process.', e) |
1018 | 255 | 255 | ||
1019 | 256 | 256 | ||
1020 | === modified file 'ubuntu_sso/utils/webclient/gsettings.py' | |||
1021 | --- ubuntu_sso/utils/webclient/gsettings.py 2012-04-09 17:38:24 +0000 | |||
1022 | +++ ubuntu_sso/utils/webclient/gsettings.py 2012-06-27 15:30:29 +0000 | |||
1023 | @@ -30,7 +30,11 @@ | |||
1024 | 30 | 30 | ||
1025 | 31 | import subprocess | 31 | import subprocess |
1026 | 32 | 32 | ||
1027 | 33 | from ubuntu_sso.logger import setup_logging | ||
1028 | 34 | |||
1029 | 35 | logger = setup_logging("ubuntu_sso.utils.webclient.gsettings") | ||
1030 | 33 | GSETTINGS_CMDLINE = "gsettings list-recursively org.gnome.system.proxy" | 36 | GSETTINGS_CMDLINE = "gsettings list-recursively org.gnome.system.proxy" |
1031 | 37 | CANNOT_PARSE_WARNING = "Cannot parse gsettings value: %r" | ||
1032 | 34 | 38 | ||
1033 | 35 | 39 | ||
1034 | 36 | def parse_proxy_host(hostname): | 40 | def parse_proxy_host(hostname): |
1035 | @@ -80,12 +84,15 @@ | |||
1036 | 80 | continue | 84 | continue |
1037 | 81 | if value.startswith("'"): | 85 | if value.startswith("'"): |
1038 | 82 | parsed_value = value[1:-1] | 86 | parsed_value = value[1:-1] |
1040 | 83 | elif value.startswith('['): | 87 | elif value.startswith(('[', '@')): |
1041 | 84 | parsed_value = value | 88 | parsed_value = value |
1042 | 85 | elif value in ('true', 'false'): | 89 | elif value in ('true', 'false'): |
1043 | 86 | parsed_value = (value == 'true') | 90 | parsed_value = (value == 'true') |
1044 | 91 | elif value.isdigit(): | ||
1045 | 92 | parsed_value = int(value) | ||
1046 | 87 | else: | 93 | else: |
1048 | 88 | parsed_value = int(value) | 94 | logger.warning(CANNOT_PARSE_WARNING, value) |
1049 | 95 | parsed_value = value | ||
1050 | 89 | relative_key = (path + "." + key)[base_len:] | 96 | relative_key = (path + "." + key)[base_len:] |
1051 | 90 | gsettings[relative_key] = parsed_value | 97 | gsettings[relative_key] = parsed_value |
1052 | 91 | mode = gsettings["mode"] | 98 | mode = gsettings["mode"] |
1053 | 92 | 99 | ||
1054 | === modified file 'ubuntu_sso/utils/webclient/libsoup.py' | |||
1055 | --- ubuntu_sso/utils/webclient/libsoup.py 2012-04-12 12:07:46 +0000 | |||
1056 | +++ ubuntu_sso/utils/webclient/libsoup.py 2012-06-27 15:30:29 +0000 | |||
1057 | @@ -131,7 +131,7 @@ | |||
1058 | 131 | d = defer.Deferred() | 131 | d = defer.Deferred() |
1059 | 132 | message = self.soup.Message.new(method, uri) | 132 | message = self.soup.Message.new(method, uri) |
1060 | 133 | 133 | ||
1062 | 134 | for key, value in headers.iteritems(): | 134 | for key, value in headers.items(): |
1063 | 135 | message.request_headers.append(key, value) | 135 | message.request_headers.append(key, value) |
1064 | 136 | 136 | ||
1065 | 137 | if post_content: | 137 | if post_content: |
1066 | 138 | 138 | ||
1067 | === modified file 'ubuntu_sso/utils/webclient/qtnetwork.py' | |||
1068 | --- ubuntu_sso/utils/webclient/qtnetwork.py 2012-04-24 14:05:22 +0000 | |||
1069 | +++ ubuntu_sso/utils/webclient/qtnetwork.py 2012-06-27 15:30:29 +0000 | |||
1070 | @@ -158,14 +158,14 @@ | |||
1071 | 158 | headers = yield self.build_request_headers(uri, method, extra_headers, | 158 | headers = yield self.build_request_headers(uri, method, extra_headers, |
1072 | 159 | oauth_credentials) | 159 | oauth_credentials) |
1073 | 160 | 160 | ||
1075 | 161 | for key, value in headers.iteritems(): | 161 | for key, value in headers.items(): |
1076 | 162 | request.setRawHeader(key, value) | 162 | request.setRawHeader(key, value) |
1077 | 163 | 163 | ||
1078 | 164 | post_buffer = QBuffer() | 164 | post_buffer = QBuffer() |
1079 | 165 | post_buffer.setData(post_content) | 165 | post_buffer.setData(post_content) |
1080 | 166 | try: | 166 | try: |
1081 | 167 | result = yield self._perform_request(request, method, post_buffer) | 167 | result = yield self._perform_request(request, method, post_buffer) |
1083 | 168 | except ProxyUnauthorizedError, e: | 168 | except ProxyUnauthorizedError as e: |
1084 | 169 | app_proxy = QNetworkProxy.applicationProxy() | 169 | app_proxy = QNetworkProxy.applicationProxy() |
1085 | 170 | proxy_host = app_proxy.hostName() if app_proxy else "proxy server" | 170 | proxy_host = app_proxy.hostName() if app_proxy else "proxy server" |
1086 | 171 | got_creds = yield self.request_proxy_auth_credentials( | 171 | got_creds = yield self.request_proxy_auth_credentials( |
1087 | @@ -221,7 +221,7 @@ | |||
1088 | 221 | QSslCertificate.CountryName: 'country_name', | 221 | QSslCertificate.CountryName: 'country_name', |
1089 | 222 | QSslCertificate.StateOrProvinceName: 'state_name'} | 222 | QSslCertificate.StateOrProvinceName: 'state_name'} |
1090 | 223 | details = {} | 223 | details = {} |
1092 | 224 | for info, title in detail_titles.iteritems(): | 224 | for info, title in detail_titles.items(): |
1093 | 225 | details[title] = str(cert.issuerInfo(info)) | 225 | details[title] = str(cert.issuerInfo(info)) |
1094 | 226 | return self.format_ssl_details(details) | 226 | return self.format_ssl_details(details) |
1095 | 227 | 227 | ||
1096 | 228 | 228 | ||
1097 | === modified file 'ubuntu_sso/utils/webclient/restful.py' | |||
1098 | --- ubuntu_sso/utils/webclient/restful.py 2012-04-09 17:38:24 +0000 | |||
1099 | +++ ubuntu_sso/utils/webclient/restful.py 2012-06-27 15:30:29 +0000 | |||
1100 | @@ -33,8 +33,11 @@ | |||
1101 | 33 | 33 | ||
1102 | 34 | from twisted.internet import defer | 34 | from twisted.internet import defer |
1103 | 35 | 35 | ||
1104 | 36 | from ubuntu_sso.logger import setup_logging | ||
1105 | 36 | from ubuntu_sso.utils import webclient | 37 | from ubuntu_sso.utils import webclient |
1106 | 37 | 38 | ||
1107 | 39 | logger = setup_logging("ubuntu_sso.utils.webclient.restful") | ||
1108 | 40 | |||
1109 | 38 | POST_HEADERS = { | 41 | POST_HEADERS = { |
1110 | 39 | "content-type": "application/x-www-form-urlencoded", | 42 | "content-type": "application/x-www-form-urlencoded", |
1111 | 40 | } | 43 | } |
1112 | @@ -67,11 +70,19 @@ | |||
1113 | 67 | encoded_args = urllib.urlencode(params) | 70 | encoded_args = urllib.urlencode(params) |
1114 | 68 | iri = self.service_iri + namespace | 71 | iri = self.service_iri + namespace |
1115 | 69 | creds = self.oauth_credentials | 72 | creds = self.oauth_credentials |
1116 | 73 | logger.debug('Performing REST call to %r.', iri) | ||
1117 | 70 | result = yield self.webclient.request(iri, method="POST", | 74 | result = yield self.webclient.request(iri, method="POST", |
1118 | 71 | oauth_credentials=creds, | 75 | oauth_credentials=creds, |
1119 | 72 | post_content=encoded_args, | 76 | post_content=encoded_args, |
1120 | 73 | extra_headers=POST_HEADERS) | 77 | extra_headers=POST_HEADERS) |
1122 | 74 | defer.returnValue(json.loads(result.content)) | 78 | try: |
1123 | 79 | response = json.loads(result.content) | ||
1124 | 80 | except: | ||
1125 | 81 | logger.exception('Can not load json from REST request response ' | ||
1126 | 82 | '(content is %r).', result.content) | ||
1127 | 83 | raise | ||
1128 | 84 | else: | ||
1129 | 85 | defer.returnValue(response) | ||
1130 | 75 | 86 | ||
1131 | 76 | def shutdown(self): | 87 | def shutdown(self): |
1132 | 77 | """Stop the webclient used by this class.""" | 88 | """Stop the webclient used by this class.""" |
1133 | 78 | 89 | ||
1134 | === modified file 'ubuntu_sso/utils/webclient/tests/test_gsettings.py' | |||
1135 | --- ubuntu_sso/utils/webclient/tests/test_gsettings.py 2012-04-09 17:38:24 +0000 | |||
1136 | +++ ubuntu_sso/utils/webclient/tests/test_gsettings.py 2012-06-27 15:30:29 +0000 | |||
1137 | @@ -28,7 +28,10 @@ | |||
1138 | 28 | # files in the program, then also delete it here. | 28 | # files in the program, then also delete it here. |
1139 | 29 | """Test the gsettings parser.""" | 29 | """Test the gsettings parser.""" |
1140 | 30 | 30 | ||
1141 | 31 | import logging | ||
1142 | 32 | |||
1143 | 31 | from twisted.trial.unittest import TestCase | 33 | from twisted.trial.unittest import TestCase |
1144 | 34 | from ubuntuone.devtools.handlers import MementoHandler | ||
1145 | 32 | 35 | ||
1146 | 33 | from ubuntu_sso.utils.webclient import gsettings | 36 | from ubuntu_sso.utils.webclient import gsettings |
1147 | 34 | from ubuntu_sso.utils.webclient.tests import ( | 37 | from ubuntu_sso.utils.webclient.tests import ( |
1148 | @@ -91,6 +94,35 @@ | |||
1149 | 91 | """Test a parser of gsettings.""" | 94 | """Test a parser of gsettings.""" |
1150 | 92 | self._assert_parser_anonymous('https') | 95 | self._assert_parser_anonymous('https') |
1151 | 93 | 96 | ||
1152 | 97 | def test_gsettings_empty_ignore_hosts(self): | ||
1153 | 98 | """Missing values in the ignore hosts.""" | ||
1154 | 99 | troublesome_value = "@as []" | ||
1155 | 100 | template_values = dict(BASE_GSETTINGS_VALUES) | ||
1156 | 101 | template_values["ignore_hosts"] = troublesome_value | ||
1157 | 102 | fake_output = TEMPLATE_GSETTINGS_OUTPUT.format(**template_values) | ||
1158 | 103 | self.patch(gsettings.subprocess, "check_output", | ||
1159 | 104 | lambda _: fake_output) | ||
1160 | 105 | ps = gsettings.get_proxy_settings() | ||
1161 | 106 | self.assertEqual(ps, {}) | ||
1162 | 107 | |||
1163 | 108 | def test_gsettings_cannot_parse(self): | ||
1164 | 109 | """Some weird setting that cannot be parsed is logged with warning.""" | ||
1165 | 110 | memento = MementoHandler() | ||
1166 | 111 | memento.setLevel(logging.DEBUG) | ||
1167 | 112 | gsettings.logger.addHandler(memento) | ||
1168 | 113 | self.addCleanup(gsettings.logger.removeHandler, memento) | ||
1169 | 114 | |||
1170 | 115 | troublesome_value = "#bang" | ||
1171 | 116 | template_values = dict(BASE_GSETTINGS_VALUES) | ||
1172 | 117 | template_values["ignore_hosts"] = troublesome_value | ||
1173 | 118 | fake_output = TEMPLATE_GSETTINGS_OUTPUT.format(**template_values) | ||
1174 | 119 | self.patch(gsettings.subprocess, "check_output", | ||
1175 | 120 | lambda _: fake_output) | ||
1176 | 121 | ps = gsettings.get_proxy_settings() | ||
1177 | 122 | self.assertTrue(memento.check_warning(gsettings.CANNOT_PARSE_WARNING % | ||
1178 | 123 | troublesome_value)) | ||
1179 | 124 | self.assertEqual(ps, {}) | ||
1180 | 125 | |||
1181 | 94 | def test_gsettings_parser_http_authenticated(self): | 126 | def test_gsettings_parser_http_authenticated(self): |
1182 | 95 | """Test a parser of gsettings.""" | 127 | """Test a parser of gsettings.""" |
1183 | 96 | template_values = dict(BASE_GSETTINGS_VALUES) | 128 | template_values = dict(BASE_GSETTINGS_VALUES) |
1184 | 97 | 129 | ||
1185 | === modified file 'ubuntu_sso/utils/webclient/tests/test_restful.py' | |||
1186 | --- ubuntu_sso/utils/webclient/tests/test_restful.py 2012-04-09 17:38:24 +0000 | |||
1187 | +++ ubuntu_sso/utils/webclient/tests/test_restful.py 2012-06-27 15:30:29 +0000 | |||
1188 | @@ -28,9 +28,11 @@ | |||
1189 | 28 | # files in the program, then also delete it here. | 28 | # files in the program, then also delete it here. |
1190 | 29 | """Tests for the proxy-enabled restful client.""" | 29 | """Tests for the proxy-enabled restful client.""" |
1191 | 30 | 30 | ||
1192 | 31 | import logging | ||
1193 | 31 | import urlparse | 32 | import urlparse |
1194 | 32 | 33 | ||
1195 | 33 | from twisted.internet import defer | 34 | from twisted.internet import defer |
1196 | 35 | from ubuntuone.devtools.handlers import MementoHandler | ||
1197 | 34 | from ubuntuone.devtools.testcases import TestCase | 36 | from ubuntuone.devtools.testcases import TestCase |
1198 | 35 | 37 | ||
1199 | 36 | from ubuntu_sso.utils.webclient import restful | 38 | from ubuntu_sso.utils.webclient import restful |
1200 | @@ -184,3 +186,45 @@ | |||
1201 | 184 | yield rc.restcall(SAMPLE_OPERATION, **SAMPLE_ARGS) | 186 | yield rc.restcall(SAMPLE_OPERATION, **SAMPLE_ARGS) |
1202 | 185 | _, _, kwargs = self.wc.called[0] | 187 | _, _, kwargs = self.wc.called[0] |
1203 | 186 | self.assertEqual(kwargs["oauth_credentials"], SAMPLE_OAUTH_CREDS) | 188 | self.assertEqual(kwargs["oauth_credentials"], SAMPLE_OAUTH_CREDS) |
1204 | 189 | |||
1205 | 190 | |||
1206 | 191 | class LogginTestCase(BaseTestCase): | ||
1207 | 192 | """Ensure that proper debug logging is done.""" | ||
1208 | 193 | |||
1209 | 194 | @defer.inlineCallbacks | ||
1210 | 195 | def setUp(self): | ||
1211 | 196 | """Initialize this testcase.""" | ||
1212 | 197 | yield super(LogginTestCase, self).setUp() | ||
1213 | 198 | self.memento = MementoHandler() | ||
1214 | 199 | restful.logger.addHandler(self.memento) | ||
1215 | 200 | restful.logger.setLevel(logging.DEBUG) | ||
1216 | 201 | self.addCleanup(restful.logger.removeHandler, self.memento) | ||
1217 | 202 | |||
1218 | 203 | self.rc = restful.RestfulClient(SAMPLE_SERVICE_IRI) | ||
1219 | 204 | self.addCleanup(self.rc.shutdown) | ||
1220 | 205 | |||
1221 | 206 | @defer.inlineCallbacks | ||
1222 | 207 | def test_log_rest_call(self): | ||
1223 | 208 | """Check that proper DEBUG is made for every REST call.""" | ||
1224 | 209 | yield self.rc.restcall(SAMPLE_OPERATION, **SAMPLE_ARGS) | ||
1225 | 210 | |||
1226 | 211 | expected_msgs = ( | ||
1227 | 212 | SAMPLE_SERVICE_IRI + SAMPLE_NAMESPACE, | ||
1228 | 213 | ) | ||
1229 | 214 | self.assertTrue(self.memento.check_debug(*expected_msgs)) | ||
1230 | 215 | |||
1231 | 216 | @defer.inlineCallbacks | ||
1232 | 217 | def test_log_json_loads_exception(self): | ||
1233 | 218 | """Check that json load errors are properly logged.""" | ||
1234 | 219 | invalid_json = 'NOTAVALIDJSON' | ||
1235 | 220 | self.patch(self.wc, 'return_value', invalid_json) | ||
1236 | 221 | yield self.assertFailure(self.rc.restcall(SAMPLE_OPERATION), | ||
1237 | 222 | ValueError) | ||
1238 | 223 | |||
1239 | 224 | self.memento.debug = True | ||
1240 | 225 | expected_msgs = ( | ||
1241 | 226 | ValueError, | ||
1242 | 227 | 'Can not load json from REST request response', | ||
1243 | 228 | invalid_json | ||
1244 | 229 | ) | ||
1245 | 230 | self.assertTrue(self.memento.check_exception(*expected_msgs)) | ||
1246 | 187 | 231 | ||
1247 | === modified file 'ubuntu_sso/utils/webclient/tests/test_webclient.py' | |||
1248 | --- ubuntu_sso/utils/webclient/tests/test_webclient.py 2012-04-24 14:05:22 +0000 | |||
1249 | +++ ubuntu_sso/utils/webclient/tests/test_webclient.py 2012-06-27 15:30:29 +0000 | |||
1250 | @@ -753,7 +753,7 @@ | |||
1251 | 753 | 753 | ||
1252 | 754 | self.assertEqual(method, "OAuth") | 754 | self.assertEqual(method, "OAuth") |
1253 | 755 | 755 | ||
1255 | 756 | for k, expected_value in self.expected_params.iteritems(): | 756 | for k, expected_value in self.expected_params.items(): |
1256 | 757 | self.assertIn(k, params) | 757 | self.assertIn(k, params) |
1257 | 758 | if expected_value is not ANY_VALUE: | 758 | if expected_value is not ANY_VALUE: |
1258 | 759 | self.assertEqual(params[k], expected_value) | 759 | self.assertEqual(params[k], expected_value) |
1259 | @@ -782,7 +782,7 @@ | |||
1260 | 782 | self.assert_headers_correct(request.to_header()) | 782 | self.assert_headers_correct(request.to_header()) |
1261 | 783 | self.assertEqual(request.http_url, self.sample_url) | 783 | self.assertEqual(request.http_url, self.sample_url) |
1262 | 784 | if params is not None: | 784 | if params is not None: |
1264 | 785 | for param, value in params.iteritems(): | 785 | for param, value in params.items(): |
1265 | 786 | self.assertIn(param, request.parameters) | 786 | self.assertIn(param, request.parameters) |
1266 | 787 | actual = request.parameters[param] | 787 | actual = request.parameters[param] |
1267 | 788 | self.assertEqual(value, actual) | 788 | self.assertEqual(value, actual) |
1268 | 789 | 789 | ||
1269 | === modified file 'ubuntu_sso/utils/webclient/timestamp.py' | |||
1270 | --- ubuntu_sso/utils/webclient/timestamp.py 2012-04-09 17:38:24 +0000 | |||
1271 | +++ ubuntu_sso/utils/webclient/timestamp.py 2012-06-27 15:30:29 +0000 | |||
1272 | @@ -83,7 +83,7 @@ | |||
1273 | 83 | logger.debug("Calculated server time skew: %r", self.skew) | 83 | logger.debug("Calculated server time skew: %r", self.skew) |
1274 | 84 | # We just log all exceptions while trying to get the server time | 84 | # We just log all exceptions while trying to get the server time |
1275 | 85 | # pylint: disable=W0703 | 85 | # pylint: disable=W0703 |
1277 | 86 | except Exception, e: | 86 | except Exception as e: |
1278 | 87 | logger.debug("Error while verifying server time skew: %r", e) | 87 | logger.debug("Error while verifying server time skew: %r", e) |
1279 | 88 | self.next_check = local_time + self.ERROR_INTERVAL | 88 | self.next_check = local_time + self.ERROR_INTERVAL |
1280 | 89 | # delay import, otherwise a default reactor gets installed | 89 | # delay import, otherwise a default reactor gets installed |
1281 | 90 | 90 | ||
1282 | === removed directory 'ubuntu_sso/xdg_base_directory' | |||
1283 | === removed file 'ubuntu_sso/xdg_base_directory/__init__.py' | |||
1284 | --- ubuntu_sso/xdg_base_directory/__init__.py 2012-04-09 17:38:24 +0000 | |||
1285 | +++ ubuntu_sso/xdg_base_directory/__init__.py 1970-01-01 00:00:00 +0000 | |||
1286 | @@ -1,104 +0,0 @@ | |||
1287 | 1 | # -*- coding: utf-8 -*- | ||
1288 | 2 | # | ||
1289 | 3 | # Copyright 2011-2012 Canonical Ltd. | ||
1290 | 4 | # | ||
1291 | 5 | # This program is free software: you can redistribute it and/or modify it | ||
1292 | 6 | # under the terms of the GNU General Public License version 3, as published | ||
1293 | 7 | # by the Free Software Foundation. | ||
1294 | 8 | # | ||
1295 | 9 | # This program is distributed in the hope that it will be useful, but | ||
1296 | 10 | # WITHOUT ANY WARRANTY; without even the implied warranties of | ||
1297 | 11 | # MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR | ||
1298 | 12 | # PURPOSE. See the GNU General Public License for more details. | ||
1299 | 13 | # | ||
1300 | 14 | # You should have received a copy of the GNU General Public License along | ||
1301 | 15 | # with this program. If not, see <http://www.gnu.org/licenses/>. | ||
1302 | 16 | # | ||
1303 | 17 | # In addition, as a special exception, the copyright holders give | ||
1304 | 18 | # permission to link the code of portions of this program with the | ||
1305 | 19 | # OpenSSL library under certain conditions as described in each | ||
1306 | 20 | # individual source file, and distribute linked combinations | ||
1307 | 21 | # including the two. | ||
1308 | 22 | # You must obey the GNU General Public License in all respects | ||
1309 | 23 | # for all of the code used other than OpenSSL. If you modify | ||
1310 | 24 | # file(s) with this exception, you may extend this exception to your | ||
1311 | 25 | # version of the file(s), but you are not obligated to do so. If you | ||
1312 | 26 | # do not wish to do so, delete this exception statement from your | ||
1313 | 27 | # version. If you delete this exception statement from all source | ||
1314 | 28 | # files in the program, then also delete it here. | ||
1315 | 29 | """XDG multiplatform.""" | ||
1316 | 30 | |||
1317 | 31 | import os | ||
1318 | 32 | import sys | ||
1319 | 33 | import warnings | ||
1320 | 34 | |||
1321 | 35 | |||
1322 | 36 | def unicode_path(utf8path): | ||
1323 | 37 | """Turn an utf8 path into a unicode path.""" | ||
1324 | 38 | return utf8path.decode("utf-8") | ||
1325 | 39 | |||
1326 | 40 | |||
1327 | 41 | def native_path(utf8path): | ||
1328 | 42 | """Turn an utf8 path into a path useable in the current encoding.""" | ||
1329 | 43 | warnings.warn('native_path will be removed soon', DeprecationWarning) | ||
1330 | 44 | return unicode_path(utf8path) | ||
1331 | 45 | |||
1332 | 46 | |||
1333 | 47 | def syncdaemon_path(mbcspath): | ||
1334 | 48 | """Turn a mbcs path in a utf-8 path as CURRENTLY used inside syncdaemon.""" | ||
1335 | 49 | warnings.warn('syncdaemon_path will be removed soon', DeprecationWarning) | ||
1336 | 50 | return mbcspath.decode(sys.getfilesystemencoding()).encode("utf-8") | ||
1337 | 51 | |||
1338 | 52 | |||
1339 | 53 | # pylint: disable=C0103,F0401,E0611,E1101 | ||
1340 | 54 | if sys.platform == "win32": | ||
1341 | 55 | from ubuntu_sso.xdg_base_directory import windows | ||
1342 | 56 | source = windows | ||
1343 | 57 | xdg_home = source.home_path | ||
1344 | 58 | else: | ||
1345 | 59 | import xdg.BaseDirectory | ||
1346 | 60 | source = xdg.BaseDirectory | ||
1347 | 61 | xdg_home = os.path.expanduser('~') | ||
1348 | 62 | |||
1349 | 63 | xdg_cache_home = source.xdg_cache_home | ||
1350 | 64 | |||
1351 | 65 | xdg_config_home = source.xdg_config_home | ||
1352 | 66 | xdg_config_dirs = source.xdg_config_dirs | ||
1353 | 67 | |||
1354 | 68 | xdg_data_home = source.xdg_data_home | ||
1355 | 69 | xdg_data_dirs = source.xdg_data_dirs | ||
1356 | 70 | |||
1357 | 71 | |||
1358 | 72 | def load_config_paths(*resource): | ||
1359 | 73 | """Iterator of configuration paths. | ||
1360 | 74 | |||
1361 | 75 | Return an iterator which gives each directory named 'resource' in | ||
1362 | 76 | the configuration search path. Information provided by earlier | ||
1363 | 77 | directories should take precedence over later ones (ie, the user's | ||
1364 | 78 | config dir comes first). | ||
1365 | 79 | """ | ||
1366 | 80 | resource = os.path.join(*resource) | ||
1367 | 81 | for config_dir in xdg_config_dirs: | ||
1368 | 82 | path = os.path.join(config_dir, resource) | ||
1369 | 83 | # access the file system always with unicode | ||
1370 | 84 | # to properly behave in some operating systems | ||
1371 | 85 | if os.path.exists(unicode_path(path)): | ||
1372 | 86 | yield path | ||
1373 | 87 | |||
1374 | 88 | |||
1375 | 89 | def save_config_path(*resource): | ||
1376 | 90 | """Path to save configuration. | ||
1377 | 91 | |||
1378 | 92 | Ensure $XDG_CONFIG_HOME/<resource>/ exists, and return its path. | ||
1379 | 93 | 'resource' should normally be the name of your application. Use this | ||
1380 | 94 | when SAVING configuration settings. Use the xdg_config_dirs variable | ||
1381 | 95 | for loading. | ||
1382 | 96 | """ | ||
1383 | 97 | resource = os.path.join(*resource) | ||
1384 | 98 | assert not resource.startswith('/') | ||
1385 | 99 | path = os.path.join(xdg_config_home, resource) | ||
1386 | 100 | # access the file system always with unicode | ||
1387 | 101 | # to properly behave in some operating systems | ||
1388 | 102 | if not os.path.isdir(unicode_path(path)): | ||
1389 | 103 | os.makedirs(unicode_path(path), 0700) | ||
1390 | 104 | return path | ||
1391 | 105 | 0 | ||
1392 | === removed directory 'ubuntu_sso/xdg_base_directory/tests' | |||
1393 | === removed file 'ubuntu_sso/xdg_base_directory/tests/__init__.py' | |||
1394 | --- ubuntu_sso/xdg_base_directory/tests/__init__.py 2012-04-09 17:38:24 +0000 | |||
1395 | +++ ubuntu_sso/xdg_base_directory/tests/__init__.py 1970-01-01 00:00:00 +0000 | |||
1396 | @@ -1,29 +0,0 @@ | |||
1397 | 1 | # ubuntu_sso - Ubuntu Single Sign On client support for desktop apps | ||
1398 | 2 | # | ||
1399 | 3 | # Copyright 2009-2012 Canonical Ltd. | ||
1400 | 4 | # | ||
1401 | 5 | # This program is free software: you can redistribute it and/or modify it | ||
1402 | 6 | # under the terms of the GNU General Public License version 3, as published | ||
1403 | 7 | # by the Free Software Foundation. | ||
1404 | 8 | # | ||
1405 | 9 | # This program is distributed in the hope that it will be useful, but | ||
1406 | 10 | # WITHOUT ANY WARRANTY; without even the implied warranties of | ||
1407 | 11 | # MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR | ||
1408 | 12 | # PURPOSE. See the GNU General Public License for more details. | ||
1409 | 13 | # | ||
1410 | 14 | # You should have received a copy of the GNU General Public License along | ||
1411 | 15 | # with this program. If not, see <http://www.gnu.org/licenses/>. | ||
1412 | 16 | # | ||
1413 | 17 | # In addition, as a special exception, the copyright holders give | ||
1414 | 18 | # permission to link the code of portions of this program with the | ||
1415 | 19 | # OpenSSL library under certain conditions as described in each | ||
1416 | 20 | # individual source file, and distribute linked combinations | ||
1417 | 21 | # including the two. | ||
1418 | 22 | # You must obey the GNU General Public License in all respects | ||
1419 | 23 | # for all of the code used other than OpenSSL. If you modify | ||
1420 | 24 | # file(s) with this exception, you may extend this exception to your | ||
1421 | 25 | # version of the file(s), but you are not obligated to do so. If you | ||
1422 | 26 | # do not wish to do so, delete this exception statement from your | ||
1423 | 27 | # version. If you delete this exception statement from all source | ||
1424 | 28 | # files in the program, then also delete it here. | ||
1425 | 29 | """XDG tests.""" | ||
1426 | 30 | 0 | ||
1427 | === removed file 'ubuntu_sso/xdg_base_directory/tests/test_common.py' | |||
1428 | --- ubuntu_sso/xdg_base_directory/tests/test_common.py 2012-04-09 17:38:24 +0000 | |||
1429 | +++ ubuntu_sso/xdg_base_directory/tests/test_common.py 1970-01-01 00:00:00 +0000 | |||
1430 | @@ -1,91 +0,0 @@ | |||
1431 | 1 | # -*- coding: utf-8 -*- | ||
1432 | 2 | # | ||
1433 | 3 | # Authors: Natalia B. Bidart <natalia.bidart@canonical.com> | ||
1434 | 4 | # | ||
1435 | 5 | # Copyright 2011-2012 Canonical Ltd. | ||
1436 | 6 | # | ||
1437 | 7 | # This program is free software: you can redistribute it and/or modify it | ||
1438 | 8 | # under the terms of the GNU General Public License version 3, as published | ||
1439 | 9 | # by the Free Software Foundation. | ||
1440 | 10 | # | ||
1441 | 11 | # This program is distributed in the hope that it will be useful, but | ||
1442 | 12 | # WITHOUT ANY WARRANTY; without even the implied warranties of | ||
1443 | 13 | # MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR | ||
1444 | 14 | # PURPOSE. See the GNU General Public License for more details. | ||
1445 | 15 | # | ||
1446 | 16 | # You should have received a copy of the GNU General Public License along | ||
1447 | 17 | # with this program. If not, see <http://www.gnu.org/licenses/>. | ||
1448 | 18 | # | ||
1449 | 19 | # In addition, as a special exception, the copyright holders give | ||
1450 | 20 | # permission to link the code of portions of this program with the | ||
1451 | 21 | # OpenSSL library under certain conditions as described in each | ||
1452 | 22 | # individual source file, and distribute linked combinations | ||
1453 | 23 | # including the two. | ||
1454 | 24 | # You must obey the GNU General Public License in all respects | ||
1455 | 25 | # for all of the code used other than OpenSSL. If you modify | ||
1456 | 26 | # file(s) with this exception, you may extend this exception to your | ||
1457 | 27 | # version of the file(s), but you are not obligated to do so. If you | ||
1458 | 28 | # do not wish to do so, delete this exception statement from your | ||
1459 | 29 | # version. If you delete this exception statement from all source | ||
1460 | 30 | # files in the program, then also delete it here. | ||
1461 | 31 | """Platform independent tests for the XDG constants.""" | ||
1462 | 32 | |||
1463 | 33 | import os | ||
1464 | 34 | |||
1465 | 35 | from twisted.trial.unittest import TestCase | ||
1466 | 36 | |||
1467 | 37 | from ubuntu_sso import xdg_base_directory | ||
1468 | 38 | |||
1469 | 39 | |||
1470 | 40 | class TestBaseDirectory(TestCase): | ||
1471 | 41 | """Tests for the BaseDirectory module.""" | ||
1472 | 42 | |||
1473 | 43 | def assert_utf8_bytes(self, value): | ||
1474 | 44 | """Check that 'value' is a bytes sequence encoded with utf-8.""" | ||
1475 | 45 | self.assertIsInstance(value, str) | ||
1476 | 46 | try: | ||
1477 | 47 | value.decode('utf-8') | ||
1478 | 48 | except UnicodeDecodeError: | ||
1479 | 49 | self.fail('%r should be a utf8 encoded string.' % value) | ||
1480 | 50 | |||
1481 | 51 | def test_xdg_home_is_utf8_bytes(self): | ||
1482 | 52 | """The returned path is bytes.""" | ||
1483 | 53 | actual = xdg_base_directory.xdg_home | ||
1484 | 54 | self.assert_utf8_bytes(actual) | ||
1485 | 55 | |||
1486 | 56 | def test_xdg_cache_home_is_utf8_bytes(self): | ||
1487 | 57 | """The returned path is bytes.""" | ||
1488 | 58 | actual = xdg_base_directory.xdg_cache_home | ||
1489 | 59 | self.assert_utf8_bytes(actual) | ||
1490 | 60 | |||
1491 | 61 | def test_xdg_config_home_is_utf8_bytes(self): | ||
1492 | 62 | """The returned path is bytes.""" | ||
1493 | 63 | actual = xdg_base_directory.xdg_config_home | ||
1494 | 64 | self.assert_utf8_bytes(actual) | ||
1495 | 65 | |||
1496 | 66 | def test_xdg_config_dirs_are_bytes(self): | ||
1497 | 67 | """The returned path is bytes.""" | ||
1498 | 68 | result = xdg_base_directory.xdg_config_dirs | ||
1499 | 69 | for actual in result: | ||
1500 | 70 | self.assert_utf8_bytes(actual) | ||
1501 | 71 | |||
1502 | 72 | def test_xdg_data_home_is_utf8_bytes(self): | ||
1503 | 73 | """The returned path is bytes.""" | ||
1504 | 74 | actual = xdg_base_directory.xdg_data_home | ||
1505 | 75 | self.assert_utf8_bytes(actual) | ||
1506 | 76 | |||
1507 | 77 | def test_xdg_data_dirs_are_bytes(self): | ||
1508 | 78 | """The returned path is bytes.""" | ||
1509 | 79 | result = xdg_base_directory.xdg_data_dirs | ||
1510 | 80 | for actual in result: | ||
1511 | 81 | self.assert_utf8_bytes(actual) | ||
1512 | 82 | |||
1513 | 83 | def test_load_config_paths_filter(self): | ||
1514 | 84 | """Since those folders don't exist, this should be empty.""" | ||
1515 | 85 | self.assertEqual(list(xdg_base_directory.load_config_paths("x")), []) | ||
1516 | 86 | |||
1517 | 87 | def test_save_config_path(self): | ||
1518 | 88 | """The path should end with xdg_config/x (respecting the separator).""" | ||
1519 | 89 | self.patch(os, "makedirs", lambda *args: None) | ||
1520 | 90 | result = xdg_base_directory.save_config_path("x") | ||
1521 | 91 | self.assertEqual(result.split(os.sep)[-2:], ['xdg_config', 'x']) | ||
1522 | 92 | 0 | ||
1523 | === removed file 'ubuntu_sso/xdg_base_directory/tests/test_windows.py' | |||
1524 | --- ubuntu_sso/xdg_base_directory/tests/test_windows.py 2012-04-09 17:38:24 +0000 | |||
1525 | +++ ubuntu_sso/xdg_base_directory/tests/test_windows.py 1970-01-01 00:00:00 +0000 | |||
1526 | @@ -1,157 +0,0 @@ | |||
1527 | 1 | # -*- coding: utf-8 -*- | ||
1528 | 2 | # | ||
1529 | 3 | # Copyright 2011-2012 Canonical Ltd. | ||
1530 | 4 | # | ||
1531 | 5 | # This program is free software: you can redistribute it and/or modify it | ||
1532 | 6 | # under the terms of the GNU General Public License version 3, as published | ||
1533 | 7 | # by the Free Software Foundation. | ||
1534 | 8 | # | ||
1535 | 9 | # This program is distributed in the hope that it will be useful, but | ||
1536 | 10 | # WITHOUT ANY WARRANTY; without even the implied warranties of | ||
1537 | 11 | # MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR | ||
1538 | 12 | # PURPOSE. See the GNU General Public License for more details. | ||
1539 | 13 | # | ||
1540 | 14 | # You should have received a copy of the GNU General Public License along | ||
1541 | 15 | # with this program. If not, see <http://www.gnu.org/licenses/>. | ||
1542 | 16 | # | ||
1543 | 17 | # In addition, as a special exception, the copyright holders give | ||
1544 | 18 | # permission to link the code of portions of this program with the | ||
1545 | 19 | # OpenSSL library under certain conditions as described in each | ||
1546 | 20 | # individual source file, and distribute linked combinations | ||
1547 | 21 | # including the two. | ||
1548 | 22 | # You must obey the GNU General Public License in all respects | ||
1549 | 23 | # for all of the code used other than OpenSSL. If you modify | ||
1550 | 24 | # file(s) with this exception, you may extend this exception to your | ||
1551 | 25 | # version of the file(s), but you are not obligated to do so. If you | ||
1552 | 26 | # do not wish to do so, delete this exception statement from your | ||
1553 | 27 | # version. If you delete this exception statement from all source | ||
1554 | 28 | # files in the program, then also delete it here. | ||
1555 | 29 | """Windows-specific tests for the XDG constants.""" | ||
1556 | 30 | |||
1557 | 31 | import os | ||
1558 | 32 | import sys | ||
1559 | 33 | |||
1560 | 34 | from twisted.trial.unittest import TestCase | ||
1561 | 35 | |||
1562 | 36 | |||
1563 | 37 | # pylint: disable=E1101, E0611, F0401 | ||
1564 | 38 | import win32com.shell | ||
1565 | 39 | from ubuntu_sso.xdg_base_directory.windows import ( | ||
1566 | 40 | get_config_dirs, | ||
1567 | 41 | get_data_dirs, | ||
1568 | 42 | get_env_path, | ||
1569 | 43 | get_special_folders, | ||
1570 | 44 | ) | ||
1571 | 45 | |||
1572 | 46 | |||
1573 | 47 | class FakeShellConModule(object): | ||
1574 | 48 | """Override CSIDL_ constants.""" | ||
1575 | 49 | |||
1576 | 50 | CSIDL_PROFILE = 0 | ||
1577 | 51 | CSIDL_LOCAL_APPDATA = 1 | ||
1578 | 52 | CSIDL_COMMON_APPDATA = 2 | ||
1579 | 53 | |||
1580 | 54 | |||
1581 | 55 | class FakeShellModule(object): | ||
1582 | 56 | |||
1583 | 57 | """Fake Shell Module.""" | ||
1584 | 58 | |||
1585 | 59 | def __init__(self): | ||
1586 | 60 | """Set the proper mapping between CSIDL_ consts.""" | ||
1587 | 61 | self.values = { | ||
1588 | 62 | 0: u'c:\\path\\to\\users\\home', | ||
1589 | 63 | 1: u'c:\\path\\to\\users\\home\\appData\\local', | ||
1590 | 64 | 2: u'c:\\programData', | ||
1591 | 65 | } | ||
1592 | 66 | |||
1593 | 67 | # pylint: disable=C0103 | ||
1594 | 68 | def SHGetFolderPath(self, dummy0, shellconValue, dummy2, dummy3): | ||
1595 | 69 | """Override SHGetFolderPath functionality.""" | ||
1596 | 70 | return self.values[shellconValue] | ||
1597 | 71 | # pylint: enable=C0103 | ||
1598 | 72 | |||
1599 | 73 | |||
1600 | 74 | class TestBaseDirectoryWindows(TestCase): | ||
1601 | 75 | """Tests for the BaseDirectory module.""" | ||
1602 | 76 | |||
1603 | 77 | def test_get_special_folders(self): | ||
1604 | 78 | """Make sure we can import the platform module.""" | ||
1605 | 79 | |||
1606 | 80 | shell_module = FakeShellModule() | ||
1607 | 81 | self.patch(win32com.shell, "shell", shell_module) | ||
1608 | 82 | self.patch(win32com.shell, "shellcon", FakeShellConModule()) | ||
1609 | 83 | special_folders = get_special_folders() | ||
1610 | 84 | self.assertTrue('Personal' in special_folders) | ||
1611 | 85 | self.assertTrue('Local AppData' in special_folders) | ||
1612 | 86 | self.assertTrue('AppData' in special_folders) | ||
1613 | 87 | self.assertTrue('Common AppData' in special_folders) | ||
1614 | 88 | |||
1615 | 89 | self.assertTrue(special_folders['Personal'] == \ | ||
1616 | 90 | shell_module.values[FakeShellConModule.CSIDL_PROFILE]) | ||
1617 | 91 | self.assertTrue(special_folders['Local AppData'] == \ | ||
1618 | 92 | shell_module.values[FakeShellConModule.CSIDL_LOCAL_APPDATA]) | ||
1619 | 93 | self.assertTrue(special_folders['Local AppData'].startswith( | ||
1620 | 94 | special_folders['AppData'])) | ||
1621 | 95 | self.assertTrue(special_folders['Common AppData'] == \ | ||
1622 | 96 | shell_module.values[FakeShellConModule.CSIDL_COMMON_APPDATA]) | ||
1623 | 97 | |||
1624 | 98 | for val in special_folders.itervalues(): | ||
1625 | 99 | self.assertIsInstance(val, str) | ||
1626 | 100 | val.decode('utf8') | ||
1627 | 101 | # Should not raise exceptions | ||
1628 | 102 | |||
1629 | 103 | def test_get_data_dirs(self): | ||
1630 | 104 | """Check thet get_data_dirs uses pathsep correctly.""" | ||
1631 | 105 | bad_sep = filter(lambda x: x not in os.pathsep, ":;") | ||
1632 | 106 | dir_list = ["A", "B", bad_sep, "C"] | ||
1633 | 107 | self.patch(os, "environ", | ||
1634 | 108 | dict(XDG_DATA_DIRS=os.pathsep.join( | ||
1635 | 109 | dir_list))) | ||
1636 | 110 | dirs = get_data_dirs() | ||
1637 | 111 | self.assertEqual(dirs, dir_list) | ||
1638 | 112 | |||
1639 | 113 | def test_get_config_dirs(self): | ||
1640 | 114 | """Check thet get_data_dirs uses pathsep correctly.""" | ||
1641 | 115 | bad_sep = filter(lambda x: x not in os.pathsep, ":;") | ||
1642 | 116 | dir_list = ["A", "B", bad_sep, "C"] | ||
1643 | 117 | self.patch(os, "environ", | ||
1644 | 118 | dict(XDG_CONFIG_DIRS=os.pathsep.join( | ||
1645 | 119 | dir_list))) | ||
1646 | 120 | dirs = get_config_dirs()[1:] | ||
1647 | 121 | self.assertEqual(dirs, dir_list) | ||
1648 | 122 | |||
1649 | 123 | def set_fake_environ(self, key, value): | ||
1650 | 124 | """Set (and restore) a fake environ variable.""" | ||
1651 | 125 | if key in os.environ: | ||
1652 | 126 | prev = os.environ[key] | ||
1653 | 127 | self.addCleanup(os.environ.__setitem__, key, prev) | ||
1654 | 128 | else: | ||
1655 | 129 | self.addCleanup(os.environ.__delitem__, key) | ||
1656 | 130 | os.environ[key] = value | ||
1657 | 131 | |||
1658 | 132 | def unset_fake_environ(self, key): | ||
1659 | 133 | """Unset (and restore) a fake environ variable.""" | ||
1660 | 134 | if key in os.environ: | ||
1661 | 135 | current_value = os.environ[key] | ||
1662 | 136 | self.addCleanup(os.environ.__setitem__, key, current_value) | ||
1663 | 137 | del(os.environ[key]) | ||
1664 | 138 | |||
1665 | 139 | def test_get_env_path_var(self): | ||
1666 | 140 | """Test that get_env_path transforms an env var.""" | ||
1667 | 141 | fake_path = u"C:\\Users\\Ñandú" | ||
1668 | 142 | fake_env_var = "FAKE_ENV_VAR" | ||
1669 | 143 | |||
1670 | 144 | mbcs_path = fake_path.encode(sys.getfilesystemencoding()) | ||
1671 | 145 | utf8_path = fake_path.encode("utf-8") | ||
1672 | 146 | |||
1673 | 147 | self.set_fake_environ(fake_env_var, mbcs_path) | ||
1674 | 148 | self.assertEqual(get_env_path(fake_env_var, "unexpected"), utf8_path) | ||
1675 | 149 | |||
1676 | 150 | def test_get_env_path_no_var(self): | ||
1677 | 151 | """Test that get_env_path returns the default when env var not set.""" | ||
1678 | 152 | fake_path = u"C:\\Users\\Ñandú" | ||
1679 | 153 | fake_env_var = "fake_env_var" | ||
1680 | 154 | default = fake_path.encode(sys.getfilesystemencoding()) | ||
1681 | 155 | |||
1682 | 156 | self.unset_fake_environ(fake_env_var) | ||
1683 | 157 | self.assertEqual(get_env_path(fake_env_var, default), default) | ||
1684 | 158 | 0 | ||
1685 | === removed file 'ubuntu_sso/xdg_base_directory/windows.py' | |||
1686 | --- ubuntu_sso/xdg_base_directory/windows.py 2012-04-09 17:38:24 +0000 | |||
1687 | +++ ubuntu_sso/xdg_base_directory/windows.py 1970-01-01 00:00:00 +0000 | |||
1688 | @@ -1,113 +0,0 @@ | |||
1689 | 1 | # -*- coding: utf-8 -*- | ||
1690 | 2 | # | ||
1691 | 3 | # Copyright 2011-2012 Canonical Ltd. | ||
1692 | 4 | # | ||
1693 | 5 | # This program is free software: you can redistribute it and/or modify it | ||
1694 | 6 | # under the terms of the GNU General Public License version 3, as published | ||
1695 | 7 | # by the Free Software Foundation. | ||
1696 | 8 | # | ||
1697 | 9 | # This program is distributed in the hope that it will be useful, but | ||
1698 | 10 | # WITHOUT ANY WARRANTY; without even the implied warranties of | ||
1699 | 11 | # MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR | ||
1700 | 12 | # PURPOSE. See the GNU General Public License for more details. | ||
1701 | 13 | # | ||
1702 | 14 | # You should have received a copy of the GNU General Public License along | ||
1703 | 15 | # with this program. If not, see <http://www.gnu.org/licenses/>. | ||
1704 | 16 | # | ||
1705 | 17 | # In addition, as a special exception, the copyright holders give | ||
1706 | 18 | # permission to link the code of portions of this program with the | ||
1707 | 19 | # OpenSSL library under certain conditions as described in each | ||
1708 | 20 | # individual source file, and distribute linked combinations | ||
1709 | 21 | # including the two. | ||
1710 | 22 | # You must obey the GNU General Public License in all respects | ||
1711 | 23 | # for all of the code used other than OpenSSL. If you modify | ||
1712 | 24 | # file(s) with this exception, you may extend this exception to your | ||
1713 | 25 | # version of the file(s), but you are not obligated to do so. If you | ||
1714 | 26 | # do not wish to do so, delete this exception statement from your | ||
1715 | 27 | # version. If you delete this exception statement from all source | ||
1716 | 28 | # files in the program, then also delete it here. | ||
1717 | 29 | """XDG helpers for windows.""" | ||
1718 | 30 | |||
1719 | 31 | import os | ||
1720 | 32 | import sys | ||
1721 | 33 | |||
1722 | 34 | |||
1723 | 35 | # pylint: disable=C0103 | ||
1724 | 36 | def get_special_folders(): | ||
1725 | 37 | """ Routine to grab all the Windows Special Folders locations. | ||
1726 | 38 | |||
1727 | 39 | If successful, returns dictionary | ||
1728 | 40 | of shell folder locations indexed on Windows keyword for each; | ||
1729 | 41 | otherwise, returns an empty dictionary. | ||
1730 | 42 | """ | ||
1731 | 43 | # pylint: disable=W0621, F0401, E0611 | ||
1732 | 44 | special_folders = {} | ||
1733 | 45 | |||
1734 | 46 | from win32com.shell import shell, shellcon | ||
1735 | 47 | # CSIDL_LOCAL_APPDATA = C:\Users\<username>\AppData\Local | ||
1736 | 48 | # CSIDL_PROFILE = C:\Users\<username> | ||
1737 | 49 | # CSIDL_COMMON_APPDATA = C:\ProgramData | ||
1738 | 50 | # More information on these constants at | ||
1739 | 51 | # http://msdn.microsoft.com/en-us/library/bb762494 | ||
1740 | 52 | |||
1741 | 53 | # as per http://msdn.microsoft.com/en-us/library/windows/desktop/bb762181, | ||
1742 | 54 | # SHGetFolderPath is deprecated, we should migrate to SHGetKnownFolderPath | ||
1743 | 55 | # (http://msdn.microsoft.com/en-us/library/windows/desktop/bb762188) | ||
1744 | 56 | get_path = lambda name: shell.SHGetFolderPath( | ||
1745 | 57 | 0, getattr(shellcon, name), None, 0).encode('utf8') | ||
1746 | 58 | special_folders['Personal'] = get_path("CSIDL_PROFILE") | ||
1747 | 59 | special_folders['Local AppData'] = get_path("CSIDL_LOCAL_APPDATA") | ||
1748 | 60 | special_folders['AppData'] = os.path.dirname( | ||
1749 | 61 | special_folders['Local AppData']) | ||
1750 | 62 | special_folders['Common AppData'] = get_path("CSIDL_COMMON_APPDATA") | ||
1751 | 63 | return special_folders | ||
1752 | 64 | |||
1753 | 65 | |||
1754 | 66 | def get_env_path(key, default): | ||
1755 | 67 | """Get a utf8 path from an environment variable.""" | ||
1756 | 68 | if key in os.environ: | ||
1757 | 69 | # on windows, environment variables are mbcs bytes | ||
1758 | 70 | # so we must turn them into utf-8 Syncdaemon paths | ||
1759 | 71 | path = os.environ.get(key) | ||
1760 | 72 | return path.decode(sys.getfilesystemencoding()).encode("utf-8") | ||
1761 | 73 | else: | ||
1762 | 74 | return default | ||
1763 | 75 | |||
1764 | 76 | |||
1765 | 77 | special_folders = get_special_folders() | ||
1766 | 78 | |||
1767 | 79 | home_path = special_folders['Personal'] | ||
1768 | 80 | app_local_data_path = special_folders['Local AppData'] | ||
1769 | 81 | app_global_data_path = special_folders['Common AppData'] | ||
1770 | 82 | |||
1771 | 83 | xdg_data_home = get_env_path('XDG_DATA_HOME', | ||
1772 | 84 | os.path.join(app_local_data_path, 'xdg')) | ||
1773 | 85 | |||
1774 | 86 | xdg_cache_home = get_env_path('XDG_CACHE_HOME', | ||
1775 | 87 | os.path.join(xdg_data_home, 'cache')) | ||
1776 | 88 | |||
1777 | 89 | xdg_config_home = get_env_path('XDG_CONFIG_HOME', | ||
1778 | 90 | app_local_data_path) | ||
1779 | 91 | |||
1780 | 92 | |||
1781 | 93 | def get_data_dirs(): | ||
1782 | 94 | """Returns XDG data directories.""" | ||
1783 | 95 | return get_env_path('XDG_DATA_DIRS', | ||
1784 | 96 | '{0}{1}{2}'.format(app_local_data_path, os.pathsep, | ||
1785 | 97 | app_global_data_path)).split(os.pathsep) | ||
1786 | 98 | |||
1787 | 99 | |||
1788 | 100 | xdg_data_dirs = get_data_dirs() | ||
1789 | 101 | |||
1790 | 102 | |||
1791 | 103 | def get_config_dirs(): | ||
1792 | 104 | """Return XDG config directories.""" | ||
1793 | 105 | return [xdg_config_home] + \ | ||
1794 | 106 | get_env_path('XDG_CONFIG_DIRS', | ||
1795 | 107 | app_global_data_path, | ||
1796 | 108 | ).split(os.pathsep) | ||
1797 | 109 | |||
1798 | 110 | xdg_config_dirs = get_config_dirs() | ||
1799 | 111 | |||
1800 | 112 | xdg_data_dirs = filter(lambda x: x, xdg_data_dirs) | ||
1801 | 113 | xdg_config_dirs = filter(lambda x: x, xdg_config_dirs) |
+1 looks good