145 lines
4.7 KiB
Rust
145 lines
4.7 KiB
Rust
use crate::common::TestServer;
|
|
use serde_json::json;
|
|
|
|
/// Helper: insert a finding directly via MongoDB for testing query endpoints.
|
|
async fn insert_finding(server: &TestServer, repo_id: &str, title: &str, severity: &str) {
|
|
// We insert via the agent's DB by posting to the internal test path.
|
|
// Since there's no direct "create finding" API, we use MongoDB directly.
|
|
let mongodb_uri = std::env::var("TEST_MONGODB_URI")
|
|
.unwrap_or_else(|_| "mongodb://root:example@localhost:27017/?authSource=admin".into());
|
|
|
|
// Extract the database name from the server's unique DB
|
|
// We'll use the agent's internal DB through the stats endpoint to verify
|
|
let client = mongodb::Client::with_uri_str(&mongodb_uri).await.unwrap();
|
|
|
|
// Get the DB name from the test server by parsing the health response
|
|
// For now, we use a direct insert approach
|
|
let db = client.database(&server.db_name());
|
|
|
|
let now = mongodb::bson::DateTime::now();
|
|
db.collection::<mongodb::bson::Document>("findings")
|
|
.insert_one(mongodb::bson::doc! {
|
|
"repo_id": repo_id,
|
|
"fingerprint": format!("fp-{title}-{severity}"),
|
|
"scanner": "test-scanner",
|
|
"scan_type": "sast",
|
|
"title": title,
|
|
"description": format!("Test finding: {title}"),
|
|
"severity": severity,
|
|
"status": "open",
|
|
"created_at": now,
|
|
"updated_at": now,
|
|
})
|
|
.await
|
|
.unwrap();
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn list_findings_empty() {
|
|
let server = TestServer::start().await;
|
|
|
|
let resp = server.get("/api/v1/findings").await;
|
|
assert_eq!(resp.status(), 200);
|
|
|
|
let body: serde_json::Value = resp.json().await.unwrap();
|
|
assert_eq!(body["data"].as_array().unwrap().len(), 0);
|
|
assert_eq!(body["total"], 0);
|
|
|
|
server.cleanup().await;
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn list_findings_with_data() {
|
|
let server = TestServer::start().await;
|
|
|
|
insert_finding(&server, "repo1", "SQL Injection", "critical").await;
|
|
insert_finding(&server, "repo1", "XSS", "high").await;
|
|
insert_finding(&server, "repo2", "Info Leak", "low").await;
|
|
|
|
let resp = server.get("/api/v1/findings").await;
|
|
assert_eq!(resp.status(), 200);
|
|
let body: serde_json::Value = resp.json().await.unwrap();
|
|
assert_eq!(body["total"], 3);
|
|
|
|
// Filter by severity
|
|
let resp = server.get("/api/v1/findings?severity=critical").await;
|
|
let body: serde_json::Value = resp.json().await.unwrap();
|
|
assert_eq!(body["total"], 1);
|
|
assert_eq!(body["data"][0]["title"], "SQL Injection");
|
|
|
|
// Filter by repo
|
|
let resp = server.get("/api/v1/findings?repo_id=repo1").await;
|
|
let body: serde_json::Value = resp.json().await.unwrap();
|
|
assert_eq!(body["total"], 2);
|
|
|
|
server.cleanup().await;
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn update_finding_status() {
|
|
let server = TestServer::start().await;
|
|
|
|
insert_finding(&server, "repo1", "Test Bug", "medium").await;
|
|
|
|
// Get the finding ID
|
|
let resp = server.get("/api/v1/findings").await;
|
|
let body: serde_json::Value = resp.json().await.unwrap();
|
|
let finding_id = body["data"][0]["_id"]["$oid"].as_str().unwrap();
|
|
|
|
// Update status to resolved
|
|
let resp = server
|
|
.patch(
|
|
&format!("/api/v1/findings/{finding_id}/status"),
|
|
&json!({ "status": "resolved" }),
|
|
)
|
|
.await;
|
|
assert_eq!(resp.status(), 200);
|
|
|
|
// Verify it's updated
|
|
let resp = server.get(&format!("/api/v1/findings/{finding_id}")).await;
|
|
assert_eq!(resp.status(), 200);
|
|
let body: serde_json::Value = resp.json().await.unwrap();
|
|
assert_eq!(body["data"]["status"], "resolved");
|
|
|
|
server.cleanup().await;
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn bulk_update_finding_status() {
|
|
let server = TestServer::start().await;
|
|
|
|
insert_finding(&server, "repo1", "Bug A", "high").await;
|
|
insert_finding(&server, "repo1", "Bug B", "high").await;
|
|
|
|
// Get both finding IDs
|
|
let resp = server.get("/api/v1/findings").await;
|
|
let body: serde_json::Value = resp.json().await.unwrap();
|
|
let ids: Vec<String> = body["data"]
|
|
.as_array()
|
|
.unwrap()
|
|
.iter()
|
|
.map(|f| f["_id"]["$oid"].as_str().unwrap().to_string())
|
|
.collect();
|
|
|
|
// Bulk update
|
|
let resp = server
|
|
.patch(
|
|
"/api/v1/findings/bulk-status",
|
|
&json!({
|
|
"ids": ids,
|
|
"status": "false_positive"
|
|
}),
|
|
)
|
|
.await;
|
|
assert_eq!(resp.status(), 200);
|
|
|
|
// Verify both are updated
|
|
for id in &ids {
|
|
let resp = server.get(&format!("/api/v1/findings/{id}")).await;
|
|
let body: serde_json::Value = resp.json().await.unwrap();
|
|
assert_eq!(body["data"]["status"], "false_positive");
|
|
}
|
|
|
|
server.cleanup().await;
|
|
}
|