""" 测试 qBittorrent 下载器 """ import pytest import requests from unittest.mock import Mock, patch, MagicMock from loguru import logger import sys import os # 添加项目路径 sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..')) from ariaDownloaderService.QbittorrentDownloader import QbittorrentDownloader from dataService.dto.SeedInfo import SeedInfo class TestQbittorrentDownloader: """qBittorrent 下载器测试类""" def setup_method(self): """每个测试方法前的设置""" # 配置 loguru 输出到控制台 logger.remove() logger.add(sys.stderr, level="DEBUG") def test_initialization_without_auth(self): """测试不使用认证的初始化""" downloader = QbittorrentDownloader( host="192.168.123.199", api_port=8085 ) assert downloader.host == "192.168.123.199" assert downloader.api_port == 8085 assert downloader.api_base_url == "http://192.168.123.199:8085/api/v2" assert downloader.username == "" assert downloader.password == "" logger.info("不使用认证的初始化测试通过") def test_initialization_with_auth(self): """测试使用认证的初始化""" downloader = QbittorrentDownloader( host="192.168.123.199", api_port=8085, username="admin", password="GUOxy.5157" ) assert downloader.host == "192.168.123.199" assert downloader.api_port == 8085 assert downloader.username == "admin" assert downloader.password == "GUOxy.5157" assert downloader.api_base_url == "http://192.168.123.199:8085/api/v2" logger.info("使用认证的初始化测试通过") @patch('ariaDownloaderService.QbittorrentDownloader.session.post') def test_download_by_magnet_success(self, mock_post): """测试通过 magnet 链接成功添加下载任务""" # 模拟成功的响应 mock_response = Mock() mock_response.status_code = 200 mock_response.text = "" mock_post.return_value = mock_response downloader = QbittorrentDownloader( host="192.168.123.199", api_port=8085 ) magnet_url = "magnet:?xt=urn:btih:1234567890abcdef" result = downloader.download_by_magnet(magnet_url) assert result == "1" mock_post.assert_called_once() # 验证请求参数 call_args = mock_post.call_args assert call_args[0][0] == "http://192.168.123.199:8085/api/v2/torrents/add" assert call_args[1]['data']['urls'] == magnet_url logger.info("通过 magnet 链接成功添加下载任务测试通过") @patch('ariaDownloaderService.QbittorrentDownloader.session.post') def test_download_by_magnet_failure_status(self, mock_post): """测试请求返回非200状态码的情况""" # 模拟失败的响应 mock_response = Mock() mock_response.status_code = 500 mock_response.text = "Internal Server Error" mock_post.return_value = mock_response downloader = QbittorrentDownloader( host="192.168.123.199", api_port=8085 ) magnet_url = "magnet:?xt=urn:btih:1234567890abcdef" result = downloader.download_by_magnet(magnet_url) assert result == "-1" logger.info("请求返回非200状态码测试通过") @patch('ariaDownloaderService.QbittorrentDownloader.session.post') def test_download_by_magnet_exception(self, mock_post): """测试请求过程中发生异常的情况""" # 模拟异常 mock_post.side_effect = requests.exceptions.ConnectionError("Connection refused") downloader = QbittorrentDownloader( host="192.168.123.199", api_port=8085 ) magnet_url = "magnet:?xt=urn:btih:1234567890abcdef" result = downloader.download_by_magnet(magnet_url) assert result == "0" logger.info("请求过程中发生异常测试通过") @patch('ariaDownloaderService.QbittorrentDownloader.session.post') def test_download_by_seed_success(self, mock_post): """测试通过种子信息成功添加下载任务""" # 模拟成功的响应 mock_response = Mock() mock_response.status_code = 200 mock_response.text = "" mock_post.return_value = mock_response # 创建种子信息对象 seed_info = SeedInfo(name="测试种子", seedUrl="magnet:?xt=urn:btih:1234567890abcdef") downloader = QbittorrentDownloader( host="192.168.123.199", api_port=8085 ) result = downloader.download_by_seed(seed_info) assert result == "1" mock_post.assert_called_once() # 验证传递的 URL 是种子信息中的 seedUrl call_args = mock_post.call_args assert call_args[1]['data']['urls'] == "magnet:?xt=urn:btih:1234567890abcdef" logger.info("通过种子信息成功添加下载任务测试通过") @patch('ariaDownloaderService.QbittorrentDownloader.session.post') def test_download_by_seed_empty_url(self, mock_post): """测试种子信息中没有 URL 的情况""" # 创建种子信息对象,seedUrl 为空 seed_info = SeedInfo(name="测试种子", seedUrl=None) downloader = QbittorrentDownloader( host="192.168.123.199", api_port=8085 ) result = downloader.download_by_seed(seed_info) assert result == "0" logger.info("种子信息中没有 URL 测试通过") @patch('ariaDownloaderService.QbittorrentDownloader.session.post') def test_download_by_magnet_with_options(self, mock_post): """测试带保存路径和分类的下载""" # 模拟成功的响应 mock_response = Mock() mock_response.status_code = 200 mock_response.text = "" mock_post.return_value = mock_response downloader = QbittorrentDownloader( host="192.168.123.199", api_port=8085 ) magnet_url = "magnet:?xt=urn:btih:1234567890abcdef" result = downloader.download_by_magnet( magnet_url, save_path="/downloads/test", category="movies", tags="test" ) assert result == "1" # 验证请求参数包含所有选项 call_args = mock_post.call_args data = call_args[1]['data'] assert data['urls'] == magnet_url assert data['savepath'] == "/downloads/test" assert data['category'] == "movies" assert data['tags'] == "test" logger.info("带保存路径和分类的下载测试通过") @patch('ariaDownloaderService.QbittorrentDownloader.session.get') def test_test_connection_success(self, mock_get): """测试连接测试成功""" # 模拟成功的响应 mock_response = Mock() mock_response.status_code = 200 mock_response.text = "v4.6.0" mock_get.return_value = mock_response downloader = QbittorrentDownloader( host="192.168.123.199", api_port=8085 ) result = downloader.test_connection() assert result is True mock_get.assert_called_once_with("http://192.168.123.199:8085/api/v2/app/version") logger.info("连接测试成功测试通过") @patch('ariaDownloaderService.QbittorrentDownloader.session.get') def test_test_connection_failure(self, mock_get): """测试连接测试失败""" # 模拟失败的响应 mock_response = Mock() mock_response.status_code = 404 mock_get.return_value = mock_response downloader = QbittorrentDownloader( host="192.168.123.199", api_port=8085 ) result = downloader.test_connection() assert result is False logger.info("连接测试失败测试通过") @patch('ariaDownloaderService.QbittorrentDownloader.session.get') def test_get_downloads_success(self, mock_get): """测试获取下载列表成功""" # 模拟成功的响应 mock_response = Mock() mock_response.status_code = 200 mock_response.json.return_value = [ {"name": "测试任务1", "progress": 50}, {"name": "测试任务2", "progress": 100} ] mock_get.return_value = mock_response downloader = QbittorrentDownloader( host="192.168.123.199", api_port=8085 ) result = downloader.get_downloads() assert len(result) == 2 assert result[0]["name"] == "测试任务1" mock_get.assert_called_once_with("http://192.168.123.199:8085/api/v2/torrents/info") logger.info("获取下载列表成功测试通过") @patch('ariaDownloaderService.QbittorrentDownloader.session.get') def test_get_downloads_failure(self, mock_get): """测试获取下载列表失败""" # 模拟失败的响应 mock_response = Mock() mock_response.status_code = 500 mock_get.return_value = mock_response downloader = QbittorrentDownloader( host="192.168.123.199", api_port=8085 ) result = downloader.get_downloads() assert result == [] logger.info("获取下载列表失败测试通过") def run_tests(): """运行所有测试""" pytest.main([ __file__, "-v", "--tb=short", "--log-cli-level=INFO" ]) if __name__ == "__main__": run_tests()