All files / src/components/admin/monitoring ErrorDetailsTab.test.tsx

0% Statements 0/130
100% Branches 0/0
0% Functions 0/1
0% Lines 0/130

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131                                                                                                                                                                                                                                                                     
import React from 'react';
import { render, screen, fireEvent } from '@testing-library/react';
import { ErrorDetailsTab } from './ErrorDetailsTab';

const mockError = {
  id: 1,
  fingerprint: 'abc123',
  category: 'API',
  message: 'Test error message',
  count: 10,
  lastSeen: new Date().toISOString(),
  firstSeen: new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString(),
  status: 'open',
  resolvedAt: null,
  resolvedBy: null,
  assignedTo: null,
  assignedAt: null,
  priority: 'MEDIUM' as const,
  snoozedUntil: null,
  ignoredReason: null,
};

const mockRecentLogs = [
  {
    id: 1,
    level: 'error',
    message: 'Test error message',
    stack: 'Error: Test\n  at line 1',
    url: '/api/test',
    metadata: { key: 'value' },
    createdAt: new Date().toISOString(),
  },
];

describe('ErrorDetailsTab', () => {
  const mockOnUpdate = jest.fn();

  beforeEach(() => {
    mockOnUpdate.mockClear();
  });

  it('renders details tab', () => {
    render(<ErrorDetailsTab error={mockError} recentLogs={mockRecentLogs} onUpdate={mockOnUpdate} />);
    expect(screen.getByTestId('error-details-tab')).toBeInTheDocument();
  });

  it('displays error info', () => {
    render(<ErrorDetailsTab error={mockError} recentLogs={mockRecentLogs} onUpdate={mockOnUpdate} />);
    expect(screen.getByText('Test error message')).toBeInTheDocument();
    expect(screen.getByText('API')).toBeInTheDocument();
    expect(screen.getByText('10')).toBeInTheDocument();
  });

  it('shows priority selector', () => {
    render(<ErrorDetailsTab error={mockError} recentLogs={mockRecentLogs} onUpdate={mockOnUpdate} />);
    expect(screen.getByText('Priority')).toBeInTheDocument();
  });

  it('calls onUpdate when priority changes', () => {
    render(<ErrorDetailsTab error={mockError} recentLogs={mockRecentLogs} onUpdate={mockOnUpdate} />);
    const prioritySelector = screen.getByTestId('priority-selector');
    fireEvent.change(prioritySelector, { target: { value: 'HIGH' } });
    expect(mockOnUpdate).toHaveBeenCalledWith({ priority: 'HIGH' });
  });

  it('shows team member selector when teamMembers provided', () => {
    const teamMembers = [
      { id: 1, email: 'alice@example.com', name: 'Alice' },
      { id: 2, email: 'bob@example.com', name: 'Bob' },
    ];
    render(
      <ErrorDetailsTab
        error={mockError}
        recentLogs={mockRecentLogs}
        onUpdate={mockOnUpdate}
        teamMembers={teamMembers}
      />
    );
    expect(screen.getByText('Assigned To')).toBeInTheDocument();
    expect(screen.getByText('Alice')).toBeInTheDocument();
  });

  it('displays recent occurrences', () => {
    render(<ErrorDetailsTab error={mockError} recentLogs={mockRecentLogs} onUpdate={mockOnUpdate} />);
    expect(screen.getByText('Recent Occurrences (1)')).toBeInTheDocument();
  });

  it('shows no occurrences message when empty', () => {
    render(<ErrorDetailsTab error={mockError} recentLogs={[]} onUpdate={mockOnUpdate} />);
    expect(screen.getByText('No recent occurrences')).toBeInTheDocument();
  });

  it('shows snooze info when error is snoozed', () => {
    const snoozedError = {
      ...mockError,
      status: 'snoozed',
      snoozedUntil: new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString(),
    };
    render(<ErrorDetailsTab error={snoozedError} recentLogs={mockRecentLogs} onUpdate={mockOnUpdate} />);
    expect(screen.getByText(/Snoozed until/)).toBeInTheDocument();
  });

  it('shows ignored reason when error is ignored', () => {
    const ignoredError = {
      ...mockError,
      status: 'ignored',
      ignoredReason: 'Known issue',
    };
    render(<ErrorDetailsTab error={ignoredError} recentLogs={mockRecentLogs} onUpdate={mockOnUpdate} />);
    expect(screen.getByText('Ignored Reason:')).toBeInTheDocument();
    expect(screen.getByText('Known issue')).toBeInTheDocument();
  });

  it('disables controls when isUpdating is true', () => {
    render(
      <ErrorDetailsTab
        error={mockError}
        recentLogs={mockRecentLogs}
        onUpdate={mockOnUpdate}
        isUpdating
      />
    );
    expect(screen.getByTestId('priority-selector')).toBeDisabled();
  });

  it('shows stack trace in recent logs', () => {
    render(<ErrorDetailsTab error={mockError} recentLogs={mockRecentLogs} onUpdate={mockOnUpdate} />);
    expect(screen.getByText('Stack trace')).toBeInTheDocument();
  });
});