Add skip tracking, compressed heatmap, listening log, docs, tests, and OpenAI support

Major changes:
- Add skip tracking: poll currently-playing every 15s, detect skips (<30s listened)
- Add listening-log and sessions API endpoints
- Fix ReccoBeats client to extract spotify_id from href response
- Compress heatmap from 24 hours to 6 x 4-hour blocks
- Add OpenAI support in narrative service (use max_completion_tokens for new models)
- Add ListeningLog component with timeline and list views
- Update all frontend components to use real data (album art, play counts)
- Add docker-compose external network (dockernet) support
- Add comprehensive documentation (API, DATA_MODEL, ARCHITECTURE, FRONTEND)
- Add unit tests for ingest and API endpoints
This commit is contained in:
bnair123
2025-12-30 00:15:01 +04:00
parent faee830545
commit 887e78bf47
26 changed files with 1942 additions and 662 deletions

View File

@@ -0,0 +1,49 @@
import pytest
from unittest.mock import MagicMock, patch, AsyncMock
from datetime import datetime
@pytest.fixture
def mock_db():
return MagicMock()
class TestSnapshotsEndpoint:
def test_snapshots_endpoint_exists(self, mock_db):
with patch("app.main.SessionLocal", return_value=mock_db):
from fastapi.testclient import TestClient
from app.main import app
mock_db.query.return_value.order_by.return_value.limit.return_value.all.return_value = []
with TestClient(app) as client:
response = client.get("/snapshots?limit=1")
assert response.status_code == 200
class TestListeningLogEndpoint:
def test_listening_log_endpoint_exists(self, mock_db):
with patch("app.main.SessionLocal", return_value=mock_db):
from fastapi.testclient import TestClient
from app.main import app
mock_db.query.return_value.options.return_value.filter.return_value.order_by.return_value.limit.return_value.all.return_value = []
with TestClient(app) as client:
response = client.get("/listening-log?days=7&limit=100")
assert response.status_code == 200
class TestSessionsEndpoint:
def test_sessions_endpoint_exists(self, mock_db):
with patch("app.main.SessionLocal", return_value=mock_db):
from fastapi.testclient import TestClient
from app.main import app
mock_db.query.return_value.options.return_value.filter.return_value.order_by.return_value.all.return_value = []
with TestClient(app) as client:
response = client.get("/sessions?days=7")
assert response.status_code == 200
data = response.json()
assert "session_list" in data