import pytest from unittest.mock import patch, MagicMock from app.pipeline import youtube @pytest.fixture def fresh_db(monkeypatch, tmp_path): from app import db monkeypatch.setattr(db, "DB_PATH", str(tmp_path / "music.db")) db.init_db() return db def _setup_token(db_module): db_module.upsert_oauth_token( channel_id="UC1", channel_title="t", avatar_url=None, refresh_token="r1", access_token="a1", expires_at="2099-01-01T00:00:00", ) @patch("app.pipeline.youtube._build_youtube_client") def test_upload_succeeds_after_resumable(mock_client, fresh_db, tmp_path, monkeypatch): monkeypatch.setenv("YOUTUBE_OAUTH_CLIENT_ID", "cid") monkeypatch.setenv("YOUTUBE_OAUTH_CLIENT_SECRET", "sec") _setup_token(fresh_db) yt = MagicMock() insert = MagicMock() # next_chunk: first call returns (None, None), second returns (None, response with id) insert.next_chunk.side_effect = [(None, None), (None, {"id": "VID123"})] yt.videos().insert.return_value = insert mock_client.return_value = yt video_path = tmp_path / "v.mp4" video_path.write_bytes(b"\x00" * 100) out = youtube.upload_video( video_path=str(video_path), thumbnail_path=None, metadata={"title": "T", "description": "D", "tags": ["x"], "category_id": 10}, privacy="private", ) assert out["video_id"] == "VID123" def test_upload_no_token_raises(fresh_db, tmp_path): video_path = tmp_path / "v.mp4" video_path.write_bytes(b"\x00") with pytest.raises(youtube.NotAuthenticatedError): youtube.upload_video( video_path=str(video_path), thumbnail_path=None, metadata={"title":"T","description":"D","tags":[],"category_id":10}, privacy="private", ) @patch("app.pipeline.youtube._build_youtube_client") def test_upload_quota_exceeded_marks_quota(mock_client, fresh_db, tmp_path, monkeypatch): from googleapiclient.errors import HttpError monkeypatch.setenv("YOUTUBE_OAUTH_CLIENT_ID", "cid") monkeypatch.setenv("YOUTUBE_OAUTH_CLIENT_SECRET", "sec") _setup_token(fresh_db) yt = MagicMock() err = HttpError(MagicMock(status=403), b'{"error":{"errors":[{"reason":"quotaExceeded"}]}}') insert_call = MagicMock() insert_call.next_chunk.side_effect = err yt.videos().insert.return_value = insert_call mock_client.return_value = yt video_path = tmp_path / "v.mp4" video_path.write_bytes(b"\x00") with pytest.raises(youtube.QuotaExceededError): youtube.upload_video( video_path=str(video_path), thumbnail_path=None, metadata={"title":"T","description":"D","tags":[],"category_id":10}, privacy="private", ) def test_get_status_returns_none_when_not_connected(fresh_db): assert youtube.get_status() is None def test_get_status_returns_channel_info(fresh_db): _setup_token(fresh_db) s = youtube.get_status() assert s["channel_id"] == "UC1" assert s["channel_title"] == "t"