Merge lp:~nataliabidart/ubuntu-sso-client/better-errors into lp:ubuntu-sso-client
- better-errors
- Merge into trunk
Proposed by
Natalia Bidart
Status: | Merged | ||||||||
---|---|---|---|---|---|---|---|---|---|
Approved by: | Natalia Bidart | ||||||||
Approved revision: | 603 | ||||||||
Merged at revision: | 600 | ||||||||
Proposed branch: | lp:~nataliabidart/ubuntu-sso-client/better-errors | ||||||||
Merge into: | lp:ubuntu-sso-client | ||||||||
Diff against target: |
488 lines (+173/-45) 4 files modified
ubuntu_sso/gui.py (+40/-13) ubuntu_sso/main.py (+8/-5) ubuntu_sso/tests/test_gui.py (+96/-24) ubuntu_sso/tests/test_main.py (+29/-3) |
||||||||
To merge this branch: | bzr merge lp:~nataliabidart/ubuntu-sso-client/better-errors | ||||||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
John Lenton (community) | Approve | ||
Vincenzo Di Somma (community) | Approve | ||
Review via email: mp+33846@code.launchpad.net |
Description of the change
Errors from SSO servers are being shown now to users, matching error-specific to fields.
To post a comment you must log in.
Revision history for this message
Natalia Bidart (nataliabidart) wrote : | # |
- 603. By Natalia Bidart
-
Merged trunk in.
Revision history for this message
Vincenzo Di Somma (vds) : | # |
review:
Approve
Revision history for this message
John Lenton (chipaca) : | # |
review:
Approve
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'ubuntu_sso/gui.py' | |||
2 | --- ubuntu_sso/gui.py 2010-08-26 18:44:24 +0000 | |||
3 | +++ ubuntu_sso/gui.py 2010-08-26 22:54:41 +0000 | |||
4 | @@ -547,7 +547,6 @@ | |||
5 | 547 | 547 | ||
6 | 548 | def _build_success_page(self): | 548 | def _build_success_page(self): |
7 | 549 | """Build the success page.""" | 549 | """Build the success page.""" |
8 | 550 | #self.success_vbox.help_text = '' | ||
9 | 551 | self.success_label.set_markup('<span size="x-large">%s</span>' % | 550 | self.success_label.set_markup('<span size="x-large">%s</span>' % |
10 | 552 | self.SUCCESS) | 551 | self.SUCCESS) |
11 | 553 | return self.success_vbox | 552 | return self.success_vbox |
12 | @@ -846,6 +845,17 @@ | |||
13 | 846 | 845 | ||
14 | 847 | # backend callbacks | 846 | # backend callbacks |
15 | 848 | 847 | ||
16 | 848 | def _build_general_error_message(self, errordict): | ||
17 | 849 | """Concatenate __all__ and message from the errordict.""" | ||
18 | 850 | result = None | ||
19 | 851 | msg1 = errordict.get('__all__') | ||
20 | 852 | msg2 = errordict.get('message') | ||
21 | 853 | if msg1 is not None and msg2 is not None: | ||
22 | 854 | result = '\n'.join((msg1, msg2)) | ||
23 | 855 | else: | ||
24 | 856 | result = msg1 if msg1 is not None else msg2 | ||
25 | 857 | return result | ||
26 | 858 | |||
27 | 849 | @log_call | 859 | @log_call |
28 | 850 | def on_captcha_generated(self, app_name, captcha_id, *args, **kwargs): | 860 | def on_captcha_generated(self, app_name, captcha_id, *args, **kwargs): |
29 | 851 | """Captcha image has been generated and is available to be shown.""" | 861 | """Captcha image has been generated and is available to be shown.""" |
30 | @@ -868,10 +878,21 @@ | |||
31 | 868 | @log_call | 878 | @log_call |
32 | 869 | def on_user_registration_error(self, app_name, error, *args, **kwargs): | 879 | def on_user_registration_error(self, app_name, error, *args, **kwargs): |
33 | 870 | """Captcha image generation failed.""" | 880 | """Captcha image generation failed.""" |
36 | 871 | self._set_current_page(self.enter_details_vbox, | 881 | msg = error.get('email') |
37 | 872 | warning_text=self.UNKNOWN_ERROR) | 882 | if msg is not None: |
38 | 883 | self.email1_entry.set_warning(msg) | ||
39 | 884 | self.email2_entry.set_warning(msg) | ||
40 | 885 | |||
41 | 886 | msg = error.get('password') | ||
42 | 887 | if msg is not None: | ||
43 | 888 | self.password1_entry.set_warning(msg) | ||
44 | 889 | self.password2_entry.set_warning(msg) | ||
45 | 890 | |||
46 | 891 | msg = self._build_general_error_message(error) | ||
47 | 892 | self._set_current_page(self.enter_details_vbox, warning_text=msg) | ||
48 | 893 | |||
49 | 873 | self._gtk_signal_log.append((SIG_REGISTRATION_FAILED, self.app_name, | 894 | self._gtk_signal_log.append((SIG_REGISTRATION_FAILED, self.app_name, |
51 | 874 | error)) | 895 | msg)) |
52 | 875 | 896 | ||
53 | 876 | @log_call | 897 | @log_call |
54 | 877 | def on_email_validated(self, app_name, email, *args, **kwargs): | 898 | def on_email_validated(self, app_name, email, *args, **kwargs): |
55 | @@ -883,10 +904,15 @@ | |||
56 | 883 | @log_call | 904 | @log_call |
57 | 884 | def on_email_validation_error(self, app_name, error, *args, **kwargs): | 905 | def on_email_validation_error(self, app_name, error, *args, **kwargs): |
58 | 885 | """User email validation failed.""" | 906 | """User email validation failed.""" |
61 | 886 | self._set_current_page(self.verify_email_vbox, | 907 | msg = error.get('email_token') |
62 | 887 | warning_text=self.UNKNOWN_ERROR) | 908 | if msg is not None: |
63 | 909 | self.email_token_entry.set_warning(msg) | ||
64 | 910 | |||
65 | 911 | msg = self._build_general_error_message(error) | ||
66 | 912 | self._set_current_page(self.verify_email_vbox, warning_text=msg) | ||
67 | 913 | |||
68 | 888 | self._gtk_signal_log.append((SIG_REGISTRATION_FAILED, self.app_name, | 914 | self._gtk_signal_log.append((SIG_REGISTRATION_FAILED, self.app_name, |
70 | 889 | error)) | 915 | msg)) |
71 | 890 | 916 | ||
72 | 891 | @log_call | 917 | @log_call |
73 | 892 | def on_logged_in(self, app_name, email, *args, **kwargs): | 918 | def on_logged_in(self, app_name, email, *args, **kwargs): |
74 | @@ -898,10 +924,10 @@ | |||
75 | 898 | @log_call | 924 | @log_call |
76 | 899 | def on_login_error(self, app_name, error, *args, **kwargs): | 925 | def on_login_error(self, app_name, error, *args, **kwargs): |
77 | 900 | """User was not successfully logged in.""" | 926 | """User was not successfully logged in.""" |
80 | 901 | self._set_current_page(self.login_vbox, | 927 | msg = self._build_general_error_message(error) |
81 | 902 | warning_text=self.UNKNOWN_ERROR) | 928 | self._set_current_page(self.login_vbox, warning_text=msg) |
82 | 903 | self._gtk_signal_log.append((SIG_LOGIN_FAILED, self.app_name, | 929 | self._gtk_signal_log.append((SIG_LOGIN_FAILED, self.app_name, |
84 | 904 | error)) | 930 | msg)) |
85 | 905 | 931 | ||
86 | 906 | @log_call | 932 | @log_call |
87 | 907 | def on_password_reset_token_sent(self, app_name, email, *args, **kwargs): | 933 | def on_password_reset_token_sent(self, app_name, email, *args, **kwargs): |
88 | @@ -913,8 +939,8 @@ | |||
89 | 913 | @log_call | 939 | @log_call |
90 | 914 | def on_password_reset_error(self, app_name, error, *args, **kwargs): | 940 | def on_password_reset_error(self, app_name, error, *args, **kwargs): |
91 | 915 | """Password reset failed.""" | 941 | """Password reset failed.""" |
94 | 916 | self._set_current_page(self.login_vbox, | 942 | msg = self._build_general_error_message(error) |
95 | 917 | warning_text=self.UNKNOWN_ERROR) | 943 | self._set_current_page(self.login_vbox, warning_text=msg) |
96 | 918 | 944 | ||
97 | 919 | @log_call | 945 | @log_call |
98 | 920 | def on_password_changed(self, app_name, email, *args, **kwargs): | 946 | def on_password_changed(self, app_name, email, *args, **kwargs): |
99 | @@ -925,5 +951,6 @@ | |||
100 | 925 | @log_call | 951 | @log_call |
101 | 926 | def on_password_change_error(self, app_name, error, *args, **kwargs): | 952 | def on_password_change_error(self, app_name, error, *args, **kwargs): |
102 | 927 | """Password reset failed.""" | 953 | """Password reset failed.""" |
103 | 954 | msg = self._build_general_error_message(error) | ||
104 | 928 | self._set_current_page(self.request_password_token_vbox, | 955 | self._set_current_page(self.request_password_token_vbox, |
106 | 929 | warning_text=self.UNKNOWN_ERROR) | 956 | warning_text=msg) |
107 | 930 | 957 | ||
108 | === modified file 'ubuntu_sso/main.py' | |||
109 | --- ubuntu_sso/main.py 2010-08-26 21:06:36 +0000 | |||
110 | +++ ubuntu_sso/main.py 2010-08-26 22:54:41 +0000 | |||
111 | @@ -139,8 +139,12 @@ | |||
112 | 139 | def _format_webservice_errors(self, errdict): | 139 | def _format_webservice_errors(self, errdict): |
113 | 140 | """Turn each list of strings in the errdict into a LF separated str.""" | 140 | """Turn each list of strings in the errdict into a LF separated str.""" |
114 | 141 | result = {} | 141 | result = {} |
117 | 142 | for k in errdict: | 142 | for k, v in errdict.iteritems(): |
118 | 143 | result[k] = "\n".join(errdict[k]) | 143 | # workaround until bug #624955 is solved |
119 | 144 | if isinstance(v, basestring): | ||
120 | 145 | result[k] = v | ||
121 | 146 | else: | ||
122 | 147 | result[k] = "\n".join(v) | ||
123 | 144 | return result | 148 | return result |
124 | 145 | 149 | ||
125 | 146 | def generate_captcha(self, filename): | 150 | def generate_captcha(self, filename): |
126 | @@ -239,7 +243,7 @@ | |||
127 | 239 | result = service(email=email) | 243 | result = service(email=email) |
128 | 240 | except HTTPError, e: | 244 | except HTTPError, e: |
129 | 241 | logger.exception('request_password_reset_token failed with:') | 245 | logger.exception('request_password_reset_token failed with:') |
131 | 242 | raise ResetPasswordTokenError(e.content) | 246 | raise ResetPasswordTokenError(e.content.split('\n')[0]) |
132 | 243 | 247 | ||
133 | 244 | if result['status'] == 'ok': | 248 | if result['status'] == 'ok': |
134 | 245 | return email | 249 | return email |
135 | @@ -261,7 +265,7 @@ | |||
136 | 261 | new_password=new_password) | 265 | new_password=new_password) |
137 | 262 | except HTTPError, e: | 266 | except HTTPError, e: |
138 | 263 | logger.exception('set_new_password failed with:') | 267 | logger.exception('set_new_password failed with:') |
140 | 264 | raise NewPasswordError(e.content) | 268 | raise NewPasswordError(e.content.split('\n')[0]) |
141 | 265 | 269 | ||
142 | 266 | if result['status'] == 'ok': | 270 | if result['status'] == 'ok': |
143 | 267 | return email | 271 | return email |
144 | @@ -273,7 +277,6 @@ | |||
145 | 273 | """Turn an exception into a dictionary to return thru DBus.""" | 277 | """Turn an exception into a dictionary to return thru DBus.""" |
146 | 274 | result = { | 278 | result = { |
147 | 275 | "errtype": e.__class__.__name__, | 279 | "errtype": e.__class__.__name__, |
148 | 276 | "errargs": repr(e.args), | ||
149 | 277 | } | 280 | } |
150 | 278 | if len(e.args) == 0: | 281 | if len(e.args) == 0: |
151 | 279 | result["message"] = e.__class__.__doc__ | 282 | result["message"] = e.__class__.__doc__ |
152 | 280 | 283 | ||
153 | === modified file 'ubuntu_sso/tests/test_gui.py' | |||
154 | --- ubuntu_sso/tests/test_gui.py 2010-08-26 18:44:24 +0000 | |||
155 | +++ ubuntu_sso/tests/test_gui.py 2010-08-26 22:54:41 +0000 | |||
156 | @@ -44,7 +44,6 @@ | |||
157 | 44 | CAPTCHA_SOLUTION = 'william Byrd' | 44 | CAPTCHA_SOLUTION = 'william Byrd' |
158 | 45 | EMAIL = 'test@example.com' | 45 | EMAIL = 'test@example.com' |
159 | 46 | EMAIL_TOKEN = 'B2Pgtf' | 46 | EMAIL_TOKEN = 'B2Pgtf' |
160 | 47 | ERROR = 'Something bad happened!' | ||
161 | 48 | NAME = 'Juanito Pérez' | 47 | NAME = 'Juanito Pérez' |
162 | 49 | PASSWORD = 'h3lloWorld' | 48 | PASSWORD = 'h3lloWorld' |
163 | 50 | RESET_PASSWORD_TOKEN = '8G5Wtq' | 49 | RESET_PASSWORD_TOKEN = '8G5Wtq' |
164 | @@ -344,6 +343,7 @@ | |||
165 | 344 | 'tc_browser', 'login', 'request_password_token', | 343 | 'tc_browser', 'login', 'request_password_token', |
166 | 345 | 'set_new_password') | 344 | 'set_new_password') |
167 | 346 | self.ui = self.gui_class(**self.kwargs) | 345 | self.ui = self.gui_class(**self.kwargs) |
168 | 346 | self.ERROR = {'message': self.ui.UNKNOWN_ERROR} | ||
169 | 347 | 347 | ||
170 | 348 | def tearDown(self): | 348 | def tearDown(self): |
171 | 349 | """Clean up.""" | 349 | """Clean up.""" |
172 | @@ -866,17 +866,39 @@ | |||
173 | 866 | """Init.""" | 866 | """Init.""" |
174 | 867 | super(UserRegistrationErrorTestCase, self).setUp() | 867 | super(UserRegistrationErrorTestCase, self).setUp() |
175 | 868 | self.click_join_with_valid_data() | 868 | self.click_join_with_valid_data() |
176 | 869 | self.ui.on_user_registration_error(app_name=APP_NAME, error=ERROR) | ||
177 | 870 | 869 | ||
178 | 871 | def test_previous_page_is_shown(self): | 870 | def test_previous_page_is_shown(self): |
179 | 872 | """On UserRegistrationError the previous page is shown.""" | 871 | """On UserRegistrationError the previous page is shown.""" |
180 | 872 | self.ui.on_user_registration_error(app_name=APP_NAME, error=self.ERROR) | ||
181 | 873 | self.assert_pages_visibility(enter_details=True) | 873 | self.assert_pages_visibility(enter_details=True) |
182 | 874 | 874 | ||
183 | 875 | def test_warning_label_is_shown(self): | 875 | def test_warning_label_is_shown(self): |
184 | 876 | """On UserRegistrationError the warning label is shown.""" | 876 | """On UserRegistrationError the warning label is shown.""" |
185 | 877 | self.ui.on_user_registration_error(app_name=APP_NAME, error=self.ERROR) | ||
186 | 877 | self.assert_correct_label_warning(self.ui.warning_label, | 878 | self.assert_correct_label_warning(self.ui.warning_label, |
187 | 878 | self.ui.UNKNOWN_ERROR) | 879 | self.ui.UNKNOWN_ERROR) |
188 | 879 | 880 | ||
189 | 881 | def test_specific_errors_from_backend_are_shown(self): | ||
190 | 882 | """Specific errors from backend are used.""" | ||
191 | 883 | error = {'errtype': 'RegistrationError', | ||
192 | 884 | 'message': 'We\'re so doomed.', | ||
193 | 885 | 'email': 'Enter a valid e-mail address.', | ||
194 | 886 | 'password': 'I don\'t like your password.', | ||
195 | 887 | '__all__': 'Wrong captcha solution.'} | ||
196 | 888 | |||
197 | 889 | self.ui.on_user_registration_error(app_name=APP_NAME, error=error) | ||
198 | 890 | |||
199 | 891 | expected = '\n'.join((error['__all__'], error['message'])) | ||
200 | 892 | self.assert_correct_label_warning(self.ui.warning_label, expected) | ||
201 | 893 | self.assert_correct_entry_warning(self.ui.email1_entry, | ||
202 | 894 | error['email']) | ||
203 | 895 | self.assert_correct_entry_warning(self.ui.email2_entry, | ||
204 | 896 | error['email']) | ||
205 | 897 | self.assert_correct_entry_warning(self.ui.password1_entry, | ||
206 | 898 | error['password']) | ||
207 | 899 | self.assert_correct_entry_warning(self.ui.password2_entry, | ||
208 | 900 | error['password']) | ||
209 | 901 | |||
210 | 880 | 902 | ||
211 | 881 | class VerifyEmailTestCase(UbuntuSSOClientTestCase): | 903 | class VerifyEmailTestCase(UbuntuSSOClientTestCase): |
212 | 882 | """Test suite for the user registration (verify email page).""" | 904 | """Test suite for the user registration (verify email page).""" |
213 | @@ -926,19 +948,33 @@ | |||
214 | 926 | self.ui.on_email_validated(app_name=APP_NAME, email=EMAIL) | 948 | self.ui.on_email_validated(app_name=APP_NAME, email=EMAIL) |
215 | 927 | self.assert_pages_visibility(success=True) | 949 | self.assert_pages_visibility(success=True) |
216 | 928 | 950 | ||
219 | 929 | def test_on_email_validated_clears_the_help_text(self): | 951 | def test_on_email_validated_does_not_clear_the_help_text(self): |
220 | 930 | """On email validated the help text is removed.""" | 952 | """On email validated the help text is not removed.""" |
221 | 931 | self.ui.on_email_validated(app_name=APP_NAME, email=EMAIL) | 953 | self.ui.on_email_validated(app_name=APP_NAME, email=EMAIL) |
224 | 932 | self.assertEqual('', self.ui.help_label.get_text()) | 954 | self.assertEqual(self.ui.verify_email_vbox.help_text, |
225 | 933 | test_on_email_validated_clears_the_help_text.skip = 'Maybe this is wrong.' | 955 | self.ui.help_label.get_label()) |
226 | 934 | 956 | ||
227 | 935 | def test_on_email_validation_error_verify_email_is_shown(self): | 957 | def test_on_email_validation_error_verify_email_is_shown(self): |
228 | 936 | """On email validation error, the verify_email page is shown.""" | 958 | """On email validation error, the verify_email page is shown.""" |
230 | 937 | self.ui.on_email_validation_error(app_name=APP_NAME, error=ERROR) | 959 | self.ui.on_email_validation_error(app_name=APP_NAME, error=self.ERROR) |
231 | 938 | self.assert_pages_visibility(verify_email=True) | 960 | self.assert_pages_visibility(verify_email=True) |
232 | 939 | self.assert_correct_label_warning(self.ui.warning_label, | 961 | self.assert_correct_label_warning(self.ui.warning_label, |
233 | 940 | self.ui.UNKNOWN_ERROR) | 962 | self.ui.UNKNOWN_ERROR) |
234 | 941 | 963 | ||
235 | 964 | def test_specific_errors_from_backend_are_shown(self): | ||
236 | 965 | """Specific errors from backend are used.""" | ||
237 | 966 | error = {'errtype': 'EmailValidationError', | ||
238 | 967 | 'message': 'We\'re so doomed.', | ||
239 | 968 | 'email_token': 'Enter a valid e-mail address.', | ||
240 | 969 | '__all__': 'We all are gonna die.'} | ||
241 | 970 | |||
242 | 971 | self.ui.on_email_validation_error(app_name=APP_NAME, error=error) | ||
243 | 972 | |||
244 | 973 | expected = '\n'.join((error['__all__'], error['message'])) | ||
245 | 974 | self.assert_correct_label_warning(self.ui.warning_label, expected) | ||
246 | 975 | self.assert_correct_entry_warning(self.ui.email_token_entry, | ||
247 | 976 | error['email_token']) | ||
248 | 977 | |||
249 | 942 | def test_success_label_is_correct(self): | 978 | def test_success_label_is_correct(self): |
250 | 943 | """The success message is correct.""" | 979 | """The success message is correct.""" |
251 | 944 | self.assertEqual(self.ui.SUCCESS, self.ui.success_label.get_text()) | 980 | self.assertEqual(self.ui.SUCCESS, self.ui.success_label.get_text()) |
252 | @@ -1152,20 +1188,31 @@ | |||
253 | 1152 | def test_on_login_error_morphs_to_login_page(self): | 1188 | def test_on_login_error_morphs_to_login_page(self): |
254 | 1153 | """On user login error, the previous page is shown.""" | 1189 | """On user login error, the previous page is shown.""" |
255 | 1154 | self.click_connect_with_valid_data() | 1190 | self.click_connect_with_valid_data() |
257 | 1155 | self.ui.on_login_error(app_name=APP_NAME, error=ERROR) | 1191 | self.ui.on_login_error(app_name=APP_NAME, error=self.ERROR) |
258 | 1156 | self.assert_pages_visibility(login=True) | 1192 | self.assert_pages_visibility(login=True) |
259 | 1157 | 1193 | ||
260 | 1158 | def test_on_login_error_a_warning_is_shown(self): | 1194 | def test_on_login_error_a_warning_is_shown(self): |
261 | 1159 | """On user login error, a warning is shown with proper wording.""" | 1195 | """On user login error, a warning is shown with proper wording.""" |
262 | 1160 | self.click_connect_with_valid_data() | 1196 | self.click_connect_with_valid_data() |
264 | 1161 | self.ui.on_login_error(app_name=APP_NAME, error=ERROR) | 1197 | self.ui.on_login_error(app_name=APP_NAME, error=self.ERROR) |
265 | 1162 | self.assert_correct_label_warning(self.ui.warning_label, | 1198 | self.assert_correct_label_warning(self.ui.warning_label, |
266 | 1163 | self.ui.UNKNOWN_ERROR) | 1199 | self.ui.UNKNOWN_ERROR) |
267 | 1164 | 1200 | ||
268 | 1201 | def test_specific_errors_from_backend_are_shown(self): | ||
269 | 1202 | """Specific errors from backend are used.""" | ||
270 | 1203 | error = {'errtype': 'AuthenticationError', | ||
271 | 1204 | 'message': 'We\'re so doomed.', | ||
272 | 1205 | '__all__': 'We all are gonna die.'} | ||
273 | 1206 | |||
274 | 1207 | self.ui.on_login_error(app_name=APP_NAME, error=error) | ||
275 | 1208 | |||
276 | 1209 | expected = '\n'.join((error['__all__'], error['message'])) | ||
277 | 1210 | self.assert_correct_label_warning(self.ui.warning_label, expected) | ||
278 | 1211 | |||
279 | 1165 | def test_back_to_registration_hides_warning(self): | 1212 | def test_back_to_registration_hides_warning(self): |
280 | 1166 | """After user login error, warning is hidden when clicking 'Back'.""" | 1213 | """After user login error, warning is hidden when clicking 'Back'.""" |
281 | 1167 | self.click_connect_with_valid_data() | 1214 | self.click_connect_with_valid_data() |
283 | 1168 | self.ui.on_login_error(app_name=APP_NAME, error=ERROR) | 1215 | self.ui.on_login_error(app_name=APP_NAME, error=self.ERROR) |
284 | 1169 | self.ui.login_back_button.clicked() | 1216 | self.ui.login_back_button.clicked() |
285 | 1170 | self.assertFalse(self.ui.warning_label.get_property('visible')) | 1217 | self.assertFalse(self.ui.warning_label.get_property('visible')) |
286 | 1171 | 1218 | ||
287 | @@ -1317,11 +1364,22 @@ | |||
288 | 1317 | 1364 | ||
289 | 1318 | def test_on_password_reset_error_shows_login_page(self): | 1365 | def test_on_password_reset_error_shows_login_page(self): |
290 | 1319 | """When reset token wasn't successfuly sent the login page is shown.""" | 1366 | """When reset token wasn't successfuly sent the login page is shown.""" |
292 | 1320 | self.ui.on_password_reset_error(app_name=APP_NAME, error=ERROR) | 1367 | self.ui.on_password_reset_error(app_name=APP_NAME, error=self.ERROR) |
293 | 1321 | self.assert_correct_label_warning(self.ui.warning_label, | 1368 | self.assert_correct_label_warning(self.ui.warning_label, |
294 | 1322 | self.ui.UNKNOWN_ERROR) | 1369 | self.ui.UNKNOWN_ERROR) |
295 | 1323 | self.assert_pages_visibility(login=True) | 1370 | self.assert_pages_visibility(login=True) |
296 | 1324 | 1371 | ||
297 | 1372 | def test_specific_errors_from_backend_are_shown(self): | ||
298 | 1373 | """Specific errors from backend are used.""" | ||
299 | 1374 | error = {'errtype': 'ResetPasswordTokenError', | ||
300 | 1375 | 'message': 'We\'re so doomed.', | ||
301 | 1376 | '__all__': 'We all are gonna die.'} | ||
302 | 1377 | |||
303 | 1378 | self.ui.on_password_reset_error(app_name=APP_NAME, error=error) | ||
304 | 1379 | |||
305 | 1380 | expected = '\n'.join((error['__all__'], error['message'])) | ||
306 | 1381 | self.assert_correct_label_warning(self.ui.warning_label, expected) | ||
307 | 1382 | |||
308 | 1325 | 1383 | ||
309 | 1326 | class SetNewPasswordTestCase(UbuntuSSOClientTestCase): | 1384 | class SetNewPasswordTestCase(UbuntuSSOClientTestCase): |
310 | 1327 | """Test suite for setting a new password functionality.""" | 1385 | """Test suite for setting a new password functionality.""" |
311 | @@ -1374,11 +1432,22 @@ | |||
312 | 1374 | 1432 | ||
313 | 1375 | def test_on_password_change_error_shows_login_page(self): | 1433 | def test_on_password_change_error_shows_login_page(self): |
314 | 1376 | """When password wasn't changed the reset password page is shown.""" | 1434 | """When password wasn't changed the reset password page is shown.""" |
316 | 1377 | self.ui.on_password_change_error(app_name=APP_NAME, error=ERROR) | 1435 | self.ui.on_password_change_error(app_name=APP_NAME, error=self.ERROR) |
317 | 1378 | self.assert_correct_label_warning(self.ui.warning_label, | 1436 | self.assert_correct_label_warning(self.ui.warning_label, |
318 | 1379 | self.ui.UNKNOWN_ERROR) | 1437 | self.ui.UNKNOWN_ERROR) |
319 | 1380 | self.assert_pages_visibility(request_password_token=True) | 1438 | self.assert_pages_visibility(request_password_token=True) |
320 | 1381 | 1439 | ||
321 | 1440 | def test_specific_errors_from_backend_are_shown(self): | ||
322 | 1441 | """Specific errors from backend are used.""" | ||
323 | 1442 | error = {'errtype': 'NewPasswordError', | ||
324 | 1443 | 'message': 'We\'re so doomed.', | ||
325 | 1444 | '__all__': 'We all are gonna die.'} | ||
326 | 1445 | |||
327 | 1446 | self.ui.on_password_change_error(app_name=APP_NAME, error=error) | ||
328 | 1447 | |||
329 | 1448 | expected = '\n'.join((error['__all__'], error['message'])) | ||
330 | 1449 | self.assert_correct_label_warning(self.ui.warning_label, expected) | ||
331 | 1450 | |||
332 | 1382 | 1451 | ||
333 | 1383 | class DbusTestCase(UbuntuSSOClientTestCase): | 1452 | class DbusTestCase(UbuntuSSOClientTestCase): |
334 | 1384 | """Test suite for the dbus calls.""" | 1453 | """Test suite for the dbus calls.""" |
335 | @@ -1458,9 +1527,10 @@ | |||
336 | 1458 | 1527 | ||
337 | 1459 | def test_on_user_registration_error_proper_signal_is_emitted(self): | 1528 | def test_on_user_registration_error_proper_signal_is_emitted(self): |
338 | 1460 | """On UserRegistrationError, 'registration-failed' signal is sent.""" | 1529 | """On UserRegistrationError, 'registration-failed' signal is sent.""" |
340 | 1461 | self.ui.on_user_registration_error(app_name=APP_NAME, error=ERROR) | 1530 | self.ui.on_user_registration_error(app_name=APP_NAME, error=self.ERROR) |
341 | 1462 | self.ui.on_close_clicked() | 1531 | self.ui.on_close_clicked() |
343 | 1463 | self.assertEqual((self.ui.window, (APP_NAME, ERROR), {}), | 1532 | expected = (self.ui.window, (APP_NAME, self.ui.UNKNOWN_ERROR), {}) |
344 | 1533 | self.assertEqual(expected, | ||
345 | 1464 | self._called[gui.SIG_REGISTRATION_FAILED]) | 1534 | self._called[gui.SIG_REGISTRATION_FAILED]) |
346 | 1465 | 1535 | ||
347 | 1466 | def test_on_email_validated_proper_signals_is_emitted(self): | 1536 | def test_on_email_validated_proper_signals_is_emitted(self): |
348 | @@ -1472,10 +1542,11 @@ | |||
349 | 1472 | 1542 | ||
350 | 1473 | def test_on_email_validation_error_proper_signals_is_emitted(self): | 1543 | def test_on_email_validation_error_proper_signals_is_emitted(self): |
351 | 1474 | """On EmailValidationError, 'registration-failed' signal is sent.""" | 1544 | """On EmailValidationError, 'registration-failed' signal is sent.""" |
353 | 1475 | self.ui.on_email_validation_error(app_name=APP_NAME, error=ERROR) | 1545 | self.ui.on_email_validation_error(app_name=APP_NAME, error=self.ERROR) |
354 | 1476 | self.ui.on_close_clicked() | 1546 | self.ui.on_close_clicked() |
357 | 1477 | self.assertEqual((self.ui.window, (APP_NAME, ERROR), {}), | 1547 | expected = (self.ui.window, (APP_NAME, self.ui.UNKNOWN_ERROR), {}) |
358 | 1478 | self._called[gui.SIG_REGISTRATION_FAILED]) | 1548 | self.assertEqual(expected, |
359 | 1549 | self._called[gui.SIG_REGISTRATION_FAILED]) | ||
360 | 1479 | 1550 | ||
361 | 1480 | def test_on_logged_in_proper_signals_is_emitted(self): | 1551 | def test_on_logged_in_proper_signals_is_emitted(self): |
362 | 1481 | """On LoggedIn, 'login-succeeded' signal is sent.""" | 1552 | """On LoggedIn, 'login-succeeded' signal is sent.""" |
363 | @@ -1487,15 +1558,16 @@ | |||
364 | 1487 | def test_on_login_error_proper_signals_is_emitted(self): | 1558 | def test_on_login_error_proper_signals_is_emitted(self): |
365 | 1488 | """On LoginError, 'login-failed' signal is sent.""" | 1559 | """On LoginError, 'login-failed' signal is sent.""" |
366 | 1489 | self.click_connect_with_valid_data() | 1560 | self.click_connect_with_valid_data() |
368 | 1490 | self.ui.on_login_error(app_name=APP_NAME, error=ERROR) | 1561 | self.ui.on_login_error(app_name=APP_NAME, error=self.ERROR) |
369 | 1491 | self.ui.on_close_clicked() | 1562 | self.ui.on_close_clicked() |
372 | 1492 | self.assertEqual((self.ui.window, (APP_NAME, ERROR), {}), | 1563 | expected = (self.ui.window, (APP_NAME, self.ui.UNKNOWN_ERROR), {}) |
373 | 1493 | self._called[gui.SIG_LOGIN_FAILED]) | 1564 | self.assertEqual(expected, |
374 | 1565 | self._called[gui.SIG_LOGIN_FAILED]) | ||
375 | 1494 | 1566 | ||
376 | 1495 | def test_registration_successfull_even_if_prior_registration_error(self): | 1567 | def test_registration_successfull_even_if_prior_registration_error(self): |
377 | 1496 | """Only one signal is sent with the final outcome.""" | 1568 | """Only one signal is sent with the final outcome.""" |
378 | 1497 | self.click_join_with_valid_data() | 1569 | self.click_join_with_valid_data() |
380 | 1498 | self.ui.on_user_registration_error(app_name=APP_NAME, error=ERROR) | 1570 | self.ui.on_user_registration_error(app_name=APP_NAME, error=self.ERROR) |
381 | 1499 | self.click_join_with_valid_data() | 1571 | self.click_join_with_valid_data() |
382 | 1500 | self.ui.on_email_validated(app_name=APP_NAME, email=EMAIL) | 1572 | self.ui.on_email_validated(app_name=APP_NAME, email=EMAIL) |
383 | 1501 | self.ui.on_close_clicked() | 1573 | self.ui.on_close_clicked() |
384 | @@ -1506,7 +1578,7 @@ | |||
385 | 1506 | def test_login_successfull_even_if_prior_login_error(self): | 1578 | def test_login_successfull_even_if_prior_login_error(self): |
386 | 1507 | """Only one signal is sent with the final outcome.""" | 1579 | """Only one signal is sent with the final outcome.""" |
387 | 1508 | self.click_connect_with_valid_data() | 1580 | self.click_connect_with_valid_data() |
389 | 1509 | self.ui.on_login_error(app_name=APP_NAME, error=ERROR) | 1581 | self.ui.on_login_error(app_name=APP_NAME, error=self.ERROR) |
390 | 1510 | self.click_connect_with_valid_data() | 1582 | self.click_connect_with_valid_data() |
391 | 1511 | self.ui.on_logged_in(app_name=APP_NAME, email=EMAIL) | 1583 | self.ui.on_logged_in(app_name=APP_NAME, email=EMAIL) |
392 | 1512 | self.ui.on_close_clicked() | 1584 | self.ui.on_close_clicked() |
393 | @@ -1517,7 +1589,7 @@ | |||
394 | 1517 | def test_user_cancelation_even_if_prior_registration_error(self): | 1589 | def test_user_cancelation_even_if_prior_registration_error(self): |
395 | 1518 | """Only one signal is sent with the final outcome.""" | 1590 | """Only one signal is sent with the final outcome.""" |
396 | 1519 | self.click_join_with_valid_data() | 1591 | self.click_join_with_valid_data() |
398 | 1520 | self.ui.on_user_registration_error(app_name=APP_NAME, error=ERROR) | 1592 | self.ui.on_user_registration_error(app_name=APP_NAME, error=self.ERROR) |
399 | 1521 | self.ui.join_cancel_button.clicked() | 1593 | self.ui.join_cancel_button.clicked() |
400 | 1522 | 1594 | ||
401 | 1523 | self.assertEqual(len(self._called), 1) | 1595 | self.assertEqual(len(self._called), 1) |
402 | @@ -1526,7 +1598,7 @@ | |||
403 | 1526 | def test_user_cancelation_even_if_prior_login_error(self): | 1598 | def test_user_cancelation_even_if_prior_login_error(self): |
404 | 1527 | """Only one signal is sent with the final outcome.""" | 1599 | """Only one signal is sent with the final outcome.""" |
405 | 1528 | self.click_connect_with_valid_data() | 1600 | self.click_connect_with_valid_data() |
407 | 1529 | self.ui.on_login_error(app_name=APP_NAME, error=ERROR) | 1601 | self.ui.on_login_error(app_name=APP_NAME, error=self.ERROR) |
408 | 1530 | self.ui.login_cancel_button.clicked() | 1602 | self.ui.login_cancel_button.clicked() |
409 | 1531 | 1603 | ||
410 | 1532 | self.assertEqual(len(self._called), 1) | 1604 | self.assertEqual(len(self._called), 1) |
411 | 1533 | 1605 | ||
412 | === modified file 'ubuntu_sso/tests/test_main.py' | |||
413 | --- ubuntu_sso/tests/test_main.py 2010-08-26 21:04:47 +0000 | |||
414 | +++ ubuntu_sso/tests/test_main.py 2010-08-26 22:54:41 +0000 | |||
415 | @@ -54,6 +54,7 @@ | |||
416 | 54 | "Can't reset password for this account" | 54 | "Can't reset password for this account" |
417 | 55 | RESET_TOKEN_INVALID_CONTENT = "AuthToken matching query does not exist." | 55 | RESET_TOKEN_INVALID_CONTENT = "AuthToken matching query does not exist." |
418 | 56 | EMAIL = 'test@example.com' | 56 | EMAIL = 'test@example.com' |
419 | 57 | EMAIL_ALREADY_REGISTERED = 'a@example.com' | ||
420 | 57 | EMAIL_TOKEN = 'B2Pgtf' | 58 | EMAIL_TOKEN = 'B2Pgtf' |
421 | 58 | HELP = 'help text' | 59 | HELP = 'help text' |
422 | 59 | PASSWORD = 'be4tiFul' | 60 | PASSWORD = 'be4tiFul' |
423 | @@ -102,7 +103,10 @@ | |||
424 | 102 | 103 | ||
425 | 103 | def register(self, email, password, captcha_id, captcha_solution): | 104 | def register(self, email, password, captcha_id, captcha_solution): |
426 | 104 | """Fake registration. Return a fix result.""" | 105 | """Fake registration. Return a fix result.""" |
428 | 105 | if captcha_id is None and captcha_solution is None: | 106 | if email == EMAIL_ALREADY_REGISTERED: |
429 | 107 | return {'status': 'error', | ||
430 | 108 | 'errors': {'email': 'Email already registered'}} | ||
431 | 109 | elif captcha_id is None and captcha_solution is None: | ||
432 | 106 | return STATUS_UNKNOWN | 110 | return STATUS_UNKNOWN |
433 | 107 | elif captcha_id != CAPTCHA_ID or captcha_solution != CAPTCHA_SOLUTION: | 111 | elif captcha_id != CAPTCHA_ID or captcha_solution != CAPTCHA_SOLUTION: |
434 | 108 | return STATUS_ERROR | 112 | return STATUS_ERROR |
435 | @@ -146,7 +150,10 @@ | |||
436 | 146 | """Fake the email validation. Return a fix result.""" | 150 | """Fake the email validation. Return a fix result.""" |
437 | 147 | if email_token is None: | 151 | if email_token is None: |
438 | 148 | return STATUS_EMAIL_UNKNOWN | 152 | return STATUS_EMAIL_UNKNOWN |
440 | 149 | if email_token != EMAIL_TOKEN: | 153 | elif email_token == EMAIL_ALREADY_REGISTERED: |
441 | 154 | return {'status': 'error', | ||
442 | 155 | 'errors': {'email': 'Email already registered'}} | ||
443 | 156 | elif email_token != EMAIL_TOKEN: | ||
444 | 150 | return STATUS_EMAIL_ERROR | 157 | return STATUS_EMAIL_ERROR |
445 | 151 | else: | 158 | else: |
446 | 152 | return STATUS_EMAIL_OK | 159 | return STATUS_EMAIL_OK |
447 | @@ -234,6 +241,16 @@ | |||
448 | 234 | self.assertIn(k, STATUS_ERROR['errors']) | 241 | self.assertIn(k, STATUS_ERROR['errors']) |
449 | 235 | self.assertEqual(v, "\n".join(STATUS_ERROR['errors'][k])) | 242 | self.assertEqual(v, "\n".join(STATUS_ERROR['errors'][k])) |
450 | 236 | 243 | ||
451 | 244 | def test_register_user_if_status_error_with_string_message(self): | ||
452 | 245 | """Proper error is raised if register fails.""" | ||
453 | 246 | self.register_kwargs['email'] = EMAIL_ALREADY_REGISTERED | ||
454 | 247 | failure = self.assertRaises(RegistrationError, | ||
455 | 248 | self.processor.register_user, | ||
456 | 249 | **self.register_kwargs) | ||
457 | 250 | for k, v in failure.args[0].items(): | ||
458 | 251 | self.assertIn(k, {'email': 'Email already registered'}) | ||
459 | 252 | self.assertEqual(v, 'Email already registered') | ||
460 | 253 | |||
461 | 237 | def test_register_user_if_status_unknown(self): | 254 | def test_register_user_if_status_unknown(self): |
462 | 238 | """Proper error is raised if register returns an unknown status.""" | 255 | """Proper error is raised if register returns an unknown status.""" |
463 | 239 | self.register_kwargs['captcha_id'] = None | 256 | self.register_kwargs['captcha_id'] = None |
464 | @@ -274,6 +291,16 @@ | |||
465 | 274 | self.assertIn(k, STATUS_EMAIL_ERROR['errors']) | 291 | self.assertIn(k, STATUS_EMAIL_ERROR['errors']) |
466 | 275 | self.assertEqual(v, "\n".join(STATUS_EMAIL_ERROR['errors'][k])) | 292 | self.assertEqual(v, "\n".join(STATUS_EMAIL_ERROR['errors'][k])) |
467 | 276 | 293 | ||
468 | 294 | def test_validate_email_if_status_error_with_string_message(self): | ||
469 | 295 | """Proper error is raised if register fails.""" | ||
470 | 296 | self.login_kwargs['email_token'] = EMAIL_ALREADY_REGISTERED | ||
471 | 297 | failure = self.assertRaises(EmailTokenError, | ||
472 | 298 | self.processor.validate_email, | ||
473 | 299 | **self.login_kwargs) | ||
474 | 300 | for k, v in failure.args[0].items(): | ||
475 | 301 | self.assertIn(k, {'email': 'Email already registered'}) | ||
476 | 302 | self.assertEqual(v, 'Email already registered') | ||
477 | 303 | |||
478 | 277 | def test_validate_email_if_status_unknown(self): | 304 | def test_validate_email_if_status_unknown(self): |
479 | 278 | """Proper error is raised if email validation returns unknown.""" | 305 | """Proper error is raised if email validation returns unknown.""" |
480 | 279 | self.login_kwargs['email_token'] = None | 306 | self.login_kwargs['email_token'] = None |
481 | @@ -797,7 +824,6 @@ | |||
482 | 797 | e = TestExceptToErrdictException(*sample_args) | 824 | e = TestExceptToErrdictException(*sample_args) |
483 | 798 | result = except_to_errdict(e) | 825 | result = except_to_errdict(e) |
484 | 799 | self.assertEqual(result["errtype"], e.__class__.__name__) | 826 | self.assertEqual(result["errtype"], e.__class__.__name__) |
485 | 800 | self.assertEqual(result["errargs"], repr(sample_args)) | ||
486 | 801 | 827 | ||
487 | 802 | 828 | ||
488 | 803 | class KeyringCredentialsTestCase(MockerTestCase): | 829 | class KeyringCredentialsTestCase(MockerTestCase): |
To test this, you should try both registration and login using email address like '@' (that will make the GUI accept the address as valid but SSO will reject it).
You can also try registering with an already registered email address, etc.
Also, you can try logging with non existing accounts, and resetting passwords for non-existing accounts, and resetting password for a valid account but using a bad token.