Fix fields on interface not being resolved when used with fragments (#923, #922)

This commit is contained in:
ArsileLuci 2021-04-30 15:13:54 +03:00 committed by GitHub
parent 106e322f68
commit dc99ae70b8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 139 additions and 3 deletions

View file

@ -0,0 +1,128 @@
use juniper::*;
struct Query;
#[juniper::graphql_object]
impl Query {
fn characters() -> Vec<CharacterValue> {
vec![
Into::into(Human {
id: 0,
name: "human-32".to_owned(),
}),
Into::into(Droid {
id: 1,
name: "R2-D2".to_owned(),
}),
]
}
}
#[juniper::graphql_interface(for = [Human, Droid])]
trait Character {
fn id(&self) -> i32;
fn name(&self) -> String;
}
#[derive(juniper::GraphQLObject)]
#[graphql(impl = CharacterValue)]
struct Human {
pub id: i32,
pub name: String,
}
#[juniper::graphql_interface]
impl Character for Human {
fn id(&self) -> i32 {
self.id
}
fn name(&self) -> String {
self.name.clone()
}
}
#[derive(juniper::GraphQLObject)]
#[graphql(impl = CharacterValue)]
struct Droid {
pub id: i32,
pub name: String,
}
#[juniper::graphql_interface]
impl Character for Droid {
fn id(&self) -> i32 {
self.id
}
fn name(&self) -> String {
self.name.clone()
}
}
type Schema = juniper::RootNode<'static, Query, EmptyMutation<()>, EmptySubscription<()>>;
#[tokio::test]
async fn test_fragment_on_interface() {
let query = r#"
query Query {
characters {
...CharacterFragment
}
}
fragment CharacterFragment on Character {
__typename
... on Human {
id
name
}
... on Droid {
id
name
}
}
"#;
let (res, errors) = juniper::execute(
query,
None,
&Schema::new(Query, EmptyMutation::new(), EmptySubscription::new()),
&Variables::new(),
&(),
)
.await
.unwrap();
assert_eq!(errors.len(), 0);
assert_eq!(
res,
graphql_value!({
"characters": [
{"__typename": "Human", "id": 0, "name": "human-32"},
{"__typename": "Droid", "id": 1, "name": "R2-D2"},
],
}),
);
let (res, errors) = juniper::execute_sync(
query,
None,
&Schema::new(Query, EmptyMutation::new(), EmptySubscription::new()),
&Variables::new(),
&(),
)
.unwrap();
assert_eq!(errors.len(), 0);
assert_eq!(
res,
graphql_value!({
"characters": [
{"__typename": "Human", "id": 0, "name": "human-32"},
{"__typename": "Droid", "id": 1, "name": "R2-D2"},
],
}),
);
}

View file

@ -21,4 +21,6 @@ mod issue_500;
#[cfg(test)]
mod issue_914;
#[cfg(test)]
mod issue_922;
#[cfg(test)]
mod pre_parse;

View file

@ -1,6 +1,6 @@
# master
- No changes yet
- Fix fields on interfaces not being resolved when used with fragments ([#923](https://github.com/graphql-rust/juniper/pull/923))
# [[0.15.4] 2021-04-03](https://github.com/graphql-rust/juniper/releases/tag/juniper-0.15.4)

View file

@ -306,7 +306,10 @@ where
);
let concrete_type_name = instance.concrete_type_name(sub_exec.context(), info);
if fragment.type_condition.item == concrete_type_name {
let type_name = instance.type_name(info);
if fragment.type_condition.item == concrete_type_name
|| Some(fragment.type_condition.item) == type_name
{
let sub_result = instance
.resolve_into_type_async(
info,

View file

@ -515,7 +515,10 @@ where
);
let concrete_type_name = instance.concrete_type_name(sub_exec.context(), info);
if fragment.type_condition.item == concrete_type_name {
let type_name = instance.type_name(info);
if fragment.type_condition.item == concrete_type_name
|| Some(fragment.type_condition.item) == type_name
{
let sub_result = instance.resolve_into_type(
info,
fragment.type_condition.item,