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