O2Sound_ver2_final/backend/tests/api/v1/test_uservideo.py

152 lines
6.3 KiB
Python

import pytest
import os
import tempfile
from unittest.mock import patch, MagicMock
class TestUserVideoAPI:
"""사용자 비디오 스트리밍 관련 API 테스트"""
def test_stream_video_success(self, client):
"""비디오 스트리밍 성공 테스트"""
# 임시 파일 생성
with tempfile.NamedTemporaryFile(delete=False, suffix=".mp4") as tmp_file:
tmp_file.write(b"fake video content")
tmp_filename = os.path.basename(tmp_file.name)
# uploads 디렉토리 mock
with patch('os.path.exists', return_value=True):
with patch('os.path.join', return_value=tmp_file.name):
# 테스트 실행
response = client.get(f"/api/v1/user/video/{tmp_filename}")
# 검증
assert response.status_code == 200
assert response.headers["content-type"] == "video/mp4"
# 임시 파일 삭제
os.unlink(tmp_file.name)
def test_stream_video_not_found(self, client):
"""존재하지 않는 비디오 스트리밍 테스트"""
# 파일이 존재하지 않도록 설정
with patch('os.path.exists', return_value=False):
# 테스트 실행
response = client.get("/api/v1/user/video/non_existent_video.mp4")
# 검증
assert response.status_code == 404
assert response.json()["detail"] == "Video not found"
def test_stream_video_with_encoded_filename(self, client):
"""URL 인코딩된 파일명으로 비디오 스트리밍 테스트"""
# URL 인코딩된 파일명
encoded_filename = "test%20video%20file.mp4"
decoded_filename = "test video file.mp4"
# 임시 파일 생성
with tempfile.NamedTemporaryFile(delete=False, suffix=".mp4") as tmp_file:
tmp_file.write(b"fake video content")
# Mock 설정
with patch('os.path.basename', return_value=decoded_filename):
with patch('os.path.exists', return_value=True):
with patch('os.path.join', return_value=tmp_file.name):
# 테스트 실행
response = client.get(f"/api/v1/user/video/{encoded_filename}")
# 검증
assert response.status_code == 200
assert response.headers["content-type"] == "video/mp4"
# 임시 파일 삭제
os.unlink(tmp_file.name)
def test_stream_video_with_special_characters(self, client):
"""특수문자가 포함된 파일명 테스트"""
# 특수문자가 포함된 파일명
filename = "video@2024#test!.mp4"
# 임시 파일 생성
with tempfile.NamedTemporaryFile(delete=False, suffix=".mp4") as tmp_file:
tmp_file.write(b"fake video content")
# Mock 설정
with patch('os.path.basename', return_value=filename):
with patch('os.path.exists', return_value=True):
with patch('os.path.join', return_value=tmp_file.name):
# 테스트 실행
response = client.get(f"/api/v1/user/video/{filename}")
# 검증
assert response.status_code == 200
# 임시 파일 삭제
os.unlink(tmp_file.name)
def test_stream_video_path_traversal_protection(self, client):
"""경로 탐색 공격 방지 테스트"""
# 경로 탐색 시도
malicious_filename = "../../../etc/passwd"
safe_filename = "passwd"
# basename이 경로를 제거하고 파일명만 반환
with patch('os.path.basename', return_value=safe_filename):
with patch('os.path.exists', return_value=False):
# 테스트 실행
response = client.get(f"/api/v1/user/video/{malicious_filename}")
# 검증 - 파일을 찾을 수 없음
assert response.status_code == 404
def test_stream_video_empty_filename(self, client):
"""빈 파일명으로 요청 테스트"""
# 테스트 실행
response = client.get("/api/v1/user/video/")
# 검증 - 404 (라우트를 찾을 수 없음)
assert response.status_code == 404
def test_stream_video_large_file(self, client):
"""대용량 파일 스트리밍 테스트"""
# 10MB 크기의 임시 파일 생성
with tempfile.NamedTemporaryFile(delete=False, suffix=".mp4") as tmp_file:
# 10MB 더미 데이터 작성
tmp_file.write(b"0" * (10 * 1024 * 1024))
tmp_filename = os.path.basename(tmp_file.name)
# uploads 디렉토리 mock
with patch('os.path.exists', return_value=True):
with patch('os.path.join', return_value=tmp_file.name):
# 테스트 실행
response = client.get(f"/api/v1/user/video/{tmp_filename}")
# 검증
assert response.status_code == 200
assert response.headers["content-type"] == "video/mp4"
# 임시 파일 삭제
os.unlink(tmp_file.name)
def test_stream_video_different_extensions(self, client):
"""다양한 비디오 확장자 테스트"""
extensions = [".mp4", ".avi", ".mov", ".mkv", ".webm"]
for ext in extensions:
# 임시 파일 생성
with tempfile.NamedTemporaryFile(delete=False, suffix=ext) as tmp_file:
tmp_file.write(b"fake video content")
tmp_filename = os.path.basename(tmp_file.name)
# uploads 디렉토리 mock
with patch('os.path.exists', return_value=True):
with patch('os.path.join', return_value=tmp_file.name):
# 테스트 실행
response = client.get(f"/api/v1/user/video/{tmp_filename}")
# 검증 - 모든 확장자가 video/mp4로 반환됨
assert response.status_code == 200
assert response.headers["content-type"] == "video/mp4"
# 임시 파일 삭제
os.unlink(tmp_file.name)