Add household support: multi-household isolation, each with own admin and users, 38 tests
This commit is contained in:
+96
-7
@@ -5,24 +5,31 @@ def test_register_page(client):
|
||||
resp = client.get("/register")
|
||||
assert resp.status_code == 200
|
||||
assert b"Create Account" in resp.data
|
||||
assert b"Household" in resp.data
|
||||
|
||||
|
||||
def test_register_success(client):
|
||||
def test_register_create_household(client):
|
||||
"""Registering with 'create household' should succeed and make admin."""
|
||||
resp = client.post("/register", data={
|
||||
"username": "testuser",
|
||||
"password": "secret123",
|
||||
"confirm": "secret123",
|
||||
"household_action": "create",
|
||||
"new_household_name": "My House",
|
||||
}, follow_redirects=True)
|
||||
assert resp.status_code == 200
|
||||
assert b"Account created" in resp.data
|
||||
assert b"My House" in resp.data # Shows in nav
|
||||
|
||||
|
||||
def test_register_first_user_is_admin(client):
|
||||
"""First registered user should be admin."""
|
||||
def test_register_first_in_household_is_admin(client):
|
||||
"""First user in a new household should be admin."""
|
||||
client.post("/register", data={
|
||||
"username": "firstuser",
|
||||
"password": "secret123",
|
||||
"confirm": "secret123",
|
||||
"household_action": "create",
|
||||
"new_household_name": "First House",
|
||||
})
|
||||
from models import get_user_by_username
|
||||
user = get_user_by_username("firstuser")
|
||||
@@ -30,17 +37,91 @@ def test_register_first_user_is_admin(client):
|
||||
assert user["is_admin"] == 1
|
||||
|
||||
|
||||
def test_register_join_household_not_admin(client):
|
||||
"""Joining an existing household makes you a non-admin."""
|
||||
# First user creates household
|
||||
client.post("/register", data={
|
||||
"username": "creator",
|
||||
"password": "secret123",
|
||||
"confirm": "secret123",
|
||||
"household_action": "create",
|
||||
"new_household_name": "Shared Home",
|
||||
})
|
||||
client.get("/logout")
|
||||
# Second user joins
|
||||
client.post("/register", data={
|
||||
"username": "joiner",
|
||||
"password": "pass4321",
|
||||
"confirm": "pass4321",
|
||||
"household_action": "join",
|
||||
"household_id": "1",
|
||||
})
|
||||
from models import get_user_by_username
|
||||
joiner = get_user_by_username("joiner")
|
||||
assert joiner is not None
|
||||
assert joiner["is_admin"] == 0
|
||||
assert joiner["household_id"] == 1
|
||||
|
||||
|
||||
def test_register_create_duplicate_household_name(client):
|
||||
"""Creating a household with an existing name should fail."""
|
||||
client.post("/register", data={
|
||||
"username": "u1",
|
||||
"password": "pass1234",
|
||||
"confirm": "pass1234",
|
||||
"household_action": "create",
|
||||
"new_household_name": "DupHouse",
|
||||
})
|
||||
client.get("/logout")
|
||||
resp = client.post("/register", data={
|
||||
"username": "u2",
|
||||
"password": "pass5678",
|
||||
"confirm": "pass5678",
|
||||
"household_action": "create",
|
||||
"new_household_name": "DupHouse",
|
||||
}, follow_redirects=True)
|
||||
assert b"already exists" in resp.data
|
||||
|
||||
|
||||
def test_register_missing_household_name(client):
|
||||
"""Creating a household without a name should fail."""
|
||||
resp = client.post("/register", data={
|
||||
"username": "u3",
|
||||
"password": "pass1234",
|
||||
"confirm": "pass1234",
|
||||
"household_action": "create",
|
||||
"new_household_name": "",
|
||||
}, follow_redirects=True)
|
||||
assert b"Household name is required" in resp.data
|
||||
|
||||
|
||||
def test_register_no_household_selected(client):
|
||||
"""Joining without selecting a household should fail."""
|
||||
resp = client.post("/register", data={
|
||||
"username": "u4",
|
||||
"password": "pass1234",
|
||||
"confirm": "pass1234",
|
||||
"household_action": "join",
|
||||
"household_id": "",
|
||||
}, follow_redirects=True)
|
||||
assert b"Please select a household" in resp.data
|
||||
|
||||
|
||||
def test_register_duplicate_username(client):
|
||||
client.post("/register", data={
|
||||
"username": "dup",
|
||||
"password": "pass1234",
|
||||
"confirm": "pass1234",
|
||||
"household_action": "create",
|
||||
"new_household_name": "DupHouse",
|
||||
})
|
||||
client.get("/logout")
|
||||
resp = client.post("/register", data={
|
||||
"username": "dup",
|
||||
"password": "other5678",
|
||||
"confirm": "other5678",
|
||||
"household_action": "create",
|
||||
"new_household_name": "OtherHouse",
|
||||
}, follow_redirects=True)
|
||||
assert b"Username already taken" in resp.data
|
||||
|
||||
@@ -50,6 +131,8 @@ def test_register_password_mismatch(client):
|
||||
"username": "someone",
|
||||
"password": "abc12345",
|
||||
"confirm": "abc12346",
|
||||
"household_action": "create",
|
||||
"new_household_name": "AnyHouse",
|
||||
}, follow_redirects=True)
|
||||
assert b"Passwords do not match" in resp.data
|
||||
|
||||
@@ -59,6 +142,8 @@ def test_register_short_username(client):
|
||||
"username": "x",
|
||||
"password": "pass1234",
|
||||
"confirm": "pass1234",
|
||||
"household_action": "create",
|
||||
"new_household_name": "AnyHouse",
|
||||
}, follow_redirects=True)
|
||||
assert b"at least 2 characters" in resp.data
|
||||
|
||||
@@ -68,6 +153,8 @@ def test_register_short_password(client):
|
||||
"username": "validname",
|
||||
"password": "ab",
|
||||
"confirm": "ab",
|
||||
"household_action": "create",
|
||||
"new_household_name": "AnyHouse",
|
||||
}, follow_redirects=True)
|
||||
assert b"at least 4 characters" in resp.data
|
||||
|
||||
@@ -79,20 +166,20 @@ def test_login_page(client):
|
||||
|
||||
|
||||
def test_login_success(client):
|
||||
# Register first
|
||||
client.post("/register", data={
|
||||
"username": "logintest",
|
||||
"password": "mypassword",
|
||||
"confirm": "mypassword",
|
||||
"household_action": "create",
|
||||
"new_household_name": "LoginHouse",
|
||||
})
|
||||
client.get("/logout")
|
||||
# Then login
|
||||
resp = client.post("/login", data={
|
||||
"username": "logintest",
|
||||
"password": "mypassword",
|
||||
}, follow_redirects=True)
|
||||
assert resp.status_code == 200
|
||||
assert b"Today" in resp.data # Dashboard
|
||||
assert b"Today" in resp.data
|
||||
|
||||
|
||||
def test_login_wrong_password(client):
|
||||
@@ -100,6 +187,8 @@ def test_login_wrong_password(client):
|
||||
"username": "logintest2",
|
||||
"password": "mypassword",
|
||||
"confirm": "mypassword",
|
||||
"household_action": "create",
|
||||
"new_household_name": "LoginHouse2",
|
||||
})
|
||||
client.get("/logout")
|
||||
resp = client.post("/login", data={
|
||||
@@ -120,7 +209,7 @@ def test_login_nonexistent_user(client):
|
||||
def test_logout(auth_client):
|
||||
resp = auth_client.get("/logout", follow_redirects=True)
|
||||
assert resp.status_code == 200
|
||||
assert b"Log In" in resp.data # Redirected to login
|
||||
assert b"Log In" in resp.data
|
||||
|
||||
|
||||
def test_unauthenticated_redirect(client):
|
||||
|
||||
Reference in New Issue
Block a user