Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 22 additions & 1 deletion juniper/src/tests/query_tests.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::{
graphql,
GraphQLError, RuleError, graphql,
parser::SourcePosition,
schema::model::RootNode,
tests::fixtures::starwars::schema::{Database, Query},
types::scalars::{EmptyMutation, EmptySubscription},
Expand Down Expand Up @@ -290,6 +291,26 @@ async fn test_query_name_invalid_variable() {
);
}

#[tokio::test]
async fn test_rejects_unknown_argument_on_query_field_without_args() {
let doc = "{ hero { name(unknownArg: true) } }";
let database = Database::new();
let schema = RootNode::new(
Query,
EmptyMutation::<Database>::new(),
EmptySubscription::<Database>::new(),
);

assert_eq!(
crate::execute(doc, None, &schema, &graphql::vars! {}, &database).await,
Err(GraphQLError::ValidationError(vec![RuleError::new(
r#"Unknown argument "unknownArg" on field "name" of type "Character""#,
&[SourcePosition::new(14, 0, 14)],
)])),
"expected validation error, got successful response",
);
}

#[tokio::test]
async fn test_query_friends_names() {
let doc = r#"{ human(id: "1000") { friends { name } } }"#;
Expand Down
10 changes: 5 additions & 5 deletions juniper/src/tests/subscriptions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ fn create_and_execute(
#[test]
fn returns_requested_object() {
let query = r#"subscription {
asyncHuman(id: "1") {
asyncHuman {
id
name
}
Expand Down Expand Up @@ -176,7 +176,7 @@ fn returns_requested_object() {
#[test]
fn returns_error() {
let query = r#"subscription {
errorHuman(id: "1") {
errorHuman {
id
name
}
Expand Down Expand Up @@ -227,7 +227,7 @@ fn can_access_context() {
fn resolves_typed_inline_fragments() {
let query = r#"subscription {
... on MySubscription {
asyncHuman(id: "32") {
asyncHuman {
id
}
}
Expand Down Expand Up @@ -255,7 +255,7 @@ fn resolves_typed_inline_fragments() {
fn resolves_nontyped_inline_fragments() {
let query = r#"subscription {
... {
asyncHuman(id: "32") {
asyncHuman {
id
}
}
Expand Down Expand Up @@ -310,7 +310,7 @@ fn can_access_arguments() {
#[test]
fn type_alias() {
let query = r#"subscription {
aliasedHuman: asyncHuman(id: "1") {
aliasedHuman: asyncHuman {
id
name
}
Expand Down
28 changes: 18 additions & 10 deletions juniper/src/validation/rules/known_argument_names.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ enum ArgumentPosition<'a> {
}

pub struct KnownArgumentNames<'a, S: Debug + 'a> {
current_args: Option<(ArgumentPosition<'a>, &'a Vec<Argument<S>>)>,
current_args: Option<(ArgumentPosition<'a>, &'a [Argument<S>])>,
}

pub fn factory<'a, S: Debug>() -> KnownArgumentNames<'a, S> {
Expand All @@ -36,7 +36,7 @@ where
.map(|d| {
(
ArgumentPosition::Directive(directive.item.name.item),
&d.arguments,
d.arguments.as_slice(),
)
});
}
Expand All @@ -48,18 +48,14 @@ where
fn enter_field(&mut self, ctx: &mut ValidatorContext<'a, S>, field: &'a Spanning<Field<S>>) {
self.current_args = ctx
.parent_type()
.and_then(|t| t.field_by_name(field.item.name.item))
.and_then(|f| f.arguments.as_ref())
.map(|args| {
.and_then(|t| t.field_by_name(field.item.name.item).map(|f| (t, f)))
.map(|(t, f)| {
(
ArgumentPosition::Field(
field.item.name.item,
ctx.parent_type()
.expect("Parent type should exist")
.name()
.expect("Parent type should be named"),
t.name().expect("Parent type should be named"),
),
args,
f.arguments.as_deref().unwrap_or(&[]),
)
});
}
Expand Down Expand Up @@ -144,6 +140,18 @@ mod tests {
);
}

#[test]
fn field_with_no_args_fails_on_provided_args() {
expect_fails_rule::<_, _, DefaultScalarValue>(
factory,
r#"{ dog { nickname(unknownArg: SIT) } }"#,
&[RuleError::new(
&field_error_message("unknownArg", "nickname", "Dog"),
&[SourcePosition::new(17, 0, 17)],
)],
);
}

#[test]
fn multiple_args_in_reverse_order_are_known() {
expect_passes_rule::<_, _, DefaultScalarValue>(
Expand Down