Skip to content

Commit

Permalink
Add missing context for subscription loaders (#567)
Browse files Browse the repository at this point in the history
  • Loading branch information
ekosz authored Sep 20, 2021
1 parent e0f672c commit bc08c0f
Show file tree
Hide file tree
Showing 2 changed files with 174 additions and 1 deletion.
2 changes: 1 addition & 1 deletion lib/subscription-connection.js
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ module.exports = class SubscriptionConnection {
pubsub: sc,
lruGatewayResolvers: this.lruGatewayResolvers,
reply: {
[kLoaders]: subscriptionLoaders && subscriptionLoaders.create(),
[kLoaders]: subscriptionLoaders && subscriptionLoaders.create(context),
[kEntityResolvers]: this.entityResolvers,
request: { headers: {} }
}
Expand Down
173 changes: 173 additions & 0 deletions test/subscription.js
Original file line number Diff line number Diff line change
Expand Up @@ -1876,3 +1876,176 @@ test('subscription server works with fastify-websocket', t => {
}))
})
})

test('subscription passes context to its loaders', t => {
const app = Fastify()
t.teardown(async () => {
await app.close()
})

const sendTestMutation = () => {
app.inject({
method: 'POST',
url: '/graphql',
body: {
query: `
mutation {
addNotification(message: "Hello World") {
id
}
}
`
}
}, () => {})
}

const emitter = mq()
const schema = `
type Notification {
id: ID!
message: String
}
type Query {
notifications: [Notification]
}
type Mutation {
addNotification(message: String): Notification
}
type Subscription {
notificationAdded: Notification
}
`

let idCount = 1
const notifications = [{
id: idCount,
message: 'Notification message'
}]

const loaders = {
Notification: {
message: async (queries, context) => {
t.ok(context, 'context is not missing')
const { username } = context
return queries.map(({ obj }) => `${obj.message} ${username}`)
}
}
}

const resolvers = {
Query: {
notifications: () => notifications
},
Mutation: {
addNotification: async (_, { message }) => {
const id = idCount++
const notification = {
id,
message
}
notifications.push(notification)
await emitter.emit({
topic: 'NOTIFICATION_ADDED',
payload: {
notificationAdded: notification
}
})

return notification
}
},
Subscription: {
notificationAdded: {
subscribe: (root, args, { pubsub, topic }) => pubsub.subscribe(topic)
}
}
}

app.register(GQL, {
schema,
resolvers,
loaders,
subscription: {
emitter,
context: () => ({
topic: 'NOTIFICATION_ADDED',
username: 'foobar'
})
}
})

app.listen(0, err => {
t.error(err)

const ws = new WebSocket('ws://localhost:' + (app.server.address()).port + '/graphql', 'graphql-ws')
const client = WebSocket.createWebSocketStream(ws, { encoding: 'utf8', objectMode: true })
t.teardown(client.destroy.bind(client))
client.setEncoding('utf8')

client.write(JSON.stringify({
type: 'connection_init'
}))

client.write(JSON.stringify({
id: 1,
type: 'start',
payload: {
query: `
subscription {
notificationAdded {
id
message
}
}
`
}
}))

client.write(JSON.stringify({
id: 2,
type: 'start',
payload: {
query: `
subscription {
notificationAdded {
id
message
}
}
`
}
}))

client.write(JSON.stringify({
id: 2,
type: 'stop'
}))

client.on('data', chunk => {
const data = JSON.parse(chunk)

if (data.id === 1 && data.type === 'data') {
t.equal(chunk, JSON.stringify({
type: 'data',
id: 1,
payload: {
data: {
notificationAdded: {
id: '1',
message: 'Hello World foobar'
}
}
}
}))

client.end()
t.end()
} else if (data.id === 2 && data.type === 'complete') {
sendTestMutation()
}
})
})
})

0 comments on commit bc08c0f

Please sign in to comment.