spriteforge/tests/test_studio_store.py

56 lines
2.3 KiB
Python
Raw Normal View History

from __future__ import annotations
import io
from PIL import Image
import pytest
from spriteforge.studio.models import Asset, GenerationRecipe, StyleBible
from spriteforge.studio.store import ProjectStore
def png(color=(12, 34, 56, 255)) -> bytes:
image = Image.new("RGBA", (8, 6), color)
output = io.BytesIO()
image.save(output, "PNG")
return output.getvalue()
def test_project_asset_candidate_approval_roundtrip(tmp_path):
store = ProjectStore.create(tmp_path / "art", "horror_ops", "Horror Ops")
store.update_style(StyleBible(description="industrial biomechanical horror"))
store.add_asset(Asset(id="field_agent", name="Field Agent", kind="character",
target_width=60, target_height=60))
reference = store.import_png(png(), "reference")
store.attach_reference("field_agent", reference)
_, shot = store.add_shot("field_agent", "idle", 0, 0)
candidate_media = store.import_png(png((90, 10, 10, 255)), "candidate")
recipe = GenerationRecipe(provider="test", model="fake", seed=7, prompt="agent",
width=256, height=256, reference_hashes=[reference.hash])
_, candidate = store.add_candidate("field_agent", shot.id, candidate_media, recipe)
store.decide("field_agent", shot.id, candidate.id, "approved")
project = store.load()
saved = project.assets[0].shots[0]
assert saved.approved_candidate_id == candidate.id
assert saved.candidates[0].decision == "approved"
assert store.media_path(saved.candidates[0].image.path).is_file()
def test_media_is_content_addressed_and_canonicalized(tmp_path):
store = ProjectStore.create(tmp_path / "art", "test_project", "Test")
first = store.import_png(png(), "reference")
second = store.import_png(png(), "candidate")
assert first.hash == second.hash
assert first.path == second.path
def test_store_rejects_escape_and_duplicate_asset(tmp_path):
store = ProjectStore.create(tmp_path / "art", "test_project", "Test")
asset = Asset(id="agent", name="Agent", kind="character", target_width=60, target_height=60)
store.add_asset(asset)
with pytest.raises(ValueError, match="already exists"):
store.add_asset(asset)
with pytest.raises(ValueError, match="escapes"):
store.media_path("../secret.png")