async-graphql/tests/connection.rs

229 lines
6.1 KiB
Rust
Raw Normal View History

use async_graphql::connection::*;
use async_graphql::*;
use serde_json::json;
2020-05-20 16:15:47 +00:00
#[async_std::test]
pub async fn test_slice_datasource() {
struct Query;
2020-05-20 16:15:47 +00:00
#[Object]
impl Query {
async fn values(
2020-05-20 16:15:47 +00:00
&self,
after: Option<String>,
before: Option<String>,
2020-05-20 16:15:47 +00:00
first: Option<i32>,
last: Option<i32>,
) -> FieldResult<Connection<usize, &&str>> {
const ROWS: &[&str] = &[
"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p",
"q", "r", "s", "t", "u", "v", "w", "x", "y", "z",
];
2020-06-02 09:43:13 +00:00
ROWS.query(after, before, first, last).await
2020-05-20 16:15:47 +00:00
}
}
static QUERY: &str = r#"
query(
$after: String
$before: String
2020-05-20 16:15:47 +00:00
$first: Int
$last: Int
) {
values(
2020-05-20 16:15:47 +00:00
after: $after
before: $before
first: $first
last: $last
) {
pageInfo {
hasPreviousPage
hasNextPage
}
edges {
node
}
}
}
"#;
async fn do_test(
vars: serde_json::Value,
(has_prev_page, has_next_page, nodes): (bool, bool, &[&str]),
2020-05-20 16:15:47 +00:00
) {
let schema = Schema::new(Query, EmptyMutation, EmptySubscription);
2020-05-20 16:15:47 +00:00
let query = QueryBuilder::new(QUERY).variables(Variables::parse_from_json(vars).unwrap());
let edges = nodes
2020-05-20 16:15:47 +00:00
.iter()
.map(|s| json!({ "node": s.to_owned() }))
2020-05-20 16:15:47 +00:00
.collect::<Vec<_>>();
assert_eq!(
query.execute(&schema).await.unwrap().data,
serde_json::json!({
"values": {
2020-05-20 16:15:47 +00:00
"pageInfo": {
"hasPreviousPage": has_prev_page,
"hasNextPage": has_next_page,
},
"edges": edges,
},
})
);
}
do_test(
json!({ "after": null, "before": null, "first": 2, "last": null }),
(false, true, &["a", "b"]),
)
.await;
do_test(
json!({ "after": 1usize.encode_cursor().unwrap(), "before": null, "first": 2, "last": null }),
(true, true, &["c", "d"]),
)
.await;
do_test(
json!({ "after": 1usize.encode_cursor().unwrap(), "before": null, "first": 6, "last": null }),
(true, true, &["c", "d", "e", "f", "g", "h"]),
)
.await;
do_test(
json!({ "after": null, "before": null, "first": 3, "last": null }),
(false, true, &["a", "b", "c"]),
)
.await;
do_test(
json!({ "after": null, "before": null, "first": null, "last": 3 }),
(true, false, &["x", "y", "z"]),
)
.await;
do_test(
json!({ "after": null, "before": 1usize.encode_cursor().unwrap(), "first": 10, "last": null }),
(false, true, &["a"]),
)
.await;
do_test(
json!({ "after": null, "before": 1usize.encode_cursor().unwrap(), "first": null, "last": 10 }),
(false, true, &["a"]),
)
.await;
}
2020-05-20 16:15:47 +00:00
#[async_std::test]
pub async fn test_datasource_additional_fields() {
struct QueryRoot;
2020-05-20 16:15:47 +00:00
struct Numbers;
2020-05-20 16:15:47 +00:00
#[SimpleObject]
struct ConnectionFields {
total_count: i32,
2020-05-20 16:15:47 +00:00
}
#[SimpleObject]
struct Diff {
diff: i32,
2020-05-20 16:15:47 +00:00
}
#[DataSource]
impl DataSource for Numbers {
type CursorType = usize;
type NodeType = i32;
type ConnectionFieldsType = ConnectionFields;
type EdgeFieldsType = Diff;
2020-05-20 16:15:47 +00:00
async fn execute_query(
&self,
after: Option<usize>,
before: Option<usize>,
first: Option<usize>,
last: Option<usize>,
) -> FieldResult<
Connection<
Self::CursorType,
Self::NodeType,
Self::ConnectionFieldsType,
Self::EdgeFieldsType,
>,
> {
let mut start = after.map(|after| after + 1).unwrap_or(0);
let mut end = before.unwrap_or(10000);
if let Some(first) = first {
end = (start + first).min(end);
}
if let Some(last) = last {
start = if last > end - start { end } else { end - last };
}
2020-05-29 03:12:43 +00:00
let mut connection = Connection::with_additional_fields(
start > 0,
end < 10000,
ConnectionFields { total_count: 10000 },
);
connection.append((start..end).into_iter().map(|n| {
2020-05-29 03:12:43 +00:00
Edge::with_additional_fields(
n,
n as i32,
Diff {
diff: (10000 - n) as i32,
},
)
}));
Ok(connection)
}
2020-05-20 16:15:47 +00:00
}
#[Object]
impl QueryRoot {
async fn numbers(
&self,
after: Option<String>,
before: Option<String>,
first: Option<i32>,
last: Option<i32>,
) -> FieldResult<Connection<usize, i32, ConnectionFields, Diff>> {
2020-06-02 09:43:13 +00:00
Numbers.query(after, before, first, last).await
}
2020-05-20 16:15:47 +00:00
}
let schema = Schema::new(QueryRoot, EmptyMutation, EmptySubscription);
2020-05-20 16:15:47 +00:00
assert_eq!(
schema
.execute("{ numbers(first: 2) { totalCount edges { node diff } } }")
.await
.unwrap()
.data,
serde_json::json!({
"numbers": {
"totalCount": 10000,
"edges": [
{"node": 0, "diff": 10000},
{"node": 1, "diff": 9999},
]
},
})
);
assert_eq!(
schema
.execute("{ numbers(last: 2) { edges { node diff } } }")
.await
.unwrap()
.data,
serde_json::json!({
"numbers": {
"edges": [
{"node": 9998, "diff": 2},
{"node": 9999, "diff": 1},
]
},
})
);
2020-05-20 16:15:47 +00:00
}