Skip to content

Instantly share code, notes, and snippets.

@rcarver
Created October 25, 2023 22:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rcarver/fac5683ae6b3cbfd2474fa6e24506fbf to your computer and use it in GitHub Desktop.
Save rcarver/fac5683ae6b3cbfd2474fa6e24506fbf to your computer and use it in GitHub Desktop.
Shows that dependencies loses its context when called from within a GraphQL resolver
import CustomDump
import Dependencies
import Graphiti
import GraphQL
import Vapor
import XCTest
final class DependenciesTests: XCTestCase {
func testStatic() async throws {
let result = try await self.resolve(
app: Application(.testing),
api: try TestAPI(),
context: Context(),
query: """
query { uuidsStatic }
"""
)
XCTAssertNoDifference(result, GraphQLResult(data: [
"uuidsStatic": [
.string(UUID(0).uuidString),
.string(UUID(1).uuidString),
.string(UUID(2).uuidString),
]
]))
}
func testContextDeps() async throws {
try await withDependencies {
$0.uuid = .incrementing
} operation: {
let result = try await self.resolve(
app: Application(.testing),
api: try TestAPI(),
context: Context(),
query: """
query { uuidsContextDeps }
"""
)
XCTAssertNoDifference(result, GraphQLResult(data: [
"uuidsContextDeps": [
.string(UUID(0).uuidString),
.string(UUID(1).uuidString),
.string(UUID(2).uuidString),
]
]))
}
}
func testResolverDeps() async throws {
try await withDependencies {
$0.uuid = .incrementing
} operation: {
let result = try await self.resolve(
app: Application(.testing),
api: try TestAPI(),
context: Context(),
query: """
query { uuidsResolverDeps }
"""
)
XCTAssertNoDifference(result, GraphQLResult(data: [
"uuidsResolverDeps": [
.string(UUID(0).uuidString),
.string(UUID(1).uuidString),
.string(UUID(2).uuidString),
]
]))
}
}
struct Context {
@Dependency(\.uuid) var uuid
}
struct Resolver {
func uuidsStatic(context: Context, arguments: NoArguments) -> [UUID] {
return [
UUID(0),
UUID(1),
UUID(2),
]
}
func uuidsContextDeps(context: Context, arguments: NoArguments) -> [UUID] {
return [
context.uuid(),
context.uuid(),
context.uuid(),
]
}
func uuidsResolverDeps(context: Context, arguments: NoArguments) -> [UUID] {
@Dependency(\.uuid) var uuid
return [
uuid(),
uuid(),
uuid(),
]
}
}
struct TestAPI: API {
let resolver: Resolver
let schema: Schema<Resolver, Context>
init() throws {
self.resolver = Resolver()
self.schema = try Schema {
Scalar(UUID.self)
Query {
Field("uuidsStatic", at: Resolver.uuidsStatic)
Field("uuidsContextDeps", at: Resolver.uuidsContextDeps)
Field("uuidsResolverDeps", at: Resolver.uuidsResolverDeps)
}
}
}
}
func resolve<A: API>(
app: Application,
api: A,
context: Context,
query: String
) async throws -> GraphQLResult where A.ContextType == Context {
let future = api.schema.execute(
request: query,
resolver: api.resolver,
context: context,
eventLoopGroup: app.eventLoopGroup
)
return try await future.get()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment