feat: EC2 UI polished + storage persisting
This commit is contained in:
@@ -0,0 +1,138 @@
|
||||
import {describe, expect, test} from 'bun:test'
|
||||
import {
|
||||
CreateTopicCommand,
|
||||
DeleteTopicCommand,
|
||||
GetSubscriptionAttributesCommand,
|
||||
GetTopicAttributesCommand,
|
||||
ListSubscriptionsByTopicCommand,
|
||||
ListTopicsCommand,
|
||||
PublishCommand,
|
||||
SubscribeCommand,
|
||||
type SNSClient,
|
||||
UnsubscribeCommand,
|
||||
} from '@aws-sdk/client-sns'
|
||||
import {AwsSnsAdapter} from './AwsSnsAdapter'
|
||||
import {ValidationError} from '../cloud-spi/errors'
|
||||
|
||||
const ORDERS_ARN = 'arn:aws:sns:us-east-1:000000000000:orders'
|
||||
const ALERTS_ARN = 'arn:aws:sns:us-east-1:000000000000:alerts'
|
||||
|
||||
function stubSns() {
|
||||
const sent: object[] = []
|
||||
const client = {
|
||||
async send(command: object) {
|
||||
sent.push(command)
|
||||
if (command instanceof ListTopicsCommand) return {Topics: [{TopicArn: ORDERS_ARN}, {TopicArn: ALERTS_ARN}]}
|
||||
if (command instanceof GetTopicAttributesCommand) {
|
||||
return {Attributes: {DisplayName: 'Order notifications', FifoTopic: 'false'}}
|
||||
}
|
||||
if (command instanceof CreateTopicCommand) {
|
||||
return {TopicArn: `arn:aws:sns:us-east-1:000000000000:${command.input.Name}`}
|
||||
}
|
||||
if (command instanceof PublishCommand) return {MessageId: 'e5a98c5b-cd94-4c38-a9ac-7260ec3e575f'}
|
||||
if (command instanceof ListSubscriptionsByTopicCommand) return {Subscriptions: [{
|
||||
SubscriptionArn: 'arn:aws:sns:us-east-1:000000000000:orders:sub-1',
|
||||
Protocol: 'sqs',
|
||||
Endpoint: 'arn:aws:sqs:us-east-1:000000000000:orders',
|
||||
}]}
|
||||
if (command instanceof GetSubscriptionAttributesCommand) return {Attributes: {FilterPolicy: '{"eventType":["created"]}'}}
|
||||
if (command instanceof SubscribeCommand) return {SubscriptionArn: 'arn:aws:sns:us-east-1:000000000000:orders:sub-2'}
|
||||
return {}
|
||||
},
|
||||
} as unknown as SNSClient
|
||||
return {client, sent}
|
||||
}
|
||||
|
||||
describe('AwsSnsAdapter', () => {
|
||||
test('lists SNS topic ARNs as topic resources', async () => {
|
||||
const {client} = stubSns()
|
||||
const [topic] = await new AwsSnsAdapter(client).list()
|
||||
|
||||
expect(topic).toMatchObject({id: ORDERS_ARN, name: 'orders', service: 'notifications', type: 'topic'})
|
||||
expect(topic?.metadata.arn).toBe(ORDERS_ARN)
|
||||
})
|
||||
|
||||
test('gets a topic with its SNS attributes', async () => {
|
||||
const {client, sent} = stubSns()
|
||||
const topic = await new AwsSnsAdapter(client).get(ORDERS_ARN)
|
||||
|
||||
expect(sent[0]).toBeInstanceOf(GetTopicAttributesCommand)
|
||||
expect(topic?.metadata.displayName).toBe('Order notifications')
|
||||
})
|
||||
|
||||
test('creates and reads back an SNS topic', async () => {
|
||||
const {client, sent} = stubSns()
|
||||
const topic = await new AwsSnsAdapter(client).create({values: {name: 'orders'}})
|
||||
|
||||
expect(sent[0]).toBeInstanceOf(CreateTopicCommand)
|
||||
expect((sent[0] as CreateTopicCommand).input.Name).toBe('orders')
|
||||
expect(sent[1]).toBeInstanceOf(GetTopicAttributesCommand)
|
||||
expect(topic.id).toBe(ORDERS_ARN)
|
||||
})
|
||||
|
||||
test('deletes a topic by ARN', async () => {
|
||||
const {client, sent} = stubSns()
|
||||
await new AwsSnsAdapter(client).delete(ORDERS_ARN)
|
||||
|
||||
expect((sent[0] as DeleteTopicCommand).input.TopicArn).toBe(ORDERS_ARN)
|
||||
})
|
||||
|
||||
test('publishes a message with optional subject and string message attributes', async () => {
|
||||
const {client, sent} = stubSns()
|
||||
const result = await new AwsSnsAdapter(client).publish(ORDERS_ARN, {
|
||||
message: 'Order placed',
|
||||
subject: 'Order update',
|
||||
messageAttributes: {orderId: '1234'},
|
||||
})
|
||||
|
||||
expect(result.messageId).toBe('e5a98c5b-cd94-4c38-a9ac-7260ec3e575f')
|
||||
expect((sent[0] as PublishCommand).input).toEqual({
|
||||
TopicArn: ORDERS_ARN,
|
||||
Message: 'Order placed',
|
||||
Subject: 'Order update',
|
||||
MessageAttributes: {orderId: {DataType: 'String', StringValue: '1234'}},
|
||||
})
|
||||
})
|
||||
|
||||
test('manages SNS subscriptions with direct SDK commands and exposes their attributes', async () => {
|
||||
const {client, sent} = stubSns()
|
||||
const adapter = new AwsSnsAdapter(client)
|
||||
|
||||
const created = await adapter.createSnsSubscription(ORDERS_ARN, {
|
||||
protocol: 'sqs',
|
||||
endpoint: 'arn:aws:sqs:us-east-1:000000000000:orders',
|
||||
})
|
||||
const subscriptions = await adapter.listSnsSubscriptions(ORDERS_ARN)
|
||||
await adapter.deleteSnsSubscription('arn:aws:sns:us-east-1:000000000000:orders:sub-1')
|
||||
|
||||
expect((sent[0] as SubscribeCommand).input).toEqual({
|
||||
TopicArn: ORDERS_ARN,
|
||||
Protocol: 'sqs',
|
||||
Endpoint: 'arn:aws:sqs:us-east-1:000000000000:orders',
|
||||
})
|
||||
expect((sent[1] as ListSubscriptionsByTopicCommand).input).toEqual({TopicArn: ORDERS_ARN})
|
||||
expect((sent[2] as GetSubscriptionAttributesCommand).input).toEqual({
|
||||
SubscriptionArn: 'arn:aws:sns:us-east-1:000000000000:orders:sub-1',
|
||||
})
|
||||
expect((sent[3] as UnsubscribeCommand).input).toEqual({
|
||||
SubscriptionArn: 'arn:aws:sns:us-east-1:000000000000:orders:sub-1',
|
||||
})
|
||||
expect(created).toMatchObject({arn: 'arn:aws:sns:us-east-1:000000000000:orders:sub-2', protocol: 'sqs', status: 'Confirmed'})
|
||||
expect(subscriptions).toEqual([{
|
||||
arn: 'arn:aws:sns:us-east-1:000000000000:orders:sub-1',
|
||||
protocol: 'sqs',
|
||||
endpoint: 'arn:aws:sqs:us-east-1:000000000000:orders',
|
||||
status: 'Confirmed',
|
||||
filterPolicy: '{"eventType":["created"]}',
|
||||
}])
|
||||
})
|
||||
|
||||
test('rejects invalid topic names and blank messages before calling SNS', async () => {
|
||||
const {client, sent} = stubSns()
|
||||
const adapter = new AwsSnsAdapter(client)
|
||||
|
||||
await expect(adapter.create({values: {name: 'has space'}})).rejects.toBeInstanceOf(ValidationError)
|
||||
await expect(adapter.publish(ORDERS_ARN, {message: ''})).rejects.toBeInstanceOf(ValidationError)
|
||||
expect(sent).toEqual([])
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user