from django.contrib.auth import get_user_model from django.test import TestCase from django.urls import reverse User = get_user_model() class ChangePasswordViewTestCase(TestCase): def setUp(self): self.user = User.objects.create_user(username="alice", password="oldpassword") self.client.force_login(self.user) def _post(self, old, new1, new2): return self.client.post( reverse("settings-account"), {"old_password": old, "new_password1": new1, "new_password2": new2}, ) def test_get_renders_form(self): response = self.client.get(reverse("settings-account")) self.assertEqual(response.status_code, 200) self.assertContains(response, "Change password") self.assertContains(response, "old_password") def test_requires_login(self): self.client.logout() response = self.client.get(reverse("settings-account")) self.assertEqual(response.status_code, 302) def test_valid_change_updates_password(self): response = self._post("oldpassword", "brandnewpass", "brandnewpass") self.assertRedirects(response, reverse("settings-account")) self.user.refresh_from_db() self.assertTrue(self.user.check_password("brandnewpass")) self.assertFalse(self.user.check_password("oldpassword")) def test_valid_change_keeps_session(self): self._post("oldpassword", "brandnewpass", "brandnewpass") # Session must survive the password change (update_session_auth_hash), # so a follow-up authenticated request still succeeds. response = self.client.get(reverse("settings-account")) self.assertEqual(response.status_code, 200) def test_wrong_current_password_rejected(self): response = self._post("WRONG", "brandnewpass", "brandnewpass") self.assertEqual(response.status_code, 200) # re-render with errors, no redirect self.user.refresh_from_db() self.assertTrue(self.user.check_password("oldpassword")) def test_mismatched_new_password_rejected(self): response = self._post("oldpassword", "brandnewpass", "different") self.assertEqual(response.status_code, 200) self.user.refresh_from_db() self.assertTrue(self.user.check_password("oldpassword"))