"""HMAC 인증 단위 테스트. - verify_request_hmac: Vercel ↔ backend 요청 시그니처 검증 - verify_upload_token: 일회성 업로드 토큰 검증 (jti 단발성) """ import json import os import time import uuid import pytest from fastapi import HTTPException # 환경변수 먼저 세팅 (auth import 전) os.environ["BACKEND_HMAC_SECRET"] = "test-secret-32-bytes-XXXXXXXXXXXX" from app import auth # noqa: E402 def test_verify_request_hmac_valid(): body = b'{"file_path":"/x"}' ts = str(int(time.time())) sig = auth._sign(ts.encode() + b"." + body) auth.verify_request_hmac(body, ts, sig) # 예외 X def test_verify_request_hmac_expired(): body = b'{}' old_ts = str(int(time.time()) - 600) # 10분 전 sig = auth._sign(old_ts.encode() + b"." + body) with pytest.raises(HTTPException) as exc: auth.verify_request_hmac(body, old_ts, sig) assert exc.value.status_code == 401 def test_verify_request_hmac_wrong_sig(): body = b'{}' ts = str(int(time.time())) with pytest.raises(HTTPException): auth.verify_request_hmac(body, ts, "deadbeef") def test_upload_token_roundtrip(): payload = { "tier": "master", "label": "샘플 영상", "filename": "sample.mp4", "size_bytes": 1024, "expires_at": int(time.time()) + 600, "jti": uuid.uuid4().hex, } token = auth.mint_upload_token(payload) decoded = auth.verify_upload_token(token) assert decoded["filename"] == "sample.mp4" assert decoded["jti"] == payload["jti"] def test_upload_token_replay_rejected(): payload = { "tier": "starter", "label": "x", "filename": "y.pdf", "size_bytes": 1, "expires_at": int(time.time()) + 600, "jti": uuid.uuid4().hex, } token = auth.mint_upload_token(payload) auth.verify_upload_token(token) # 첫 사용 OK with pytest.raises(HTTPException) as exc: auth.verify_upload_token(token) # 재사용 assert "이미" in exc.value.detail or "used" in exc.value.detail.lower() def test_upload_token_expired(): payload = { "tier": "starter", "label": "x", "filename": "y.pdf", "size_bytes": 1, "expires_at": int(time.time()) - 100, "jti": uuid.uuid4().hex, } token = auth.mint_upload_token(payload) with pytest.raises(HTTPException): auth.verify_upload_token(token)