Files
floci-ui/packages/frontend/src/components/CloudWatchAlarmPanel.test.tsx
T
2026-10-24 22:48:41 -04:00

75 lines
3.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import {QueryClient, QueryClientProvider} from '@tanstack/react-query'
import {render, screen, within} from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import {beforeEach, expect, test, vi} from 'vitest'
import {CloudWatchAlarmPanel} from './CloudWatchAlarmPanel'
import {HttpError} from '@/api/HttpClient'
import type {CloudResource} from '@/types/resource'
const api = vi.hoisted(() => ({
getCloudResource: vi.fn(),
describeAlarmHistory: vi.fn(),
getMetricSeries: vi.fn(),
setAlarmState: vi.fn(),
setAlarmActionsEnabled: vi.fn(),
}))
vi.mock('@/api/cloudProxyClient', () => api)
vi.mock('@/lib/accountStore', () => ({useAccountId: () => '000000000000'}))
const alarm: CloudResource = {
id: 'high-errors', name: 'high-errors', cloud: 'aws', service: 'monitoring', type: 'alarm', region: 'us-east-1', createdAt: null, status: 'ALARM',
metadata: {
alarmType: 'metric', stateReason: 'Threshold crossed', actionsEnabled: true, alarmActions: ['arn:aws:sns:us-east-1:000000000000:alerts'], okActions: [],
namespace: 'App', metricName: 'Errors', dimensions: [], statistic: 'Sum', threshold: 5, condition: 'Errors Sum > 5 for 1 × 5 min',
},
}
function renderPanel() {
const client = new QueryClient({defaultOptions: {queries: {retry: false}}})
return render(<QueryClientProvider client={client}><CloudWatchAlarmPanel resource={alarm} runtimeReachable/></QueryClientProvider>)
}
beforeEach(() => {
vi.clearAllMocks()
api.getCloudResource.mockResolvedValue(alarm)
api.describeAlarmHistory.mockResolvedValue([{timestamp: null, type: 'StateUpdate', summary: 'Alarm updated from OK to ALARM'}])
api.getMetricSeries.mockResolvedValue({label: 'Errors', statistic: 'Sum', periodSeconds: 60, points: [{timestamp: '2026-10-25T10:00:00Z', value: 7}]})
api.setAlarmState.mockResolvedValue(undefined)
api.setAlarmActionsEnabled.mockResolvedValue(undefined)
})
test('shows the state, its metric with the threshold, the targets and the history', async () => {
renderPanel()
expect(screen.getByText('Threshold crossed')).toBeInTheDocument()
expect(await screen.findByText('Threshold 5')).toBeInTheDocument()
expect(screen.getByText('arn:aws:sns:us-east-1:000000000000:alerts')).toBeInTheDocument()
expect(await screen.findByText('Alarm updated from OK to ALARM')).toBeInTheDocument()
expect(api.getMetricSeries).toHaveBeenCalledWith('aws', expect.objectContaining({namespace: 'App', metricName: 'Errors', statistic: 'Sum', rangeMinutes: 180}), expect.anything())
})
test('sets a state to test the actions, and turns the actions off', async () => {
const user = userEvent.setup()
renderPanel()
const form = await screen.findByRole('form', {name: 'Set alarm state'})
await user.selectOptions(within(form).getByLabelText('State'), 'OK')
await user.type(within(form).getByLabelText('Reason'), 'Testing')
await user.click(within(form).getByRole('button', {name: 'Set state'}))
expect(api.setAlarmState).toHaveBeenCalledWith('aws', 'high-errors', 'OK', 'Testing')
expect(await screen.findByText(/Set to OK/)).toBeInTheDocument()
await user.click(within(form).getByRole('button', {name: 'Turn actions off'}))
expect(api.setAlarmActionsEnabled).toHaveBeenCalledWith('aws', 'high-errors', false)
})
test('says when the runtime does not record alarm history, without an error', async () => {
api.describeAlarmHistory.mockRejectedValue(new HttpError(501, 'Not Implemented', {code: 'operation_not_implemented', error: 'Operation is not implemented by the selected runtime'}, '/history'))
renderPanel()
expect(await screen.findByText(/does not record alarm history yet/)).toBeInTheDocument()
expect(screen.queryByRole('alert')).not.toBeInTheDocument()
})