Docs: [3.0.0] 전체 문서 업데이트 — YouTube Data API + n8n Discord 전송 구조 반영
All checks were successful
news-summary-bot-cicd / build_push_deploy (push) Successful in 25m15s
All checks were successful
news-summary-bot-cicd / build_push_deploy (push) Successful in 25m15s
- README: 아키텍처, 환경변수, API 응답 형식 업데이트 - n8n-setup: RSS → YouTube Data API playlistItems 전환, 노드별 상세 설정 - development: discord.py 제거 반영, API 응답 형식 추가 - operations: CI/CD 자동 배포 설명, DISCORD_WEBHOOK_URL 제거 - testing: DISCORD_WEBHOOK_URL 더미값 제거 - .env.example: DISCORD_WEBHOOK_URL 제거 - tests/test_discord.py 삭제 (모듈 삭제됨) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,137 +0,0 @@
|
||||
"""discord.py 유닛 테스트 — 파싱, 비디오 ID 추출, 임베드 구성."""
|
||||
|
||||
from unittest.mock import AsyncMock, patch
|
||||
|
||||
import pytest
|
||||
|
||||
from app.discord import _extract_video_id, _parse_summary, send_to_discord
|
||||
|
||||
|
||||
# ── _extract_video_id ──
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"url, expected",
|
||||
[
|
||||
("https://youtu.be/abc123", "abc123"),
|
||||
("https://www.youtube.com/watch?v=xyz789", "xyz789"),
|
||||
("https://www.youtube.com/watch?v=xyz789&t=10", "xyz789"),
|
||||
("https://youtu.be/abc123?si=something", "abc123"),
|
||||
("https://example.com/no-video", None),
|
||||
],
|
||||
)
|
||||
def test_extract_video_id(url: str, expected: str | None):
|
||||
assert _extract_video_id(url) == expected
|
||||
|
||||
|
||||
# ── _parse_summary ──
|
||||
|
||||
|
||||
SAMPLE_SUMMARY_BOLD = """\
|
||||
- **한줄 요약**: 한국 경제가 위기에 처했다.
|
||||
|
||||
- **주요 내용**:
|
||||
- GDP 성장률 하락
|
||||
- 수출 감소
|
||||
- 환율 불안정
|
||||
|
||||
- **결론/시사점**: 정부의 적극적 대응이 필요하다.
|
||||
"""
|
||||
|
||||
SAMPLE_SUMMARY_HEADING = """\
|
||||
## 한줄 요약
|
||||
한국 경제가 위기에 처했다.
|
||||
|
||||
## 주요 내용
|
||||
- GDP 성장률 하락
|
||||
- 수출 감소
|
||||
- 환율 불안정
|
||||
|
||||
## 결론/시사점
|
||||
정부의 적극적 대응이 필요하다.
|
||||
"""
|
||||
|
||||
|
||||
def test_parse_summary_bold_format():
|
||||
result = _parse_summary(SAMPLE_SUMMARY_BOLD)
|
||||
assert "한줄요약" in result
|
||||
assert "한국 경제가 위기에 처했다." in result["한줄요약"]
|
||||
assert "주요내용" in result
|
||||
assert "GDP 성장률 하락" in result["주요내용"]
|
||||
assert "결론/시사점" in result or "결론시사점" in result
|
||||
|
||||
|
||||
def test_parse_summary_heading_format():
|
||||
result = _parse_summary(SAMPLE_SUMMARY_HEADING)
|
||||
assert "한줄요약" in result
|
||||
assert "한국 경제가 위기에 처했다." in result["한줄요약"]
|
||||
assert "주요내용" in result
|
||||
assert "GDP 성장률 하락" in result["주요내용"]
|
||||
|
||||
|
||||
def test_parse_summary_empty():
|
||||
result = _parse_summary("이건 파싱 안 되는 텍스트")
|
||||
assert result == {}
|
||||
|
||||
|
||||
# ── send_to_discord ──
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_send_to_discord_embed_structure():
|
||||
"""send_to_discord가 올바른 임베드 구조로 웹훅을 호출하는지 확인."""
|
||||
mock_response = AsyncMock()
|
||||
mock_response.raise_for_status = lambda: None
|
||||
|
||||
with patch("app.discord.httpx.AsyncClient") as mock_client_cls:
|
||||
mock_client = AsyncMock()
|
||||
mock_client.post.return_value = mock_response
|
||||
mock_client_cls.return_value.__aenter__ = AsyncMock(return_value=mock_client)
|
||||
mock_client_cls.return_value.__aexit__ = AsyncMock(return_value=False)
|
||||
|
||||
await send_to_discord(
|
||||
title="테스트 영상",
|
||||
video_url="https://youtu.be/abc123",
|
||||
summary=SAMPLE_SUMMARY_BOLD,
|
||||
)
|
||||
|
||||
mock_client.post.assert_called_once()
|
||||
payload = mock_client.post.call_args[1]["json"]
|
||||
|
||||
embed = payload["embeds"][0]
|
||||
assert "📰 테스트 영상" == embed["title"]
|
||||
assert embed["url"] == "https://youtu.be/abc123"
|
||||
assert embed["thumbnail"]["url"] == "https://img.youtube.com/vi/abc123/hqdefault.jpg"
|
||||
assert embed["footer"]["text"] == "YouTube 뉴스 요약 봇"
|
||||
assert "timestamp" in embed
|
||||
|
||||
# 필드 확인
|
||||
field_names = [f["name"] for f in embed["fields"]]
|
||||
assert "📋 주요 내용" in field_names
|
||||
assert "🎯 결론 / 시사점" in field_names
|
||||
assert "🔗 원본 영상" in field_names
|
||||
|
||||
# description에 한줄 요약 포함
|
||||
assert "한국 경제가 위기에 처했다" in embed["description"]
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_send_to_discord_fallback_on_unparsable():
|
||||
"""파싱 실패 시 전체 summary가 description에 들어가는지 확인."""
|
||||
mock_response = AsyncMock()
|
||||
mock_response.raise_for_status = lambda: None
|
||||
|
||||
with patch("app.discord.httpx.AsyncClient") as mock_client_cls:
|
||||
mock_client = AsyncMock()
|
||||
mock_client.post.return_value = mock_response
|
||||
mock_client_cls.return_value.__aenter__ = AsyncMock(return_value=mock_client)
|
||||
mock_client_cls.return_value.__aexit__ = AsyncMock(return_value=False)
|
||||
|
||||
raw = "이건 섹션 없는 요약 텍스트입니다."
|
||||
await send_to_discord("테스트", "https://youtu.be/abc", raw)
|
||||
|
||||
payload = mock_client.post.call_args[1]["json"]
|
||||
embed = payload["embeds"][0]
|
||||
assert embed["description"] == raw
|
||||
assert len(embed["fields"]) == 1
|
||||
assert embed["fields"][0]["name"] == "🔗 원본 영상"
|
||||
Reference in New Issue
Block a user