| 1 | import sys |
| 2 | import unittest |
| 3 | from pathlib import Path |
| 4 | from unittest.mock import MagicMock, mock_open, patch |
| 5 | |
| 6 | sys.path.insert(0, str(Path(__file__).parent.parent.parent)) |
| 7 | |
| 8 | from app.services.upload_post import UploadPostService |
| 9 | |
| 10 | |
| 11 | _CONFIG_BASE = { |
| 12 | "upload_post_enabled": True, |
| 13 | "upload_post_api_key": "test-key", |
| 14 | "upload_post_username": "testuser", |
| 15 | "upload_post_platforms": ["tiktok", "instagram", "youtube"], |
| 16 | "upload_post_auto_upload": True, |
| 17 | "upload_post_youtube_privacy_status": "unlisted", |
| 18 | } |
| 19 | |
| 20 | |
| 21 | def _mock_response(success=True): |
| 22 | r = MagicMock() |
| 23 | r.json.return_value = {"success": success, "request_id": "abc123"} |
| 24 | r.raise_for_status = MagicMock() |
| 25 | return r |
| 26 | |
| 27 | |
| 28 | def _get(data, key): |
| 29 | for k, v in data: |
| 30 | if k == key: |
| 31 | return v |
| 32 | return None |
| 33 | |
| 34 | |
| 35 | def _get_all(data, key): |
| 36 | return [v for k, v in data if k == key] |
| 37 | |
| 38 | |
| 39 | def _has_key(data, key): |
| 40 | return any(k == key for k, v in data) |
| 41 | |
| 42 | |
| 43 | class TestUploadPostYouTube(unittest.TestCase): |
| 44 | |
| 45 | @patch("app.services.upload_post.config.app", _CONFIG_BASE) |
| 46 | @patch("app.services.upload_post.os.path.exists", return_value=True) |
| 47 | @patch("builtins.open", mock_open(read_data=b"fake")) |
| 48 | @patch("app.services.upload_post.requests.post") |
| 49 | def test_youtube_fields_en_payload(self, mock_post, _exists): |
| 50 | mock_post.return_value = _mock_response() |
| 51 | svc = UploadPostService() |
| 52 | |
| 53 | svc.upload_video("/fake/v.mp4", "Título", youtube_extra={ |
| 54 | "youtube_title": "Mi Short", |
| 55 | "youtube_description": "Descripción", |
| 56 | "tags": ["ia", "shorts"], |
| 57 | "privacyStatus": "unlisted", |
| 58 | }) |
| 59 | |
| 60 | data = mock_post.call_args[1]["data"] |
| 61 | self.assertEqual(_get(data, "youtube_title"), "Mi Short") |
| 62 | self.assertEqual(_get(data, "youtube_description"), "Descripción") |
| 63 | self.assertEqual(_get_all(data, "tags[]"), ["ia", "shorts"]) |
| 64 | self.assertEqual(_get(data, "privacyStatus"), "unlisted") |
| 65 | self.assertEqual(_get(data, "containsSyntheticMedia"), "true") |
| 66 | |
| 67 | @patch("app.services.upload_post.config.app", _CONFIG_BASE) |
| 68 | @patch("app.services.upload_post.os.path.exists", return_value=True) |
| 69 | @patch("builtins.open", mock_open(read_data=b"fake")) |
| 70 | @patch("app.services.upload_post.requests.post") |
| 71 | def test_contains_synthetic_media_siempre_true(self, mock_post, _exists): |
| 72 | mock_post.return_value = _mock_response() |
| 73 | svc = UploadPostService() |
| 74 | |
| 75 | svc.upload_video("/fake/v.mp4", "T", youtube_extra={"containsSyntheticMedia": False}) |
| 76 | |
| 77 | data = mock_post.call_args[1]["data"] |
| 78 | self.assertEqual(_get(data, "containsSyntheticMedia"), "true") |
| 79 | |
| 80 | @patch("app.services.upload_post.config.app", { |
| 81 | **_CONFIG_BASE, |
| 82 | "upload_post_platforms": ["tiktok", "instagram"], |
| 83 | }) |
| 84 | @patch("app.services.upload_post.os.path.exists", return_value=True) |
| 85 | @patch("builtins.open", mock_open(read_data=b"fake")) |
| 86 | @patch("app.services.upload_post.requests.post") |
| 87 | def test_tiktok_instagram_sin_youtube_fields(self, mock_post, _exists): |
| 88 | mock_post.return_value = _mock_response() |
| 89 | svc = UploadPostService() |
| 90 | svc.upload_video("/fake/v.mp4", "T") |
| 91 | |
| 92 | data = mock_post.call_args[1]["data"] |
| 93 | self.assertFalse(_has_key(data, "youtube_title")) |
| 94 | self.assertFalse(_has_key(data, "containsSyntheticMedia")) |
| 95 | self.assertFalse(_has_key(data, "privacyStatus")) |
| 96 | |
| 97 | @patch("app.services.upload_post.config.app", { |
| 98 | **_CONFIG_BASE, |
| 99 | "upload_post_platforms": ["tiktok"], |
| 100 | }) |
| 101 | @patch("app.services.upload_post.os.path.exists", return_value=True) |
| 102 | @patch("builtins.open", mock_open(read_data=b"fake")) |
| 103 | @patch("app.services.upload_post.requests.post") |
| 104 | def test_youtube_extra_ignorado_si_youtube_no_en_platforms(self, mock_post, _exists): |
| 105 | mock_post.return_value = _mock_response() |
| 106 | svc = UploadPostService() |
| 107 | svc.upload_video("/fake/v.mp4", "T", youtube_extra={"youtube_title": "irrelevante"}) |
| 108 | |
| 109 | data = mock_post.call_args[1]["data"] |
| 110 | self.assertFalse(_has_key(data, "youtube_title")) |
| 111 | |
| 112 | @patch("app.services.upload_post.config.app", _CONFIG_BASE) |
| 113 | @patch("app.services.upload_post.os.path.exists", return_value=True) |
| 114 | @patch("builtins.open", mock_open(read_data=b"fake")) |
| 115 | @patch("app.services.upload_post.requests.post") |
| 116 | def test_endpoint_y_platform_format_correcto(self, mock_post, _exists): |
| 117 | mock_post.return_value = _mock_response() |
| 118 | svc = UploadPostService() |
| 119 | svc.upload_video("/fake/v.mp4", "T") |
| 120 | |
| 121 | call_url = mock_post.call_args[0][0] |
| 122 | self.assertTrue(call_url.endswith("/api/upload"), f"Endpoint incorrecto: {call_url}") |
| 123 | |
| 124 | data = mock_post.call_args[1]["data"] |
| 125 | platforms = _get_all(data, "platform[]") |
| 126 | self.assertIn("tiktok", platforms) |
| 127 | self.assertIn("instagram", platforms) |
| 128 | self.assertIn("youtube", platforms) |
| 129 | |
| 130 | |
| 131 | if __name__ == "__main__": |
| 132 | unittest.main() |
| 133 |