Skip to main content

api_testing_core/rest/
expect.rs

1use crate::Result;
2use crate::rest::runner::RestExecutedRequest;
3use crate::rest::schema::RestRequest;
4
5pub fn evaluate_main_response(request: &RestRequest, executed: &RestExecutedRequest) -> Result<()> {
6    let status = executed.response.status;
7
8    if let Some(expect) = &request.expect {
9        if status != expect.status {
10            anyhow::bail!("Expected HTTP status {} but got {}.", expect.status, status);
11        }
12
13        if let Some(expr) = &expect.jq {
14            let body_json: Option<serde_json::Value> =
15                serde_json::from_slice(&executed.response.body).ok();
16            let ok = body_json
17                .and_then(|json| crate::jq::eval_exit_status(&json, expr).ok())
18                .unwrap_or(false);
19            if !ok {
20                anyhow::bail!("expect.jq failed: {expr}");
21            }
22        }
23
24        return Ok(());
25    }
26
27    if !(200..300).contains(&status) {
28        anyhow::bail!(
29            "HTTP request failed with status {status}: {} {}",
30            executed.method,
31            executed.url
32        );
33    }
34
35    Ok(())
36}
37
38#[cfg(test)]
39mod tests {
40    use super::*;
41
42    fn executed_with(status: u16, body: serde_json::Value) -> RestExecutedRequest {
43        RestExecutedRequest {
44            method: "GET".to_string(),
45            url: "http://localhost:6700/health".to_string(),
46            response: crate::rest::runner::RestHttpResponse {
47                status,
48                body: serde_json::to_vec(&body).unwrap(),
49                content_type: Some("application/json".to_string()),
50            },
51        }
52    }
53
54    #[test]
55    fn rest_expect_status_mismatch_fails() {
56        let request = crate::rest::schema::parse_rest_request_json(serde_json::json!({
57            "method": "GET",
58            "path": "/health",
59            "expect": { "status": 200 }
60        }))
61        .unwrap();
62        let executed = executed_with(500, serde_json::json!({"ok": false}));
63        let err = evaluate_main_response(&request, &executed).unwrap_err();
64        assert!(
65            err.to_string()
66                .contains("Expected HTTP status 200 but got 500")
67        );
68    }
69
70    #[test]
71    fn rest_expect_jq_false_fails() {
72        let request = crate::rest::schema::parse_rest_request_json(serde_json::json!({
73            "method": "GET",
74            "path": "/health",
75            "expect": { "status": 200, "jq": ".ok == true" }
76        }))
77        .unwrap();
78        let executed = executed_with(200, serde_json::json!({"ok": false}));
79        let err = evaluate_main_response(&request, &executed).unwrap_err();
80        assert!(err.to_string().contains("expect.jq failed"));
81    }
82
83    #[test]
84    fn rest_expect_default_non_2xx_fails() {
85        let request = crate::rest::schema::parse_rest_request_json(serde_json::json!({
86            "method": "GET",
87            "path": "/health"
88        }))
89        .unwrap();
90        let executed = executed_with(404, serde_json::json!({"error": "no"}));
91        let err = evaluate_main_response(&request, &executed).unwrap_err();
92        assert!(
93            err.to_string()
94                .contains("HTTP request failed with status 404")
95        );
96    }
97}