Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 103 additions & 0 deletions guards/github-guard/rust-guard/src/labels/response_paths.rs
Original file line number Diff line number Diff line change
Expand Up @@ -640,3 +640,106 @@ pub fn label_response_paths(
// Not a collection or not supported - return None to use resource labels
None
}

#[cfg(test)]
mod tests {
use super::*;
use crate::labels::constants::label_constants;
use serde_json::json;

fn ctx() -> PolicyContext {
PolicyContext::default()
}

#[test]
fn search_repositories_private_gets_secrecy_public_gets_empty() {
let tool_args = json!({});
let response = json!({
"content": [{
"type": "text",
"text": serde_json::to_string(&json!({
"items": [
{"full_name": "octocat/private-repo", "private": true},
{"full_name": "octocat/public-repo", "private": false}
]
}))
.expect("response should serialize")
}]
});

let result = label_response_paths("search_repositories", &tool_args, &response, &ctx())
.expect("should produce path labels");

assert_eq!(result.labeled_paths.len(), 2);

let private_entry = &result.labeled_paths[0];
let public_entry = &result.labeled_paths[1];

assert!(
!private_entry.labels.secrecy.is_empty(),
"private repo should have non-empty secrecy"
);
assert!(
public_entry.labels.secrecy.is_empty(),
"public repo should have empty secrecy"
);
}

#[test]
fn list_pull_requests_merged_pr_gets_merged_integrity() {
let tool_args = json!({"owner": "octocat", "repo": "hello-world"});
let pr = json!({
"number": 1,
"merged_at": "2024-01-01T00:00:00Z",
"base": {"repo": {"full_name": "octocat/hello-world"}},
"head": {"repo": {"full_name": "octocat/hello-world"}}
});
let response = json!({
"content": [{
"type": "text",
"text": serde_json::to_string(&json!([pr])).expect("response should serialize")
}]
});

let result = label_response_paths("list_pull_requests", &tool_args, &response, &ctx())
.expect("should produce path labels");
assert_eq!(result.labeled_paths.len(), 1);

let entry = &result.labeled_paths[0];
let merged_label = format!("{}octocat/hello-world", label_constants::MERGED_PREFIX);
assert!(
entry.labels.integrity.contains(&merged_label),
"merged PR should have merged integrity; got {:?}",
entry.labels.integrity
);
}

#[test]
fn search_issues_uses_repo_qualifier_from_query_scope() {
let tool_args = json!({"query": "is:issue repo:octocat/hello-world bug"});
let response = json!({
"content": [{
"type": "text",
"text": serde_json::to_string(&json!({
"items": [{"number": 42}]
}))
.expect("response should serialize")
}]
});

let result = label_response_paths("search_issues", &tool_args, &response, &ctx())
.expect("search_issues should produce path labels");

assert_eq!(result.labeled_paths.len(), 1);
assert_eq!(
result.labeled_paths[0].labels.description,
"issue:octocat/hello-world#42"
);
}

#[test]
fn unknown_tool_returns_none() {
let result = label_response_paths("unknown_tool", &json!({}), &json!({}), &ctx());
assert!(result.is_none(), "unknown tool should produce no path labels");
}
}
8 changes: 4 additions & 4 deletions guards/github-guard/rust-guard/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ pub struct ResourceLabels {
#[derive(Debug, Serialize)]
struct LabelResourceOutput {
resource: ResourceLabels,
operation: String,
operation: &'static str,
}

/// Input structure for label_response
Expand Down Expand Up @@ -314,7 +314,7 @@ enum ReposValue {
#[derive(Debug, Serialize)]
struct LabelAgentOutput {
agent: AgentLabels,
difc_mode: String,
difc_mode: &'static str,
normalized_policy: NormalizedPolicy,
}

Expand Down Expand Up @@ -567,7 +567,7 @@ pub extern "C" fn label_agent(

let output = LabelAgentOutput {
agent: AgentLabels { secrecy, integrity },
difc_mode: DIFC_MODE.to_string(),
difc_mode: DIFC_MODE,
normalized_policy,
};

Expand Down Expand Up @@ -713,7 +713,7 @@ pub extern "C" fn label_resource(
secrecy: final_secrecy,
integrity: final_integrity,
},
operation: operation.to_string(),
operation,
};

// Serialize output
Expand Down
Loading