82 lines
5.1 KiB
TypeScript
82 lines
5.1 KiB
TypeScript
import {QueryClient, QueryClientProvider} from '@tanstack/react-query'
|
|
import {render, screen, waitFor} from '@testing-library/react'
|
|
import userEvent from '@testing-library/user-event'
|
|
import {expect, test, vi} from 'vitest'
|
|
import {EventBridgeRulePanel} from './EventBridgeRulePanel'
|
|
import type {CloudResource} from '@/types/resource'
|
|
|
|
const apiMocks = vi.hoisted(() => ({
|
|
createEventBridgeRule: vi.fn(),
|
|
deleteEventBridgeRule: vi.fn(),
|
|
listCloudResources: vi.fn(),
|
|
listEventBridgeRules: vi.fn(),
|
|
}))
|
|
|
|
vi.mock('@/api/cloudProxyClient', () => apiMocks)
|
|
|
|
const eventBus: CloudResource = {id: 'event-bus:orders', name: 'orders', cloud: 'aws', service: 'events', type: 'event-bus', region: null, createdAt: null, metadata: {}}
|
|
const lambda: CloudResource = {id: 'worker', name: 'worker', cloud: 'aws', service: 'serverless', type: 'lambda', region: null, createdAt: null, metadata: {arn: 'arn:aws:lambda:us-east-1:000000000000:function:worker'}}
|
|
const topic: CloudResource = {id: 'orders-topic', name: 'orders-topic', cloud: 'aws', service: 'notifications', type: 'topic', region: null, createdAt: null, metadata: {arn: 'arn:aws:sns:us-east-1:000000000000:orders-topic'}}
|
|
|
|
function renderPanel() {
|
|
const queryClient = new QueryClient({defaultOptions: {queries: {retry: false}}})
|
|
render(<QueryClientProvider client={queryClient}><EventBridgeRulePanel cloud="aws" resource={eventBus} runtimeReachable/></QueryClientProvider>)
|
|
}
|
|
|
|
test('creates a scheduled EventBridge rule with the selected resource ARN', async () => {
|
|
apiMocks.listCloudResources.mockImplementation((_: string, service: string) => Promise.resolve(service === 'serverless' ? [lambda] : []))
|
|
apiMocks.listEventBridgeRules.mockResolvedValue([])
|
|
apiMocks.createEventBridgeRule.mockResolvedValue({name: 'hourly-report'})
|
|
const user = userEvent.setup()
|
|
renderPanel()
|
|
|
|
await screen.findByRole('option', {name: 'worker'})
|
|
await user.type(screen.getByLabelText(/rule name/i), 'hourly-report')
|
|
await user.selectOptions(screen.getByLabelText(/target resource/i), String(lambda.metadata.arn))
|
|
expect(screen.getByText(/No Lambda, SQS queue, SNS topic, or Step Functions resources will be created/i)).toBeVisible()
|
|
await user.click(screen.getByRole('button', {name: 'Create rule'}))
|
|
|
|
await waitFor(() => expect(apiMocks.createEventBridgeRule).toHaveBeenCalledWith('aws', 'event-bus:orders', {
|
|
name: 'hourly-report', scheduleExpression: 'rate(5 minutes)', state: 'ENABLED', targets: [{id: 'worker', arn: lambda.metadata.arn}],
|
|
}))
|
|
})
|
|
|
|
test('creates an EventBridge rule with a selected SNS topic target', async () => {
|
|
apiMocks.listCloudResources.mockImplementation((_: string, service: string) => Promise.resolve(service === 'notifications' ? [topic] : []))
|
|
apiMocks.listEventBridgeRules.mockResolvedValue([])
|
|
apiMocks.createEventBridgeRule.mockResolvedValue({name: 'topic-notifications'})
|
|
const user = userEvent.setup()
|
|
renderPanel()
|
|
|
|
await screen.findByRole('option', {name: 'orders-topic'})
|
|
await user.selectOptions(screen.getByLabelText(/target service/i), 'sns')
|
|
await user.type(screen.getByLabelText(/rule name/i), 'topic-notifications')
|
|
await user.selectOptions(screen.getByLabelText(/target resource/i), String(topic.metadata.arn))
|
|
await user.click(screen.getByRole('button', {name: 'Create rule'}))
|
|
|
|
await waitFor(() => expect(apiMocks.createEventBridgeRule).toHaveBeenCalledWith('aws', eventBus.id, {
|
|
name: 'topic-notifications', scheduleExpression: 'rate(5 minutes)', state: 'ENABLED', targets: [{id: 'orders-topic', arn: topic.metadata.arn}],
|
|
}))
|
|
})
|
|
|
|
test('creates an event-pattern rule and confirms before deletion', async () => {
|
|
apiMocks.listCloudResources.mockImplementation((_: string, service: string) => Promise.resolve(service === 'serverless' ? [lambda] : []))
|
|
apiMocks.listEventBridgeRules.mockResolvedValue([{name: 'billing-events', busName: 'orders', busId: eventBus.id, arn: null, eventPattern: '{"source":["billing"]}', state: 'DISABLED', targets: [{id: 'worker', arn: String(lambda.metadata.arn)}]}])
|
|
apiMocks.createEventBridgeRule.mockResolvedValue({name: 'billing-events'})
|
|
apiMocks.deleteEventBridgeRule.mockResolvedValue(undefined)
|
|
const user = userEvent.setup()
|
|
renderPanel()
|
|
|
|
await user.click(screen.getByLabelText(/mode/i))
|
|
await user.selectOptions(screen.getByLabelText(/mode/i), 'event-pattern')
|
|
await user.type(screen.getByLabelText(/rule name/i), 'billing-events')
|
|
await user.selectOptions(screen.getByLabelText(/target resource/i), String(lambda.metadata.arn))
|
|
await user.click(screen.getByRole('button', {name: 'Create rule'}))
|
|
await waitFor(() => expect(apiMocks.createEventBridgeRule).toHaveBeenCalledWith('aws', eventBus.id, expect.objectContaining({eventPattern: '{\n "source": ["orders"]\n}'})))
|
|
|
|
await user.click(await screen.findByRole('button', {name: 'Delete rule billing-events'}))
|
|
expect(screen.getByText('Delete rule?')).toBeVisible()
|
|
await user.click(screen.getByRole('button', {name: 'Delete'}))
|
|
await waitFor(() => expect(apiMocks.deleteEventBridgeRule).toHaveBeenCalledWith('aws', eventBus.id, 'billing-events'))
|
|
})
|