262 lines
9.1 KiB
Python
262 lines
9.1 KiB
Python
import uuid
|
|
from datetime import datetime, timezone
|
|
from unittest.mock import MagicMock, patch
|
|
|
|
import pytest
|
|
from fastapi import status
|
|
from sqlalchemy.orm import Session
|
|
|
|
from app.auth.dependencies import get_current_user
|
|
|
|
# Import the router we're testing
|
|
from app.routers.playlist import (
|
|
ProcessStatus,
|
|
ValidationProcessResponse,
|
|
ValidationResultResponse,
|
|
router,
|
|
validation_processes,
|
|
)
|
|
from app.utils.database import get_db
|
|
|
|
# Import mocks and fixtures
|
|
from tests.utils.auth_test_fixtures import (
|
|
admin_user_client,
|
|
db_session,
|
|
non_admin_user_client,
|
|
)
|
|
from tests.utils.db_mocks import MockChannelDB
|
|
|
|
# --- Test Fixtures ---
|
|
|
|
|
|
@pytest.fixture
|
|
def mock_stream_manager():
|
|
with patch("app.routers.playlist.StreamManager") as mock:
|
|
yield mock
|
|
|
|
|
|
# --- Test Cases For Stream Validation ---
|
|
|
|
|
|
def test_start_stream_validation_success(
|
|
db_session: Session, admin_user_client, mock_stream_manager
|
|
):
|
|
"""Test starting a stream validation process"""
|
|
mock_instance = mock_stream_manager.return_value
|
|
mock_instance.validate_and_select_stream.return_value = "http://valid.stream.url"
|
|
|
|
response = admin_user_client.post(
|
|
"/playlist/validate-streams", json={"channel_id": "test-channel"}
|
|
)
|
|
|
|
assert response.status_code == status.HTTP_202_ACCEPTED
|
|
data = response.json()
|
|
assert "process_id" in data
|
|
assert data["status"] == ProcessStatus.PENDING
|
|
assert data["message"] == "Validation process started"
|
|
|
|
# Verify process was added to tracking
|
|
process_id = data["process_id"]
|
|
assert process_id in validation_processes
|
|
# In test environment, background tasks run synchronously so status may be COMPLETED
|
|
assert validation_processes[process_id]["status"] in [
|
|
ProcessStatus.PENDING,
|
|
ProcessStatus.COMPLETED,
|
|
]
|
|
assert validation_processes[process_id]["channel_id"] == "test-channel"
|
|
|
|
|
|
def test_get_validation_status_pending(db_session: Session, admin_user_client):
|
|
"""Test checking status of pending validation"""
|
|
process_id = str(uuid.uuid4())
|
|
validation_processes[process_id] = {
|
|
"status": ProcessStatus.PENDING,
|
|
"channel_id": "test-channel",
|
|
}
|
|
|
|
response = admin_user_client.get(f"/playlist/validate-streams/{process_id}")
|
|
|
|
assert response.status_code == status.HTTP_200_OK
|
|
data = response.json()
|
|
assert data["process_id"] == process_id
|
|
assert data["status"] == ProcessStatus.PENDING
|
|
assert data["working_streams"] is None
|
|
assert data["error"] is None
|
|
|
|
|
|
def test_get_validation_status_completed(db_session: Session, admin_user_client):
|
|
"""Test checking status of completed validation"""
|
|
process_id = str(uuid.uuid4())
|
|
validation_processes[process_id] = {
|
|
"status": ProcessStatus.COMPLETED,
|
|
"channel_id": "test-channel",
|
|
"result": {
|
|
"working_streams": [
|
|
{"channel_id": "test-channel", "stream_url": "http://valid.stream.url"}
|
|
]
|
|
},
|
|
}
|
|
|
|
response = admin_user_client.get(f"/playlist/validate-streams/{process_id}")
|
|
|
|
assert response.status_code == status.HTTP_200_OK
|
|
data = response.json()
|
|
assert data["process_id"] == process_id
|
|
assert data["status"] == ProcessStatus.COMPLETED
|
|
assert len(data["working_streams"]) == 1
|
|
assert data["working_streams"][0]["channel_id"] == "test-channel"
|
|
assert data["working_streams"][0]["stream_url"] == "http://valid.stream.url"
|
|
assert data["error"] is None
|
|
|
|
|
|
def test_get_validation_status_completed_with_error(
|
|
db_session: Session, admin_user_client
|
|
):
|
|
"""Test checking status of completed validation with error"""
|
|
process_id = str(uuid.uuid4())
|
|
validation_processes[process_id] = {
|
|
"status": ProcessStatus.COMPLETED,
|
|
"channel_id": "test-channel",
|
|
"error": "No working streams found for channel test-channel",
|
|
}
|
|
|
|
response = admin_user_client.get(f"/playlist/validate-streams/{process_id}")
|
|
|
|
assert response.status_code == status.HTTP_200_OK
|
|
data = response.json()
|
|
assert data["process_id"] == process_id
|
|
assert data["status"] == ProcessStatus.COMPLETED
|
|
assert data["working_streams"] is None
|
|
assert data["error"] == "No working streams found for channel test-channel"
|
|
|
|
|
|
def test_get_validation_status_failed(db_session: Session, admin_user_client):
|
|
"""Test checking status of failed validation"""
|
|
process_id = str(uuid.uuid4())
|
|
validation_processes[process_id] = {
|
|
"status": ProcessStatus.FAILED,
|
|
"channel_id": "test-channel",
|
|
"error": "Validation error occurred",
|
|
}
|
|
|
|
response = admin_user_client.get(f"/playlist/validate-streams/{process_id}")
|
|
|
|
assert response.status_code == status.HTTP_200_OK
|
|
data = response.json()
|
|
assert data["process_id"] == process_id
|
|
assert data["status"] == ProcessStatus.FAILED
|
|
assert data["working_streams"] is None
|
|
assert data["error"] == "Validation error occurred"
|
|
|
|
|
|
def test_get_validation_status_not_found(db_session: Session, admin_user_client):
|
|
"""Test checking status of non-existent process"""
|
|
random_uuid = str(uuid.uuid4())
|
|
response = admin_user_client.get(f"/playlist/validate-streams/{random_uuid}")
|
|
|
|
assert response.status_code == status.HTTP_404_NOT_FOUND
|
|
assert "Process not found" in response.json()["detail"]
|
|
|
|
|
|
def test_run_stream_validation_success(mock_stream_manager, db_session):
|
|
"""Test the background validation task success case"""
|
|
process_id = str(uuid.uuid4())
|
|
validation_processes[process_id] = {
|
|
"status": ProcessStatus.PENDING,
|
|
"channel_id": "test-channel",
|
|
}
|
|
|
|
mock_instance = mock_stream_manager.return_value
|
|
mock_instance.validate_and_select_stream.return_value = "http://valid.stream.url"
|
|
|
|
from app.routers.playlist import run_stream_validation
|
|
|
|
run_stream_validation(process_id, "test-channel", db_session)
|
|
|
|
assert validation_processes[process_id]["status"] == ProcessStatus.COMPLETED
|
|
assert len(validation_processes[process_id]["result"]["working_streams"]) == 1
|
|
assert (
|
|
validation_processes[process_id]["result"]["working_streams"][0].channel_id
|
|
== "test-channel"
|
|
)
|
|
assert (
|
|
validation_processes[process_id]["result"]["working_streams"][0].stream_url
|
|
== "http://valid.stream.url"
|
|
)
|
|
|
|
|
|
def test_run_stream_validation_failure(mock_stream_manager, db_session):
|
|
"""Test the background validation task failure case"""
|
|
process_id = str(uuid.uuid4())
|
|
validation_processes[process_id] = {
|
|
"status": ProcessStatus.PENDING,
|
|
"channel_id": "test-channel",
|
|
}
|
|
|
|
mock_instance = mock_stream_manager.return_value
|
|
mock_instance.validate_and_select_stream.return_value = None
|
|
|
|
from app.routers.playlist import run_stream_validation
|
|
|
|
run_stream_validation(process_id, "test-channel", db_session)
|
|
|
|
assert validation_processes[process_id]["status"] == ProcessStatus.COMPLETED
|
|
assert "error" in validation_processes[process_id]
|
|
assert "No working streams found" in validation_processes[process_id]["error"]
|
|
|
|
|
|
def test_run_stream_validation_exception(mock_stream_manager, db_session):
|
|
"""Test the background validation task exception case"""
|
|
process_id = str(uuid.uuid4())
|
|
validation_processes[process_id] = {
|
|
"status": ProcessStatus.PENDING,
|
|
"channel_id": "test-channel",
|
|
}
|
|
|
|
mock_instance = mock_stream_manager.return_value
|
|
mock_instance.validate_and_select_stream.side_effect = Exception("Test error")
|
|
|
|
from app.routers.playlist import run_stream_validation
|
|
|
|
run_stream_validation(process_id, "test-channel", db_session)
|
|
|
|
assert validation_processes[process_id]["status"] == ProcessStatus.FAILED
|
|
assert "error" in validation_processes[process_id]
|
|
assert "Test error" in validation_processes[process_id]["error"]
|
|
|
|
|
|
def test_start_stream_validation_no_channel_id(
|
|
db_session: Session, admin_user_client, mock_stream_manager
|
|
):
|
|
"""Test starting validation without channel_id"""
|
|
response = admin_user_client.post("/playlist/validate-streams", json={})
|
|
|
|
assert response.status_code == status.HTTP_202_ACCEPTED
|
|
data = response.json()
|
|
assert "process_id" in data
|
|
assert data["status"] == ProcessStatus.PENDING
|
|
|
|
# Verify process was added to tracking
|
|
process_id = data["process_id"]
|
|
assert process_id in validation_processes
|
|
assert validation_processes[process_id]["status"] in [
|
|
ProcessStatus.PENDING,
|
|
ProcessStatus.COMPLETED,
|
|
]
|
|
assert validation_processes[process_id]["channel_id"] is None
|
|
assert "not yet implemented" in validation_processes[process_id].get("error", "")
|
|
|
|
|
|
def test_run_stream_validation_no_channel_id(mock_stream_manager, db_session):
|
|
"""Test background validation without channel_id"""
|
|
process_id = str(uuid.uuid4())
|
|
validation_processes[process_id] = {"status": ProcessStatus.PENDING}
|
|
|
|
from app.routers.playlist import run_stream_validation
|
|
|
|
run_stream_validation(process_id, None, db_session)
|
|
|
|
assert validation_processes[process_id]["status"] == ProcessStatus.COMPLETED
|
|
assert "error" in validation_processes[process_id]
|
|
assert "not yet implemented" in validation_processes[process_id]["error"]
|