Skip to content

Commit

Permalink
Validation to prevent all field types as @hidden (#646)
Browse files Browse the repository at this point in the history
* added validation to prevent all field types being hidden

* moved validation error and removed extra arg

* added validation to prevent all field types being hidden

* moved validation error and removed extra arg

* master checkout

* master checkout

* added validation to prevent all field types being hidden

* make variable constant

* added tests for validation

* added tests for validation

* removed comments and annotations

* removed unnecessary imports

* refactor and error message update

* added a positive test for allowing schema with at least one field as not hidden

* revert unwanted file change
  • Loading branch information
priyam-atlas authored Dec 17, 2024
1 parent 8a5e1b4 commit 1030fc8
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package graphql.nadel.validation

import graphql.nadel.engine.util.unwrapAll
import graphql.nadel.schema.NadelDirectives
import graphql.nadel.validation.NadelSchemaValidationError.IncompatibleArgumentInputType
import graphql.nadel.validation.NadelSchemaValidationError.IncompatibleFieldOutputType
import graphql.nadel.validation.NadelSchemaValidationError.MissingArgumentOnUnderlying
Expand Down Expand Up @@ -36,6 +37,9 @@ class NadelFieldValidation internal constructor(
parent: NadelServiceSchemaElement.FieldsContainer,
overallFields: List<GraphQLFieldDefinition>,
): NadelSchemaValidationResult {
if(areAllFieldsHidden(overallFields)) {
return NadelSchemaValidationError.AllFieldsUsingHiddenDirective(parent)
}
return overallFields
.asSequence()
.let { fieldSequence ->
Expand All @@ -53,6 +57,10 @@ class NadelFieldValidation internal constructor(
.toResult()
}

private fun areAllFieldsHidden(overallFields: List<GraphQLFieldDefinition>): Boolean {
return overallFields.all { it.hasAppliedDirective(NadelDirectives.hiddenDirectiveDefinition.name) };
}

context(NadelValidationContext)
fun validate(
parent: NadelServiceSchemaElement.FieldsContainer,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,19 @@ sealed interface NadelSchemaValidationError : NadelSchemaValidationResult {

override val subject = overallField
}

data class AllFieldsUsingHiddenDirective(
val parentType: NadelServiceSchemaElement,
) : NadelSchemaValidationError {
val service: Service get() = parentType.service

override val message = run {
val ot = parentType.overall.name
"Must have at least one field without @hidden on type $ot"
}

override val subject = parentType.overall
}
}

private fun toString(element: GraphQLNamedSchemaElement): String {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -676,5 +676,55 @@ class NadelFieldValidationTest : DescribeSpec({

assert(error.message == "The overall field Query.fieldA defines argument id which does not exist in service test field Query.fieldA")
}

it("fails if schema contains all fields as hidden") {
val fixture = NadelValidationTestFixture(
overallSchema = mapOf(
"test" to """
type Query {
echo: String @hidden
}
""".trimIndent(),
),
underlyingSchema = mapOf(
"test" to """
type Query {
echo: String
}
""".trimIndent(),
),
)

val errors = validate(fixture)
assert(errors.map { it.message }.isNotEmpty())

val error = errors.assertSingleOfType<NadelSchemaValidationError>()
assert(error.message == "Must have at least one field without @hidden on type Query")
}

it("passes if schema contains at least one field as not hidden") {
val fixture = NadelValidationTestFixture(
overallSchema = mapOf(
"test" to """
type Query {
echo: String @hidden
hello: String

}
""".trimIndent(),
),
underlyingSchema = mapOf(
"test" to """
type Query {
echo: String
hello: String
}
""".trimIndent(),
),
)

val errors = validate(fixture)
assert(errors.isEmpty())
}
}
})

0 comments on commit 1030fc8

Please sign in to comment.