fix: time selection click and shiftclick
This commit is contained in:
@@ -0,0 +1,93 @@
|
||||
# Test Verification Suite for Technical Roadmap 22_CLIENT_DESK.md
|
||||
import os
|
||||
import pytest
|
||||
import numpy as np
|
||||
from fastapi import HTTPException
|
||||
|
||||
from app.core.dsp_utils import find_zero_crossing, apply_micro_crossfade
|
||||
from app.core.vst_engine import render_midi_events_to_audio
|
||||
from app.api.v1.auth import enforce_password_changed
|
||||
|
||||
def test_kpi_1_zero_crossing_detection():
|
||||
"""Kiểm thử Zero-Crossing: Cắt lát nhạc bằng AI Cut ở mốc giây lẻ (22_CLIENT_DESK.md §5)."""
|
||||
sr = 44100
|
||||
# Generate 1 second sine wave at 440 Hz
|
||||
t = np.linspace(0, 1.0, sr)
|
||||
signal = np.sin(2 * np.pi * 440 * t)
|
||||
|
||||
target_time = 0.1234 # Odd time offset
|
||||
zc_time = find_zero_crossing(signal, sr, target_time, window_seconds=0.04)
|
||||
|
||||
assert zc_time is not None
|
||||
zc_sample = int(zc_time * sr)
|
||||
# Verify physical sign inversion x[i] * x[i+1] <= 0
|
||||
if 0 <= zc_sample < len(signal) - 1:
|
||||
assert signal[zc_sample] * signal[zc_sample + 1] <= 0.05
|
||||
print(f"Zero crossing test passed: target {target_time}s -> zc {zc_time}s")
|
||||
|
||||
def test_kpi_2_micro_crossfade_splicing():
|
||||
"""Kiểm thử Micro-Crossfade (10ms) tại hai đầu điểm ráp nối để triệt tiêu click/pop."""
|
||||
sr = 44100
|
||||
original = np.ones(sr, dtype=np.float32) * 0.5
|
||||
edited = np.ones(sr // 2, dtype=np.float32) * 0.8
|
||||
start_sample = sr // 4
|
||||
|
||||
output = apply_micro_crossfade(original, edited, start_sample, fade_len_ms=10, sr=sr)
|
||||
assert len(output) == len(original)
|
||||
# Check smooth transition at start
|
||||
assert 0.49 <= output[start_sample] <= 0.81
|
||||
print("Micro-crossfade splicing test passed.")
|
||||
|
||||
def test_kpi_3_vst_synth_midi_rendering():
|
||||
"""Kiểm thử Docker VSTi: Gửi chuỗi MIDI nốt và nạp synth tổng hợp ra mảng Stereo."""
|
||||
midi_events = [
|
||||
{"note": 60, "start_beat": 0.0, "duration_beats": 1.0, "velocity": 100}, # C4
|
||||
{"note": 64, "start_beat": 1.0, "duration_beats": 1.0, "velocity": 90}, # E4
|
||||
{"note": 67, "start_beat": 2.0, "duration_beats": 2.0, "velocity": 110} # G4
|
||||
]
|
||||
|
||||
audio_array = render_midi_events_to_audio(midi_events, sr=44100, bpm=120.0)
|
||||
|
||||
assert isinstance(audio_array, np.ndarray)
|
||||
assert audio_array.shape[0] == 2 # Stereo channels (L, R)
|
||||
assert audio_array.shape[1] > 0
|
||||
assert np.max(np.abs(audio_array)) > 0.01
|
||||
print(f"VSTi MIDI rendering test passed: stereo output shape {audio_array.shape}")
|
||||
|
||||
def test_kpi_4_auth_security_must_change_password():
|
||||
"""Kiểm thử Bảo Mật Auth: Đăng nhập tài khoản mặc định và gọi API (22_CLIENT_DESK.md §5)."""
|
||||
user_must_change = {"user_id": "test_user_1", "must_change_password": True}
|
||||
user_password_changed = {"user_id": "test_user_2", "must_change_password": False}
|
||||
|
||||
# Should raise HTTP 403 Forbidden when must_change_password = True
|
||||
with pytest.raises(HTTPException) as exc_info:
|
||||
enforce_password_changed(user_must_change)
|
||||
assert exc_info.value.status_code == 403
|
||||
|
||||
# Should pass without error when must_change_password = False
|
||||
enforce_password_changed(user_password_changed)
|
||||
print("Auth Security 403 Forbidden test passed.")
|
||||
|
||||
def test_kpi_5_storage_quota_calculation():
|
||||
"""Kiểm thử Quota: S_used + S_new <= S_limit."""
|
||||
s_limit_mb = 500
|
||||
s_used_mb = 480
|
||||
s_new_mb = 30 # Total = 510MB > 500MB limit
|
||||
|
||||
total = s_used_mb + s_new_mb
|
||||
is_quota_exceeded = total > s_limit_mb
|
||||
|
||||
assert is_quota_exceeded is True
|
||||
print("Storage Quota calculation test passed.")
|
||||
|
||||
def test_kpi_6_shift_click_range_anchor_math():
|
||||
"""Kiểm thử Shift+Click: Bôi chọn cục bộ [min(T_anchor, T_end), max(T_anchor, T_end)]."""
|
||||
t_anchor = 5.4
|
||||
t_end = 2.1
|
||||
|
||||
sel_start = min(t_anchor, t_end)
|
||||
sel_end = max(t_anchor, t_end)
|
||||
|
||||
assert sel_start == 2.1
|
||||
assert sel_end == 5.4
|
||||
print("Shift+Click range anchor math test passed.")
|
||||
Reference in New Issue
Block a user