152 lines
6.3 KiB
Python
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)
|