Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Query/Schema validation for default values on object type field arguments not captured (ValueOfCorrectType rule) #965

Closed
maloku opened this issue Feb 20, 2023 · 2 comments

Comments

@maloku
Copy link
Contributor

maloku commented Feb 20, 2023

From the documentation https://sangria-graphql.github.io/learn/#query-validation

Query validation can also be used for SDL validation. ...

Regarding documentation, I expected the following validation to fail, but it is passing:

// test can be added to sangria.validation.rules.ValuesOfCorrectTypeSpec
"Type field arguments default values" should {
    "fail when wrong field name" in {

      val Success(doc) = QueryParser.parse(
        """
          |input A {
          | f1: Int
          | f2: Float
          |}
          |""".stripMargin
      )
      val stubSchema = Schema.buildStubFromAst(doc)
      val Success(docUnderTest) = QueryParser.parse(
        """
          |type Test {
          | f(a: A = {wrong: 50}): String
          |}
          |""".stripMargin
      )
      val violations = validator(defaultRule.toList).validateQuery(stubSchema, docUnderTest)
      violations shouldNot be(empty) // but it is empty
      violations.head shouldBe a[UnknownFieldViolation] 

    }
  }

I have spent some time recently in the library code, and I think the issue is in TypeInfo.scala as it does not push in the inputTypeStack the input type, which leads ctx.typeInfo.inputType to be None and ignore the checking altogether.

The following change in TypeInfo.scala fixes this issue, and I did not get any other failing tests. It does check the InputValueDefinition with defaultValue and adds the type into the stack, which later can be found by the rule.

  def enter(node: ast.AstNode) = {
    ancestorStack.push(node)

    node match {
      //code omitted
      case ast.InputValueDefinition(_, valueType, Some(_), _, _, _, _) =>
        inputTypeStack.push(schema.getInputType(valueType))
    }
  }
  def leave(node: ast.AstNode) = {
    node match {
      //code omitted
      case ast.InputValueDefinition(_, _, Some(_), _, _, _, _) => 
        inputTypeStack.pop()
    }

    ancestorStack.pop()
  }

It is very hard to get around this issue (or at least I could not find one) since all the stacks in this class are private; extending this class does not help. Adding public methods for pop and push to the stacks could be helpful if one wants to add specific validation rules if the default implementation does not handle specific AstNodes.

I am new to the library, but if you think this would be enough, I can PR this fix and add public methods for pop and push.

@yanns
Copy link
Contributor

yanns commented Feb 20, 2023

Thanks a lot for the investigation, and the time spent to explain the issue.

I'm not very familiar with this part of the code. I don't know if this change would have some strange side-effects.
I can propose the following:

  • you can open a PR
  • I'll try the change on some internal applications

WDYT?

@maloku
Copy link
Contributor Author

maloku commented Feb 21, 2023

Thanks for the prompt response. I will open a PR as soon as I have it.

@yanns yanns closed this as completed in 229b507 Feb 24, 2023
yanns added a commit that referenced this issue Feb 24, 2023
Values of correct type when validating SDL. Fixes #965
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants