104 lines
3.0 KiB
Rust
104 lines
3.0 KiB
Rust
use hmac::{Hmac, Mac};
|
|
use serde_json::json;
|
|
use sgclaw::pipe::{Action, AgentMessage, BrowserMessage};
|
|
use sgclaw::security::sign_command;
|
|
use sha2::Sha256;
|
|
|
|
type HmacSha256 = Hmac<Sha256>;
|
|
|
|
#[test]
|
|
fn browser_submit_task_round_trip_uses_task_wire_format() {
|
|
let raw = r#"{"type":"submit_task","instruction":"打开百度并搜索今日汇率","conversation_id":"conversation-1","messages":[{"role":"assistant","content":"上一轮完成"}],"page_url":"https://www.baidu.com/","page_title":"百度一下"}"#;
|
|
let message: BrowserMessage = serde_json::from_str(raw).unwrap();
|
|
|
|
assert_eq!(
|
|
message,
|
|
BrowserMessage::SubmitTask {
|
|
instruction: "打开百度并搜索今日汇率".to_string(),
|
|
conversation_id: "conversation-1".to_string(),
|
|
messages: vec![sgclaw::pipe::ConversationMessage {
|
|
role: "assistant".to_string(),
|
|
content: "上一轮完成".to_string(),
|
|
}],
|
|
page_url: "https://www.baidu.com/".to_string(),
|
|
page_title: "百度一下".to_string(),
|
|
}
|
|
);
|
|
assert_eq!(serde_json::to_string(&message).unwrap(), raw);
|
|
}
|
|
|
|
#[test]
|
|
fn agent_task_complete_and_log_entry_serialize_with_expected_tags() {
|
|
let complete_raw = serde_json::to_string(&AgentMessage::TaskComplete {
|
|
success: true,
|
|
summary: "任务执行完成".to_string(),
|
|
})
|
|
.unwrap();
|
|
let log_raw = serde_json::to_string(&AgentMessage::LogEntry {
|
|
level: "info".to_string(),
|
|
message: "click #submit".to_string(),
|
|
})
|
|
.unwrap();
|
|
|
|
assert_eq!(
|
|
complete_raw,
|
|
r#"{"type":"task_complete","success":true,"summary":"任务执行完成"}"#
|
|
);
|
|
assert_eq!(
|
|
log_raw,
|
|
r#"{"type":"log_entry","level":"info","message":"click #submit"}"#
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn sign_command_uses_newline_canonical_string_with_stable_json() {
|
|
let session_key = vec![1, 2, 3, 4, 5, 6, 7, 8];
|
|
let params = json!({
|
|
"z": 9,
|
|
"a": { "b": 2, "a": 1 }
|
|
});
|
|
let canonical = r#"42
|
|
click
|
|
{"a":{"a":1,"b":2},"z":9}
|
|
oa.example.com"#;
|
|
|
|
let mut mac = HmacSha256::new_from_slice(&session_key).unwrap();
|
|
mac.update(canonical.as_bytes());
|
|
let expected = hex::encode(mac.finalize().into_bytes());
|
|
|
|
let actual = sign_command(&session_key, 42, &Action::Click, ¶ms, "oa.example.com").unwrap();
|
|
assert_eq!(actual, expected);
|
|
}
|
|
|
|
#[test]
|
|
fn sign_command_is_order_independent_for_object_params() {
|
|
let session_key = vec![8, 7, 6, 5, 4, 3, 2, 1];
|
|
let params_a = json!({
|
|
"z": 9,
|
|
"a": { "b": 2, "a": 1 }
|
|
});
|
|
let params_b = json!({
|
|
"a": { "a": 1, "b": 2 },
|
|
"z": 9
|
|
});
|
|
|
|
let sig_a = sign_command(
|
|
&session_key,
|
|
7,
|
|
&Action::Navigate,
|
|
¶ms_a,
|
|
"oa.example.com",
|
|
)
|
|
.unwrap();
|
|
let sig_b = sign_command(
|
|
&session_key,
|
|
7,
|
|
&Action::Navigate,
|
|
¶ms_b,
|
|
"oa.example.com",
|
|
)
|
|
.unwrap();
|
|
|
|
assert_eq!(sig_a, sig_b);
|
|
}
|