postjevsql.git / tests / happy_path.rs
1//! The happy path end to end: a real Postgres with the built extension,
2//! asking a mock Jev one Noul question about one row.
3
4use serde_json::json;
5use support::mock_jev::{MockJev, Reply};
6use support::{TICKET, jev_instance, noul};
7
8const QUESTION: &str = "Does this convey urgency?";
9
10#[tokio::test(flavor = "multi_thread")]
11async fn jev_prob_asks_one_noul_question_about_a_row() {
12    let mock = MockJev::start(|_| Reply::json(200, noul(0.95))).await;
13    let (_pg, client) = jev_instance(&mock).await;
14
15    let row = client
16        .query_one("SELECT jev_prob(t, $1) FROM tickets t", &[&QUESTION])
17        .await
18        .expect("jev_prob runs");
19    assert_eq!(row.get::<_, f64>(0), 0.95);
20
21    let requests = mock.requests();
22    assert_eq!(requests.len(), 1, "one row, one request");
23    let req = &requests[0];
24    assert_eq!(req.version, http::Version::HTTP_2);
25    assert_eq!(req.method, http::Method::POST);
26    assert_eq!(req.path, "/v1/systemone");
27    assert_eq!(req.headers["authorization"], "Bearer test-key");
28    assert_eq!(req.headers["content-type"], "application/json");
29    assert!(!req.headers.contains_key("x-typesafe-retry-count"));
30
31    let body: serde_json::Value = serde_json::from_slice(&req.body).unwrap();
32    assert_eq!(body["model"], "jev-1.13.0");
33    // The row is the state, canonicalized (JCS: sorted keys, no spaces).
34    assert_eq!(body["state"], json!({ "body": TICKET, "id": 1 }));
35    let body_text = std::str::from_utf8(&req.body).unwrap();
36    assert!(
37        body_text.contains(&format!(r#""state":{{"body":"{TICKET}","id":1}}"#)),
38        "state is sent in canonical form: {body_text}"
39    );
40    let questions = body["questions"].as_object().unwrap();
41    assert_eq!(questions.len(), 1);
42    let question = questions.values().next().unwrap();
43    assert_eq!(question, &json!({ "type": "noul", "instructions": QUESTION }));
44}