fix: restore polished account experience and align AI with Lark design

This commit is contained in:
yuxuanhui
2026-09-07 23:31:23 +08:00
parent 3f3d417296
commit 7dcf46836f
23 changed files with 1669 additions and 807 deletions
+46 -2
View File
@@ -83,13 +83,57 @@ def create_test_app():
path = request.url.path
if path == "/authentication" and request.method == "POST":
return httpx.Response(
201, json={"user": {"id": "TEST_USER"}}, headers={"Set-Cookie": "mock=only; Path=/"}
201,
json={
"user": {"id": "TEST_USER"},
"token": {"expiry": 14400},
"permissions": [
"CONSULTANT",
"SUPER_ALPHA",
"MULTI_SIMULATION",
"PROD_ALPHAS",
"BRAIN_LABS",
"BRAIN_LABS_JUPYTER_LAB",
"REFERRAL",
"VISUALIZATION",
"WORKDAY",
"BEFORE_AND_AFTER_PERFORMANCE_V2",
],
},
headers={"Set-Cookie": "mock=only; Path=/"},
)
if request.method != "GET":
raise AssertionError("Browser acceptance attempted an upstream mutation")
if path == "/users/self":
return httpx.Response(
200, json={"id": "TEST_USER", "name": "模拟研究员", "email": "test@example.com"}
200,
json={
"id": "TEST_USER",
"fullName": "模拟研究员",
"email": "test@example.com",
"level": "CONSULTANT",
"geniusLevel": "GOLD",
"verified": True,
"approved": True,
"dateCreated": "2025-01-01T00:00:00Z",
},
)
if path == "/users/self/alphas/summary":
return httpx.Response(200, json={"unsubmitted": 413, "active": 207, "decommissioned": 0})
if path in ("/users/self/activities/simulations", "/users/self/activities/submissions"):
from zoneinfo import ZoneInfo
today = datetime.now(ZoneInfo("America/New_York")).date()
return httpx.Response(
200,
json={
"yesterday": {"end": (today - timedelta(days=1)).isoformat(), "value": 2},
"total": {"value": 207},
"records": {
"schema": {"properties": [{"name": "date"}, {"name": "value"}]},
"records": [[today.isoformat(), 3]],
},
},
)
if path == "/users/self/alphas":
unsubmitted = "status" in request.url.params
+4
View File
@@ -19,6 +19,7 @@ class FakePlatform:
self.fail_id = True
self.require_verification = False
self.block = None
self.permissions = ["CONSULTANT", "SUPER_ALPHA"]
async def authenticate(self, *args, **kwargs):
if self.require_verification:
@@ -32,6 +33,9 @@ class FakePlatform:
async def profile(self):
return {"id": "user1", "email": "test@example.com", "password": "never-save", "unknown": 1}
async def account_usage(self):
return {"date": "2026-09-07", "alphas": {"active": 99}, "errors": {}}
async def alphas(self, submission, hidden, offset, before):
self.page_calls.append((submission, hidden, offset, before))
if self.block:
+81
View File
@@ -35,6 +35,87 @@ async def test_cookie_auth_expiry_and_read_only_boundary(settings):
await client.close()
async def test_auth_metadata_usage_and_local_simulation_allowance(settings):
from datetime import datetime
from zoneinfo import ZoneInfo
today = datetime.now(ZoneInfo("America/New_York")).date().isoformat()
calls = []
def handler(request):
calls.append((request.method, request.url.path))
if request.url.path == "/authentication":
return httpx.Response(
201,
json={
"permissions": ["CONSULTANT", "SUPER_ALPHA", "CONSULTANT"],
"token": {"expiry": 14400, "value": "private-token"},
"password": "private-password",
},
)
if request.url.path.endswith("/simulations"):
return httpx.Response(
200,
json={
"records": {
"schema": {"properties": [{"name": "value"}, {"name": "date"}]},
"records": [[0, today]],
},
"yesterday": {"value": 40},
"total": {"value": 900},
},
)
if request.url.path.endswith("/submissions"):
return httpx.Response(403)
assert request.headers["Accept"] == "application/json;version=4.0"
return httpx.Response(200, json={"active": 99, "unsubmitted": 100, "decommissioned": 0})
client = WqClient(settings, transport=httpx.MockTransport(handler))
await client.authenticate("test@example.com", "secret")
assert client.permissions == ["CONSULTANT", "SUPER_ALPHA"]
info = client.session_info()
assert info["authenticated"] and 14395 < info["remaining_seconds"] <= 14400
assert "private" not in str(info)
usage = await client.account_usage()
assert usage["simulations"]["today"] == 0
assert usage["simulations"]["limit"] == 10_000 and usage["simulations"]["remaining"] == 10_000
assert usage["alphas"]["active"] == 99
assert "submissions" in usage["errors"] and "submissions" not in usage
assert all(method == "GET" or path == "/authentication" for method, path in calls)
client.disconnect()
assert client.permissions is None and client.session_info()["remaining_seconds"] is None
assert not client.session_info()["authenticated"]
await client.close()
def test_activity_missing_today_is_unknown_not_zero():
from app.account_data import daily_activity
data = {
"records": {
"schema": {"properties": [{"name": "date"}, {"name": "value"}]},
"records": [["2026-09-06", 2]],
}
}
assert daily_activity(data, "2026-09-07")["today"] is None
assert daily_activity({}, "2026-09-07")["limit"] is None
local_budget = daily_activity(data, "2026-09-07", daily_limit=10_000)
assert local_budget["limit"] == 10_000 and local_budget["remaining"] is None
@pytest.mark.parametrize(
"recordset", [None, {"records": None}, {"schema": None}, {"schema": {"properties": None}}]
)
def test_malformed_optional_activity_does_not_discard_other_sections(recordset):
from app.account_data import usage_snapshot
result = usage_snapshot(
{"simulations": {"records": recordset}, "submissions": {}, "alphas": {"active": 99}}, {}
)
assert "simulations" in result["errors"] and "simulations" not in result
assert result["submissions"]["today"] is None and result["alphas"]["active"] == 99
async def test_persona_verification_uses_same_cookie_and_safe_location(settings):
complete = False