feat: restore zhihu browser skills
Reconnect the recovered Zhihu skill flows to the live browser runtime and resolve their resources relative to the executable so they work outside the repo root. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
441
tests/skill_router_test.rs
Normal file
441
tests/skill_router_test.rs
Normal file
@@ -0,0 +1,441 @@
|
||||
use sgclaw::skill::router::{route_instruction, RoutedSkill, RouterError};
|
||||
|
||||
#[test]
|
||||
fn route_instruction_parses_explicit_zhihu_skill() {
|
||||
let routed = route_instruction(
|
||||
r#"skill:zhihu_write {"title":"自动发文能力测试","body":"第一段\n\n第二段","publish":false}"#,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
assert!(matches!(
|
||||
routed,
|
||||
Some(RoutedSkill::ZhihuWrite(req))
|
||||
if req.title == "自动发文能力测试"
|
||||
&& req.body == "第一段\n\n第二段"
|
||||
&& !req.publish
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn route_instruction_parses_explicit_zhihu_hotlist_collect_skill() {
|
||||
let routed = route_instruction(
|
||||
r#"skill:zhihu_hotlist_collect {"top_n":5,"comments_per_item":8,"store_dir":"data/zhihu_hotlist"}"#,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
assert!(matches!(
|
||||
routed,
|
||||
Some(RoutedSkill::ZhihuHotlistCollect(req))
|
||||
if req.top_n == 5
|
||||
&& req.comments_per_item == 8
|
||||
&& req.store_dir.as_deref() == Some("data/zhihu_hotlist")
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn route_instruction_parses_explicit_zhihu_hotlist_report_skill() {
|
||||
let routed =
|
||||
route_instruction(r#"skill:zhihu_hotlist_report {"snapshot_id":"snap-1","top_n":3}"#)
|
||||
.unwrap();
|
||||
|
||||
assert!(matches!(
|
||||
routed,
|
||||
Some(RoutedSkill::ZhihuHotlistReport(req))
|
||||
if req.snapshot_id.as_deref() == Some("snap-1")
|
||||
&& req.top_n == 3
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn route_instruction_parses_explicit_zhihu_navigation_skill() {
|
||||
let routed = route_instruction(
|
||||
r#"skill:zhihu_navigate {"page":"content_analysis","ensure_loaded":true}"#,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
assert!(matches!(
|
||||
routed,
|
||||
Some(RoutedSkill::ZhihuNavigate(req))
|
||||
if req.page == "content_analysis" && req.ensure_loaded
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn route_instruction_routes_zhihu_content_analysis_natural_language() {
|
||||
let routed = route_instruction("帮我打开知乎中的内容分析页面").unwrap();
|
||||
|
||||
assert!(matches!(
|
||||
routed,
|
||||
Some(RoutedSkill::ZhihuNavigate(req))
|
||||
if req.page == "content_analysis" && req.ensure_loaded
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn route_instruction_routes_short_zhihu_content_analysis_phrase() {
|
||||
let routed = route_instruction("打开知乎内容分析").unwrap();
|
||||
|
||||
assert!(matches!(
|
||||
routed,
|
||||
Some(RoutedSkill::ZhihuNavigate(req))
|
||||
if req.page == "content_analysis" && req.ensure_loaded
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn route_instruction_routes_zhihu_income_analysis_natural_language() {
|
||||
let routed = route_instruction("打开知乎收益分析页面").unwrap();
|
||||
|
||||
assert!(matches!(
|
||||
routed,
|
||||
Some(RoutedSkill::ZhihuNavigate(req))
|
||||
if req.page == "income_analysis" && req.ensure_loaded
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn route_instruction_routes_zhihu_home_natural_language() {
|
||||
let routed = route_instruction("打开知乎首页").unwrap();
|
||||
|
||||
assert!(matches!(
|
||||
routed,
|
||||
Some(RoutedSkill::ZhihuNavigate(req))
|
||||
if req.page == "home" && req.ensure_loaded
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn route_instruction_routes_zhihu_hot_list_natural_language() {
|
||||
let routed = route_instruction("打开知乎热榜页面").unwrap();
|
||||
|
||||
assert!(matches!(
|
||||
routed,
|
||||
Some(RoutedSkill::ZhihuNavigate(req))
|
||||
if req.page == "hot_list" && req.ensure_loaded
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn route_instruction_routes_zhihu_column_home_natural_language() {
|
||||
let routed = route_instruction("打开知乎专栏页").unwrap();
|
||||
|
||||
assert!(matches!(
|
||||
routed,
|
||||
Some(RoutedSkill::ZhihuNavigate(req))
|
||||
if req.page == "column_home" && req.ensure_loaded
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn route_instruction_routes_zhihu_question_page_natural_language() {
|
||||
let routed = route_instruction("打开知乎问题页").unwrap();
|
||||
|
||||
assert!(matches!(
|
||||
routed,
|
||||
Some(RoutedSkill::ZhihuNavigate(req))
|
||||
if req.page == "question_page" && req.ensure_loaded
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn route_instruction_routes_zhihu_messages_page_natural_language() {
|
||||
let routed = route_instruction("打开知乎消息分栏").unwrap();
|
||||
|
||||
assert!(matches!(
|
||||
routed,
|
||||
Some(RoutedSkill::ZhihuNavigate(req))
|
||||
if req.page == "messages_page" && req.ensure_loaded
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn route_instruction_routes_zhihu_messages_all_tab_natural_language() {
|
||||
let routed = route_instruction("打开知乎消息分栏全部私信").unwrap();
|
||||
|
||||
assert!(matches!(
|
||||
routed,
|
||||
Some(RoutedSkill::ZhihuNavigate(req))
|
||||
if req.page == "messages_all_tab" && req.ensure_loaded
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn route_instruction_routes_zhihu_messages_unread_tab_natural_language() {
|
||||
let routed = route_instruction("打开知乎消息分栏未读消息").unwrap();
|
||||
|
||||
assert!(matches!(
|
||||
routed,
|
||||
Some(RoutedSkill::ZhihuNavigate(req))
|
||||
if req.page == "messages_unread_tab" && req.ensure_loaded
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn route_instruction_routes_zhihu_messages_strangers_tab_natural_language() {
|
||||
let routed = route_instruction("打开知乎消息分栏陌生人消息").unwrap();
|
||||
|
||||
assert!(matches!(
|
||||
routed,
|
||||
Some(RoutedSkill::ZhihuNavigate(req))
|
||||
if req.page == "messages_strangers_tab" && req.ensure_loaded
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn route_instruction_routes_zhihu_messages_settings_menu_natural_language() {
|
||||
let routed = route_instruction("打开知乎消息设置菜单").unwrap();
|
||||
|
||||
assert!(matches!(
|
||||
routed,
|
||||
Some(RoutedSkill::ZhihuNavigate(req))
|
||||
if req.page == "messages_settings_menu" && req.ensure_loaded
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn route_instruction_routes_zhihu_notifications_page_natural_language() {
|
||||
let routed = route_instruction("打开知乎通知分栏").unwrap();
|
||||
|
||||
assert!(matches!(
|
||||
routed,
|
||||
Some(RoutedSkill::ZhihuNavigate(req))
|
||||
if req.page == "notifications_page" && req.ensure_loaded
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn route_instruction_routes_zhihu_notifications_replies_tab_natural_language() {
|
||||
let routed = route_instruction("打开知乎通知分栏回复我的").unwrap();
|
||||
|
||||
assert!(matches!(
|
||||
routed,
|
||||
Some(RoutedSkill::ZhihuNavigate(req))
|
||||
if req.page == "notifications_replies_tab" && req.ensure_loaded
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn route_instruction_routes_zhihu_notifications_votes_favorites_tab_natural_language() {
|
||||
let routed = route_instruction("打开知乎通知分栏赞同与收藏").unwrap();
|
||||
|
||||
assert!(matches!(
|
||||
routed,
|
||||
Some(RoutedSkill::ZhihuNavigate(req))
|
||||
if req.page == "notifications_votes_favorites_tab" && req.ensure_loaded
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn route_instruction_routes_zhihu_notifications_follows_tab_natural_language() {
|
||||
let routed = route_instruction("打开知乎通知分栏关注我的").unwrap();
|
||||
|
||||
assert!(matches!(
|
||||
routed,
|
||||
Some(RoutedSkill::ZhihuNavigate(req))
|
||||
if req.page == "notifications_follows_tab" && req.ensure_loaded
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn route_instruction_routes_zhihu_notifications_system_tab_natural_language() {
|
||||
let routed = route_instruction("打开知乎通知分栏系统通知").unwrap();
|
||||
|
||||
assert!(matches!(
|
||||
routed,
|
||||
Some(RoutedSkill::ZhihuNavigate(req))
|
||||
if req.page == "notifications_system_tab" && req.ensure_loaded
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn route_instruction_routes_zhihu_notifications_settings_menu_natural_language() {
|
||||
let routed = route_instruction("打开知乎通知设置菜单").unwrap();
|
||||
|
||||
assert!(matches!(
|
||||
routed,
|
||||
Some(RoutedSkill::ZhihuNavigate(req))
|
||||
if req.page == "notifications_settings_menu" && req.ensure_loaded
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn route_instruction_routes_zhihu_profile_page_natural_language() {
|
||||
let routed = route_instruction("打开知乎个人主页").unwrap();
|
||||
|
||||
assert!(matches!(
|
||||
routed,
|
||||
Some(RoutedSkill::ZhihuNavigate(req))
|
||||
if req.page == "profile_page" && req.ensure_loaded
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn route_instruction_routes_zhihu_profile_answers_tab_natural_language() {
|
||||
let routed = route_instruction("打开知乎个人主页回答分栏").unwrap();
|
||||
|
||||
assert!(matches!(
|
||||
routed,
|
||||
Some(RoutedSkill::ZhihuNavigate(req))
|
||||
if req.page == "profile_answers_tab" && req.ensure_loaded
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn route_instruction_routes_zhihu_profile_followers_tab_natural_language() {
|
||||
let routed = route_instruction("打开知乎个人主页粉丝分栏").unwrap();
|
||||
|
||||
assert!(matches!(
|
||||
routed,
|
||||
Some(RoutedSkill::ZhihuNavigate(req))
|
||||
if req.page == "profile_followers_tab" && req.ensure_loaded
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn route_instruction_routes_zhihu_account_settings_natural_language() {
|
||||
let routed = route_instruction("打开知乎账号设置菜单").unwrap();
|
||||
|
||||
assert!(matches!(
|
||||
routed,
|
||||
Some(RoutedSkill::ZhihuNavigate(req))
|
||||
if req.page == "settings_account_menu" && req.ensure_loaded
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn route_instruction_routes_zhihu_privacy_settings_natural_language() {
|
||||
let routed = route_instruction("打开知乎隐私设置菜单").unwrap();
|
||||
|
||||
assert!(matches!(
|
||||
routed,
|
||||
Some(RoutedSkill::ZhihuNavigate(req))
|
||||
if req.page == "settings_privacy_menu" && req.ensure_loaded
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn route_instruction_routes_zhihu_security_settings_natural_language() {
|
||||
let routed = route_instruction("打开知乎安全设置菜单").unwrap();
|
||||
|
||||
assert!(matches!(
|
||||
routed,
|
||||
Some(RoutedSkill::ZhihuNavigate(req))
|
||||
if req.page == "settings_security_menu" && req.ensure_loaded
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn route_instruction_routes_zhihu_search_filter_menu_natural_language() {
|
||||
let routed = route_instruction("打开知乎搜索筛选菜单").unwrap();
|
||||
|
||||
assert!(matches!(
|
||||
routed,
|
||||
Some(RoutedSkill::ZhihuNavigate(req))
|
||||
if req.page == "search_filter_menu" && req.ensure_loaded
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn route_instruction_routes_zhihu_context_more_menu_natural_language() {
|
||||
let routed = route_instruction("打开知乎更多菜单").unwrap();
|
||||
|
||||
assert!(matches!(
|
||||
routed,
|
||||
Some(RoutedSkill::ZhihuNavigate(req))
|
||||
if req.page == "context_more_menu" && req.ensure_loaded
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn route_instruction_routes_zhihu_notifications_menu_natural_language() {
|
||||
let routed = route_instruction("打开知乎通知菜单").unwrap();
|
||||
|
||||
assert!(matches!(
|
||||
routed,
|
||||
Some(RoutedSkill::ZhihuNavigate(req))
|
||||
if req.page == "notifications_menu" && req.ensure_loaded
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn route_instruction_routes_zhihu_notifications_entry_natural_language() {
|
||||
let routed = route_instruction("打开知乎通知按钮").unwrap();
|
||||
|
||||
assert!(matches!(
|
||||
routed,
|
||||
Some(RoutedSkill::ZhihuNavigate(req))
|
||||
if req.page == "notifications_entry" && req.ensure_loaded
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn route_instruction_routes_zhihu_search_box_natural_language() {
|
||||
let routed = route_instruction("打开知乎搜索框").unwrap();
|
||||
|
||||
assert!(matches!(
|
||||
routed,
|
||||
Some(RoutedSkill::ZhihuNavigate(req))
|
||||
if req.page == "search_box" && req.ensure_loaded
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn route_instruction_routes_creator_write_button_natural_language() {
|
||||
let routed = route_instruction("打开知乎创作中心写文章按钮").unwrap();
|
||||
|
||||
assert!(matches!(
|
||||
routed,
|
||||
Some(RoutedSkill::ZhihuNavigate(req))
|
||||
if req.page == "creator_write_button" && req.ensure_loaded
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn route_instruction_routes_open_hot_from_home_flow_natural_language() {
|
||||
let routed = route_instruction("从知乎首页进入热榜").unwrap();
|
||||
|
||||
assert!(matches!(
|
||||
routed,
|
||||
Some(RoutedSkill::ZhihuNavigate(req))
|
||||
if req.page == "open_hot_from_home" && req.ensure_loaded
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn route_instruction_returns_none_for_non_skill_text() {
|
||||
let routed = route_instruction("打开百度搜索天气").unwrap();
|
||||
|
||||
assert!(routed.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn route_instruction_returns_none_for_vague_zhihu_navigation_text() {
|
||||
let routed = route_instruction("打开知乎").unwrap();
|
||||
|
||||
assert!(routed.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn route_instruction_returns_none_for_ambiguous_zhihu_notification_phrase() {
|
||||
let routed = route_instruction("打开知乎通知").unwrap();
|
||||
|
||||
assert!(routed.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn route_instruction_routes_zhihu_hot_button_phrase_to_hot_tab() {
|
||||
let routed = route_instruction("打开知乎热榜按钮").unwrap();
|
||||
|
||||
assert!(matches!(
|
||||
routed,
|
||||
Some(RoutedSkill::ZhihuNavigate(req))
|
||||
if req.page == "hot_tab" && req.ensure_loaded
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn route_instruction_rejects_unknown_skill_name() {
|
||||
let err = route_instruction(r#"skill:unknown {"x":1}"#).unwrap_err();
|
||||
|
||||
assert!(matches!(err, RouterError::UnknownSkill(name) if name == "unknown"));
|
||||
}
|
||||
Reference in New Issue
Block a user