3
0
Fork 0
wuttaweb/tests/views/test_auth.py
Lance Edgar 4d0693862d fix: format all code with black
and from now on should not deviate from that...
2025-08-31 12:26:43 -05:00

195 lines
6.7 KiB
Python

# -*- coding: utf-8; -*-
from unittest.mock import MagicMock, patch
from pyramid.httpexceptions import HTTPFound, HTTPForbidden
from wuttaweb.views import auth as mod
from wuttaweb.testing import WebTestCase
class TestAuthView(WebTestCase):
def setUp(self):
self.setup_web()
self.pyramid_config.include("wuttaweb.views.common")
def make_view(self):
return mod.AuthView(self.request)
def test_includeme(self):
self.pyramid_config.include("wuttaweb.views.auth")
def test_login(self):
model = self.app.model
auth = self.app.get_auth_handler()
view = self.make_view()
# until user exists, will redirect
self.assertEqual(self.session.query(model.User).count(), 0)
response = view.login(session=self.session)
self.assertEqual(response.status_code, 302)
# make a user
barney = model.User(username="barney")
auth.set_user_password(barney, "testpass")
self.session.add(barney)
self.session.commit()
# now since user exists, form will display
context = view.login(session=self.session)
self.assertIn("form", context)
# redirect if user already logged in
with patch.object(self.request, "user", new=barney):
view = self.make_view()
response = view.login(session=self.session)
self.assertEqual(response.status_code, 302)
# login fails w/ wrong password
self.request.method = "POST"
self.request.POST = {"username": "barney", "password": "WRONG"}
view = self.make_view()
context = view.login(session=self.session)
self.assertIn("form", context)
# redirect if login succeeds
self.request.method = "POST"
self.request.POST = {"username": "barney", "password": "testpass"}
view = self.make_view()
response = view.login(session=self.session)
self.assertEqual(response.status_code, 302)
def test_logout(self):
self.pyramid_config.add_route("login", "/login")
view = self.make_view()
self.request.session.delete = MagicMock()
response = view.logout()
self.request.session.delete.assert_called_once_with()
self.assertEqual(response.status_code, 302)
def test_change_password(self):
model = self.app.model
auth = self.app.get_auth_handler()
barney = model.User(username="barney")
self.session.add(barney)
self.session.commit()
view = self.make_view()
# unauthenticated user is redirected
redirect = view.change_password()
self.assertIsInstance(redirect, HTTPFound)
# set initial password
auth.set_user_password(barney, "foo")
self.session.commit()
# forbidden if prevent_edit is set for user
self.request.user = barney
barney.prevent_edit = True
self.assertRaises(HTTPForbidden, view.change_password)
# okay let's test with edit allowed
barney.prevent_edit = False
# view should now return context w/ form
context = view.change_password()
self.assertIn("form", context)
# submit valid form, ensure password is changed
# (nb. this also would redirect user to home page)
self.request.method = "POST"
self.request.POST = {
"current_password": "foo",
# nb. new_password requires colander mapping structure
"__start__": "new_password:mapping",
"new_password": "bar",
"new_password-confirm": "bar",
"__end__": "new_password:mapping",
}
redirect = view.change_password()
self.assertIsInstance(redirect, HTTPFound)
self.session.commit()
self.assertFalse(auth.check_user_password(barney, "foo"))
self.assertTrue(auth.check_user_password(barney, "bar"))
# at this point 'foo' is the password, now let's submit some
# invalid forms and make sure we get back a context w/ form
# first try empty data
self.request.POST = {}
context = view.change_password()
self.assertIn("form", context)
dform = context["form"].get_deform()
self.assertEqual(dform["current_password"].errormsg, "Required")
self.assertEqual(dform["new_password"].errormsg, "Required")
# now try bad current password
self.request.POST = {
"current_password": "blahblah",
"__start__": "new_password:mapping",
"new_password": "baz",
"new_password-confirm": "baz",
"__end__": "new_password:mapping",
}
context = view.change_password()
self.assertIn("form", context)
dform = context["form"].get_deform()
self.assertEqual(
dform["current_password"].errormsg, "Current password is incorrect."
)
# now try bad new password
self.request.POST = {
"current_password": "bar",
"__start__": "new_password:mapping",
"new_password": "bar",
"new_password-confirm": "bar",
"__end__": "new_password:mapping",
}
context = view.change_password()
self.assertIn("form", context)
dform = context["form"].get_deform()
self.assertEqual(
dform["new_password"].errormsg,
"New password must be different from old password.",
)
def test_become_root(self):
view = mod.AuthView(self.request)
# GET not allowed
self.request.method = "GET"
self.assertRaises(HTTPForbidden, view.become_root)
# non-admin users also not allowed
self.request.method = "POST"
self.request.is_admin = False
self.assertRaises(HTTPForbidden, view.become_root)
# but admin users can become root
self.request.is_admin = True
self.assertNotIn("is_root", self.request.session)
redirect = view.become_root()
self.assertIsInstance(redirect, HTTPFound)
self.assertTrue(self.request.session["is_root"])
def test_stop_root(self):
view = mod.AuthView(self.request)
# GET not allowed
self.request.method = "GET"
self.assertRaises(HTTPForbidden, view.stop_root)
# non-admin users also not allowed
self.request.method = "POST"
self.request.is_admin = False
self.assertRaises(HTTPForbidden, view.stop_root)
# but admin users can stop being root
# (nb. there is no check whether user is currently root)
self.request.is_admin = True
self.assertNotIn("is_root", self.request.session)
redirect = view.stop_root()
self.assertIsInstance(redirect, HTTPFound)
self.assertFalse(self.request.session["is_root"])