@@ -21,15 +21,11 @@ def setUp(self):
2121 username = "username" ,
2222 password = "password" ,
2323 email = "niklas@sundin.se" ,
24- search_visibility = User .SEARCH_PUBLIC ,
2524 membership = None ,
2625 )
2726 self .user2 = UserFactory (
2827 username = "spameggs" ,
2928 password = "password" ,
30- search_visibility = User .SEARCH_PRIVATE ,
31- email_privacy = User .EMAIL_PRIVATE ,
32- public_profile = False ,
3329 )
3430
3531 def assertUserCreated (self , data = None , template_name = "account/verification_sent.html" ): # noqa: N802 - unittest assertion naming convention
@@ -136,90 +132,37 @@ def test_user_update_redirect(self):
136132 response = self .client .get (url )
137133 self .assertEqual (response .status_code , 200 )
138134
139- # should return 200 if the user does want to see their user profile
135+ # should redirect to the profile page after saving
140136 post_data = {
141137 "username" : "username" ,
142- "search_visibility" : 0 ,
143- "email_privacy" : 1 ,
144- "public_profile" : False ,
145138 "email" : "niklas@sundin.se" ,
146139 settings .HONEYPOT_FIELD_NAME : settings .HONEYPOT_VALUE ,
147140 }
148141 response = self .client .post (url , post_data )
149- profile_url = reverse ("users:user_detail" , kwargs = { "slug" : "username" } )
142+ profile_url = reverse ("users:user_detail" )
150143 self .assertRedirects (response , profile_url )
151144
152- # should return 404 for another user
153- another_user_url = reverse ("users:user_detail" , kwargs = {"slug" : "spameggs" })
154- response = self .client .get (another_user_url )
155- self .assertEqual (response .status_code , 404 )
156-
157- # should return 404 if the user is not logged-in
145+ # should redirect to login if the user is not logged-in
158146 self .client .logout ()
159147 response = self .client .get (profile_url )
160- self .assertEqual (response . status_code , 404 )
148+ self .assertRedirects (response , "{}?next={}" . format ( reverse ( "account_login" ), profile_url ) )
161149
162150 def test_user_detail (self ):
163- # Ensure detail page is viewable without login, but that edit URLs
164- # do not appear
165- detail_url = reverse ("users:user_detail" , kwargs = {"slug" : self .user .username })
151+ # Ensure the detail page shows the logged-in user's own profile
152+ detail_url = reverse ("users:user_detail" )
166153 edit_url = reverse ("users:user_profile_edit" )
154+ self .client .login (username = self .user2 .username , password = "password" )
167155 response = self .client .get (detail_url )
168- self .assertTrue (self .user .is_active )
169- self .assertNotContains (response , edit_url )
170-
171- # Ensure edit url is available to logged in users
172- self .client .login (username = "username" , password = "password" )
173- response = self .client .get (detail_url )
156+ self .assertEqual (response .context ["object" ], self .user2 )
174157 self .assertContains (response , edit_url )
175158
176- # Ensure inactive accounts shouldn't be shown to users.
177- user = User .objects .create_user (
178- username = "foobar" ,
179- password = "baz" ,
180- email = "paradiselost@example.com" ,
181- )
182- user .is_active = False
183- user .save ()
184- self .assertFalse (user .is_active )
185- detail_url = reverse ("users:user_detail" , kwargs = {"slug" : user .username })
186- response = self .client .get (detail_url )
187- self .assertEqual (response .status_code , 404 )
188-
189- def test_special_usernames (self ):
190- # Ensure usernames in the forms of:
191- # first.last
192- # user@host.com
193- # are allowed to view their profile pages since we allow them in
194- # the username field
195- u1 = User .objects .create_user (
196- username = "user.name" ,
197- password = "password" ,
198- )
199- detail_url = reverse ("users:user_detail" , kwargs = {"slug" : u1 .username })
200- edit_url = reverse ("users:user_profile_edit" )
201-
202- self .client .login (username = u1 .username , password = "password" )
203- response = self .client .get (detail_url )
204- self .assertEqual (response .status_code , 200 )
205-
206- response = self .client .get (edit_url )
207- self .assertEqual (response .status_code , 200 )
208-
209- u2 = User .objects .create_user (
210- username = "user@example.com" ,
211- password = "password" ,
212- )
213-
214- detail_url = reverse ("users:user_detail" , kwargs = {"slug" : u2 .username })
215- edit_url = reverse ("users:user_profile_edit" )
216-
217- self .client .login (username = u2 .username , password = "password" )
218- response = self .client .get (detail_url )
219- self .assertEqual (response .status_code , 200 )
220-
221- response = self .client .get (edit_url )
222- self .assertEqual (response .status_code , 200 )
159+ def test_user_detail_not_addressable_by_username (self ):
160+ # Profiles used to live at /users/<username>/; existing and unknown
161+ # usernames must be indistinguishable to prevent user enumeration.
162+ existing = self .client .get (f"/users/{ self .user .username } /" )
163+ unknown = self .client .get ("/users/thisusernamedoesntexist/" )
164+ self .assertEqual (existing .status_code , 404 )
165+ self .assertEqual (unknown .status_code , 404 )
223166
224167 def test_user_new_account (self ):
225168 self .assertUserCreated (
@@ -298,62 +241,61 @@ def test_is_active_login(self):
298241 self .assertRedirects (response , "{}?next={}" .format (reverse ("account_login" ), url ))
299242
300243 def test_user_delete_needs_to_be_logged_in (self ):
301- url = reverse ("users:user_delete" , kwargs = { "slug" : self . user . username } )
244+ url = reverse ("users:user_delete" )
302245 response = self .client .delete (url )
303246 self .assertRedirects (response , "{}?next={}" .format (reverse ("account_login" ), url ))
304247
305248 def test_user_delete_invalid_request_method (self ):
306- url = reverse ("users:user_delete" , kwargs = { "slug" : self . user . username } )
249+ url = reverse ("users:user_delete" )
307250 self .client .login (username = self .user .username , password = "password" )
308251 response = self .client .get (url )
309252 self .assertEqual (response .status_code , 405 )
310253
311- def test_user_delete_different_user (self ):
312- url = reverse ("users:user_delete" , kwargs = {"slug" : self .user .username })
313- self .client .login (username = self .user2 .username , password = "password" )
314- response = self .client .delete (url )
315- self .assertEqual (response .status_code , 403 )
316-
317254 def test_user_delete (self ):
318- url = reverse ("users:user_delete" , kwargs = { "slug" : self . user . username } )
255+ url = reverse ("users:user_delete" )
319256 self .client .login (username = self .user .username , password = "password" )
320257 response = self .client .delete (url )
321258 self .assertRedirects (response , reverse ("home" ))
322259 self .assertRaises (User .DoesNotExist , User .objects .get , username = self .user .username )
323260 self .assertRaises (Membership .DoesNotExist , Membership .objects .get , creator = self .user )
261+ self .assertTrue (User .objects .filter (username = self .user2 .username ).exists ())
324262
325263 def test_membership_delete_needs_to_be_logged_in (self ):
326- url = reverse ("users:user_membership_delete" , kwargs = { "slug" : self . user2 . username } )
264+ url = reverse ("users:user_membership_delete" )
327265 response = self .client .delete (url )
328266 self .assertRedirects (response , "{}?next={}" .format (reverse ("account_login" ), url ))
329267
330268 def test_membership_delete_invalid_request_method (self ):
331- url = reverse ("users:user_membership_delete" , kwargs = { "slug" : self . user2 . username } )
269+ url = reverse ("users:user_membership_delete" )
332270 self .client .login (username = self .user2 .username , password = "password" )
333271 response = self .client .get (url )
334272 self .assertEqual (response .status_code , 405 )
335273
336- def test_membership_delete_different_user_membership (self ):
337- user = UserFactory ()
338- self .assertTrue (user .has_membership )
339- url = reverse ("users:user_membership_delete" , kwargs = {"slug" : user .username })
274+ def test_membership_delete_not_addressable_by_username (self ):
275+ # Membership deletion used to live at /users/membership/delete/<username>/
276+ # and answered 403 for members and 404 for everyone else.
277+ member = UserFactory ()
278+ self .assertTrue (member .has_membership )
340279 self .client .login (username = self .user2 .username , password = "password" )
341- response = self .client .delete (url )
342- self .assertEqual (response .status_code , 403 )
280+ existing = self .client .delete (f"/users/membership/delete/{ member .username } /" )
281+ unknown = self .client .delete ("/users/membership/delete/thisusernamedoesntexist/" )
282+ self .assertEqual (existing .status_code , 404 )
283+ self .assertEqual (unknown .status_code , 404 )
284+ self .assertTrue (Membership .objects .filter (creator = member ).exists ())
343285
344286 def test_membership_does_not_exist (self ):
345287 self .assertFalse (self .user .has_membership )
346- url = reverse ("users:user_membership_delete" , kwargs = { "slug" : self . user . username } )
288+ url = reverse ("users:user_membership_delete" )
347289 self .client .login (username = self .user .username , password = "password" )
348290 response = self .client .delete (url )
349291 self .assertEqual (response .status_code , 404 )
350292
351293 def test_membership_delete (self ):
352294 self .assertTrue (self .user2 .has_membership )
353- url = reverse ("users:user_membership_delete" , kwargs = { "slug" : self . user2 . username } )
295+ url = reverse ("users:user_membership_delete" )
354296 self .client .login (username = self .user2 .username , password = "password" )
355297 response = self .client .delete (url )
356- self .assertRedirects (response , reverse ("users:user_detail" , kwargs = { "slug" : self . user2 . username } ))
298+ self .assertRedirects (response , reverse ("users:user_detail" ))
357299 # TODO: We can't use 'self.user2.refresh_from_db()' because
358300 # of https://code.djangoproject.com/ticket/27846.
359301 with self .assertRaises (Membership .DoesNotExist ):
0 commit comments