test / behavior_backend /tests /unit /services /test_video_service.py
hibatorrahmen's picture
Add backend application and Dockerfile
8ae78b0
import pytest
from unittest.mock import MagicMock, patch
import os
from fastapi import UploadFile, HTTPException
from app.services.video_service import VideoService
from app.db.repositories.video import VideoRepository
from app.db.repositories.results import ResultsRepository
from app.models.video import VideoMetadata
from app.core.exceptions import VideoNotFoundError
class TestVideoService:
"""Tests for the VideoService class."""
@pytest.fixture
def mock_video_repo(self):
"""Create a mock video repository."""
return MagicMock(spec=VideoRepository)
@pytest.fixture
def mock_results_repo(self):
"""Create a mock results repository."""
return MagicMock(spec=ResultsRepository)
@pytest.fixture
def video_service(self, mock_video_repo, mock_results_repo, db_session):
"""Create a video service with mock repositories."""
service = VideoService(db_session)
service.video_repo = mock_video_repo
service.results_repo = mock_results_repo
return service
@patch('app.services.video_service.save_upload_file')
@patch('app.services.video_service.get_video_duration')
@patch('os.path.getsize')
async def test_upload_video(self, mock_getsize, mock_get_duration, mock_save_upload, video_service, mock_video_repo):
"""Test uploading a video."""
# Arrange
mock_file = MagicMock(spec=UploadFile)
mock_file.filename = "test_video.mp4"
mock_save_upload.return_value = ("test-video-id", "test_video.mp4")
mock_getsize.return_value = 1000
mock_get_duration.return_value = 10.0
mock_video = MagicMock()
mock_video.id = "test-video-id"
mock_video.original_filename = "test_video.mp4"
mock_video.upload_date = "2023-01-01T00:00:00"
mock_video.size = 1000
mock_video.duration = 10.0
mock_video.status = "uploaded"
mock_video_repo.create.return_value = mock_video
# Act
result = await video_service.upload_video(mock_file)
# Assert
assert isinstance(result, VideoMetadata)
assert result.video_id == "test-video-id"
assert result.original_filename == "test_video.mp4"
assert result.size == 1000
assert result.duration == 10.0
assert result.status == "uploaded"
mock_save_upload.assert_called_once_with(mock_file)
mock_getsize.assert_called_once()
mock_get_duration.assert_called_once()
mock_video_repo.create.assert_called_once()
async def test_upload_video_no_filename(self, video_service):
"""Test uploading a video with no filename."""
# Arrange
mock_file = MagicMock(spec=UploadFile)
mock_file.filename = None
# Act & Assert
with pytest.raises(HTTPException) as excinfo:
await video_service.upload_video(mock_file)
assert excinfo.value.status_code == 400
assert "No file provided" in str(excinfo.value.detail)
def test_get_video_metadata(self, video_service, mock_video_repo):
"""Test getting video metadata."""
# Arrange
video_id = "test-video-id"
mock_video = MagicMock()
mock_video.id = video_id
mock_video.original_filename = "test_video.mp4"
mock_video.upload_date = "2023-01-01T00:00:00"
mock_video.size = 1000
mock_video.duration = 10.0
mock_video.status = "uploaded"
mock_video_repo.get_by_id.return_value = mock_video
# Act
result = video_service.get_video_metadata(video_id)
# Assert
assert isinstance(result, VideoMetadata)
assert result.video_id == video_id
assert result.original_filename == "test_video.mp4"
assert result.size == 1000
assert result.duration == 10.0
assert result.status == "uploaded"
mock_video_repo.get_by_id.assert_called_once_with(video_id)
def test_get_video_metadata_not_found(self, video_service, mock_video_repo):
"""Test getting video metadata for a video that doesn't exist."""
# Arrange
video_id = "non-existent-id"
mock_video_repo.get_by_id.return_value = None
# Act & Assert
with pytest.raises(HTTPException) as excinfo:
video_service.get_video_metadata(video_id)
assert excinfo.value.status_code == 404
assert "Video not found" in str(excinfo.value.detail)
mock_video_repo.get_by_id.assert_called_once_with(video_id)
def test_list_videos(self, video_service, mock_video_repo):
"""Test listing videos."""
# Arrange
mock_video1 = MagicMock()
mock_video1.id = "test-video-id-1"
mock_video1.original_filename = "test_video1.mp4"
mock_video1.upload_date = "2023-01-01T00:00:00"
mock_video1.size = 1000
mock_video1.duration = 10.0
mock_video1.status = "uploaded"
mock_video2 = MagicMock()
mock_video2.id = "test-video-id-2"
mock_video2.original_filename = "test_video2.mp4"
mock_video2.upload_date = "2023-01-02T00:00:00"
mock_video2.size = 2000
mock_video2.duration = 20.0
mock_video2.status = "completed"
mock_video_repo.get_all.return_value = [mock_video1, mock_video2]
# Act
result = video_service.list_videos()
# Assert
assert isinstance(result, list)
assert len(result) == 2
assert all(isinstance(item, VideoMetadata) for item in result)
assert result[0].video_id == "test-video-id-1"
assert result[1].video_id == "test-video-id-2"
mock_video_repo.get_all.assert_called_once()
def test_delete_video_with_results(self, video_service, mock_video_repo, mock_results_repo):
"""Test deleting a video with associated processing results."""
# Arrange
video_id = "test-video-id"
file_path = "/path/to/test_video.mp4"
mock_video = MagicMock()
mock_video.id = video_id
mock_video.file_path = file_path
mock_video_repo.get_by_id.return_value = mock_video
mock_video_repo.delete.return_value = True
# Mock os.path.exists and os.remove
with patch('os.path.exists', return_value=True), \
patch('os.remove') as mock_remove:
# Act
result = video_service.delete_video(video_id)
# Assert
assert result is True
mock_video_repo.get_by_id.assert_called_once_with(video_id)
mock_results_repo.delete_by_video_id.assert_called_once_with(video_id)
mock_video_repo.delete.assert_called_once_with(video_id)
mock_remove.assert_called_once_with(file_path)
def test_delete_video_not_found(self, video_service, mock_video_repo):
"""Test deleting a video that doesn't exist."""
# Arrange
video_id = "non-existent-id"
mock_video_repo.get_by_id.return_value = None
# Act & Assert
with pytest.raises(VideoNotFoundError):
video_service.delete_video(video_id)
mock_video_repo.get_by_id.assert_called_once_with(video_id)
mock_video_repo.delete.assert_not_called()