fix(api): align zone content kind validation with model
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -21,8 +21,8 @@ def _maybe_migrate_tab_json_to_zone():
|
||||
class Zone(Model):
|
||||
"""Preset layout row (stored in ``db/zone.json``); legacy storage was ``tab.json`` / Tab.
|
||||
|
||||
Optional ``content_kind`` on a row: ``\"presets\"`` (preset tiles only) or ``\"sequences\"``
|
||||
(sequence tiles only). Legacy rows without ``content_kind`` are inferred on load.
|
||||
Optional legacy ``content_kind`` (``\"presets\"`` / ``\"sequences\"``) is kept for older data;
|
||||
zones may hold both preset tiles and ``sequence_ids``.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
@@ -95,13 +95,8 @@ class Zone(Model):
|
||||
return "presets"
|
||||
|
||||
def _enforce_content_kind_invariants(self, doc):
|
||||
"""Presets-only zones hold no sequences; sequences-only hold no preset tiles."""
|
||||
kind = self._normalized_content_kind(doc)
|
||||
if kind == "presets":
|
||||
doc["sequence_ids"] = []
|
||||
elif kind == "sequences":
|
||||
doc["presets"] = []
|
||||
doc["presets_flat"] = []
|
||||
"""No-op: presets and sequences may coexist on one zone."""
|
||||
_ = doc
|
||||
|
||||
def create(self, name="", names=None, presets=None, group_ids=None, content_kind=None):
|
||||
next_id = self.get_next_id()
|
||||
@@ -135,13 +130,7 @@ class Zone(Model):
|
||||
if id_str not in self:
|
||||
return False
|
||||
patch = dict(data) if isinstance(data, dict) else {}
|
||||
doc = self[id_str]
|
||||
locked_kind = self._normalized_content_kind(doc) or self._infer_content_kind(doc)
|
||||
if "content_kind" in patch:
|
||||
patch["content_kind"] = locked_kind
|
||||
self[id_str].update(patch)
|
||||
if "content_kind" in patch:
|
||||
self._enforce_content_kind_invariants(self[id_str])
|
||||
self.save()
|
||||
return True
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"""Zone content_kind is fixed after create."""
|
||||
"""Zones may hold both presets and sequences."""
|
||||
|
||||
import json
|
||||
import os
|
||||
@@ -12,7 +12,7 @@ sys.path.insert(0, str(PROJECT_ROOT / "src"))
|
||||
from models.zone import Zone # noqa: E402
|
||||
|
||||
|
||||
def test_update_cannot_change_content_kind():
|
||||
def test_zone_presets_and_sequences_can_coexist():
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
path = os.path.join(tmp, "zone.json")
|
||||
with open(path, "w", encoding="utf-8") as f:
|
||||
@@ -20,8 +20,16 @@ def test_update_cannot_change_content_kind():
|
||||
z = Zone()
|
||||
z.file = path
|
||||
z.clear()
|
||||
zid = z.create("preset zone", group_ids=[], content_kind="presets")
|
||||
z.update(zid, {"content_kind": "sequences", "name": "preset zone"})
|
||||
zid = z.create("mixed zone", group_ids=[], content_kind="presets")
|
||||
z.update(
|
||||
zid,
|
||||
{
|
||||
"presets": [["p1", "p2"]],
|
||||
"sequence_ids": ["seq1"],
|
||||
},
|
||||
)
|
||||
doc = z.read(zid)
|
||||
assert doc["content_kind"] == "presets"
|
||||
assert doc.get("sequence_ids") == []
|
||||
assert doc.get("sequence_ids") == ["seq1"]
|
||||
preset_ids = Zone._preset_ids_in_doc(doc)
|
||||
assert "p1" in preset_ids
|
||||
assert "p2" in preset_ids
|
||||
|
||||
Reference in New Issue
Block a user