feat: the artist picker on Patreon and SubscribeStar too — and the Patreon name is canon (milestone 429)
CI and images / lint (push) Successful in 3s
CI and images / extension-version (push) Successful in 3s
CI and images / extension-test (push) Successful in 19s
CI and images / frontend-build (push) Successful in 25s
CI and images / backend-lint-and-test (push) Successful in 33s
CI and images / integration (push) Successful in 2m22s
CI and images / build-agent (push) Successful in 6s
CI and images / sign-extension (push) Successful in 4m48s
CI and images / build-web (push) Failing after 6s
CI and images / smoke-web (push) Skipped
CI and images / promote (push) Skipped
CI and images / lint (push) Successful in 3s
CI and images / extension-version (push) Successful in 3s
CI and images / extension-test (push) Successful in 19s
CI and images / frontend-build (push) Successful in 25s
CI and images / backend-lint-and-test (push) Successful in 33s
CI and images / integration (push) Successful in 2m22s
CI and images / build-agent (push) Successful in 6s
CI and images / sign-extension (push) Successful in 4m48s
CI and images / build-web (push) Failing after 6s
CI and images / smoke-web (push) Skipped
CI and images / promote (push) Skipped
Operator: "yes add the artist picker to patreon and subscribestar too. but generally we treat the patreon name as the canon" - Every add now goes through the panel. On Patreon/SubscribeStar it opens on the creator's display name (read only when the panel opens: probe?names=1), searches FC's artists with it, and auto-picks a match. An untouched URL handle sends no name, so the server still resolves it. - Patreon is canon: joining a Patreon source to an artist known by another name offers "Rename “x” to the Patreon name “X”", ticked by default. quick-add's use_platform_name renames server-side from the name it reads itself; name only, the slug never moves (#130); never to a URL handle when the name can't be read; ignored on SubscribeStar and Discord. - _platform_display_name returns None rather than the handle, bounded by the same 6s lookup budget as Discord's names. - panelDefaults / addRequest / renameOffer replace the Discord-only helpers. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LVjrnpQjRgHdvq95rASoiR
This commit is contained in:
@@ -526,6 +526,121 @@ async def test_probe_a_discord_dm_is_not_a_source(client, ext_key):
|
||||
assert body["state"] == "unknown_platform"
|
||||
|
||||
|
||||
# --- Patreon is canon: the Add panel's names and the rename (milestone 429) ---
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def platform_names(monkeypatch):
|
||||
"""Stub both platforms' display-name lookups (no network in tests)."""
|
||||
from backend.app.services import patreon_resolver
|
||||
from backend.app.services.credential_service import CredentialService
|
||||
from backend.app.services.subscribestar_client import SubscribeStarClient
|
||||
|
||||
async def _cookies(self, platform):
|
||||
return "/tmp/cookies.txt"
|
||||
|
||||
names = {"patreon": "Tamada Heijun", "subscribestar": "SS Tamada"}
|
||||
monkeypatch.setattr(CredentialService, "get_cookies_path", _cookies)
|
||||
monkeypatch.setattr(
|
||||
patreon_resolver, "resolve_display_name", lambda v, c: names["patreon"],
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
SubscribeStarClient, "resolve_display_name", lambda self, u: names["subscribestar"],
|
||||
)
|
||||
return names
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_probe_with_names_reads_the_patreon_display_name(client, ext_key, platform_names):
|
||||
resp = await client.get(
|
||||
"/api/extension/probe",
|
||||
query_string={"url": "https://www.patreon.com/tamadaheijun", "names": "1"},
|
||||
headers={"X-Extension-Key": ext_key},
|
||||
)
|
||||
body = await resp.get_json()
|
||||
assert body["state"] == "new"
|
||||
assert body["display_name"] == "Tamada Heijun"
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_a_plain_probe_does_not_look_the_name_up(client, ext_key, platform_names):
|
||||
resp = await client.get(
|
||||
"/api/extension/probe",
|
||||
query_string={"url": "https://www.patreon.com/tamadaheijun"},
|
||||
headers={"X-Extension-Key": ext_key},
|
||||
)
|
||||
assert "display_name" not in await resp.get_json()
|
||||
|
||||
|
||||
async def _artist(db, name, slug):
|
||||
artist = Artist(name=name, slug=slug, is_subscription=True)
|
||||
db.add(artist)
|
||||
await db.commit()
|
||||
return artist
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_a_patreon_source_renames_the_artist_it_joins_to_the_patreon_name(
|
||||
client, ext_key, db, db_sync, platform_names,
|
||||
):
|
||||
artist = await _artist(db, "tamada", "tamada")
|
||||
resp = await client.post(
|
||||
"/api/extension/quick-add-source",
|
||||
json={"url": "https://www.patreon.com/tamadaheijun",
|
||||
"artist_id": artist.id, "use_platform_name": True},
|
||||
headers={"X-Extension-Key": ext_key},
|
||||
)
|
||||
assert resp.status_code == 201
|
||||
body = await resp.get_json()
|
||||
assert body["artist"]["name"] == "Tamada Heijun"
|
||||
assert body["renamed_from"] == "tamada"
|
||||
# Name only: the slug, and every path keyed off it, stays.
|
||||
row = db_sync.execute(select(Artist.name, Artist.slug).where(Artist.id == artist.id)).one()
|
||||
assert tuple(row) == ("Tamada Heijun", "tamada")
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_no_rename_without_the_flag(client, ext_key, db, platform_names):
|
||||
artist = await _artist(db, "tamada", "tamada")
|
||||
body = await (await client.post(
|
||||
"/api/extension/quick-add-source",
|
||||
json={"url": "https://www.patreon.com/tamadaheijun", "artist_id": artist.id},
|
||||
headers={"X-Extension-Key": ext_key},
|
||||
)).get_json()
|
||||
assert body["artist"]["name"] == "tamada"
|
||||
assert "renamed_from" not in body
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_an_unreadable_patreon_name_never_renames_to_the_handle(
|
||||
client, ext_key, db, platform_names,
|
||||
):
|
||||
platform_names["patreon"] = None
|
||||
artist = await _artist(db, "Tamada", "tamada")
|
||||
body = await (await client.post(
|
||||
"/api/extension/quick-add-source",
|
||||
json={"url": "https://www.patreon.com/tamadaheijun",
|
||||
"artist_id": artist.id, "use_platform_name": True},
|
||||
headers={"X-Extension-Key": ext_key},
|
||||
)).get_json()
|
||||
assert body["artist"]["name"] == "Tamada"
|
||||
assert "renamed_from" not in body
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_only_patreon_names_are_canon(client, ext_key, db, platform_names):
|
||||
"""A SubscribeStar source joins the picked artist under the name it has."""
|
||||
artist = await _artist(db, "Tamada Heijun", "tamada-heijun")
|
||||
body = await (await client.post(
|
||||
"/api/extension/quick-add-source",
|
||||
json={"url": "https://subscribestar.adult/tamada",
|
||||
"artist_id": artist.id, "use_platform_name": True},
|
||||
headers={"X-Extension-Key": ext_key},
|
||||
)).get_json()
|
||||
assert body["artist"]["name"] == "Tamada Heijun"
|
||||
assert "renamed_from" not in body
|
||||
|
||||
|
||||
# --- /api/extension/manifest ---------------------------------------
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user