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() } 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() })