Skip to content

Commit 6df8277

Browse files
committed
graphql: Add a query test
Check the situation where an entity that has empty relations to other entities is followed by one that does have them and ensure that we link up the children correctly in that situation.
1 parent 41b13a6 commit 6df8277

File tree

1 file changed

+125
-23
lines changed

1 file changed

+125
-23
lines changed

store/test-store/tests/graphql/query.rs

Lines changed: 125 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -581,6 +581,7 @@ async fn insert_test_entities(
581581
vec![
582582
entity! { is => id: "m3", name: "Tom", mainBand: "b2", bands: vec!["b1", "b2"], favoriteCount: 5, birthDate: timestamp.clone(), vid: 2i64 },
583583
entity! { is => id: "m4", name: "Valerie", bands: Vec::<String>::new(), favoriteCount: 20, birthDate: timestamp.clone(), vid: 3i64 },
584+
entity! { is => id: "m5", name: "Paul", mainBand: "b2", bands: vec!["b2"], favoriteCount: 2 , birthDate: timestamp.clone(), vid: 4i64 },
584585
],
585586
)];
586587
let entities1 = insert_ops(&manifest.schema, entities1);
@@ -771,7 +772,8 @@ fn can_query_one_to_one_relationship() {
771772
object! { name: "John", mainBand: object! { name: "The Musicians" }, favoriteCount: "10", birthDate: "1710837304040956" },
772773
object! { name: "Lisa", mainBand: object! { name: "The Musicians" }, favoriteCount: "100", birthDate: "1710837304040956" },
773774
object! { name: "Tom", mainBand: object! { name: "The Amateurs" }, favoriteCount: "5", birthDate: "1710837304040956" },
774-
object! { name: "Valerie", mainBand: r::Value::Null, favoriteCount: "20", birthDate: "1710837304040956" }
775+
object! { name: "Valerie", mainBand: r::Value::Null, favoriteCount: "20", birthDate: "1710837304040956" },
776+
object! { name: "Paul", mainBand: object! { name: "The Amateurs" }, favoriteCount: "2", birthDate: "1710837304040956" }
775777
],
776778
songStats: vec![
777779
object! {
@@ -815,7 +817,8 @@ fn can_filter_by_timestamp() {
815817
object! { name: "John" },
816818
object! { name: "Lisa" },
817819
object! { name: "Tom" },
818-
object! { name: "Valerie" }
820+
object! { name: "Valerie" },
821+
object! { name: "Paul" },
819822
],
820823
};
821824
let data = extract_data!(result).unwrap();
@@ -868,6 +871,9 @@ fn can_query_one_to_many_relationships_in_both_directions() {
868871
object! {
869872
name: "Valerie", writtenSongs: Vec::<String>::new()
870873
},
874+
object! {
875+
name: "Paul", writtenSongs: Vec::<String>::new()
876+
},
871877
]
872878
};
873879

