Skip to content

Commit dc99ae7

Browse files
authored
Fix fields on interface not being resolved when used with fragments (#923, #922)
1 parent 106e322 commit dc99ae7

File tree

5 files changed

+139
-3
lines changed

5 files changed

+139
-3
lines changed
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
use juniper::*;
2+
3+
struct Query;
4+
5+
#[juniper::graphql_object]
6+
impl Query {
7+
fn characters() -> Vec<CharacterValue> {
8+
vec![
9+
Into::into(Human {
10+
id: 0,
11+
name: "human-32".to_owned(),
12+
}),
13+
Into::into(Droid {
14+
id: 1,
15+
name: "R2-D2".to_owned(),
16+
}),
17+
]
18+
}
19+
}
20+
21+
#[juniper::graphql_interface(for = [Human, Droid])]
22+
trait Character {
23+
fn id(&self) -> i32;
24+
25+
fn name(&self) -> String;
26+
}
27+
28+
#[derive(juniper::GraphQLObject)]
29+
#[graphql(impl = CharacterValue)]
30+
struct Human {
31+
pub id: i32,
32+
pub name: String,
33+
}
34+
35+
#[juniper::graphql_interface]
36+
impl Character for Human {
37+
fn id(&self) -> i32 {
38+
self.id
39+
}
40+
41+
fn name(&self) -> String {
42+
self.name.clone()
43+
}
44+
}
45+
46+
#[derive(juniper::GraphQLObject)]
47+
#[graphql(impl = CharacterValue)]
48+
struct Droid {
49+
pub id: i32,
50+
pub name: String,
51+
}
52+
53+
#[juniper::graphql_interface]
54+
impl Character for Droid {
55+
fn id(&self) -> i32 {
56+
self.id
57+
}
58+
59+
fn name(&self) -> String {
60+
self.name.clone()
61+
}
62+
}
63+
64+
type Schema = juniper::RootNode<'static, Query, EmptyMutation<()>, EmptySubscription<()>>;
65+
66+
#[tokio::test]
67+
async fn test_fragment_on_interface() {
68+
let query = r#"
69+
query Query {
70+
characters {
71+
...CharacterFragment
72+
}
73+
}
74+
75+
fragment CharacterFragment on Character {
76+
__typename
77+
... on Human {
78+
id
79+
name
80+
}
81+
... on Droid {
82+
id
83+
name
84+
}
85+
}
86+
"#;
87+
88+
let (res, errors) = juniper::execute(
89+
query,
90+
None,
91+
&Schema::new(Query, EmptyMutation::new(), EmptySubscription::new()),
92+
&Variables::new(),
93+
&(),
94+
)
95+
.await
96+
.unwrap();
97+
98+
assert_eq!(errors.len(), 0);
99+
assert_eq!(
100+
res,
101+
graphql_value!({
102+
"characters": [
103+
{"__typename": "Human", "id": 0, "name": "human-32"},
104+
{"__typename": "Droid", "id": 1, "name": "R2-D2"},
105+
],
106+
}),
107+
);
108+
109+
let (res, errors) = juniper::execute_sync(
110+
query,
111+
None,
112+
&Schema::new(Query, EmptyMutation::new(), EmptySubscription::new()),
113+
&Variables::new(),
114+
&(),
115+
)
116+
.unwrap();
117+
118+
assert_eq!(errors.len(), 0);
119+
assert_eq!(
120+
res,
121+
graphql_value!({
122+
"characters": [
123+
{"__typename": "Human", "id": 0, "name": "human-32"},
124+
{"__typename": "Droid", "id": 1, "name": "R2-D2"},
125+
],
126+
}),
127+
);
128+
}

integration_tests/juniper_tests/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,6 @@ mod issue_500;
2121
#[cfg(test)]
2222
mod issue_914;
2323
#[cfg(test)]
24+
mod issue_922;
25+
#[cfg(test)]
2426
mod pre_parse;

juniper/CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# master
22

3-
- No changes yet
3+
- Fix fields on interfaces not being resolved when used with fragments ([#923](https://github.com/graphql-rust/juniper/pull/923))
44

55
# [[0.15.4] 2021-04-03](https://github.com/graphql-rust/juniper/releases/tag/juniper-0.15.4)
66

juniper/src/types/async_await.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,10 @@ where
306306
);
307307

308308
let concrete_type_name = instance.concrete_type_name(sub_exec.context(), info);
309-
if fragment.type_condition.item == concrete_type_name {
309+
let type_name = instance.type_name(info);
310+
if fragment.type_condition.item == concrete_type_name
311+
|| Some(fragment.type_condition.item) == type_name
312+
{
310313
let sub_result = instance
311314
.resolve_into_type_async(
312315
info,

juniper/src/types/base.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -515,7 +515,10 @@ where
515515
);
516516

517517
let concrete_type_name = instance.concrete_type_name(sub_exec.context(), info);
518-
if fragment.type_condition.item == concrete_type_name {
518+
let type_name = instance.type_name(info);
519+
if fragment.type_condition.item == concrete_type_name
520+
|| Some(fragment.type_condition.item) == type_name
521+
{
519522
let sub_result = instance.resolve_into_type(
520523
info,
521524
fragment.type_condition.item,

0 commit comments

Comments
 (0)