Skip to content

Commit

Permalink
fix(gatsby): Use concrete type resolver on interface fields (#17284)
Browse files Browse the repository at this point in the history
  • Loading branch information
stefanprobst authored and sidharthachatterjee committed Sep 9, 2019
1 parent 207022a commit fd72133
Show file tree
Hide file tree
Showing 2 changed files with 123 additions and 2 deletions.
114 changes: 113 additions & 1 deletion packages/gatsby/src/schema/extensions/__tests__/interfaces.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const {
const { store } = require(`../../../redux`)
const { dispatch } = store
const { actions } = require(`../../../redux/actions`)
const { createTypes } = actions
const { createTypes, createFieldExtension } = actions
require(`../../../db/__tests__/fixtures/ensure-loki`)()

const report = require(`gatsby-cli/lib/reporter`)
Expand Down Expand Up @@ -378,6 +378,118 @@ describe(`Queryable Node interfaces`, () => {
}
expect(results).toEqual(expected)
})

it(`uses concrete type resolvers when filtering on interface fields`, async () => {
const nodes = [
{
id: `author1`,
internal: { type: `AuthorYaml` },
name: `Author 1`,
birthday: new Date(Date.UTC(1978, 8, 26)),
},
{
id: `author2`,
internal: { type: `AuthorJson` },
name: `Author 2`,
birthday: new Date(Date.UTC(1978, 8, 26)),
},
{
id: `post1`,
internal: { type: `ThisPost` },
author: `author1`,
},
{
id: `post2`,
internal: { type: `ThatPost` },
author: `author2`,
},
]
nodes.forEach(node =>
dispatch({ type: `CREATE_NODE`, payload: { ...node } })
)
dispatch(
createFieldExtension({
name: `echo`,
args: {
value: `String!`,
},
extend(options) {
return {
resolve() {
return options.value
},
}
},
})
)
dispatch(
createTypes(`
interface Post @nodeInterface {
id: ID!
author: Author @link
}
type ThisPost implements Node & Post {
author: Author @link
}
type ThatPost implements Node & Post {
author: Author @link
}
interface Author @nodeInterface {
id: ID!
name: String
echo: String @echo(value: "Interface")
}
type AuthorJson implements Node & Author {
name: String
echo: String @echo(value: "Concrete Type")
}
type AuthorYaml implements Node & Author {
name: String
echo: String @echo(value: "Another Concrete Type")
}
`)
)
const query = `
{
allPost(
filter: {
author: {
echo: {
in: ["Concrete Type", "Another Concrete Type"]
}
}
}
) {
nodes {
author {
name
echo
}
}
}
}
`
const results = await runQuery(query)
const expected = {
allPost: {
nodes: [
{
author: {
name: `Author 1`,
echo: `Another Concrete Type`,
},
},
{
author: {
name: `Author 2`,
echo: `Concrete Type`,
},
},
],
},
}
expect(results).toEqual(expected)
})
})

const buildSchema = async () => {
Expand Down
11 changes: 10 additions & 1 deletion packages/gatsby/src/schema/node-model.js
Original file line number Diff line number Diff line change
Expand Up @@ -522,6 +522,15 @@ const dropQueryOperators = filter =>
return acc
}, {})

const getFields = (schema, type, node) => {
if (!isAbstractType(type)) {
return type.getFields()
}

const concreteType = type.resolveType(node)
return schema.getType(concreteType).getFields()
}

async function resolveRecursive(
nodeModel,
schemaComposer,
Expand All @@ -531,7 +540,7 @@ async function resolveRecursive(
queryFields,
fieldsToResolve
) {
const gqlFields = type.getFields()
const gqlFields = getFields(schema, type, node)
let resolvedFields = {}
for (const fieldName of Object.keys(fieldsToResolve)) {
const fieldToResolve = fieldsToResolve[fieldName]
Expand Down

0 comments on commit fd72133

Please sign in to comment.