@@ -906,15 +912,16 @@ fn can_query_many_to_many_relationship() {
906912

907913
let the_amateurs = object! {
908914
name: "The Amateurs",
909-
members: members(vec![ "John", "Tom" ])
915+
members: members(vec![ "John", "Tom", "Paul" ])
910916
};
911917

912918
let exp = object! {
913919
musicians: vec![
914920
object! { name: "John", bands: vec![ the_musicians.clone(), the_amateurs.clone() ]},
915921
object! { name: "Lisa", bands: vec![ the_musicians.clone() ] },
916-
object! { name: "Tom", bands: vec![ the_musicians, the_amateurs ] },
917-
object! { name: "Valerie", bands: Vec::<String>::new() }
922+
object! { name: "Tom", bands: vec![ the_musicians, the_amateurs.clone() ] },
923+
object! { name: "Valerie", bands: Vec::<String>::new() },
924+
object! { name: "Paul", bands: vec![ the_amateurs ] }
918925
]
919926
};
920927

@@ -996,10 +1003,12 @@ fn can_query_with_sorting_by_child_entity() {
9961003
object! { name: "Valerie", mainBand: r::Value::Null },
9971004
object! { name: "Lisa", mainBand: object! { name: "The Musicians" } },
9981005
object! { name: "John", mainBand: object! { name: "The Musicians" } },
1006+
object! { name: "Paul", mainBand: object! { name: "The Amateurs"} },
9991007
object! { name: "Tom", mainBand: object! { name: "The Amateurs"} },
10001008
],
10011009
asc: vec![
10021010
object! { name: "Tom", mainBand: object! { name: "The Amateurs"} },
1011+
object! { name: "Paul", mainBand: object! { name: "The Amateurs"} },
10031012
object! { name: "John", mainBand: object! { name: "The Musicians" } },
10041013
object! { name: "Lisa", mainBand: object! { name: "The Musicians" } },
10051014
object! { name: "Valerie", mainBand: r::Value::Null },
@@ -1307,7 +1316,8 @@ fn can_query_with_child_filter_on_list_type_field() {
13071316
let exp = object! {
13081317
musicians: vec![
13091318
object! { name: "John", bands: vec![ the_musicians.clone(), the_amateurs.clone() ]},
1310-
object! { name: "Tom", bands: vec![ the_musicians, the_amateurs ] },
1319+
object! { name: "Tom", bands: vec![ the_musicians, the_amateurs.clone() ] },
1320+
object! { name: "Paul", bands: vec![ the_amateurs ] },
13111321
]
13121322
};
13131323

@@ -1352,7 +1362,8 @@ fn can_query_with_child_filter_on_named_type_field() {
13521362
run_query(QUERY, |result, _| {
13531363
let exp = object! {
13541364
musicians: vec![
1355-
object! { name: "Tom", mainBand: object! { id: "b2"} }
1365+
object! { name: "Tom", mainBand: object! { id: "b2"} },
1366+
object! { name: "Paul", mainBand: object! { id: "b2"} }
13561367
]
13571368
};
13581369

@@ -1703,7 +1714,7 @@ fn skip_directive_works_with_query_variables() {
17031714

17041715
run_query((QUERY, object! { skip: true }), |result, _| {
17051716
// Assert that only names are returned
1706-
let musicians: Vec<_> = ["John", "Lisa", "Tom", "Valerie"]
1717+
let musicians: Vec<_> = ["John", "Lisa", "Tom", "Valerie", "Paul"]
17071718
.into_iter()
17081719
.map(|name| object! { name: name })
17091720
.collect();
@@ -1719,7 +1730,8 @@ fn skip_directive_works_with_query_variables() {
17191730
object! { id: "m1", name: "John" },
17201731
object! { id: "m2", name: "Lisa"},
17211732
object! { id: "m3", name: "Tom" },
1722-
object! { id: "m4", name: "Valerie" }
1733+
object! { id: "m4", name: "Valerie" },
1734+
object! { id: "m5", name: "Paul" }
17231735
]
17241736
};
17251737
let data = extract_data!(result).unwrap();
@@ -1745,7 +1757,8 @@ fn include_directive_works_with_query_variables() {
17451757
object! { id: "m1", name: "John" },
17461758
object! { id: "m2", name: "Lisa"},
17471759
object! { id: "m3", name: "Tom" },
1748-
object! { id: "m4", name: "Valerie" }
1760+
object! { id: "m4", name: "Valerie" },
1761+
object! { id: "m5", name: "Paul" }
17491762
]
17501763
};
17511764
let data = extract_data!(result).unwrap();
@@ -1754,7 +1767,7 @@ fn include_directive_works_with_query_variables() {
17541767

17551768
run_query((QUERY, object! { include: false }), |result, _| {
17561769
// Assert that only names are returned
1757-
let musicians: Vec<_> = ["John", "Lisa", "Tom", "Valerie"]
1770+
let musicians: Vec<_> = ["John", "Lisa", "Tom", "Valerie", "Paul"]
17581771
.into_iter()
17591772
.map(|name| object! { name: name })
17601773
.collect();
@@ -1894,7 +1907,7 @@ fn skip_is_nullable() {
18941907
";
18951908

18961909
run_query(QUERY, |result, _| {
1897-
let musicians: Vec<_> = ["John", "Lisa", "Tom", "Valerie"]
1910+
let musicians: Vec<_> = ["John", "Lisa", "Tom", "Valerie", "Paul"]
18981911
.into_iter()
18991912
.map(|name| object! { name: name })
19001913
.collect();
@@ -1915,7 +1928,7 @@ fn first_is_nullable() {
19151928
";
19161929

19171930
run_query(QUERY, |result, _| {
1918-
let musicians: Vec<_> = ["John", "Lisa", "Tom", "Valerie"]
1931+
let musicians: Vec<_> = ["John", "Lisa", "Tom", "Valerie", "Paul"]
19191932
.into_iter()
19201933
.map(|name| object! { name: name })
19211934
.collect();
@@ -1992,7 +2005,8 @@ fn can_filter_by_relationship_fields() {
19922005

19932006
let exp = object! {
19942007
musicians: vec![
1995-
object! { id: "m3", name: "Tom", mainBand: object! { id: "b2"} }
2008+
object! { id: "m3", name: "Tom", mainBand: object! { id: "b2"} },
2009+
object! { id: "m5", name: "Paul", mainBand: object! { id: "b2"} }
19962010
],
19972011
bands: vec![
19982012
object! {
@@ -2074,6 +2088,10 @@ fn can_use_nested_filter() {
20742088
object! {
20752089
name: "Valerie",
20762090
bands: Vec::<r::Value>::new(),
2091+
},
2092+
object! {
2093+
name: "Paul",
2094+
bands: vec![ object! { id: "b2" }]
20772095
}
20782096
]
20792097
};
@@ -2096,7 +2114,7 @@ fn ignores_invalid_field_arguments() {
20962114
// Without validations
20972115
Ok(Some(r::Value::Object(obj))) => match obj.get("musicians").unwrap() {
20982116
r::Value::List(lst) => {
2099-
assert_eq!(4, lst.len());
2117+
assert_eq!(5, lst.len());
21002118
}
21012119
_ => panic!("expected a list of values"),
21022120
},
@@ -2202,6 +2220,7 @@ fn missing_variable() {
22022220
object! { id: "m2" },
22032221
object! { id: "m3" },
22042222
object! { id: "m4" },
2223+
object! { id: "m5" },
22052224
]
22062225
};
22072226

@@ -2232,6 +2251,7 @@ fn missing_variable() {
22322251
object! { id: "m2" },
22332252
object! { id: "m3" },
22342253
object! { id: "m4" },
2254+
object! { id: "m5" },
22352255
]
22362256
};
22372257

@@ -2326,13 +2346,15 @@ fn query_at_block() {
23262346
up to block number 2 and data for block number 3 is therefore not yet available";
23272347
const BLOCK_HASH_NOT_FOUND: &str = "no block with that hash found";
23282348

2349+
let all_musicians = vec!["m1", "m2", "m3", "m4", "m5"];
2350+
23292351
musicians_at("number: 7000", Err(BLOCK_NOT_INDEXED), "n7000");
23302352
musicians_at("number: 0", Ok(vec!["m1", "m2"]), "n0");
2331-
musicians_at("number: 1", Ok(vec!["m1", "m2", "m3", "m4"]), "n1");
2353+
musicians_at("number: 1", Ok(all_musicians.clone()), "n1");
23322354

23332355
musicians_at(&hash(&BLOCKS[0]), Ok(vec!["m1", "m2"]), "h0");
2334-
musicians_at(&hash(&BLOCKS[1]), Ok(vec!["m1", "m2", "m3", "m4"]), "h1");
2335-
musicians_at(&hash(&BLOCKS[2]), Ok(vec!["m1", "m2", "m3", "m4"]), "h2");
2356+
musicians_at(&hash(&BLOCKS[1]), Ok(all_musicians.clone()), "h1");
2357+
musicians_at(&hash(&BLOCKS[2]), Ok(all_musicians.clone()), "h2");
23362358
musicians_at(&hash(&BLOCKS[3]), Err(BLOCK_NOT_INDEXED2), "h3");
23372359
musicians_at(&hash(&BLOCKS[4]), Err(BLOCK_HASH_NOT_FOUND), "h4");
23382360
}
@@ -2371,17 +2393,19 @@ fn query_at_block_with_vars() {
23712393
up to block number 2 and data for block number 3 is therefore not yet available";
23722394
const BLOCK_HASH_NOT_FOUND: &str = "no block with that hash found";
23732395

2396+
let all_musicians = vec!["m1", "m2", "m3", "m4", "m5"];
2397+
23742398
musicians_at_nr(7000, Err(BLOCK_NOT_INDEXED), "n7000");
23752399
musicians_at_nr(0, Ok(vec!["m1", "m2"]), "n0");
2376-
musicians_at_nr(1, Ok(vec!["m1", "m2", "m3", "m4"]), "n1");
2400+
musicians_at_nr(1, Ok(all_musicians.clone()), "n1");
23772401

23782402
musicians_at_nr_gte(7000, Err(BLOCK_NOT_INDEXED), "ngte7000");
2379-
musicians_at_nr_gte(0, Ok(vec!["m1", "m2", "m3", "m4"]), "ngte0");
2380-
musicians_at_nr_gte(1, Ok(vec!["m1", "m2", "m3", "m4"]), "ngte1");
2403+
musicians_at_nr_gte(0, Ok(all_musicians.clone()), "ngte0");
2404+
musicians_at_nr_gte(1, Ok(all_musicians.clone()), "ngte1");
23812405

23822406
musicians_at_hash(&BLOCKS[0], Ok(vec!["m1", "m2"]), "h0");
2383-
musicians_at_hash(&BLOCKS[1], Ok(vec!["m1", "m2", "m3", "m4"]), "h1");
2384-
musicians_at_hash(&BLOCKS[2], Ok(vec!["m1", "m2", "m3", "m4"]), "h2");
2407+
musicians_at_hash(&BLOCKS[1], Ok(all_musicians.clone()), "h1");
2408+
musicians_at_hash(&BLOCKS[2], Ok(all_musicians.clone()), "h2");
23852409
musicians_at_hash(&BLOCKS[3], Err(BLOCK_NOT_INDEXED2), "h3");
23862410
musicians_at_hash(&BLOCKS[4], Err(BLOCK_HASH_NOT_FOUND), "h4");
23872411
}
@@ -2822,6 +2846,7 @@ fn can_query_with_or_and_filter() {
28222846
musicians: vec![
28232847
object! { name: "John", id: "m1" },
28242848
object! { name: "Tom", id: "m3" },
2849+
object! { name: "Paul", id: "m5" },
28252850
],
28262851
};
28272852
let data = extract_data!(result).unwrap();
@@ -2847,6 +2872,7 @@ fn can_query_with_or_explicit_and_filter() {
28472872
musicians: vec![
28482873
object! { name: "John", id: "m1" },
28492874
object! { name: "Tom", id: "m3" },
2875+
object! { name: "Paul", id: "m5" },
28502876
],
28512877
};
28522878
let data = extract_data!(result).unwrap();
@@ -3049,3 +3075,79 @@ fn simple_aggregation() {
30493075
assert_eq!(data, exp);
30503076
})
30513077
}
3078+
3079+
/// Check that if we have entities where a related entity is null, followed
3080+
/// by one where it is not null that the children are joined correctly to
3081+
/// their respective parent
3082+
#[test]
3083+
fn children_are_joined_correctly() {
3084+
// Get just the `id` for the `mainBand` and `bands`
3085+
const QUERY1: &str = "
3086+
query {
3087+
musicians {
3088+
id
3089+
mainBand { id }
3090+
bands { id }
3091+
}
3092+
}
3093+
";
3094+
3095+
// Get the `id` and one more attribute for the `mainBand` and `bands`
3096+
const QUERY2: &str = "
3097+
query {
3098+
musicians {
3099+
id
3100+
mainBand { id name }
3101+
bands { id name }
3102+
}
3103+
}
3104+
";
3105+
3106+
run_query(QUERY1, |result, _| {
3107+
fn b1() -> r::Value {
3108+
object! { id: "b1" }
3109+
}
3110+
fn b2() -> r::Value {
3111+
object! { id: "b2" }
3112+
}
3113+
let null = r::Value::Null;
3114+
let none = Vec::<r::Value>::new();
3115+
3116+
let exp = object! {
3117+
musicians: vec![
3118+
object! { id: "m1", mainBand: b1(), bands: vec![ b1(), b2() ] },
3119+
object! { id: "m2", mainBand: b1(), bands: vec![ b1() ] },
3120+
object! { id: "m3", mainBand: b2(), bands: vec![ b1(), b2() ] },
3121+
object! { id: "m4", mainBand: null, bands: none },
3122+
object! { id: "m5", mainBand: b2(), bands: vec![ b2() ] },
3123+
],
3124+
};
3125+
3126+
let data = extract_data!(result).unwrap();
3127+
assert_eq!(data, exp);
3128+
});
3129+
3130+
run_query(QUERY2, |result, _| {
3131+
fn b1() -> r::Value {
3132+
object! { id: "b1", name: "The Musicians" }
3133+
}
3134+
fn b2() -> r::Value {
3135+
object! { id: "b2", name: "The Amateurs" }
3136+
}
3137+
let null = r::Value::Null;
3138+
let none = Vec::<r::Value>::new();
3139+
3140+
let exp = object! {
3141+
musicians: vec![
3142+
object! { id: "m1", mainBand: b1(), bands: vec![ b1(), b2() ] },
3143+
object! { id: "m2", mainBand: b1(), bands: vec![ b1() ] },
3144+
object! { id: "m3", mainBand: b2(), bands: vec![ b1(), b2() ] },
3145+
object! { id: "m4", mainBand: null, bands: none },
3146+
object! { id: "m5", mainBand: b2(), bands: vec![ b2() ] },
3147+
],
3148+
};
3149+
3150+
let data = extract_data!(result).unwrap();
3151+
assert_eq!(data, exp);
3152+
});
3153+
}

0 commit comments

Comments
 (0)