second first commit
This commit is contained in:
@@ -0,0 +1,162 @@
|
||||
/**
|
||||
* S3 Notifications integration tests.
|
||||
*/
|
||||
|
||||
import { describe, it, expect, beforeAll, afterAll } from 'vitest';
|
||||
import {
|
||||
S3Client,
|
||||
CreateBucketCommand,
|
||||
PutObjectCommand,
|
||||
DeleteObjectCommand,
|
||||
DeleteBucketCommand,
|
||||
PutBucketNotificationConfigurationCommand,
|
||||
GetBucketNotificationConfigurationCommand,
|
||||
} from '@aws-sdk/client-s3';
|
||||
import {
|
||||
SQSClient,
|
||||
CreateQueueCommand,
|
||||
GetQueueAttributesCommand,
|
||||
DeleteQueueCommand,
|
||||
} from '@aws-sdk/client-sqs';
|
||||
import { SNSClient, CreateTopicCommand, DeleteTopicCommand } from '@aws-sdk/client-sns';
|
||||
import { makeClient, uniqueName } from './setup';
|
||||
|
||||
describe('S3 Notifications', () => {
|
||||
let s3: S3Client;
|
||||
let sqs: SQSClient;
|
||||
let sns: SNSClient;
|
||||
let bucketName: string;
|
||||
let queueUrl: string;
|
||||
let queueArn: string;
|
||||
let topicArn: string;
|
||||
|
||||
beforeAll(async () => {
|
||||
s3 = makeClient(S3Client, { forcePathStyle: true });
|
||||
sqs = makeClient(SQSClient);
|
||||
sns = makeClient(SNSClient);
|
||||
|
||||
bucketName = `notif-test-bucket-${uniqueName()}`;
|
||||
|
||||
// Create SQS queue
|
||||
const queueResult = await sqs.send(
|
||||
new CreateQueueCommand({ QueueName: `notif-queue-${uniqueName()}` })
|
||||
);
|
||||
queueUrl = queueResult.QueueUrl!;
|
||||
const attrs = await sqs.send(
|
||||
new GetQueueAttributesCommand({ QueueUrl: queueUrl, AttributeNames: ['QueueArn'] })
|
||||
);
|
||||
queueArn = attrs.Attributes!.QueueArn!;
|
||||
|
||||
// Create SNS topic
|
||||
const topicResult = await sns.send(
|
||||
new CreateTopicCommand({ Name: `notif-topic-${uniqueName()}` })
|
||||
);
|
||||
topicArn = topicResult.TopicArn!;
|
||||
|
||||
// Create S3 bucket
|
||||
await s3.send(new CreateBucketCommand({ Bucket: bucketName }));
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
try {
|
||||
await s3.send(new DeleteObjectCommand({ Bucket: bucketName, Key: 'test-object.txt' }));
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
try {
|
||||
await s3.send(new DeleteBucketCommand({ Bucket: bucketName }));
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
try {
|
||||
await sqs.send(new DeleteQueueCommand({ QueueUrl: queueUrl }));
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
try {
|
||||
await sns.send(new DeleteTopicCommand({ TopicArn: topicArn }));
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
});
|
||||
|
||||
it('should put bucket notification configuration', async () => {
|
||||
await s3.send(
|
||||
new PutBucketNotificationConfigurationCommand({
|
||||
Bucket: bucketName,
|
||||
NotificationConfiguration: {
|
||||
QueueConfigurations: [
|
||||
{
|
||||
Id: 'sqs-filtered',
|
||||
QueueArn: queueArn,
|
||||
Events: ['s3:ObjectCreated:*'],
|
||||
Filter: {
|
||||
Key: {
|
||||
FilterRules: [
|
||||
{ Name: 'prefix', Value: 'incoming/' },
|
||||
{ Name: 'suffix', Value: '.csv' },
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
TopicConfigurations: [
|
||||
{
|
||||
Id: 'sns-filtered',
|
||||
TopicArn: topicArn,
|
||||
Events: ['s3:ObjectRemoved:*'],
|
||||
Filter: {
|
||||
Key: {
|
||||
FilterRules: [
|
||||
{ Name: 'prefix', Value: '' },
|
||||
{ Name: 'suffix', Value: '.txt' },
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
it('should get bucket notification configuration', async () => {
|
||||
const response = await s3.send(
|
||||
new GetBucketNotificationConfigurationCommand({ Bucket: bucketName })
|
||||
);
|
||||
|
||||
// Verify SQS configuration
|
||||
const sqsConfig = response.QueueConfigurations?.find((c) => c.Id === 'sqs-filtered');
|
||||
expect(sqsConfig).toBeTruthy();
|
||||
expect(sqsConfig?.QueueArn).toBe(queueArn);
|
||||
expect(sqsConfig?.Events).toContain('s3:ObjectCreated:*');
|
||||
|
||||
const sqsRules = sqsConfig?.Filter?.Key?.FilterRules || [];
|
||||
expect(sqsRules.some((r) => r.Name === 'prefix' && r.Value === 'incoming/')).toBe(true);
|
||||
expect(sqsRules.some((r) => r.Name === 'suffix' && r.Value === '.csv')).toBe(true);
|
||||
|
||||
// Verify SNS configuration
|
||||
const snsConfig = response.TopicConfigurations?.find((c) => c.Id === 'sns-filtered');
|
||||
expect(snsConfig).toBeTruthy();
|
||||
expect(snsConfig?.TopicArn).toBe(topicArn);
|
||||
expect(snsConfig?.Events).toContain('s3:ObjectRemoved:*');
|
||||
|
||||
const snsRules = snsConfig?.Filter?.Key?.FilterRules || [];
|
||||
expect(snsRules.some((r) => r.Name === 'suffix' && r.Value === '.txt')).toBe(true);
|
||||
});
|
||||
|
||||
it('should clear notification configuration', async () => {
|
||||
await s3.send(
|
||||
new PutBucketNotificationConfigurationCommand({
|
||||
Bucket: bucketName,
|
||||
NotificationConfiguration: {},
|
||||
})
|
||||
);
|
||||
|
||||
const response = await s3.send(
|
||||
new GetBucketNotificationConfigurationCommand({ Bucket: bucketName })
|
||||
);
|
||||
expect(response.QueueConfigurations?.length || 0).toBe(0);
|
||||
expect(response.TopicConfigurations?.length || 0).toBe(0);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user