This repository has been archived on 2026-08-07. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
starmen1265 c9ca1b538d refactor(06-02): update CLI and test imports to kb_workflow.pipeline
- Remove sys.path manipulation from kb_workflow.py
- Update CLI imports to use kb_workflow.pipeline prefix
- Update all test file imports and patch paths

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 00:17:10 +08:00

232 lines
8.2 KiB
Python

"""Tests for LinkParser module
Tests URL parsing for various platforms:
- Bilibili video URLs
- Bilibili article URLs
- Zhihu answer URLs
- Zhihu zhuanlan URLs
- Short link resolution (b23.tv)
- Unknown URL handling
"""
import pytest
from unittest.mock import patch, MagicMock
class TestLinkParserBilibiliVideo:
"""Tests for Bilibili video URL parsing"""
def test_parse_bilibili_video_url_returns_correct_parsed_link(self):
"""Test 1: 解析B站视频URL返回正确的 ParsedLink (platform=bilibili, type=video, id=BVxxx)"""
from kb_workflow.pipeline.link_parser import LinkParser, ParsedLink
parser = LinkParser()
result = parser.parse("https://www.bilibili.com/video/BV1GJ411x7Qw")
assert result is not None
assert result.platform == "bilibili"
assert result.content_type == "video"
assert result.content_id == "BV1GJ411x7Qw"
assert result.original_url == "https://www.bilibili.com/video/BV1GJ411x7Qw"
def test_parse_bilibili_video_url_without_www(self):
"""B站视频URL不带www也能正确解析"""
from kb_workflow.pipeline.link_parser import LinkParser
parser = LinkParser()
result = parser.parse("https://bilibili.com/video/BV1GJ411x7Qw")
assert result is not None
assert result.platform == "bilibili"
assert result.content_type == "video"
assert result.content_id == "BV1GJ411x7Qw"
def test_parse_bilibili_video_url_with_http(self):
"""B站视频URL使用http也能正确解析"""
from kb_workflow.pipeline.link_parser import LinkParser
parser = LinkParser()
result = parser.parse("http://www.bilibili.com/video/BV1GJ411x7Qw")
assert result is not None
assert result.platform == "bilibili"
assert result.content_type == "video"
class TestLinkParserBilibiliArticle:
"""Tests for Bilibili article URL parsing"""
def test_parse_bilibili_article_url_returns_correct_parsed_link(self):
"""Test 2: 解析B站专栏URL返回正确的 ParsedLink (platform=bilibili, type=article, id=cvxxx)"""
from kb_workflow.pipeline.link_parser import LinkParser
parser = LinkParser()
result = parser.parse("https://www.bilibili.com/read/cv12345678")
assert result is not None
assert result.platform == "bilibili"
assert result.content_type == "article"
assert result.content_id == "cv12345678"
def test_parse_bilibili_article_url_with_article_prefix(self):
"""B站专栏URL使用article前缀也能正确解析"""
from kb_workflow.pipeline.link_parser import LinkParser
parser = LinkParser()
result = parser.parse("https://www.bilibili.com/article/cv12345678")
assert result is not None
assert result.platform == "bilibili"
assert result.content_type == "article"
assert result.content_id == "cv12345678"
class TestLinkParserZhihuAnswer:
"""Tests for Zhihu answer URL parsing"""
def test_parse_zhihu_answer_url_returns_correct_parsed_link(self):
"""Test 3: 解析知乎问答URL返回正确的 ParsedLink (platform=zhihu, type=answer, id=xxx)"""
from kb_workflow.pipeline.link_parser import LinkParser
parser = LinkParser()
result = parser.parse("https://www.zhihu.com/question/12345678/answer/87654321")
assert result is not None
assert result.platform == "zhihu"
assert result.content_type == "answer"
assert result.content_id == "87654321"
def test_parse_zhihu_answer_url_without_www(self):
"""知乎问答URL不带www也能正确解析"""
from kb_workflow.pipeline.link_parser import LinkParser
parser = LinkParser()
result = parser.parse("https://zhihu.com/question/12345678/answer/87654321")
assert result is not None
assert result.platform == "zhihu"
assert result.content_type == "answer"
class TestLinkParserZhihuZhuanlan:
"""Tests for Zhihu zhuanlan URL parsing"""
def test_parse_zhihu_zhuanlan_url_returns_correct_parsed_link(self):
"""Test 4: 解析知乎专栏URL返回正确的 ParsedLink (platform=zhihu, type=zhuanlan, id=xxx)"""
from kb_workflow.pipeline.link_parser import LinkParser
parser = LinkParser()
result = parser.parse("https://zhuanlan.zhihu.com/p/12345678")
assert result is not None
assert result.platform == "zhihu"
assert result.content_type == "zhuanlan"
assert result.content_id == "12345678"
class TestLinkParserShortLink:
"""Tests for short link resolution"""
@patch("kb_workflow.pipeline.link_parser.requests.head")
def test_parse_b23tv_shortlink_resolves_to_real_url(self, mock_head):
"""Test 5: 解析b23.tv短链返回解析后的真实URL"""
from kb_workflow.pipeline.link_parser import LinkParser
# Mock the redirect response
mock_response = MagicMock()
mock_response.status_code = 200
mock_response.url = "https://www.bilibili.com/video/BV1GJ411x7Qw"
mock_head.return_value = mock_response
parser = LinkParser()
result = parser.parse("https://b23.tv/abc123")
assert result is not None
assert result.platform == "bilibili"
assert result.content_type == "video"
assert result.content_id == "BV1GJ411x7Qw"
assert result.resolved_url == "https://www.bilibili.com/video/BV1GJ411x7Qw"
@patch("kb_workflow.pipeline.link_parser.requests.head")
def test_shortlink_resolution_uses_allow_redirects(self, mock_head):
"""短链解析应该使用 allow_redirects=True"""
from kb_workflow.pipeline.link_parser import LinkParser
mock_response = MagicMock()
mock_response.status_code = 200
mock_response.url = "https://www.bilibili.com/video/BV1GJ411x7Qw"
mock_head.return_value = mock_response
parser = LinkParser()
parser.parse("https://b23.tv/abc123")
mock_head.assert_called_once()
call_kwargs = mock_head.call_args[1]
assert call_kwargs.get("allow_redirects") is True
class TestLinkParserUnknownURL:
"""Tests for unknown URL handling"""
def test_parse_unknown_url_returns_none(self):
"""Test 6: 无法识别的URL返回None(不抛异常)"""
from kb_workflow.pipeline.link_parser import LinkParser
parser = LinkParser()
result = parser.parse("https://www.youtube.com/watch?v=dQw4w9WgXcQ")
assert result is None
def test_parse_invalid_url_returns_none(self):
"""无效URL返回None"""
from kb_workflow.pipeline.link_parser import LinkParser
parser = LinkParser()
result = parser.parse("not a valid url")
assert result is None
def test_parse_empty_string_returns_none(self):
"""空字符串返回None"""
from kb_workflow.pipeline.link_parser import LinkParser
parser = LinkParser()
result = parser.parse("")
assert result is None
class TestParsedLink:
"""Tests for ParsedLink dataclass"""
def test_parsed_link_has_all_required_fields(self):
"""ParsedLink 应包含所有必需字段"""
from kb_workflow.pipeline.link_parser import ParsedLink
link = ParsedLink(
platform="bilibili",
content_type="video",
content_id="BV1GJ411x7Qw",
original_url="https://www.bilibili.com/video/BV1GJ411x7Qw",
resolved_url="https://www.bilibili.com/video/BV1GJ411x7Qw"
)
assert link.platform == "bilibili"
assert link.content_type == "video"
assert link.content_id == "BV1GJ411x7Qw"
assert link.original_url == "https://www.bilibili.com/video/BV1GJ411x7Qw"
assert link.resolved_url == "https://www.bilibili.com/video/BV1GJ411x7Qw"
def test_parsed_link_resolved_url_defaults_to_original(self):
"""ParsedLink 的 resolved_url 默认等于 original_url"""
from kb_workflow.pipeline.link_parser import ParsedLink
link = ParsedLink(
platform="bilibili",
content_type="video",
content_id="BV1GJ411x7Qw",
original_url="https://www.bilibili.com/video/BV1GJ411x7Qw"
)
assert link.resolved_url == link.original_url