brad-did-something / tests /test_comic.py
qFelix's picture
Brad Did Something - Gradio/FastAPI Space on HF
78c0f6e
Raw
History Blame Contribute Delete
4.01 kB
"""Comic-panel overlay backend: image_prompt soft-validation + FLUX client."""
import copy
import os
from game import comic
from game.state import GameState
from game.validator import validate_crisis, validate_event
GOOD_CRISIS = {
"npc_reaction": "Noted, boss.",
"consequence": "It resolved somehow.",
"revenue_delta": 50_000,
"animation": "npc_happy",
"boss_title": "VP of Tests",
"log_entry": "Brad did a thing. +$50K.",
"morale_delta": 3,
"npc_id": "brad",
"relationship_delta": 5,
"pocket_money_delta": 0,
"special_next_event": None,
}
GOOD_EVENT = {
"affected_npc": "brad",
"category": "professional",
"headline": "The deck went to the wrong client",
"intro": "> A laptop is shoved toward you. 'I think I clicked send,' "
"comes the panicked whisper.",
"option_a": "Call the client and own it.",
"option_b": "Pretend it was a teaser.",
"urgency": "The client replies in five minutes.",
"setup_animation": "npc_confused",
"morale_preview": -3,
}
CLEAN_PROMPT = ("flat 2D comic panel, bold ink outlines, chibi office workers. "
"Panel 1: Brad sweating at a laptop, bubble 'I clicked send'.")
def _state():
return GameState(session_id="t")
def test_clean_image_prompt_kept_on_crisis():
p = copy.deepcopy(GOOD_CRISIS)
p["image_prompt"] = CLEAN_PROMPT
out = validate_crisis(p, _state(), "brad")
assert out is not None and out["image_prompt"] == CLEAN_PROMPT
def test_clean_image_prompt_kept_on_event():
p = copy.deepcopy(GOOD_EVENT)
p["image_prompt"] = CLEAN_PROMPT
out = validate_event(p, _state())
assert out is not None and out["image_prompt"] == CLEAN_PROMPT
def test_absent_image_prompt_is_fine():
out = validate_crisis(copy.deepcopy(GOOD_CRISIS), _state(), "brad")
assert out is not None and "image_prompt" not in out
def test_mechanics_leak_drops_image_prompt_without_rejecting():
p = copy.deepcopy(GOOD_CRISIS)
p["image_prompt"] = "comic panel showing morale dropping and revenue_delta"
out = validate_crisis(p, _state(), "brad")
# the event itself survives — only the dirty prompt is dropped
assert out is not None and "image_prompt" not in out
def test_blank_image_prompt_dropped():
p = copy.deepcopy(GOOD_EVENT)
p["image_prompt"] = " "
out = validate_event(p, _state())
assert out is not None and "image_prompt" not in out
def test_overlong_image_prompt_clamped():
p = copy.deepcopy(GOOD_CRISIS)
p["image_prompt"] = "comic panel of Brad " + "x" * 500
out = validate_crisis(p, _state(), "brad")
assert out is not None and len(out["image_prompt"]) <= 400
def test_generate_comic_none_without_flux_url():
saved = os.environ.pop("FLUX_URL", None)
try:
assert comic.flux_available() is False
assert comic.generate_comic(CLEAN_PROMPT) is None
finally:
if saved is not None:
os.environ["FLUX_URL"] = saved
def test_generate_comic_none_on_empty_prompt():
assert comic.generate_comic("") is None
def test_comic_caption_kept():
p = copy.deepcopy(GOOD_CRISIS)
p["comic_caption"] = "Brad discovers the send button is load-bearing."
out = validate_crisis(p, _state(), "brad")
assert out is not None and out["comic_caption"].startswith("Brad discovers")
def test_comic_caption_mechanics_dropped_event_survives():
p = copy.deepcopy(GOOD_EVENT)
p["comic_caption"] = "This will tank morale and your relationship_delta."
out = validate_event(p, _state())
assert out is not None and "comic_caption" not in out
def test_banned_in_image_prompt_drops_not_rejects():
# a banned real-company name in the decorative prompt must NOT fail the
# whole event — only the prompt is dropped
p = copy.deepcopy(GOOD_CRISIS)
p["image_prompt"] = CLEAN_PROMPT + " logo of Microsoft acquiring us"
out = validate_crisis(p, _state(), "brad")
assert out is not None and "image_prompt" not in out