feat: 添加 NotificationService 通知服务 + 测试
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
from datetime import datetime
|
||||
from typing import Any, Dict, List
|
||||
from app.config import settings
|
||||
from app.wechat.client import WeChatClient
|
||||
|
||||
|
||||
class NotificationService:
|
||||
def __init__(self):
|
||||
self.client = WeChatClient()
|
||||
|
||||
async def send(self, announcements: List[Dict[str, Any]]) -> int:
|
||||
if not settings.wechat_enabled:
|
||||
return 0
|
||||
if not announcements:
|
||||
return 0
|
||||
|
||||
sent = 0
|
||||
for ann in announcements:
|
||||
try:
|
||||
title = ann.get("title", "")
|
||||
if len(title) > 128:
|
||||
title = title[:125] + "..."
|
||||
|
||||
purchase_name = ann.get("purchase_name", "")
|
||||
if len(purchase_name) > 25:
|
||||
purchase_name = purchase_name[:22] + "..."
|
||||
|
||||
pub_date = ann.get("publish_date")
|
||||
time_str = pub_date.strftime("%Y-%m-%d %H:%M") if pub_date else "时间未知"
|
||||
|
||||
source_name = ann.get("source_name", "")
|
||||
|
||||
description = (
|
||||
f'<div style="font-size: 14px; margin-top: 8px;">'
|
||||
f'{source_name} | {purchase_name} | {time_str}'
|
||||
f'</div>'
|
||||
)
|
||||
|
||||
url = ann.get("content_url", "")
|
||||
|
||||
if await self.client.send_textcard(title, description, url):
|
||||
sent += 1
|
||||
except Exception:
|
||||
continue
|
||||
|
||||
return sent
|
||||
@@ -0,0 +1,40 @@
|
||||
import pytest
|
||||
from unittest.mock import AsyncMock, patch
|
||||
from app.services.notification_service import NotificationService
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_notification_send():
|
||||
svc = NotificationService()
|
||||
announcements = [
|
||||
{
|
||||
"title": "测试公告",
|
||||
"publish_date": None,
|
||||
"purchase_name": "测试单位",
|
||||
"content_url": "https://x.com/1",
|
||||
"source_code": "test",
|
||||
"source_name": "测试来源",
|
||||
"announcement_type": "purchase",
|
||||
}
|
||||
]
|
||||
|
||||
with patch.object(svc.client, "send_textcard", AsyncMock(return_value=True)):
|
||||
count = await svc.send(announcements)
|
||||
assert count == 1
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_notification_send_empty():
|
||||
svc = NotificationService()
|
||||
count = await svc.send([])
|
||||
assert count == 0
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_notification_send_disabled():
|
||||
svc = NotificationService()
|
||||
announcements = [{"title": "test"}]
|
||||
|
||||
with patch.object(svc.client, "send_textcard", AsyncMock(return_value=False)):
|
||||
count = await svc.send(announcements)
|
||||
assert count == 0
|
||||
Reference in New Issue
Block a user