From 2a1db50d8f5c1d0b19ef691163b4a3cabf514aed Mon Sep 17 00:00:00 2001 From: mic1on Date: Thu, 17 Jul 2025 21:41:44 +0800 Subject: [PATCH] =?UTF-8?q?feat(chanify):=20=E6=94=AF=E6=8C=81=E8=87=AA?= =?UTF-8?q?=E5=AE=9A=E4=B9=89base=5Furl=E5=B9=B6=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E6=B5=8B=E8=AF=95=E7=94=A8=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 添加对自定义base_url的支持,当配置中存在base_url时使用自定义地址,否则使用默认地址 同时添加了完整的测试用例,包括同步/异步发送和自定义URL的测试 --- src/use_notify/channels/chanify.py | 8 +- tests/test_chanify.py | 131 +++++++++++++++++++++++++++++ 2 files changed, 138 insertions(+), 1 deletion(-) create mode 100644 tests/test_chanify.py diff --git a/src/use_notify/channels/chanify.py b/src/use_notify/channels/chanify.py index 9fbd6cb..ed9446c 100644 --- a/src/use_notify/channels/chanify.py +++ b/src/use_notify/channels/chanify.py @@ -13,7 +13,13 @@ class Chanify(BaseChannel): @property def api_url(self): - return f"https://api.chanify.net/v1/sender/{self.config.token}" + # Check if base_url exists in config, otherwise use default + if self.config.base_url: + base_url = self.config.base_url.rstrip("/") + else: + base_url = "https://api.chanify.net" + + return f"{base_url}/v1/sender/{self.config.token}" @property def headers(self): diff --git a/tests/test_chanify.py b/tests/test_chanify.py new file mode 100644 index 0000000..6ab4326 --- /dev/null +++ b/tests/test_chanify.py @@ -0,0 +1,131 @@ +import pytest +from unittest.mock import patch, MagicMock + +from use_notify.channels.chanify import Chanify + + +@pytest.fixture +def chanify_config(): + return { + "token": "your_token" + } + + +@pytest.fixture +def custom_chanify_config(): + return { + "token": "your_token", + "base_url": "https://chanify.example.com" + } + + +def test_chanify_send(chanify_config): + # Create a mock for httpx.Client + mock_client = MagicMock() + mock_response = MagicMock() + mock_client.return_value.__enter__.return_value.post.return_value = mock_response + + # Create Chanify instance + chanify = Chanify(chanify_config) + + # Mock the httpx.Client + with patch('httpx.Client', mock_client): + chanify.send("Test Content", "Test Title") + + # Verify the request was made correctly + mock_client.return_value.__enter__.return_value.post.assert_called_once() + + # Get the call arguments + call_args = mock_client.return_value.__enter__.return_value.post.call_args + url = call_args[0][0] + kwargs = call_args[1] + + # Verify URL and headers + assert url == "https://api.chanify.net/v1/sender/your_token" + assert kwargs["headers"]["Content-Type"] == "application/x-www-form-urlencoded" + + # Verify payload + payload = kwargs["data"] + assert payload["text"] == "Test Title\nTest Content" + + +@pytest.mark.asyncio +async def test_chanify_send_async(chanify_config): + # Create a mock for httpx.AsyncClient + mock_client = MagicMock() + mock_response = MagicMock() + mock_client.return_value.__aenter__.return_value.post.return_value = mock_response + + # Create Chanify instance + chanify = Chanify(chanify_config) + + # Mock the httpx.AsyncClient + with patch('httpx.AsyncClient', mock_client): + await chanify.send_async("Test Content", "Test Title") + + # Verify the request was made correctly + mock_client.return_value.__aenter__.return_value.post.assert_called_once() + + # Get the call arguments + call_args = mock_client.return_value.__aenter__.return_value.post.call_args + url = call_args[0][0] + kwargs = call_args[1] + + # Verify URL and headers + assert url == "https://api.chanify.net/v1/sender/your_token" + assert kwargs["headers"]["Content-Type"] == "application/x-www-form-urlencoded" + + # Verify payload + payload = kwargs["data"] + assert payload["text"] == "Test Title\nTest Content" + + +def test_chanify_custom_url(custom_chanify_config): + # Create a mock for httpx.Client + mock_client = MagicMock() + mock_response = MagicMock() + mock_client.return_value.__enter__.return_value.post.return_value = mock_response + + # Create Chanify instance with custom base URL + chanify = Chanify(custom_chanify_config) + + # Mock the httpx.Client + with patch('httpx.Client', mock_client): + chanify.send("Test Content", "Test Title") + + # Verify the request was made correctly + mock_client.return_value.__enter__.return_value.post.assert_called_once() + + # Get the call arguments + call_args = mock_client.return_value.__enter__.return_value.post.call_args + url = call_args[0][0] + + # Verify custom URL is used + assert url == "https://chanify.example.com/v1/sender/your_token" + + +def test_chanify_url_with_trailing_slash(): + # Config with trailing slash in base_url + config = { + "token": "your_token", + "base_url": "https://chanify.example.com/" + } + + # Create a mock for httpx.Client + mock_client = MagicMock() + mock_response = MagicMock() + mock_client.return_value.__enter__.return_value.post.return_value = mock_response + + # Create Chanify instance + chanify = Chanify(config) + + # Mock the httpx.Client + with patch('httpx.Client', mock_client): + chanify.send("Test Content") + + # Get the call arguments + call_args = mock_client.return_value.__enter__.return_value.post.call_args + url = call_args[0][0] + + # Verify URL doesn't have double slashes + assert url == "https://chanify.example.com/v1/sender/your_token" \ No newline at end of file