from pathlib import Path import pytest from parsers import common, quest, object as object_parser ROOT = Path(__file__).parent.parent EXAMPLES = ROOT / "example_pages" FIXTURES = Path(__file__).parent / "fixtures" def read(path: Path) -> str: if not path.exists(): pytest.skip(f"{path.name} not available") return path.read_text(encoding="utf-8") @pytest.fixture(scope="module") def quest_list(): return read(EXAMPLES / "https___www.wowhead.com_forever_quests#200.htm") @pytest.fixture(scope="module") def object_list(): return read(EXAMPLES / "https___www.wowhead.com_forever_objects.htm") def test_quest_list_is_truncated_listview(quest_list): rows, truncated, _ = common.list_page(quest_list, quest.LISTVIEW_ID) assert len(rows) == 1000 and truncated def test_quest_list_row(quest_list): rows, _, _ = common.list_page(quest_list, quest.LISTVIEW_ID) row = quest.list_row(next(r for r in rows if r["id"] == 96393), common.filter_categories(quest_list)) assert row == { "id": 96393, "name": "Old Ironforge Incursion", "level": 16, "reqlevel": 9, "side": "Alliance", "category": "The Hall of Thanes", "category_id": 16919, "category2": "Dungeons", "category2_id": 2, "exp": 1450, "money": 800, } def test_category_ids_overlap_between_levels(quest_list): categories = common.filter_categories(quest_list) assert categories[1][0] == "Kalimdor" assert categories[0][1][1] == "Dun Morogh" # zone 1 under Eastern Kingdoms def test_object_list_uses_json_script(object_list): rows, truncated, _ = common.list_page(object_list, object_parser.LISTVIEW_ID) assert len(rows) == 1000 and truncated row = object_parser.list_row(next(r for r in rows if r["id"] == 3689), common.filter_categories(object_list)) assert row == {"id": 3689, "name": "Weapon Crate", "type": "Containers", "type_id": 3, "skill": 0, "zone_ids": "17;331"} def test_quest_page_baron_marinous(): html = read(EXAMPLES / "https___www.wowhead.com_forever_quest=98028_baron-marinous.htm") q = quest.parse_page(html, {"id": "98028", "category": "Darkshore"}) assert q["name"] == "Baron Marinous" assert (q["level"], q["reqlevel"], q["side"]) == (21, 17, "Alliance") assert q["objectives"] == "Bring the Clouded Water Globe to Onu at the Grove of the Ancients in Darkshore." assert q["objective_items"] == [{"type": "item", "id": 279275, "name": "Clouded Water Globe", "quantity": 1, "standing": None, "provided": True}] assert q["description"].startswith("All that remains of the powerful elemental") assert q["progress"].startswith("I can sense something far older") assert "\n\nStairs descending down in Mathystra?" in q["completion"] assert q["start"] == [] assert q["end"] == [{"type": "npc", "id": 3616, "name": "Onu"}] assert q["locations"][0] == {"role": "end", "type": "npc", "id": 3616, "name": "Onu", "zone_id": 148, "zone": "Darkshore", "coord": [43.6, 76.4], "coords": [[43.4, 76.2], [43.6, 76.4]]} assert q["rewards"]["xp"] == 1650 assert q["rewards"]["money"] == 0 assert [i["name"] for i in q["rewards"]["item_choices"]] == ["Mathystra Channeling Orb", "Onu's Patience"] assert q["rewards"]["reputation"] == [{"faction_id": 69, "faction": "Darnassus", "value": 150}] assert "Not sharable" in q["quick_facts"] def test_quest_page_with_giver_and_series(): q = quest.parse_page(read(FIXTURES / "quest_166.html"), {"id": "166"}) assert q["start"] == [{"type": "npc", "id": 234, "name": "Gryan Stoutmantle"}] giver = next(loc for loc in q["locations"] if loc["role"] == "start") assert (giver["name"], giver["zone"], giver["coord"]) == ("Gryan Stoutmantle", "Westfall", [56.2, 47.6]) assert q["series"] == [{"id": 155, "name": "The Defias Brotherhood"}, {"id": 166, "name": "The Defias Brotherhood"}] def test_object_page_weapon_crate(): html = read(EXAMPLES / "https___www.wowhead.com_forever_object=3689_weapon-crate.htm") o = object_parser.parse_page(html, {"id": "3689", "type": "Containers", "skill": "0"}) assert (o["name"], o["type"], o["type_id"], o["skill"]) == ("Weapon Crate", "Containers", 3, 0) assert [(loc["zone"], loc["count"]) for loc in o["locations"]] == [("The Barrens", 16), ("Ashenvale", 7)] assert len(o["locations"][0]["coords"]) == 16 bludgeon = next(i for i in o["contains"] if i["id"] == 1825) assert bludgeon == {"id": 1825, "name": "Bulky Bludgeon", "count": 17, "percent": 0.4, "stack": [1, 1]} def test_object_page_starts_and_ends_quests(): o = object_parser.parse_page(read(FIXTURES / "object_415106.html"), {"id": "415106"}) assert [q["id"] for q in o["starts"]] == [79007, 79192] assert [q["id"] for q in o["ends"]] == [79008] assert o["contains"] == [] def test_quest_page_with_reputation_objectives(): q = quest.parse_page(read(FIXTURES / "quest_1036.html"), {"id": "1036"}) assert [(o["type"], o["id"], o["name"], o["quantity"], o["standing"]) for o in q["objective_items"]] == [ ("faction", 87, "Bloodsail Buccaneers", None, "Friendly"), ("faction", 21, "Booty Bay", None, "Hated"), ]