extends "res://addons/gut/test.gd" const ContentDB = preload("res://scripts/content/content_db.gd") var db func before_each(): db = ContentDB.new() db.load_from(ContentDB.default_content_root()) func _deserter() -> Dictionary: return ContentDB.load_json(ContentDB.origin_path("deserter")) func test_loads_world_ids(): assert_true(db.has_location("greywater_docks")) assert_true(db.has_quest("find_the_ledger")) assert_true(db.has_item("worn_shortsword")) assert_true(db.has_item("copper")) assert_true(db.has_item("silver")) assert_true(db.has_item("gold")) assert_false(db.has_item("coin"), "the undifferentiated coin is gone") func test_currency_items_agree_with_the_code(): # The denomination ids exist twice — in code (Currency.VALUES, because the # ratios are rules) and in content (slot: "currency"). Guard the two against # drifting apart, since nothing at runtime reconciles them. var content_ids: Array = [] for id in db.items: if db.items[id].get("slot", "") == "currency": content_ids.append(id) content_ids.sort() var code_ids: Array = Currency.VALUES.keys() code_ids.sort() assert_eq(content_ids, code_ids) func test_companions_are_brannoc_and_cadwyn(): var ids := [] for n in db.companions(): ids.append(n["id"]) ids.sort() assert_eq(ids, ["brannoc_thane","cadwyn_vell"]) func test_good_origin_has_no_unresolved_refs(): assert_eq(db.unresolved_refs(_deserter()), []) func test_broken_location_ref_detected(): var o := _deserter() o["start_location_id"] = "nowhere" assert_true("location:nowhere" in db.unresolved_refs(o)) func test_broken_item_ref_detected(): var o := _deserter() o["inventory_grants"] = o["inventory_grants"].duplicate(true) o["inventory_grants"].append({"item_id": "ghost_blade", "qty": 1}) assert_true("item:ghost_blade" in db.unresolved_refs(o)) func test_null_quest_ref_resolves(): var o := _deserter() o["start_quest_id"] = null assert_eq(db.unresolved_refs(o), []) func test_loads_canon(): assert_true(db.has_canon("faction.the-seven")) assert_true(db.has_canon("person.the-warden")) assert_true(db.has_canon("rule.disposition-ladder")) func test_no_loaded_topic_has_a_body(): # Bodies are server-only (secrecy≥1 knowledge routes to content/server/topics, # never the client). Structural, so it stays a real guard even when the # topic set is empty (as it is now — the last authored topics were purged) # and automatically starts testing something the moment a topic exists. # One assertion, always executed (not per-loop-item), so an empty topic # set still exercises the check instead of asserting zero times. var leaked: Array = [] for id in db.topics: if db.topics[id].has("body"): leaked.append(id) assert_eq(leaked, [], "topic(s) leaked a body to the client") func test_legacy_npcs_still_load(): assert_true(db.has_npc("fenn"))