Add account deletion, admin user removal, household deletion, grayed-out other-user chips (47 tests)
This commit is contained in:
@@ -89,3 +89,100 @@ class TestHistoryRoute:
|
||||
resp = auth_client.get(f"/history?date={past.isoformat()}")
|
||||
assert resp.status_code == 200
|
||||
assert b"History" in resp.data
|
||||
|
||||
|
||||
class TestDeleteAccount:
|
||||
def test_delete_own_account(self, auth_client):
|
||||
"""Bob deletes his own account."""
|
||||
resp = auth_client.post("/delete-account", data={
|
||||
"password": "bobpass",
|
||||
}, follow_redirects=True)
|
||||
assert resp.status_code == 200
|
||||
assert b"has been deleted" in resp.data
|
||||
# Bob should be logged out
|
||||
resp2 = auth_client.get("/dashboard", follow_redirects=True)
|
||||
assert b"Log In" in resp2.data
|
||||
|
||||
def test_delete_own_account_wrong_password(self, auth_client):
|
||||
"""Delete fails with wrong password."""
|
||||
resp = auth_client.post("/delete-account", data={
|
||||
"password": "wrongpass",
|
||||
}, follow_redirects=True)
|
||||
assert b"Incorrect password" in resp.data
|
||||
# Still logged in
|
||||
resp2 = auth_client.get("/dashboard")
|
||||
assert resp2.status_code == 200
|
||||
|
||||
|
||||
class TestAdminRemoveUser:
|
||||
def test_admin_removes_user(self, admin_client):
|
||||
"""Admin removes a regular user."""
|
||||
# admin_client has admin as sole user — need another user to remove
|
||||
admin_client.get("/logout")
|
||||
# Register another user in admin's household
|
||||
from models import get_household_by_name
|
||||
hh = get_household_by_name("Admin Household")
|
||||
admin_client.post("/register", data={
|
||||
"username": "extra",
|
||||
"password": "extrapass",
|
||||
"confirm": "extrapass",
|
||||
"household_action": "join",
|
||||
"household_id": str(hh["id"]),
|
||||
})
|
||||
# admin_client logs back in as admin
|
||||
admin_client.get("/logout")
|
||||
admin_client.post("/login", data={
|
||||
"username": "admin", "password": "adminpass",
|
||||
})
|
||||
# Remove the extra user
|
||||
from models import get_user_by_username
|
||||
extra = get_user_by_username("extra")
|
||||
resp = admin_client.post(f"/admin/remove-user/{extra['id']}", follow_redirects=True)
|
||||
assert b"has been removed" in resp.data
|
||||
# Extra user should be gone
|
||||
admin_client.get("/dashboard")
|
||||
assert get_user_by_username("extra") is None
|
||||
|
||||
def test_non_admin_cannot_remove(self, auth_client):
|
||||
"""Regular user (bob) cannot remove others."""
|
||||
resp = auth_client.post("/admin/remove-user/1", follow_redirects=True)
|
||||
assert b"Only admins" in resp.data
|
||||
|
||||
def test_admin_cannot_remove_admin(self, admin_client):
|
||||
"""Admin cannot remove themselves via remove-user."""
|
||||
resp = admin_client.post("/admin/remove-user/1", follow_redirects=True)
|
||||
assert b"Cannot remove the admin" in resp.data
|
||||
|
||||
|
||||
class TestAdminDeleteHousehold:
|
||||
def test_admin_deletes_household(self, admin_client):
|
||||
"""Admin deletes entire household."""
|
||||
resp = admin_client.post("/admin/delete-household", data={
|
||||
"password": "adminpass",
|
||||
}, follow_redirects=True)
|
||||
assert resp.status_code == 200
|
||||
assert b"have been deleted" in resp.data
|
||||
|
||||
def test_admin_delete_household_wrong_password(self, admin_client):
|
||||
resp = admin_client.post("/admin/delete-household", data={
|
||||
"password": "wrong",
|
||||
}, follow_redirects=True)
|
||||
assert b"Incorrect password" in resp.data
|
||||
|
||||
def test_non_admin_cannot_delete_household(self, auth_client):
|
||||
resp = auth_client.post("/admin/delete-household", data={
|
||||
"password": "bobpass",
|
||||
}, follow_redirects=True)
|
||||
assert b"Only admins" in resp.data
|
||||
|
||||
|
||||
class TestDashboardOtherUsersGrayedOut:
|
||||
def test_other_users_buttons_are_disabled(self, auth_client):
|
||||
"""Bob sees alice's status as badges, not clickable buttons."""
|
||||
# Bob responds first so we can see his buttons
|
||||
auth_client.post("/respond", data={
|
||||
"meal_type": "lunch", "status": "yes",
|
||||
}, follow_redirects=True)
|
||||
resp = auth_client.get("/dashboard")
|
||||
# Alice's status should show as a badge (not a form button)
|
||||
assert b"badge-yes" in resp.data or b"badge-not_answered" in resp.data
|
||||
|
||||
Reference in New Issue
Block a user