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

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

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                                                                                                                                                                                                                                                               
import React from 'react';
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import { ErrorCommentsTab, type ErrorCommentData } from './ErrorCommentsTab';

const mockComments: ErrorCommentData[] = [
  {
    id: '1',
    userId: 1,
    userEmail: 'alice@example.com',
    content: 'First comment',
    createdAt: new Date().toISOString(),
    updatedAt: new Date().toISOString(),
  },
  {
    id: '2',
    userId: 2,
    userEmail: 'bob@example.com',
    content: 'Second comment',
    createdAt: new Date().toISOString(),
    updatedAt: new Date().toISOString(),
  },
];

describe('ErrorCommentsTab', () => {
  const mockOnAddComment = jest.fn();

  beforeEach(() => {
    mockOnAddComment.mockClear();
    mockOnAddComment.mockResolvedValue(undefined);
  });

  it('renders comments tab', () => {
    render(<ErrorCommentsTab comments={mockComments} onAddComment={mockOnAddComment} />);
    expect(screen.getByTestId('error-comments-tab')).toBeInTheDocument();
  });

  it('displays comments', () => {
    render(<ErrorCommentsTab comments={mockComments} onAddComment={mockOnAddComment} />);
    expect(screen.getByText('First comment')).toBeInTheDocument();
    expect(screen.getByText('Second comment')).toBeInTheDocument();
  });

  it('displays comment authors', () => {
    render(<ErrorCommentsTab comments={mockComments} onAddComment={mockOnAddComment} />);
    expect(screen.getByText('alice@example.com')).toBeInTheDocument();
    expect(screen.getByText('bob@example.com')).toBeInTheDocument();
  });

  it('shows empty state when no comments', () => {
    render(<ErrorCommentsTab comments={[]} onAddComment={mockOnAddComment} />);
    expect(screen.getByText(/No comments yet/)).toBeInTheDocument();
  });

  it('renders comment input', () => {
    render(<ErrorCommentsTab comments={mockComments} onAddComment={mockOnAddComment} />);
    expect(screen.getByTestId('comment-input')).toBeInTheDocument();
    expect(screen.getByTestId('add-comment-button')).toBeInTheDocument();
  });

  it('disables submit button when input is empty', () => {
    render(<ErrorCommentsTab comments={mockComments} onAddComment={mockOnAddComment} />);
    expect(screen.getByTestId('add-comment-button')).toBeDisabled();
  });

  it('enables submit button when input has content', () => {
    render(<ErrorCommentsTab comments={mockComments} onAddComment={mockOnAddComment} />);
    fireEvent.change(screen.getByTestId('comment-input'), { target: { value: 'New comment' } });
    expect(screen.getByTestId('add-comment-button')).not.toBeDisabled();
  });

  it('calls onAddComment when form is submitted', async () => {
    render(<ErrorCommentsTab comments={mockComments} onAddComment={mockOnAddComment} />);

    fireEvent.change(screen.getByTestId('comment-input'), { target: { value: 'New comment' } });
    fireEvent.click(screen.getByTestId('add-comment-button'));

    await waitFor(() => {
      expect(mockOnAddComment).toHaveBeenCalledWith('New comment');
    });
  });

  it('clears input after successful submit', async () => {
    render(<ErrorCommentsTab comments={mockComments} onAddComment={mockOnAddComment} />);

    const input = screen.getByTestId('comment-input') as HTMLTextAreaElement;
    fireEvent.change(input, { target: { value: 'New comment' } });
    fireEvent.click(screen.getByTestId('add-comment-button'));

    // Wait for async callback to complete and input to clear
    await waitFor(() => {
      expect(mockOnAddComment).toHaveBeenCalledWith('New comment');
    });

    await waitFor(() => {
      expect(input.value).toBe('');
    }, { timeout: 3000 });
  });

  it('shows loading state when isAdding is true', () => {
    render(<ErrorCommentsTab comments={mockComments} onAddComment={mockOnAddComment} isAdding />);
    expect(screen.getByText('Adding...')).toBeInTheDocument();
  });

  it('shows load more button when hasMore is true', () => {
    const mockLoadMore = jest.fn();
    render(
      <ErrorCommentsTab
        comments={mockComments}
        onAddComment={mockOnAddComment}
        hasMore
        onLoadMore={mockLoadMore}
      />
    );
    expect(screen.getByText('Load more comments')).toBeInTheDocument();
  });

  it('shows total count when provided', () => {
    render(
      <ErrorCommentsTab
        comments={mockComments}
        onAddComment={mockOnAddComment}
        total={10}
      />
    );
    expect(screen.getByText(/Showing 2 of 10 comments/)).toBeInTheDocument();
  });
});