A related list's cursor cost nothing, and a cursor is a free string: a replayed one read and enriched without end. Every request now takes a slot of the user's daily cap — taken under a lock before the work (`quota.claim_action`), so requests sent together cannot all pass the last free one, and given back when the request fails outright (`quota.refund_action`). The live search's scrape source takes its slots the same way. A limit of 0 turns the feature off: a distinct 409 `related_disabled` / `search_disabled`, and `/api/me` says `related_enabled` / `search_enabled` so the UI can leave it out. A videos.list that fails no longer reads as an empty page: `ingest_candidates` raises, and the search and the related list answer the refusal (the shared budget spent says "quota") instead of "no results". The two routes' page loops are one (`_gather`). `clear` deletes only what the caller found: a related list's rows carry no find, and any user could name them.
49 lines
1.8 KiB
Python
49 lines
1.8 KiB
Python
"""`/api/me` names the live-search source, so the search button's tooltip can say what a search costs
|
|
under the source that actually runs (the default website source spends no API quota), and says
|
|
whether live search and related videos are on at all."""
|
|
|
|
from app import sysconfig
|
|
|
|
_PW = "correct horse battery"
|
|
|
|
|
|
def _me(client):
|
|
r = client.get("/api/me")
|
|
assert r.status_code == 200 and r.json()["authenticated"] is True
|
|
return r.json()
|
|
|
|
|
|
def test_me_names_the_running_search_source(client, db, make_user):
|
|
# /api/me resolves its user through optional_current_user, which the as_user override does not
|
|
# cover — so sign in for real (see test_me_email_flag).
|
|
user = make_user(password=_PW)
|
|
login = client.post("/auth/password-login", json={"email": user.email, "password": _PW})
|
|
assert login.status_code == 200
|
|
|
|
assert _me(client)["search_source"] == "scrape" # the default
|
|
|
|
sysconfig.set_value(db, "search_source", "api")
|
|
db.commit()
|
|
assert _me(client)["search_source"] == "api"
|
|
|
|
|
|
def test_me_says_whether_live_search_and_related_videos_are_on(client, db, make_user):
|
|
# A daily limit of 0 turns the feature off; the UI leaves it out instead of offering a refusal.
|
|
user = make_user(password=_PW)
|
|
login = client.post("/auth/password-login", json={"email": user.email, "password": _PW})
|
|
assert login.status_code == 200
|
|
|
|
me = _me(client)
|
|
assert (me["search_enabled"], me["related_enabled"]) == (True, True)
|
|
|
|
sysconfig.set_value(db, "search_daily_limit_per_user", 0)
|
|
db.commit()
|
|
me = _me(client)
|
|
assert (me["search_enabled"], me["related_enabled"]) == (False, True)
|
|
|
|
sysconfig.set_value(db, "search_daily_limit_per_user", 5)
|
|
sysconfig.set_value(db, "related_daily_limit_per_user", 0)
|
|
db.commit()
|
|
me = _me(client)
|
|
assert (me["search_enabled"], me["related_enabled"]) == (True, False)
|