use ciborium::Value as CborValue;
use indexmap::IndexMap;
use serde_json::{Value, json};
use vantage_api_client::{GraphqlApi, GraphqlApiVistaFactory};
use vantage_types::Record;
use wiremock::matchers::{body_partial_json, method};
use wiremock::{Mock, MockServer, ResponseTemplate};
pub const CLIENT: &str = r#"
name: client
columns:
id: { type: string, flags: [id] }
name: { type: string, flags: [title] }
graphql:
root_field: clients
dialect: hasura
references:
orders:
table: order
kind: has_many
foreign_key: client_id
"#;
pub fn order_yaml(extra: &str) -> String {
format!(
r#"
name: order
columns:
id: {{ type: string, flags: [id] }}
client_id: {{ type: string }}
item: {{ type: string, flags: [title] }}
graphql:
root_field: orders
dialect: hasura
{extra}references:
client:
table: client
kind: has_one
foreign_key: client_id
"#
)
}
pub fn factory(server: &MockServer) -> GraphqlApiVistaFactory {
GraphqlApi::builder(server.uri())
.http_client(super::test_client())
.build()
.vista_factory()
}
pub fn registered(server: &MockServer, order_extra: &str) -> GraphqlApiVistaFactory {
let mut factory = factory(server);
factory.register_yaml(CLIENT).unwrap();
factory.register_yaml(&order_yaml(order_extra)).unwrap();
factory
}
pub async fn answer(server: &MockServer, query: &str, root: &str, rows: Value) {
Mock::given(method("POST"))
.and(body_partial_json(json!({ "query": query })))
.respond_with(ResponseTemplate::new(200).set_body_json(json!({ "data": { (root): rows } })))
.mount(server)
.await;
}
pub fn row(fields: &[(&str, &str)]) -> Record<CborValue> {
fields
.iter()
.map(|(k, v)| (k.to_string(), CborValue::Text(v.to_string())))
.collect()
}
pub fn texts(rows: &IndexMap<String, Record<CborValue>>, key: &str) -> Vec<String> {
let mut out: Vec<String> = rows
.values()
.filter_map(|r| match r.get(key) {
Some(CborValue::Text(s)) => Some(s.clone()),
_ => None,
})
.collect();
out.sort();
out
}
pub const ORDERS: &str = "orders";
pub const ALL_ORDERS: &str = "query { orders { id client_id item } }";
pub fn all_orders() -> Value {
json!([
{ "id": "o1", "client_id": "c1", "item": "skateboard" },
{ "id": "o2", "client_id": "c1", "item": "almanac" },
{ "id": "o3", "client_id": "c2", "item": "flux capacitor" }
])
}