Add 13 new Fandom wiki sources and integration tests
Expand franchise wiki mappings to cover Uma Musume, Fire Emblem, Senran Kagura, Vocaloid, Dragon Ball, League of Legends, Street Fighter, Sonic, Spy x Family, Zelda, The Witcher, Metroid, and Pokemon. Also expand Final Fantasy aliases to cover all numbered titles I–XVI with both arabic and roman numeral variants. Adds parametrized integration tests that verify each wiki endpoint returns valid CharacterData with a description and Fandom source URL. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
13
README.md
13
README.md
@@ -122,3 +122,16 @@ character_details/
|
|||||||
- Aerith Gainsborough — Final Fantasy VII
|
- Aerith Gainsborough — Final Fantasy VII
|
||||||
- Princess Peach — Super Mario
|
- Princess Peach — Super Mario
|
||||||
- Sucy Manbavaran — Little Witch Academia
|
- Sucy Manbavaran — Little Witch Academia
|
||||||
|
- Tokai Teio — Uma Musume
|
||||||
|
- Marth — Fire Emblem
|
||||||
|
- Asuka — Senran Kagura
|
||||||
|
- Hatsune Miku — Vocaloid
|
||||||
|
- Goku — Dragon Ball
|
||||||
|
- Jinx — League of Legends
|
||||||
|
- Ryu — Street Fighter
|
||||||
|
- Sonic — Sonic the Hedgehog
|
||||||
|
- Anya Forger — Spy x Family
|
||||||
|
- Link — The Legend of Zelda
|
||||||
|
- Geralt of Rivia — The Witcher
|
||||||
|
- Samus Aran — Metroid
|
||||||
|
- Pikachu — Pokemon
|
||||||
@@ -154,12 +154,24 @@ Produces a structured reference document for roleplay or creative writing. Inclu
|
|||||||
|
|
||||||
The following franchises have a dedicated Fandom wiki mapped for richer data:
|
The following franchises have a dedicated Fandom wiki mapped for richer data:
|
||||||
|
|
||||||
| Franchise | Wiki |
|
| Franchise | Wiki | Aliases |
|
||||||
|---|---|
|
|---|---|---|
|
||||||
| Final Fantasy VII / FF7 / FFVII | finalfantasy.fandom.com |
|
| Final Fantasy (I–XVI) | finalfantasy.fandom.com | final fantasy 1–16, ffi–ffxvi, ff1–ff16 |
|
||||||
| Final Fantasy | finalfantasy.fandom.com |
|
| Super Mario | mario.fandom.com | mario, super mario |
|
||||||
| Super Mario / Mario | mario.fandom.com |
|
| Little Witch Academia | little-witch-academia.fandom.com | lwa |
|
||||||
| Little Witch Academia / LWA | little-witch-academia.fandom.com |
|
| Uma Musume | umamusume.fandom.com | uma musume pretty derby |
|
||||||
|
| Fire Emblem | fireemblem.fandom.com | |
|
||||||
|
| Senran Kagura | senrankagura.fandom.com | |
|
||||||
|
| Vocaloid | vocaloid.fandom.com | |
|
||||||
|
| Dragon Ball | dragonball.fandom.com | dragon ball z, dbz, dragon ball super, dbs |
|
||||||
|
| League of Legends | leagueoflegends.fandom.com | lol |
|
||||||
|
| Street Fighter | streetfighter.fandom.com | |
|
||||||
|
| Sonic | sonic.fandom.com | sonic the hedgehog |
|
||||||
|
| Spy x Family | spy-x-family.fandom.com | spy family, spyxfamily |
|
||||||
|
| The Legend of Zelda | zelda.fandom.com | zelda, legend of zelda |
|
||||||
|
| The Witcher | witcher.fandom.com | witcher |
|
||||||
|
| Metroid | metroid.fandom.com | |
|
||||||
|
| Pokemon | pokemon.fandom.com | pokémon |
|
||||||
|
|
||||||
Characters from other franchises will still work using Wikipedia as the data source. The data will be less detailed but usable.
|
Characters from other franchises will still work using Wikipedia as the data source. The data will be less detailed but usable.
|
||||||
|
|
||||||
|
|||||||
@@ -25,15 +25,102 @@ HEADERS = {
|
|||||||
|
|
||||||
# Map franchise keywords -> Fandom community subdomain
|
# Map franchise keywords -> Fandom community subdomain
|
||||||
FRANCHISE_WIKIS: dict[str, str] = {
|
FRANCHISE_WIKIS: dict[str, str] = {
|
||||||
|
"final fantasy": "finalfantasy",
|
||||||
|
"final fantasy i": "finalfantasy",
|
||||||
|
"final fantasy 1": "finalfantasy",
|
||||||
|
"ffi": "finalfantasy",
|
||||||
|
"ff1": "finalfantasy",
|
||||||
|
"final fantasy ii": "finalfantasy",
|
||||||
|
"final fantasy 2": "finalfantasy",
|
||||||
|
"ffii": "finalfantasy",
|
||||||
|
"ff2": "finalfantasy",
|
||||||
|
"final fantasy iii": "finalfantasy",
|
||||||
|
"final fantasy 3": "finalfantasy",
|
||||||
|
"ffiii": "finalfantasy",
|
||||||
|
"ff3": "finalfantasy",
|
||||||
|
"final fantasy iv": "finalfantasy",
|
||||||
|
"final fantasy 4": "finalfantasy",
|
||||||
|
"ffiv": "finalfantasy",
|
||||||
|
"ff4": "finalfantasy",
|
||||||
|
"final fantasy v": "finalfantasy",
|
||||||
|
"final fantasy 5": "finalfantasy",
|
||||||
|
"ffv": "finalfantasy",
|
||||||
|
"ff5": "finalfantasy",
|
||||||
|
"final fantasy vi": "finalfantasy",
|
||||||
|
"final fantasy 6": "finalfantasy",
|
||||||
|
"ffvi": "finalfantasy",
|
||||||
|
"ff6": "finalfantasy",
|
||||||
"final fantasy vii": "finalfantasy",
|
"final fantasy vii": "finalfantasy",
|
||||||
"final fantasy 7": "finalfantasy",
|
"final fantasy 7": "finalfantasy",
|
||||||
"ff7": "finalfantasy",
|
|
||||||
"ffvii": "finalfantasy",
|
"ffvii": "finalfantasy",
|
||||||
"final fantasy": "finalfantasy",
|
"ff7": "finalfantasy",
|
||||||
|
"final fantasy viii": "finalfantasy",
|
||||||
|
"final fantasy 8": "finalfantasy",
|
||||||
|
"ffviii": "finalfantasy",
|
||||||
|
"ff8": "finalfantasy",
|
||||||
|
"final fantasy ix": "finalfantasy",
|
||||||
|
"final fantasy 9": "finalfantasy",
|
||||||
|
"ffix": "finalfantasy",
|
||||||
|
"ff9": "finalfantasy",
|
||||||
|
"final fantasy x": "finalfantasy",
|
||||||
|
"final fantasy 10": "finalfantasy",
|
||||||
|
"ffx": "finalfantasy",
|
||||||
|
"ff10": "finalfantasy",
|
||||||
|
"final fantasy xi": "finalfantasy",
|
||||||
|
"final fantasy 11": "finalfantasy",
|
||||||
|
"ffxi": "finalfantasy",
|
||||||
|
"ff11": "finalfantasy",
|
||||||
|
"final fantasy xii": "finalfantasy",
|
||||||
|
"final fantasy 12": "finalfantasy",
|
||||||
|
"ffxii": "finalfantasy",
|
||||||
|
"ff12": "finalfantasy",
|
||||||
|
"final fantasy xiii": "finalfantasy",
|
||||||
|
"final fantasy 13": "finalfantasy",
|
||||||
|
"ffxiii": "finalfantasy",
|
||||||
|
"ff13": "finalfantasy",
|
||||||
|
"final fantasy xiv": "finalfantasy",
|
||||||
|
"final fantasy 14": "finalfantasy",
|
||||||
|
"ffxiv": "finalfantasy",
|
||||||
|
"ff14": "finalfantasy",
|
||||||
|
"final fantasy xv": "finalfantasy",
|
||||||
|
"final fantasy 15": "finalfantasy",
|
||||||
|
"ffxv": "finalfantasy",
|
||||||
|
"ff15": "finalfantasy",
|
||||||
|
"final fantasy xvi": "finalfantasy",
|
||||||
|
"final fantasy 16": "finalfantasy",
|
||||||
|
"ffxvi": "finalfantasy",
|
||||||
|
"ff16": "finalfantasy",
|
||||||
"super mario": "mario",
|
"super mario": "mario",
|
||||||
"mario": "mario",
|
"mario": "mario",
|
||||||
"little witch academia": "little-witch-academia",
|
"little witch academia": "little-witch-academia",
|
||||||
"lwa": "little-witch-academia",
|
"lwa": "little-witch-academia",
|
||||||
|
"uma musume": "umamusume",
|
||||||
|
"umamusume": "umamusume",
|
||||||
|
"uma musume pretty derby": "umamusume",
|
||||||
|
"fire emblem": "fireemblem",
|
||||||
|
"senran kagura": "senrankagura",
|
||||||
|
"vocaloid": "vocaloid",
|
||||||
|
"dragon ball": "dragonball",
|
||||||
|
"dragon ball z": "dragonball",
|
||||||
|
"dbz": "dragonball",
|
||||||
|
"dragon ball super": "dragonball",
|
||||||
|
"dbs": "dragonball",
|
||||||
|
"league of legends": "leagueoflegends",
|
||||||
|
"lol": "leagueoflegends",
|
||||||
|
"street fighter": "streetfighter",
|
||||||
|
"sonic": "sonic",
|
||||||
|
"sonic the hedgehog": "sonic",
|
||||||
|
"spy x family": "spy-x-family",
|
||||||
|
"spy family": "spy-x-family",
|
||||||
|
"spyxfamily": "spy-x-family",
|
||||||
|
"zelda": "zelda",
|
||||||
|
"the legend of zelda": "zelda",
|
||||||
|
"legend of zelda": "zelda",
|
||||||
|
"witcher": "witcher",
|
||||||
|
"the witcher": "witcher",
|
||||||
|
"metroid": "metroid",
|
||||||
|
"pokemon": "pokemon",
|
||||||
|
"pokémon": "pokemon",
|
||||||
}
|
}
|
||||||
|
|
||||||
# Section title keywords -> model field
|
# Section title keywords -> model field
|
||||||
|
|||||||
0
tests/__init__.py
Normal file
0
tests/__init__.py
Normal file
51
tests/test_wiki_fetch.py
Normal file
51
tests/test_wiki_fetch.py
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
"""
|
||||||
|
Integration tests — hit each Fandom wiki endpoint and verify we get
|
||||||
|
meaningful character data back.
|
||||||
|
|
||||||
|
These tests make real HTTP requests, so they require network access.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
import pytest_asyncio
|
||||||
|
|
||||||
|
from character_details.fetcher import fetch_character
|
||||||
|
from character_details.models import CharacterData
|
||||||
|
|
||||||
|
CHARACTERS = [
|
||||||
|
("Tifa Lockhart", "Final Fantasy VII"),
|
||||||
|
("Y'shtola Rhul", "Final Fantasy XIV"),
|
||||||
|
("Princess Peach", "Super Mario"),
|
||||||
|
("Sucy Manbavaran", "Little Witch Academia"),
|
||||||
|
("Rice Shower", "Uma Musume"),
|
||||||
|
("Camilla", "Fire Emblem"),
|
||||||
|
("Shiki", "Senran Kagura"),
|
||||||
|
("Hatsune Miku", "Vocaloid"),
|
||||||
|
("Android 18", "Dragon Ball"),
|
||||||
|
("Jinx", "League of Legends"),
|
||||||
|
("Chun-Li", "Street Fighter"),
|
||||||
|
("Rouge the Bat", "Sonic"),
|
||||||
|
("Yor Briar", "Spy x Family"),
|
||||||
|
("Princess Zelda", "The Legend of Zelda"),
|
||||||
|
("Ciri", "The Witcher"),
|
||||||
|
("Zero Suit Samus", "Metroid"),
|
||||||
|
("Nessa", "Pokemon"),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
@pytest.mark.parametrize("name,franchise", CHARACTERS, ids=[f"{n} ({f})" for n, f in CHARACTERS])
|
||||||
|
async def test_fetch_character(name: str, franchise: str):
|
||||||
|
"""Each wiki should return a CharacterData with at least a name, franchise, description, and source URL."""
|
||||||
|
result = await fetch_character(name, franchise)
|
||||||
|
|
||||||
|
assert isinstance(result, CharacterData)
|
||||||
|
assert result.name == name
|
||||||
|
assert result.franchise == franchise
|
||||||
|
assert result.description, f"No description returned for {name} ({franchise})"
|
||||||
|
assert len(result.sources) >= 1, f"No sources returned for {name} ({franchise})"
|
||||||
|
|
||||||
|
# At least one source should be a Fandom URL (not just Wikipedia)
|
||||||
|
fandom_sources = [s for s in result.sources if "fandom.com" in s]
|
||||||
|
assert fandom_sources, (
|
||||||
|
f"No Fandom source for {name} ({franchise}) — got: {result.sources}"
|
||||||
|
)
|
||||||
Reference in New Issue
Block a user