"""Regression tests for legacy project upgrade (items must stay on their tracks with correct bar positions).""" import json from app.api.v1.projects import upgrade_project_json_if_needed def _legacy_project(): return { "id": "legacy_1", "name": "Legacy", "bpm": 120.0, # 1 bar = 2.0s "tracks": [ { "id": "1", "name": "Track 1", "volumeDb": 0.0, "pan": 0.0, "muted": False, "solo": False, "serverFileId": "abc.wav", "clips": [{"id": "c1", "name": "clip1", "startTime": 2.0}], "midiItems": [], }, { "id": "2", "name": "Track 2", "volumeDb": 0.0, "pan": 0.0, "muted": False, "solo": False, "serverFileId": None, "clips": [], "midiItems": [ {"id": "m1", "name": "midi1", "startTime": 4.0, "duration": 4.0, "notes": [{"id": "n1", "pitch": 60, "start_beat": 0.0, "duration_beats": 1.0, "velocity": 0.8}]} ], }, ], } def test_upgrade_keeps_items_on_their_tracks(): upgraded = upgrade_project_json_if_needed(_legacy_project()) tracks = upgraded["main_session"]["tracks"] assert len(tracks) == 2 t1_items = tracks[0]["items"] t2_items = tracks[1]["items"] # Items must NOT be merged into the first track assert [i["type"] for i in t1_items] == ["AUDIO_ITEM"] assert [i["type"] for i in t2_items] == ["MIDI_ITEM"] assert t1_items[0]["id"] == "c1" assert t2_items[0]["id"] == "m1" def test_upgrade_uses_bpm_based_seconds_per_bar(): upgraded = upgrade_project_json_if_needed(_legacy_project()) tracks = upgraded["main_session"]["tracks"] # 120bpm -> 1 bar = 2.0s; clip at 2.0s -> start_bar 1.0 assert tracks[0]["items"][0]["start_bar"] == 1.0 # midi at 4.0s -> start_bar 2.0; duration 4.0s -> 2.0 bars assert tracks[1]["items"][0]["start_bar"] == 2.0 assert tracks[1]["items"][0]["duration_bars"] == 2.0 def test_upgrade_skips_new_format(): data = {"main_session": {"tracks": []}} assert upgrade_project_json_if_needed(data) is data