import {QueryClient, QueryClientProvider} from '@tanstack/react-query' import {render, screen, within} from '@testing-library/react' import userEvent from '@testing-library/user-event' import {MemoryRouter} from 'react-router-dom' import {beforeEach, expect, test, vi} from 'vitest' import {PipePanel} from './PipePanel' import type {CloudResource} from '@/types/resource' const api = vi.hoisted(() => ({ getCloudResource: vi.fn(), startCloudResource: vi.fn(), stopCloudResource: vi.fn(), sendSqsMessage: vi.fn(), })) vi.mock('@/api/cloudProxyClient', () => api) vi.mock('@/lib/accountStore', () => ({useAccountId: () => '000000000000'})) function pipe(status = 'RUNNING', metadata: Record = {}): CloudResource { return { id: 'orders-pipe', name: 'orders-pipe', cloud: 'aws', service: 'pipes', type: 'pipe', region: 'us-east-1', createdAt: null, status, metadata: { desiredState: status, source: 'arn:aws:sqs:us-east-1:000000000000:pipe-src', sourceName: 'pipe-src (SQS queue)', target: 'arn:aws:lambda:us-east-1:000000000000:function:worker', targetName: 'worker (Lambda function)', filterPatterns: ['{"body":{"kind":["order"]}}'], batchSize: 5, inputTemplate: '{"id": <$.messageId>}', roleArn: 'arn:aws:iam::000000000000:role/pipe-role', ...metadata, }, } } function renderPanel(resource: CloudResource) { api.getCloudResource.mockResolvedValue(resource) const client = new QueryClient({defaultOptions: {queries: {retry: false}}}) return render() } beforeEach(() => { vi.clearAllMocks() api.startCloudResource.mockResolvedValue(undefined) api.stopCloudResource.mockResolvedValue(undefined) api.sendSqsMessage.mockResolvedValue({messageId: 'm-1'}) }) test('shows the flow from source through the filter to the target, linked to each service', async () => { renderPanel(pipe()) const flow = await screen.findByRole('list', {name: 'Event flow'}) expect(within(flow).getByRole('link', {name: 'pipe-src (SQS queue)'})).toHaveAttribute('href', '/cloud-explorer/aws/messaging') expect(within(flow).getByRole('link', {name: 'worker (Lambda function)'})).toHaveAttribute('href', '/cloud-explorer/aws/serverless') expect(within(flow).getByText('{"body":{"kind":["order"]}}')).toBeInTheDocument() expect(within(flow).getByText('batches of 5')).toBeInTheDocument() expect(within(flow).getByText('{"id": <$.messageId>}')).toBeInTheDocument() }) test('stops a running pipe', async () => { const user = userEvent.setup() renderPanel(pipe()) await user.click(await screen.findByRole('button', {name: 'Stop'})) expect(api.stopCloudResource).toHaveBeenCalledWith('aws', 'pipes', 'orders-pipe') expect(await screen.findByText(/Pipe stopped/)).toBeInTheDocument() }) test('sends a test message to an SQS source queue', async () => { const user = userEvent.setup() renderPanel(pipe()) const form = await screen.findByRole('form', {name: 'Send test message'}) await user.click(within(form).getByRole('button', {name: 'Send to pipe-src'})) expect(api.sendSqsMessage).toHaveBeenCalledWith('aws', 'pipe-src', {messageBody: '{"kind": "order", "id": 1}'}) expect(await screen.findByText(/Sent message m-1/)).toBeInTheDocument() }) test('offers no test message for a stream source, and cannot toggle a pipe mid-change', async () => { renderPanel(pipe('STARTING', {source: 'arn:aws:kinesis:us-east-1:000000000000:stream/clicks', sourceName: 'clicks (Kinesis stream)', desiredState: 'RUNNING'})) expect(await screen.findByRole('link', {name: 'clicks (Kinesis stream)'})).toBeInTheDocument() expect(screen.queryByRole('form', {name: 'Send test message'})).not.toBeInTheDocument() expect(screen.getByRole('button', {name: 'Start'})).toBeDisabled() })