Add profile/preset/sequence JSON import and export; map preset mode to wire n6 with a mode dropdown for multi-mode patterns; zone edit shows presets or sequences only with content_kind on save; update catalogue and tests for merged pattern names. Co-authored-by: Cursor <cursoragent@cursor.com>
134 lines
4.2 KiB
Python
134 lines
4.2 KiB
Python
"""Unit tests for profile/preset/sequence bundle import/export."""
|
|
|
|
import json
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
PROJECT_ROOT = Path(__file__).resolve().parents[1]
|
|
sys.path.insert(0, str(PROJECT_ROOT / "src"))
|
|
|
|
from models.pallet import Palette # noqa: E402
|
|
from models.preset import Preset # noqa: E402
|
|
from models.profile import Profile # noqa: E402
|
|
from models.sequence import Sequence # noqa: E402
|
|
from models.zone import Zone # noqa: E402
|
|
from util.profile_bundle import ( # noqa: E402
|
|
export_preset_bundle,
|
|
export_profile_bundle,
|
|
export_sequence_bundle,
|
|
import_preset_bundle,
|
|
import_profile_bundle,
|
|
import_sequence_bundle,
|
|
)
|
|
|
|
|
|
def _fresh_models(tmp_path, monkeypatch):
|
|
import models.model as model_mod
|
|
|
|
db = tmp_path / "db"
|
|
db.mkdir()
|
|
monkeypatch.setattr(model_mod, "_db_dir", lambda: str(db))
|
|
|
|
for cls in (Profile, Zone, Preset, Sequence, Palette):
|
|
if hasattr(cls, "_instance"):
|
|
delattr(cls, "_instance")
|
|
|
|
profiles = Profile()
|
|
zones = Zone()
|
|
presets = Preset()
|
|
sequences = Sequence()
|
|
palette = Palette()
|
|
return profiles, zones, presets, sequences, palette
|
|
|
|
|
|
def test_profile_export_import_round_trip(tmp_path, monkeypatch):
|
|
profiles, zones, presets, sequences, palette = _fresh_models(tmp_path, monkeypatch)
|
|
|
|
pid = profiles.create("Source")
|
|
zid = zones.create(name="main")
|
|
preset_id = presets.create(pid)
|
|
presets.update(
|
|
preset_id,
|
|
{
|
|
"name": "Test preset",
|
|
"pattern": "blink",
|
|
"colors": ["#ff0000"],
|
|
"brightness": 200,
|
|
"delay": 50,
|
|
},
|
|
)
|
|
zones.update(
|
|
zid,
|
|
{
|
|
"presets_flat": [str(preset_id)],
|
|
"default_preset": str(preset_id),
|
|
},
|
|
)
|
|
seq_id = sequences.create(pid)
|
|
sequences.update(
|
|
seq_id,
|
|
{
|
|
"name": "Beat seq",
|
|
"lanes": [[{"preset_id": str(preset_id), "group_ids": [], "beats": 2}]],
|
|
"lanes_group_ids": [[]],
|
|
},
|
|
)
|
|
zones.update(zid, {"sequence_ids": [str(seq_id)]})
|
|
profiles.update(pid, {"zones": [str(zid)]})
|
|
palette_id = profiles.read(pid)["palette_id"]
|
|
palette.update(palette_id, {"colors": ["#112233", "#445566"]})
|
|
|
|
bundle = export_profile_bundle(
|
|
str(pid), profiles, zones, presets, sequences, palette
|
|
)
|
|
assert bundle["kind"] == "profile"
|
|
assert str(preset_id) in bundle["presets"]
|
|
assert str(seq_id) in bundle["sequences"]
|
|
assert bundle["palette"]["colors"] == ["#112233", "#445566"]
|
|
|
|
new_pid, _ = import_profile_bundle(
|
|
bundle, profiles, zones, presets, sequences, palette, name="Imported"
|
|
)
|
|
assert new_pid != str(pid)
|
|
found = [
|
|
presets.read(k)
|
|
for k in presets.list()
|
|
if isinstance(presets.read(k), dict)
|
|
and str(presets.read(k).get("profile_id")) == str(new_pid)
|
|
and presets.read(k).get("name") == "Test preset"
|
|
]
|
|
assert found
|
|
|
|
|
|
def test_preset_export_import(tmp_path, monkeypatch):
|
|
profiles, zones, presets, sequences, palette = _fresh_models(tmp_path, monkeypatch)
|
|
pid = profiles.create("P")
|
|
preset_id = presets.create(pid)
|
|
presets.update(preset_id, {"name": "Solo", "pattern": "on", "colors": ["#00ff00"]})
|
|
|
|
bundle = export_preset_bundle(str(preset_id), presets)
|
|
assert bundle["kind"] == "preset"
|
|
|
|
new_id, data = import_preset_bundle(bundle, presets, str(pid))
|
|
assert new_id != str(preset_id)
|
|
assert data["name"] == "Solo"
|
|
|
|
|
|
def test_sequence_export_import_with_presets(tmp_path, monkeypatch):
|
|
profiles, zones, presets, sequences, palette = _fresh_models(tmp_path, monkeypatch)
|
|
pid = profiles.create("P")
|
|
preset_id = presets.create(pid)
|
|
presets.update(preset_id, {"name": "Step", "pattern": "off"})
|
|
seq_id = sequences.create(pid)
|
|
sequences.update(
|
|
seq_id,
|
|
{"name": "S", "lanes": [[{"preset_id": str(preset_id), "beats": 1}]]},
|
|
)
|
|
|
|
bundle = export_sequence_bundle(str(seq_id), sequences, presets, profile_id=str(pid))
|
|
assert str(preset_id) in bundle["presets"]
|
|
|
|
new_seq_id, doc = import_sequence_bundle(bundle, sequences, presets, str(pid))
|
|
assert new_seq_id != str(seq_id)
|
|
assert doc["lanes"][0][0]["preset_id"] != str(preset_id)
|