use std::path::PathBuf;
use wiremock::matchers::{method, path};
use wiremock::{Mock, MockServer, ResponseTemplate};
use super::support::{analyzer_for, hunks_for_python_at, hunks_for_python_at_two_lines};
use crate::test_support::{mount_sse, request_count, sse};
#[tokio::test]
async fn truncated_response_yields_partial_findings_and_marks_failed() {
let server = MockServer::start().await;
let body = "{\"issues\": [\
{\"line\": 100, \"severity\": \"high\", \"category\": \"bug\", \"message\": \"first\"}, \
{\"line\": 101, \"severity\": \"high\", \"category\": \"bug\", \"message\": \"sec\"";
mount_sse(
&server,
ResponseTemplate::new(200).set_body_raw(sse(&[body]), "text/event-stream"),
)
.await;
let (analyzer, _dir) = analyzer_for(&server);
let result = analyzer
.analyze_file(&hunks_for_python_at_two_lines())
.await;
assert!(
!result.findings.is_empty(),
"truncated response must yield at least one finding, got none"
);
assert!(
result
.failed_files
.contains_key(&PathBuf::from("src/lib.py")),
"truncated response must mark the file failed, got {:?}",
result.failed_files
);
}
#[tokio::test]
async fn truncated_response_is_not_cached() {
let server = MockServer::start().await;
let body = "{\"issues\": [\
{\"line\": 100, \"severity\": \"high\", \"category\": \"bug\", \"message\": \"x\"}, \
{\"line\": 101, \"severity\": \"high\", \"category\": \"bug\", \"message\": \"y\"";
Mock::given(method("POST"))
.and(path("/v1/chat/completions"))
.respond_with(ResponseTemplate::new(200).set_body_raw(sse(&[body]), "text/event-stream"))
.expect(2) .mount(&server)
.await;
let (analyzer, _dir) = analyzer_for(&server);
let hunks = hunks_for_python_at_two_lines();
let _ = analyzer.analyze_file(&hunks).await;
let _ = analyzer.analyze_file(&hunks).await;
assert_eq!(
request_count(&server).await,
2,
"a truncated response must not be cached; the second call must hit the network"
);
}
#[tokio::test]
async fn complete_response_is_cached() {
let server = MockServer::start().await;
let body = "{\"issues\": [\
{\"line\": 100, \"severity\": \"high\", \"category\": \"bug\", \"message\": \"cached\"}\
], \"summary\": \"\"}";
Mock::given(method("POST"))
.and(path("/v1/chat/completions"))
.respond_with(ResponseTemplate::new(200).set_body_raw(sse(&[body]), "text/event-stream"))
.expect(1)
.mount(&server)
.await;
let (analyzer, _dir) = analyzer_for(&server);
let hunks = hunks_for_python_at(100);
let first = analyzer.analyze_file(&hunks).await;
let second = analyzer.analyze_file(&hunks).await;
assert_eq!(
request_count(&server).await,
1,
"the second call must be served from the cache"
);
assert_eq!(first.findings, second.findings);
assert_eq!(first.findings.len(), 1);
assert_eq!(first.findings[0].message, "cached");
}