Skip to content

Commit c6dbf62

Browse files
test: Adds subscription init failure test
1 parent 1dd066e commit c6dbf62

1 file changed

Lines changed: 96 additions & 0 deletions

File tree

Tests/GraphQLHummingbirdTests/WebSocketTests.swift

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,102 @@ struct WebSocketTests {
8989
}
9090
}
9191

92+
@Test func subscriptionWithInitPayloadError() async throws {
93+
let pubsub = SimplePubSub<String>()
94+
let schema = try GraphQLSchema(
95+
subscription: GraphQLObjectType(
96+
name: "Subscription",
97+
fields: [
98+
"hello": GraphQLField(
99+
type: GraphQLString,
100+
resolve: { source, _, _, _ in
101+
source as! String
102+
},
103+
subscribe: { _, _, _, _ in
104+
await pubsub.subscribe()
105+
}
106+
),
107+
]
108+
)
109+
)
110+
111+
struct InitPayload: Equatable, Codable, Sendable {
112+
let code: String
113+
}
114+
let acceptedCode = "abc"
115+
116+
let router = Router(context: TestWebSocketContext.self)
117+
router.graphqlWebSocket(
118+
schema: schema,
119+
config: .init(
120+
subscriptionProtocols: [.websocket],
121+
websocket: .init(
122+
onWebSocketInit: { (initPayload: InitPayload, _, _) in
123+
initPayload.code == acceptedCode
124+
}
125+
)
126+
)
127+
) { inputs in
128+
// If the codes don't match, this will fail on the subscribe/execute request
129+
guard let codeIsValid = inputs.websocketInitResult, codeIsValid else {
130+
throw GraphQLError(message: "Unauthorized")
131+
}
132+
return EmptyContext()
133+
}
134+
let app = Application(
135+
router: Router(),
136+
server: .http1WebSocketUpgrade(webSocketRouter: router),
137+
configuration: .init(address: .hostname("127.0.0.1", port: 0))
138+
)
139+
140+
_ = try await app.test(.live) { client in
141+
try await client.ws(
142+
"/graphql",
143+
configuration: .init(additionalHeaders: [.secWebSocketProtocol: "graphql-transport-ws"])
144+
) { inbound, outbound, _ in
145+
// Start the sequence
146+
// Send incorrect code, expect an "Unauthorized" error on the subscribe call
147+
try await outbound.write(.text(#"{"type": "connection_init", "payload": {"code": "def"}}"#))
148+
for try await message in inbound.messages(maxSize: 1024 * 1024) {
149+
guard case let .text(message) = message else { return }
150+
#expect(!message.starts(with: "44"))
151+
let response = try #require(message.data(using: .utf8))
152+
if let _ = try? decoder.decode(GraphQLTransportWS.ConnectionAckResponse.self, from: response) {
153+
try await outbound.write(.text(#"""
154+
{
155+
"type": "subscribe",
156+
"payload": {
157+
"query": "subscription { hello }"
158+
},
159+
"id": "1"
160+
}
161+
"""#))
162+
// Must wait for a few milliseconds for the subscription to get set up.
163+
try await Task.sleep(for: .milliseconds(10))
164+
// Force the server to emit an event
165+
await pubsub.emit(event: "World")
166+
} else if let _ = try? decoder.decode(GraphQLTransportWS.NextResponse.self, from: response) {
167+
Issue.record("Expected Error: \(message)")
168+
await pubsub.cancel()
169+
break
170+
} else if let _ = try? decoder.decode(GraphQLTransportWS.CompleteResponse.self, from: response) {
171+
Issue.record("Expected Error: \(message)")
172+
try await outbound.close(.goingAway, reason: nil)
173+
break
174+
} else if let errorResult = try? decoder.decode(GraphQLTransportWS.ErrorResponse.self, from: response) {
175+
#expect(errorResult.payload[0].message == "Unauthorized")
176+
await pubsub.cancel()
177+
try await outbound.close(.goingAway, reason: nil)
178+
break
179+
} else {
180+
Issue.record("Unrecognized message: \(message)")
181+
break
182+
}
183+
}
184+
}
185+
}
186+
}
187+
92188
@Test func subscription_GraphQLWS() async throws {
93189
let pubsub = SimplePubSub<String>()
94190
let schema = try GraphQLSchema(

0 commit comments

Comments
 (0)