Edward Asquith
05/26/2022, 2:06 PMthdxr
05/26/2022, 2:09 PMAkos
05/26/2022, 2:16 PMEdward Asquith
05/26/2022, 2:17 PMEdward Asquith
05/26/2022, 2:32 PMJay
Edward Asquith
05/26/2022, 2:42 PMAdrián Mouly
05/26/2022, 2:43 PMAdrián Mouly
05/26/2022, 2:44 PMEdward Asquith
05/26/2022, 2:52 PMAkos
05/26/2022, 2:54 PMAkos
05/26/2022, 2:54 PMEdward Asquith
05/26/2022, 2:56 PMAkos
05/26/2022, 3:05 PMEdward Asquith
05/26/2022, 3:07 PMAkos
05/26/2022, 3:07 PMAkos
05/26/2022, 3:08 PMthdxr
05/26/2022, 3:36 PMthdxr
05/26/2022, 3:36 PMAdrián Mouly
05/26/2022, 3:39 PMthdxr
05/26/2022, 3:39 PMAdrián Mouly
05/26/2022, 3:39 PMthdxr
05/26/2022, 3:39 PMAdrián Mouly
05/26/2022, 3:39 PMAdrián Mouly
05/26/2022, 3:39 PMthdxr
05/26/2022, 3:39 PMAdrián Mouly
05/26/2022, 3:39 PMthdxr
05/26/2022, 3:40 PMAdrián Mouly
05/26/2022, 3:40 PMRobert Banaszak
05/26/2022, 8:13 PMAkos
05/27/2022, 12:07 PMif (env.iTestCapabilityEnabled) {
  const table = new sst.Table(scope, 'IntegrationTestEvents', {
    fields: {
      workspaceId: sst.TableFieldType.STRING,
      eventId: sst.TableFieldType.STRING,
    },
    primaryIndex: { partitionKey: 'workspaceId', sortKey: 'eventId' },
    dynamodbTable: {
      timeToLiveAttribute: 'expiresAt',
      removalPolicy: RemovalPolicy.DESTROY,
    },
  });
  const itestWriterLambda = new sst.Function(scope, 'IntegrationTestEventWriter', {
    handler: 'test-utils/eventing/integrationTestEventWriter.handler',
    environment: {
      DYNAMODB_TABLE_NAME: table.dynamodbTable.tableName,
      EXPIRY_TIME_MINUTES: '60', // 1 hour
    },
  });
  table.dynamodbTable.grantWriteData(itestWriterLambda);
  buses.forEach((bus) => {
    const catchAllRule = new events.Rule(scope, `CatchAll${bus.id}Rule`, {
      eventBus: bus.eventBus,
      eventPattern: {
        account: [cdk.Fn.sub('${AWS::AccountId}')],
      },
      targets: [new targets.LambdaFunction(itestWriterLambda)],
    });
  });
}
And the lambda function to handle it:
/* eslint-disable no-console */
import { DynamoDBDocument } from '@aws-sdk/lib-dynamodb';
import { assert } from 'assert-ts';
import { EventBridgeHandler } from 'aws-lambda';
import isSafeInteger from 'lodash/isSafeInteger';
import toInteger from 'lodash/toInteger';
import { DateTime } from 'luxon';
import { createDynamoDbClient } from 'packages/aws-clients';
import { DomainEvent } from 'packages/events';
const dynamoClient = DynamoDBDocument.from(createDynamoDbClient());
const tableName = process.env.DYNAMODB_TABLE_NAME;
const expiryTimeMinutes = process.env.EXPIRY_TIME_MINUTES;
assert(tableName, 'DYNAMODB_TABLE_NAME envvar not defined');
assert(expiryTimeMinutes, 'EXPIRY_TIME_MINUTES envvar not defined');
assert(
  Number(expiryTimeMinutes) > 0 && isSafeInteger(Number(expiryTimeMinutes)),
  'EXPIRY_TIME_MINUTES must be an integer and greater than 0'
);
// Note: this handler just casts the incoming event as a DomainEvent, will blow up if it's
// not in the right format.
export const handler: EventBridgeHandler<string, DomainEvent, void> = async (event, _context) => {
  console.log(`Handling event with AWS id: ${event.id}`);
  const workspaceId = event.detail.workspaceId;
  const eventId = event.detail.eventId;
  console.log(`Inserting event with workspaceId: ${workspaceId} and sk: ${eventId}`);
  const expiresAt = toInteger(
    DateTime.utc()
      .plus({ minutes: Number(expiryTimeMinutes) })
      .toSeconds()
  );
  await dynamoClient.put({
    TableName: tableName,
    Item: {
      ...event,
      workspaceId,
      // set sk as eventId so when we fetch them they are in the order inserted
      sk: eventId,
      expiresAt,
    },
  });
  console.log(`Successfully saved event: ${eventId}`);
};
As you can see, it's a bit specific to our events and our setup. That's the thing with integration testing, it's so unique to your application it's hard to write generic code.Robert Banaszak
05/27/2022, 12:47 PM