Reputation: 315
So I've made this little app where users have an account page were they can see and update their own details.
Now I'm writing some tests for the DetailView and UpdateView. I would like to verify that the logged in user is indeed the owner of the user details.
I've created a testdatabase with different users and added three tests.
The problem is in the last test, I tried to retrieve the logged in user and compare this with the current user details but this isn't working. Any ideas?
Edit: The test now passes successfully, so the user data belongs to the user who is logged in.
However this doesn't feel like a valid test method. Even though the user matches the owner of the details I'm looking for a way to verify if a user would be able to access the details of someone else.
Before, I would use the user id in the url like;
path('account/<int:pk>/', views.AccountDetailView.as_view(), name='account_detail'),
So someone would be able to edit the urlpath and access someone else his details if the LoginRequiredMixin wasn't added.
By using get_object(self):, this is no longer possible, what's the best way to test this possibility?
class AccountDetailView(LoginRequiredMixin, DetailView):
model = User
template_name = 'account.html'
'''
Retrieve user id from "self.request.user" instead of retrieving the user_id
from the URL. This way we can eliminate the user id in the URL.
'''
def get_object(self):
return self.request.user
class LoggedInTestCase(TestCase):
'''
Setup LoginInTestCase
'''
def setUp(self):
guest = User.objects.create_user(username='john.doe', email='[email protected]', password='1234')
guest_other = User.objects.create_user(username='david.doe', email='[email protected]', password='5678')
class AccountDetailViewTests(LoggedInTestCase):
'''
Test the UserDetailView which shows the user details
'''
def test_login_required_redirection(self):
'''
Test if only logged in users can view the user detail page
'''
self.url = reverse('account_detail')
login_url = reverse('account_login')
response = self.client.get(self.url)
self.assertRedirects(response, '{login_url}?next={url}'.format(login_url=login_url, url=self.url))
def test_logged_in_uses_correct_template(self):
'''
Test if logged in user gets to see the correct template
'''
login = self.client.login(username='john.doe', password='1234')
response = self.client.get(reverse('account_detail'))
# Check if our guest is logged in
self.assertEqual(str(response.context['user']), 'john.doe')
# Check for response "succes"
self.assertEqual(response.status_code, 200)
# Check if we get the correct template
self.assertTemplateUsed(response, 'account.html')
def test_accountdetails_belong_to_logged_in_user(self):
'''
Test if logged in user can only see the details that belong to him
'''
login = self.client.login(username='john.doe', password='1234')
response = self.client.get(reverse('account_detail'))
# Check if our guest is logged in matches the
user = User.objects.get(username='john.doe') #edited
self.assertEqual(response.context['user'], user)
# Check for response "success"
self.assertEqual(response.status_code, 200)
Upvotes: 0
Views: 811
Reputation: 309109
The client.login
method returns True
if the login succeeded, it does not return the user.
You can fetch the user from the database.
user = User.objects.get(username='john.doe')
self.assertEqual(response.context['user'], user)
Or compare the string as in your other test.
self.assertEqual(str(response.context['user']), 'john.doe')
Upvotes: 1