import { render, screen, waitFor } from '@testing-library/react';
import React from 'react';
import { useParams } from 'react-router-dom';

import { AppContext } from '../../../__mocks__/app-context-mock';
import Page from '../order-view';
import { server } from '../../../__mocks__/server/server';

jest.mock('react-router-dom', () => ({
  ...jest.requireActual('react-router-dom'),
  useParams: jest.fn(),
}));

describe('Order View page, initial load', () => {
  beforeAll(() => server.listen());
  afterEach(() => server.resetHandlers());
  afterAll(() => server.close());

  test('shows order details loading', () => {
    (useParams as jest.Mock).mockReturnValue({ orderId: 'id1' });

    const { container } = render(
      <AppContext>
        <Page />
      </AppContext>,
    );

    expect(screen.getByTestId('heading')).toBeInTheDocument();
    expect(screen.getByTestId('loader')).toBeInTheDocument();
    expect(screen.queryByTestId('order-details')).not.toBeInTheDocument();
    expect(screen.queryByTestId('error')).not.toBeInTheDocument();

    expect(container).toMatchSnapshot();
  });

  test('shows order details', async () => {
    (useParams as jest.Mock).mockReturnValue({ orderId: 'id1' });

    const { container } = render(
      <AppContext>
        <Page />
      </AppContext>,
    );

    await waitFor(() => {
      expect(screen.getByTestId('heading')).toBeInTheDocument();
      expect(screen.queryByTestId('loader')).not.toBeInTheDocument();
      expect(screen.getByTestId('order-details')).toBeInTheDocument();
      expect(screen.queryByTestId('error')).not.toBeInTheDocument();
    });

    expect(container).toMatchSnapshot();
  });

  test('shows order error', async () => {
    (useParams as jest.Mock).mockReturnValue({ orderId: null });

    const { container } = render(
      <AppContext>
        <Page />
      </AppContext>,
    );

    await waitFor(() => {
      expect(screen.getByTestId('heading')).toBeInTheDocument();
      expect(screen.queryByTestId('loader')).not.toBeInTheDocument();
      expect(screen.queryByTestId('order-details')).not.toBeInTheDocument();
      expect(screen.getByTestId('error')).toBeInTheDocument();
    });

    expect(container).toMatchSnapshot();
  });
});

afterEach(() => {
  jest.clearAllMocks();
});
