Skip to content

Commit

Permalink
fix: support dynamic arguments (#146)
Browse files Browse the repository at this point in the history
Co-authored-by: James Mortemore <[email protected]>

fixes #145
  • Loading branch information
velias authored Jan 23, 2023
1 parent 3e67653 commit 9aaf846
Show file tree
Hide file tree
Showing 22 changed files with 283 additions and 205 deletions.
6 changes: 6 additions & 0 deletions lib/query-validation-visitor.js
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,8 @@ module.exports = class QueryValidationVisitor {
}

function validateScalarTypeValue (context, currentQueryField, typeDefWithDirective, valueTypeDef, value, variableName, argName, fieldNameForError, errMessageAt) {
if (!typeDefWithDirective.astNode) { return }

const directiveArgumentMap = getDirectiveValues(constraintDirectiveTypeDefsObj, typeDefWithDirective.astNode)

if (directiveArgumentMap) {
Expand All @@ -172,13 +174,17 @@ function validateScalarTypeValue (context, currentQueryField, typeDefWithDirecti
}

function validateInputTypeValue (context, inputObjectTypeDef, argName, variableName, value, currentField, parentNames) {
if (!inputObjectTypeDef.astNode) { return }

// use new visitor to traverse input object structure
const visitor = new InputObjectValidationVisitor(context, inputObjectTypeDef, argName, variableName, value, currentField, parentNames)

visit(inputObjectTypeDef.astNode, visitor)
}

function validateArrayTypeValue (context, valueTypeDef, typeDefWithDirective, value, currentField, argName, variableName, iFieldNameFull) {
if (!typeDefWithDirective.astNode) { return }

let valueTypeDefArray = valueTypeDef.ofType

if (isNonNullType(valueTypeDefArray)) valueTypeDefArray = valueTypeDefArray.ofType
Expand Down
52 changes: 52 additions & 0 deletions test/argument-dynamic.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
const { strictEqual } = require('assert')
const { GraphQLString } = require('graphql')
const { mapSchema, getDirective, MapperKind } = require('@graphql-tools/utils')

const dateDirectiveTypeDefs = 'directive @formatDate on FIELD_DEFINITION'

const dateDirectiveTransformer = (schema) =>
mapSchema(schema, {
[MapperKind.OBJECT_FIELD] (fieldConfig) {
const dateDirective = getDirective(schema, fieldConfig, 'formatDate')?.[0]
if (dateDirective) {
fieldConfig.args.format = {
type: GraphQLString
}

fieldConfig.type = GraphQLString
return fieldConfig
}
}
})

module.exports.test = function (setup, implType) {
describe('Dynamic argument', function () {
before(async function () {
this.typeDefs = /* GraphQL */`
type Query {
getBook: String @formatDate
getBooks: [String] @formatDate
}
` + '\n' + dateDirectiveTypeDefs

this.request = await setup({ typeDefs: this.typeDefs, schemaCreatedCallback: (schema) => { return dateDirectiveTransformer(schema) } })
})

it('should pass', async function () {
const query = /* GraphQL */`
query Go {
getBook(format: "aa")
getBooks(format: "aa")
}
`
const { body, statusCode } = await this.request
.post('/graphql')
.set('Accept', 'application/json')
.send({ query })

if (statusCode !== 200) { console.log(body) }
strictEqual(statusCode, 200)
})
})
}
8 changes: 4 additions & 4 deletions test/argument.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ module.exports.test = function (setup, implType) {
authors (size: Int @constraint(max: 4)): [String]
}
`
this.request = await setup(this.typeDefs)
this.request = await setup({ typeDefs: this.typeDefs })
})

it('should pass', async function () {
Expand Down Expand Up @@ -105,7 +105,7 @@ module.exports.test = function (setup, implType) {

if (isSchemaWrapperImplType(implType)) {
it('should throw custom error', async function () {
const request = await setup(this.typeDefs, formatError)
const request = await setup({ typeDefs: this.typeDefs, formatError })
const { body, statusCode } = await request
.post('/graphql')
.set('Accept', 'application/json')
Expand Down Expand Up @@ -183,7 +183,7 @@ module.exports.test = function (setup, implType) {
}
`

this.request = await setup(this.typeDefs)
this.request = await setup({ typeDefs: this.typeDefs })
})

it('should pass', async function () {
Expand Down Expand Up @@ -257,7 +257,7 @@ module.exports.test = function (setup, implType) {

if (isSchemaWrapperImplType(implType)) {
it('should throw custom error', async function () {
const request = await setup(this.typeDefs, formatError)
const request = await setup({ typeDefs: this.typeDefs, formatError })
const { body, statusCode } = await request
.post('/graphql')
.set('Accept', 'application/json')
Expand Down
12 changes: 6 additions & 6 deletions test/array-size.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ module.exports.test = function (setup, implType) {
title: [Int!] @constraint(minItems: 3)
}`

this.request = await setup(this.typeDefs)
this.request = await setup({ typeDefs: this.typeDefs })
})

it('should pass', async function () {
Expand Down Expand Up @@ -86,7 +86,7 @@ module.exports.test = function (setup, implType) {
title: [Int!] @constraint(maxItems: 2)
}`

this.request = await setup(this.typeDefs)
this.request = await setup({ typeDefs: this.typeDefs })
})

it('should pass', async function () {
Expand Down Expand Up @@ -140,7 +140,7 @@ module.exports.test = function (setup, implType) {
createBook(input: [Int] @constraint(minItems: 3)): Book
}`

this.request = await setup(this.typeDefs)
this.request = await setup({ typeDefs: this.typeDefs })
})

it('should pass', async function () {
Expand Down Expand Up @@ -212,7 +212,7 @@ module.exports.test = function (setup, implType) {
createBook(input: [Int] @constraint(maxItems: 2, max: 100)): Book
}`

this.request = await setup(this.typeDefs)
this.request = await setup({ typeDefs: this.typeDefs })
})

it('should pass', async function () {
Expand Down Expand Up @@ -307,7 +307,7 @@ module.exports.test = function (setup, implType) {
createBook(input: [ID]! @constraint(minItems: 3)): Book
}`

this.request = await setup(this.typeDefs)
this.request = await setup({ typeDefs: this.typeDefs })
})

it('should pass', async function () {
Expand Down Expand Up @@ -365,7 +365,7 @@ module.exports.test = function (setup, implType) {
title: String @constraint(maxLength: 2)
}
`
this.request = await setup(this.typeDefs)
this.request = await setup({ typeDefs: this.typeDefs })
})

it('should pass', async function () {
Expand Down
14 changes: 7 additions & 7 deletions test/array-structures.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ module.exports.test = function (setup, implType) {
}
`

this.request = await setup(this.typeDefs)
this.request = await setup({ typeDefs: this.typeDefs })
})

it('should pass', async function () {
Expand Down Expand Up @@ -79,7 +79,7 @@ module.exports.test = function (setup, implType) {
}
`

this.request = await setup(this.typeDefs)
this.request = await setup({ typeDefs: this.typeDefs })
})

it('should pass', async function () {
Expand Down Expand Up @@ -142,7 +142,7 @@ module.exports.test = function (setup, implType) {
}
`

this.request = await setup(this.typeDefs)
this.request = await setup({ typeDefs: this.typeDefs })
})

it('should pass', async function () {
Expand Down Expand Up @@ -221,7 +221,7 @@ module.exports.test = function (setup, implType) {
}
`

this.request = await setup(this.typeDefs)
this.request = await setup({ typeDefs: this.typeDefs })
})

it('should pass', async function () {
Expand Down Expand Up @@ -264,7 +264,7 @@ module.exports.test = function (setup, implType) {
}
`

this.request = await setup(this.typeDefs)
this.request = await setup({ typeDefs: this.typeDefs })
})

it('should pass', async function () {
Expand Down Expand Up @@ -330,7 +330,7 @@ module.exports.test = function (setup, implType) {
}
`

this.request = await setup(this.typeDefs)
this.request = await setup({ typeDefs: this.typeDefs })
})

it('should pass', async function () {
Expand Down Expand Up @@ -381,7 +381,7 @@ module.exports.test = function (setup, implType) {
}
`

this.request = await setup(this.typeDefs)
this.request = await setup({ typeDefs: this.typeDefs })
})

it('should pass', async function () {
Expand Down
12 changes: 6 additions & 6 deletions test/array.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ module.exports.test = function (setup, implType) {
title: [Int!]! @constraint(min: 3)
}`

this.request = await setup(this.typeDefs)
this.request = await setup({ typeDefs: this.typeDefs })
})

it('should pass', async function () {
Expand Down Expand Up @@ -70,7 +70,7 @@ module.exports.test = function (setup, implType) {
title: [Int!] @constraint(max: 3)
}`

this.request = await setup(this.typeDefs)
this.request = await setup({ typeDefs: this.typeDefs })
})

it('should pass', async function () {
Expand Down Expand Up @@ -115,7 +115,7 @@ module.exports.test = function (setup, implType) {
title: [Int!] @constraint(multipleOf: 2)
}`

this.request = await setup(this.typeDefs)
this.request = await setup({ typeDefs: this.typeDefs })
})

if (!isServerValidatorEnvelop(implType)) {
Expand Down Expand Up @@ -174,7 +174,7 @@ module.exports.test = function (setup, implType) {
title: [String!] @constraint(minLength: 3)
}`

this.request = await setup(this.typeDefs)
this.request = await setup({ typeDefs: this.typeDefs })
})

it('should pass', async function () {
Expand Down Expand Up @@ -219,7 +219,7 @@ module.exports.test = function (setup, implType) {
title: [String] @constraint(maxLength: 3)
}`

this.request = await setup(this.typeDefs)
this.request = await setup({ typeDefs: this.typeDefs })
})

it('should pass', async function () {
Expand Down Expand Up @@ -264,7 +264,7 @@ module.exports.test = function (setup, implType) {
title: [String!]! @constraint(format: "uri")
}`

this.request = await setup(this.typeDefs)
this.request = await setup({ typeDefs: this.typeDefs })
})

it('should pass', async function () {
Expand Down
Loading

0 comments on commit 9aaf846

Please sign in to comment.