- pyproject.toml: add [tool.ruff] config suppressing E402/W293 globally, F841/E741/E702 in tests, E741 in scripts - inventory.py: split semicolon import (E702) - recipes.py: fix logger -> log (F821 undefined name) - shopping.py: rename l -> lnk in list comprehension (E741) - format_conversion.py: noqa F841 on CUDA flag (used as future hook) - backfill_keywords.py: rename done -> _done (F841) - ingest_purplecarrot.py: drop == True comparison (E712) - Auto-fix: I001 import sorting, F401 unused imports across all files
116 lines
3.6 KiB
Python
116 lines
3.6 KiB
Python
"""Tests for household session resolution in cloud_session.py."""
|
|
import os
|
|
from pathlib import Path
|
|
|
|
from fastapi.testclient import TestClient
|
|
|
|
os.environ.setdefault("CLOUD_MODE", "false")
|
|
|
|
import app.cloud_session as cs
|
|
from app.cloud_session import (
|
|
CloudUser,
|
|
)
|
|
|
|
|
|
def test_clouduser_has_household_fields():
|
|
u = CloudUser(
|
|
user_id="u1", tier="premium", db=Path("/tmp/u1.db"),
|
|
has_byok=False, household_id="hh-1", is_household_owner=True
|
|
)
|
|
assert u.household_id == "hh-1"
|
|
assert u.is_household_owner is True
|
|
|
|
|
|
def test_clouduser_household_defaults_none():
|
|
u = CloudUser(user_id="u1", tier="free", db=Path("/tmp/u1.db"), has_byok=False)
|
|
assert u.household_id is None
|
|
assert u.is_household_owner is False
|
|
|
|
|
|
def test_user_db_path_personal(tmp_path, monkeypatch):
|
|
monkeypatch.setattr(cs, "CLOUD_DATA_ROOT", tmp_path)
|
|
result = cs._user_db_path("abc123")
|
|
assert result == tmp_path / "abc123" / "kiwi.db"
|
|
|
|
|
|
def test_user_db_path_household(tmp_path, monkeypatch):
|
|
monkeypatch.setattr(cs, "CLOUD_DATA_ROOT", tmp_path)
|
|
result = cs._user_db_path("abc123", household_id="hh-xyz")
|
|
assert result == tmp_path / "household_hh-xyz" / "kiwi.db"
|
|
|
|
|
|
# ── Integration tests (require router) ─────────────────────────────────
|
|
|
|
def test_create_household_requires_premium():
|
|
"""Non-premium users cannot create a household."""
|
|
import pathlib
|
|
import tempfile
|
|
|
|
from app.cloud_session import get_session
|
|
from app.main import app
|
|
|
|
db = pathlib.Path(tempfile.mktemp(suffix=".db"))
|
|
from app.db.store import Store
|
|
Store(str(db))
|
|
|
|
free_user = CloudUser(user_id="u1", tier="free", db=db, has_byok=False)
|
|
app.dependency_overrides[get_session] = lambda: free_user
|
|
client = TestClient(app)
|
|
resp = client.post("/api/v1/household/create")
|
|
assert resp.status_code == 403
|
|
app.dependency_overrides.clear()
|
|
|
|
|
|
def test_invite_generates_token():
|
|
"""Invite endpoint returns a token and URL for owner in a household."""
|
|
import pathlib
|
|
import tempfile
|
|
|
|
from app.cloud_session import get_session
|
|
from app.main import app
|
|
|
|
db = pathlib.Path(tempfile.mktemp(suffix=".db"))
|
|
from app.db.store import Store
|
|
Store(str(db))
|
|
|
|
session = CloudUser(
|
|
user_id="owner-1", tier="premium", db=db,
|
|
has_byok=False, household_id="hh-test", is_household_owner=True
|
|
)
|
|
app.dependency_overrides[get_session] = lambda: session
|
|
client = TestClient(app)
|
|
resp = client.post("/api/v1/household/invite")
|
|
assert resp.status_code == 200
|
|
data = resp.json()
|
|
assert "token" in data
|
|
assert "invite_url" in data
|
|
assert len(data["token"]) == 64 # 32 bytes hex
|
|
app.dependency_overrides.clear()
|
|
|
|
|
|
def test_accept_invalid_token_returns_404(tmp_path, monkeypatch):
|
|
"""Accepting a non-existent token returns 404."""
|
|
import app.api.endpoints.household as hh_ep
|
|
import app.cloud_session as cs
|
|
monkeypatch.setattr(hh_ep, "CLOUD_DATA_ROOT", tmp_path)
|
|
monkeypatch.setattr(cs, "CLOUD_DATA_ROOT", tmp_path)
|
|
|
|
import pathlib
|
|
import tempfile
|
|
|
|
from app.cloud_session import get_session
|
|
from app.main import app
|
|
|
|
db = pathlib.Path(tempfile.mktemp(suffix=".db"))
|
|
from app.db.store import Store
|
|
Store(str(db))
|
|
|
|
session = CloudUser(user_id="new-user", tier="free", db=db, has_byok=False)
|
|
app.dependency_overrides[get_session] = lambda: session
|
|
client = TestClient(app)
|
|
resp = client.post("/api/v1/household/accept", json={
|
|
"household_id": "hh-test",
|
|
"token": "deadbeef" * 8,
|
|
})
|
|
assert resp.status_code == 404
|
|
app.dependency_overrides.clear()
|