juniper 0.15.11

GraphQL server library
Documentation
use crate::{
    ast::InputValue,
    executor::Variables,
    parser::SourcePosition,
    schema::model::RootNode,
    types::scalars::{EmptyMutation, EmptySubscription},
    validation::RuleError,
    value::{DefaultScalarValue, Object, Value},
    GraphQLEnum,
    GraphQLError::ValidationError,
};

#[derive(GraphQLEnum, Debug)]
enum Color {
    Red,
    Green,
    Blue,
}
struct TestType;

#[crate::graphql_object]
impl TestType {
    fn to_string(color: Color) -> String {
        format!("Color::{:?}", color)
    }

    fn a_color() -> Color {
        Color::Red
    }
}

async fn run_variable_query<F>(query: &str, vars: Variables<DefaultScalarValue>, f: F)
where
    F: Fn(&Object<DefaultScalarValue>) -> (),
{
    let schema = RootNode::new(
        TestType,
        EmptyMutation::<()>::new(),
        EmptySubscription::<()>::new(),
    );

    let (result, errs) = crate::execute(query, None, &schema, &vars, &())
        .await
        .expect("Execution failed");

    assert_eq!(errs, []);

    println!("Result: {:#?}", result);

    let obj = result.as_object_value().expect("Result is not an object");

    f(obj);
}

async fn run_query<F>(query: &str, f: F)
where
    F: Fn(&Object<DefaultScalarValue>) -> (),
{
    run_variable_query(query, Variables::new(), f).await;
}

#[tokio::test]
async fn accepts_enum_literal() {
    run_query("{ toString(color: RED) }", |result| {
        assert_eq!(
            result.get_field_value("toString"),
            Some(&Value::scalar("Color::Red"))
        );
    })
    .await;
}

#[tokio::test]
async fn serializes_as_output() {
    run_query("{ aColor }", |result| {
        assert_eq!(
            result.get_field_value("aColor"),
            Some(&Value::scalar("RED"))
        );
    })
    .await;
}

#[tokio::test]
async fn does_not_accept_string_literals() {
    let schema = RootNode::new(
        TestType,
        EmptyMutation::<()>::new(),
        EmptySubscription::<()>::new(),
    );

    let query = r#"{ toString(color: "RED") }"#;
    let vars = vec![].into_iter().collect();

    let error = crate::execute(query, None, &schema, &vars, &())
        .await
        .unwrap_err();

    assert_eq!(
        error,
        ValidationError(vec![RuleError::new(
            r#"Invalid value for argument "color", expected type "Color!""#,
            &[SourcePosition::new(18, 0, 18)],
        )])
    );
}

#[tokio::test]
async fn accepts_strings_in_variables() {
    run_variable_query(
        "query q($color: Color!) { toString(color: $color) }",
        vec![("color".to_owned(), InputValue::scalar("RED"))]
            .into_iter()
            .collect(),
        |result| {
            assert_eq!(
                result.get_field_value("toString"),
                Some(&Value::scalar("Color::Red"))
            );
        },
    )
    .await;
}

#[tokio::test]
async fn does_not_accept_incorrect_enum_name_in_variables() {
    let schema = RootNode::new(
        TestType,
        EmptyMutation::<()>::new(),
        EmptySubscription::<()>::new(),
    );

    let query = r#"query q($color: Color!) { toString(color: $color) }"#;
    let vars = vec![("color".to_owned(), InputValue::scalar("BLURPLE"))]
        .into_iter()
        .collect();

    let error = crate::execute(query, None, &schema, &vars, &())
        .await
        .unwrap_err();

    assert_eq!(
        error,
        ValidationError(vec![RuleError::new(
            r#"Variable "$color" got invalid value. Invalid value for enum "Color"."#,
            &[SourcePosition::new(8, 0, 8)],
        )])
    );
}

#[tokio::test]
async fn does_not_accept_incorrect_type_in_variables() {
    let schema = RootNode::new(
        TestType,
        EmptyMutation::<()>::new(),
        EmptySubscription::<()>::new(),
    );

    let query = r#"query q($color: Color!) { toString(color: $color) }"#;
    let vars = vec![("color".to_owned(), InputValue::scalar(123))]
        .into_iter()
        .collect();

    let error = crate::execute(query, None, &schema, &vars, &())
        .await
        .unwrap_err();

    assert_eq!(
        error,
        ValidationError(vec![RuleError::new(
            r#"Variable "$color" got invalid value. Expected "Color", found not a string or enum."#,
            &[SourcePosition::new(8, 0, 8)],
        )])
    );
}