Repository: michalkvasnicak/aws-lambda-graphql (ts)

Issue:
Set up connection/subscription manager for EventProcessors during Server instantiation
Do not use context to pass them. It's unnecessary. See comment in https://github.com/michalkvasnicak/aws-lambda-graphql/pull/63#issuecomment-571950472

Pull request description:
Fix missing connection data context in dynamodb event processor
Context value from connection.data was not provided for context resolver function in dynamodb event processor. Fix and a test.

Closes #64 

Patch:
diff --git a/packages/aws-lambda-graphql/src/DynamoDBEventProcessor.ts b/packages/aws-lambda-graphql/src/DynamoDBEventProcessor.ts
index 3873bbc..81c689f 100644
--- a/packages/aws-lambda-graphql/src/DynamoDBEventProcessor.ts
+++ b/packages/aws-lambda-graphql/src/DynamoDBEventProcessor.ts
@@ -28,11 +28,8 @@ export class DynamoDBEventProcessor<TServer extends Server = Server>
 
   public createHandler(server: TServer): DynamoDBStreamHandler {
     return async (lambdaEvent, lambdaContext) => {
-      const options = await server.createGraphQLServerOptions(
-        lambdaEvent as any,
-        lambdaContext,
-      );
-      const { connectionManager, subscriptionManager } = options.$$internal;
+      const connectionManager = server.getConnectionManager();
+      const subscriptionManager = server.getSubscriptionManager();
       const { Records } = lambdaEvent;
 
       for (const record of Records) {
@@ -63,6 +60,18 @@ export class DynamoDBEventProcessor<TServer extends Server = Server>
               // create PubSub for this subscriber
               const pubSub = new ArrayPubSub([event]);
 
+              const options = await server.createGraphQLServerOptions(
+                lambdaEvent as any,
+                lambdaContext,
+                {
+                  // this allows createGraphQLServerOptions() to append more extra data
+                  // to context from connection.data.context
+                  connection: subscriber.connection,
+                  operation: subscriber.operation,
+                  pubSub,
+                },
+              );
+
               // execute operation by executing it and then publishing the event
               const iterable = await execute({
                 connectionManager,
diff --git a/packages/aws-lambda-graphql/src/Server.ts b/packages/aws-lambda-graphql/src/Server.ts
index a934628..be2e89a 100644
--- a/packages/aws-lambda-graphql/src/Server.ts
+++ b/packages/aws-lambda-graphql/src/Server.ts
@@ -146,6 +146,14 @@ export class Server<
     this.subscriptionOptions = subscriptions;
   }
 
+  public getConnectionManager(): IConnectionManager {
+    return this.connectionManager;
+  }
+
+  public getSubscriptionManager(): ISubscriptionManager {
+    return this.subscriptionManager;
+  }
+
   public createGraphQLServerOptions(
     event: APIGatewayProxyEvent,
     context: LambdaContext,


Test patch:
diff --git a/packages/aws-lambda-graphql/src/__tests__/DynamoDBEventProcessor.test.ts b/packages/aws-lambda-graphql/src/__tests__/DynamoDBEventProcessor.test.ts
index 7fcc122..313a87b 100644
--- a/packages/aws-lambda-graphql/src/__tests__/DynamoDBEventProcessor.test.ts
+++ b/packages/aws-lambda-graphql/src/__tests__/DynamoDBEventProcessor.test.ts
@@ -142,4 +142,61 @@ describe('DynamoDBEventProcessor', () => {
       }),
     );
   });
+  it('receives context from connection data', async () => {
+    const generateContext = jest.fn();
+    generateContext.mockReturnValue({
+      pubSub: new PubSub({ eventStore: {} as any }),
+    });
+    const connectionManager = {
+      sendToConnection: jest.fn(),
+    };
+    const subscriptionManager = {
+      subscribersByEventName: jest.fn(() => ({
+        [$$asyncIterator]: () =>
+          createAsyncIterator([
+            [
+              {
+                connection: {
+                  id: '1',
+                  data: { context: { authorId: '1' } },
+                } as any,
+                event: 'test',
+                operationId: '1',
+                operation: { query, variables: {} },
+              },
+            ] as ISubscriber[],
+          ]),
+      })),
+    };
+
+    const server = new Server({
+      context: generateContext,
+      connectionManager: connectionManager as any,
+      eventProcessor: new DynamoDBEventProcessor(),
+      schema: createSchema(),
+      subscriptionManager: subscriptionManager as any,
+    });
+    const eventProcessor = server.createEventHandler();
+
+    const Records: DynamoDBRecord[] = [
+      {
+        dynamodb: {
+          NewImage: DynamoDB.Converter.marshall({
+            event: 'test',
+            payload: JSON.stringify({ authorId: '1', text: 'test 1' }),
+          }) as any,
+        },
+        eventName: 'INSERT',
+      },
+    ];
+
+    // now process events
+    await eventProcessor({ Records }, {} as any, {} as any);
+    expect(generateContext).toHaveBeenCalledWith({
+      authorId: '1',
+      $$internal: expect.any(Object),
+      event: expect.any(Object),
+      lambdaContext: expect.any(Object),
+    });
+  });
 });