1//! What the release gates' recording runs ask, shared by
2//! `tools/record-gates`, which records them, and `tests/gate_*.rs`, which
3//! replay them. A replay matches by the exact request bytes, so the rows,
4//! the question and the SQL must be the ones recorded; they live here
5//! once so the two cannot drift apart.
6
7use std::path::PathBuf;
8
9use jev_mock::replay::Fixture;
10
11pub const QUESTION: &str = "Could this person work from home?";
12
13/// The rows every run draws from, as `people` holds them.
14pub const ROWS: [&str; 4] = [
15    r#"{"name":"Ana","role":"backend engineer","country":"PT"}"#,
16    r#"{"name":"Rui","role":"nurse","country":"PT"}"#,
17    r#"{"name":"Inês","role":"accountant","country":"PT"}"#,
18    r#"{"name":"João","role":"bus driver","country":"PT"}"#,
19];
20
21/// A small occupational hierarchy for the label-tree run.
22pub const TREE_PATHS: [&str; 12] = [
23    "Office > Engineering > Backend",
24    "Office > Engineering > Frontend",
25    "Office > Finance > Accounting",
26    "Office > Finance > Audit",
27    "Care > Hospital > Nursing",
28    "Care > Hospital > Surgery",
29    "Care > Community > Home care",
30    "Care > Community > Social work",
31    "Transport > Road > Bus",
32    "Transport > Road > Freight",
33    "Transport > Rail > Driver",
34    "Transport > Rail > Signalling",
35];
36
37/// The label-tree run: `$1` is [`QUESTION`], `$2` is [`TREE_PATHS`].
38pub const LABEL_TREE_SQL: &str =
39    "SELECT (jev_choice_tree_full(p, $1, $2::text[])).path FROM people p WHERE name = 'Ana'";
40
41/// The ranking run: `$1` is [`QUESTION`].
42pub const RANKING_SQL: &str =
43    "SELECT name FROM people p WHERE name IN ('Ana', 'Rui') ORDER BY jev_prob(p, $1) DESC, name LIMIT 1";
44
45/// Creates the extension (unless there) and `people`, holding [`ROWS`].
46pub async fn setup_people(client: &tokio_postgres::Client) -> Result<(), tokio_postgres::Error> {
47    let mut setup = String::from(
48        "SET statement_timeout = '120s'; CREATE EXTENSION IF NOT EXISTS postjevsql; \
49         CREATE TABLE people (name text, role text, country text);",
50    );
51    for row in ROWS {
52        let v: serde_json::Value = serde_json::from_str(row).unwrap();
53        let quote = |k: &str| format!("'{}'", v[k].as_str().expect("the rows are text").replace('\'', "''"));
54        setup += &format!("INSERT INTO people VALUES ({}, {}, {});", quote("name"), quote("role"), quote("country"));
55    }
56    client.batch_execute(&setup).await
57}
58
59/// The committed fixture of one gate, `tests/fixtures/<gate>.json`, found
60/// through `POSTJEVSQL_FIXTURES`, which `tests/BUCK` sets.
61pub fn fixture(gate: &str) -> Fixture {
62    let dir = std::env::var_os("POSTJEVSQL_FIXTURES").expect("POSTJEVSQL_FIXTURES is set by tests/BUCK");
63    let path = PathBuf::from(dir).join(format!("{gate}.json"));
64    Fixture::load(&path).unwrap_or_else(|e| panic!("{e}"))
65}