fix: restore polished account experience and align AI with Lark design
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user