##// END OF EJS Templates
tests: fixed pull requests my account tests.
marcink -
r275:497f5ccd default
parent child Browse files
Show More
@@ -1,341 +1,344
1 1 # -*- coding: utf-8 -*-
2 2
3 3 # Copyright (C) 2010-2016 RhodeCode GmbH
4 4 #
5 5 # This program is free software: you can redistribute it and/or modify
6 6 # it under the terms of the GNU Affero General Public License, version 3
7 7 # (only), as published by the Free Software Foundation.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU Affero General Public License
15 15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 16 #
17 17 # This program is dual-licensed. If you wish to learn more about the
18 18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 20
21 21 import pytest
22 22
23 23 from rhodecode.lib import helpers as h
24 24 from rhodecode.model.db import User, UserFollowing, Repository, UserApiKeys
25 25 from rhodecode.model.meta import Session
26 26 from rhodecode.tests import (
27 27 TestController, url, TEST_USER_ADMIN_LOGIN, TEST_USER_REGULAR_EMAIL,
28 28 assert_session_flash)
29 29 from rhodecode.tests.fixture import Fixture
30 30 from rhodecode.tests.utils import AssertResponse
31 31
32 32 fixture = Fixture()
33 33
34 34
35 35 class TestMyAccountController(TestController):
36 36 test_user_1 = 'testme'
37 37 destroy_users = set()
38 38
39 39 @classmethod
40 40 def teardown_class(cls):
41 41 fixture.destroy_users(cls.destroy_users)
42 42
43 43 def test_my_account(self):
44 44 self.log_user()
45 45 response = self.app.get(url('my_account'))
46 46
47 47 response.mustcontain('test_admin')
48 48 response.mustcontain('href="/_admin/my_account/edit"')
49 49
50 50 def test_logout_form_contains_csrf(self, autologin_user, csrf_token):
51 51 response = self.app.get(url('my_account'))
52 52 assert_response = AssertResponse(response)
53 53 element = assert_response.get_element('.logout #csrf_token')
54 54 assert element.value == csrf_token
55 55
56 56 def test_my_account_edit(self):
57 57 self.log_user()
58 58 response = self.app.get(url('my_account_edit'))
59 59
60 60 response.mustcontain('value="test_admin')
61 61
62 62 def test_my_account_my_repos(self):
63 63 self.log_user()
64 64 response = self.app.get(url('my_account_repos'))
65 65 repos = Repository.query().filter(
66 66 Repository.user == User.get_by_username(
67 67 TEST_USER_ADMIN_LOGIN)).all()
68 68 for repo in repos:
69 69 response.mustcontain('"name_raw": "%s"' % repo.repo_name)
70 70
71 71 def test_my_account_my_watched(self):
72 72 self.log_user()
73 73 response = self.app.get(url('my_account_watched'))
74 74
75 75 repos = UserFollowing.query().filter(
76 76 UserFollowing.user == User.get_by_username(
77 77 TEST_USER_ADMIN_LOGIN)).all()
78 78 for repo in repos:
79 79 response.mustcontain(
80 80 '"name_raw": "%s"' % repo.follows_repository.repo_name)
81 81
82 82 @pytest.mark.backends("git", "hg")
83 83 def test_my_account_my_pullrequests(self, pr_util):
84 84 self.log_user()
85 85 response = self.app.get(url('my_account_pullrequests'))
86 86 response.mustcontain('You currently have no open pull requests.')
87 87
88 pr = pr_util.create_pull_request()
88 pr = pr_util.create_pull_request(title='TestMyAccountPR')
89 89 response = self.app.get(url('my_account_pullrequests'))
90 response.mustcontain('Pull request #%d opened' % pr.pull_request_id)
90 response.mustcontain('There are currently no open pull requests '
91 'requiring your participation')
92
93 response.mustcontain('#%s: TestMyAccountPR' % pr.pull_request_id)
91 94
92 95 def test_my_account_my_emails(self):
93 96 self.log_user()
94 97 response = self.app.get(url('my_account_emails'))
95 98 response.mustcontain('No additional emails specified')
96 99
97 100 def test_my_account_my_emails_add_existing_email(self):
98 101 self.log_user()
99 102 response = self.app.get(url('my_account_emails'))
100 103 response.mustcontain('No additional emails specified')
101 104 response = self.app.post(url('my_account_emails'),
102 105 {'new_email': TEST_USER_REGULAR_EMAIL,
103 106 'csrf_token': self.csrf_token})
104 107 assert_session_flash(response, 'This e-mail address is already taken')
105 108
106 109 def test_my_account_my_emails_add_mising_email_in_form(self):
107 110 self.log_user()
108 111 response = self.app.get(url('my_account_emails'))
109 112 response.mustcontain('No additional emails specified')
110 113 response = self.app.post(url('my_account_emails'),
111 114 {'csrf_token': self.csrf_token})
112 115 assert_session_flash(response, 'Please enter an email address')
113 116
114 117 def test_my_account_my_emails_add_remove(self):
115 118 self.log_user()
116 119 response = self.app.get(url('my_account_emails'))
117 120 response.mustcontain('No additional emails specified')
118 121
119 122 response = self.app.post(url('my_account_emails'),
120 123 {'new_email': 'foo@barz.com',
121 124 'csrf_token': self.csrf_token})
122 125
123 126 response = self.app.get(url('my_account_emails'))
124 127
125 128 from rhodecode.model.db import UserEmailMap
126 129 email_id = UserEmailMap.query().filter(
127 130 UserEmailMap.user == User.get_by_username(
128 131 TEST_USER_ADMIN_LOGIN)).filter(
129 132 UserEmailMap.email == 'foo@barz.com').one().email_id
130 133
131 134 response.mustcontain('foo@barz.com')
132 135 response.mustcontain('<input id="del_email_id" name="del_email_id" '
133 136 'type="hidden" value="%s" />' % email_id)
134 137
135 138 response = self.app.post(
136 139 url('my_account_emails'), {
137 140 'del_email_id': email_id, '_method': 'delete',
138 141 'csrf_token': self.csrf_token})
139 142 assert_session_flash(response, 'Removed email address from user account')
140 143 response = self.app.get(url('my_account_emails'))
141 144 response.mustcontain('No additional emails specified')
142 145
143 146 @pytest.mark.parametrize(
144 147 "name, attrs", [
145 148 ('firstname', {'firstname': 'new_username'}),
146 149 ('lastname', {'lastname': 'new_username'}),
147 150 ('admin', {'admin': True}),
148 151 ('admin', {'admin': False}),
149 152 ('extern_type', {'extern_type': 'ldap'}),
150 153 ('extern_type', {'extern_type': None}),
151 154 # ('extern_name', {'extern_name': 'test'}),
152 155 # ('extern_name', {'extern_name': None}),
153 156 ('active', {'active': False}),
154 157 ('active', {'active': True}),
155 158 ('email', {'email': 'some@email.com'}),
156 159 ])
157 160 def test_my_account_update(self, name, attrs):
158 161 usr = fixture.create_user(self.test_user_1, password='qweqwe',
159 162 email='testme@rhodecode.org',
160 163 extern_type='rhodecode',
161 164 extern_name=self.test_user_1,
162 165 skip_if_exists=True)
163 166 self.destroy_users.add(self.test_user_1)
164 167
165 168 params = usr.get_api_data() # current user data
166 169 user_id = usr.user_id
167 170 self.log_user(username=self.test_user_1, password='qweqwe')
168 171
169 172 params.update({'password_confirmation': ''})
170 173 params.update({'new_password': ''})
171 174 params.update({'extern_type': 'rhodecode'})
172 175 params.update({'extern_name': self.test_user_1})
173 176 params.update({'csrf_token': self.csrf_token})
174 177
175 178 params.update(attrs)
176 179 # my account page cannot set language param yet, only for admins
177 180 del params['language']
178 181 response = self.app.post(url('my_account'), params)
179 182
180 183 assert_session_flash(
181 184 response, 'Your account was updated successfully')
182 185
183 186 del params['csrf_token']
184 187
185 188 updated_user = User.get_by_username(self.test_user_1)
186 189 updated_params = updated_user.get_api_data()
187 190 updated_params.update({'password_confirmation': ''})
188 191 updated_params.update({'new_password': ''})
189 192
190 193 params['last_login'] = updated_params['last_login']
191 194 # my account page cannot set language param yet, only for admins
192 195 # but we get this info from API anyway
193 196 params['language'] = updated_params['language']
194 197
195 198 if name == 'email':
196 199 params['emails'] = [attrs['email']]
197 200 if name == 'extern_type':
198 201 # cannot update this via form, expected value is original one
199 202 params['extern_type'] = "rhodecode"
200 203 if name == 'extern_name':
201 204 # cannot update this via form, expected value is original one
202 205 params['extern_name'] = str(user_id)
203 206 if name == 'active':
204 207 # my account cannot deactivate account
205 208 params['active'] = True
206 209 if name == 'admin':
207 210 # my account cannot make you an admin !
208 211 params['admin'] = False
209 212
210 213 assert params == updated_params
211 214
212 215 def test_my_account_update_err_email_exists(self):
213 216 self.log_user()
214 217
215 218 new_email = 'test_regular@mail.com' # already exisitn email
216 219 response = self.app.post(url('my_account'),
217 220 params={
218 221 'username': 'test_admin',
219 222 'new_password': 'test12',
220 223 'password_confirmation': 'test122',
221 224 'firstname': 'NewName',
222 225 'lastname': 'NewLastname',
223 226 'email': new_email,
224 227 'csrf_token': self.csrf_token,
225 228 })
226 229
227 230 response.mustcontain('This e-mail address is already taken')
228 231
229 232 def test_my_account_update_err(self):
230 233 self.log_user('test_regular2', 'test12')
231 234
232 235 new_email = 'newmail.pl'
233 236 response = self.app.post(url('my_account'),
234 237 params={
235 238 'username': 'test_admin',
236 239 'new_password': 'test12',
237 240 'password_confirmation': 'test122',
238 241 'firstname': 'NewName',
239 242 'lastname': 'NewLastname',
240 243 'email': new_email,
241 244 'csrf_token': self.csrf_token,
242 245 })
243 246
244 247 response.mustcontain('An email address must contain a single @')
245 248 from rhodecode.model import validators
246 249 msg = validators.ValidUsername(
247 250 edit=False, old_data={})._messages['username_exists']
248 251 msg = h.html_escape(msg % {'username': 'test_admin'})
249 252 response.mustcontain(u"%s" % msg)
250 253
251 254 def test_my_account_auth_tokens(self):
252 255 usr = self.log_user('test_regular2', 'test12')
253 256 user = User.get(usr['user_id'])
254 257 response = self.app.get(url('my_account_auth_tokens'))
255 258 response.mustcontain(user.api_key)
256 259 response.mustcontain('expires: never')
257 260
258 261 @pytest.mark.parametrize("desc, lifetime", [
259 262 ('forever', -1),
260 263 ('5mins', 60*5),
261 264 ('30days', 60*60*24*30),
262 265 ])
263 266 def test_my_account_add_auth_tokens(self, desc, lifetime):
264 267 usr = self.log_user('test_regular2', 'test12')
265 268 user = User.get(usr['user_id'])
266 269 response = self.app.post(url('my_account_auth_tokens'),
267 270 {'description': desc, 'lifetime': lifetime,
268 271 'csrf_token': self.csrf_token})
269 272 assert_session_flash(response, 'Auth token successfully created')
270 273 try:
271 274 response = response.follow()
272 275 user = User.get(usr['user_id'])
273 276 for auth_token in user.auth_tokens:
274 277 response.mustcontain(auth_token)
275 278 finally:
276 279 for auth_token in UserApiKeys.query().all():
277 280 Session().delete(auth_token)
278 281 Session().commit()
279 282
280 283 def test_my_account_remove_auth_token(self):
281 284 # TODO: without this cleanup it fails when run with the whole
282 285 # test suite, so there must be some interference with other tests.
283 286 UserApiKeys.query().delete()
284 287
285 288 usr = self.log_user('test_regular2', 'test12')
286 289 User.get(usr['user_id'])
287 290 response = self.app.post(url('my_account_auth_tokens'),
288 291 {'description': 'desc', 'lifetime': -1,
289 292 'csrf_token': self.csrf_token})
290 293 assert_session_flash(response, 'Auth token successfully created')
291 294 response = response.follow()
292 295
293 296 # now delete our key
294 297 keys = UserApiKeys.query().all()
295 298 assert 1 == len(keys)
296 299
297 300 response = self.app.post(
298 301 url('my_account_auth_tokens'),
299 302 {'_method': 'delete', 'del_auth_token': keys[0].api_key,
300 303 'csrf_token': self.csrf_token})
301 304 assert_session_flash(response, 'Auth token successfully deleted')
302 305 keys = UserApiKeys.query().all()
303 306 assert 0 == len(keys)
304 307
305 308 def test_my_account_reset_main_auth_token(self):
306 309 usr = self.log_user('test_regular2', 'test12')
307 310 user = User.get(usr['user_id'])
308 311 api_key = user.api_key
309 312 response = self.app.get(url('my_account_auth_tokens'))
310 313 response.mustcontain(api_key)
311 314 response.mustcontain('expires: never')
312 315
313 316 response = self.app.post(
314 317 url('my_account_auth_tokens'),
315 318 {'_method': 'delete', 'del_auth_token_builtin': api_key,
316 319 'csrf_token': self.csrf_token})
317 320 assert_session_flash(response, 'Auth token successfully reset')
318 321 response = response.follow()
319 322 response.mustcontain(no=[api_key])
320 323
321 324 def test_password_is_updated_in_session_on_password_change(
322 325 self, user_util):
323 326 old_password = 'abcdef123'
324 327 new_password = 'abcdef124'
325 328
326 329 user = user_util.create_user(password=old_password)
327 330 session = self.log_user(user.username, old_password)
328 331 old_password_hash = session['password']
329 332
330 333 form_data = {
331 334 'current_password': old_password,
332 335 'new_password': new_password,
333 336 'new_password_confirmation': new_password,
334 337 'csrf_token': self.csrf_token
335 338 }
336 339 self.app.post(url('my_account_password'), form_data)
337 340
338 341 response = self.app.get(url('home'))
339 342 new_password_hash = response.session['rhodecode_user']['password']
340 343
341 344 assert old_password_hash != new_password_hash
General Comments 0
You need to be logged in to leave comments. Login now