import type { ReactNode } from 'react'
import { render, screen } from '@testing-library/react'
import { describe, expect, it, vi } from 'vitest'

import App from './App'

const routerProviderMock = vi.fn((props: unknown) => {
  void props
  return <div data-testid="router-provider" />
})
const errorBoundaryMock = vi.fn(({ children }: { children: ReactNode }) => (
  <div data-testid="error-boundary">{children}</div>
))

vi.mock('react-router-dom', async () => {
  const actual = await vi.importActual<typeof import('react-router-dom')>('react-router-dom')
  return {
    ...actual,
    RouterProvider: (props: unknown) => routerProviderMock(props),
  }
})

vi.mock('@/components/common', () => ({
  ErrorBoundary: (props: { children: React.ReactNode }) => errorBoundaryMock(props),
}))

describe('App', () => {
  it('renders the router provider inside the error boundary shell', () => {
    render(<App />)

    expect(screen.getByTestId('error-boundary')).toBeInTheDocument()
    expect(screen.getByTestId('router-provider')).toBeInTheDocument()
    expect(errorBoundaryMock).toHaveBeenCalledTimes(1)
    expect(routerProviderMock).toHaveBeenCalledWith(
      expect.objectContaining({
        router: expect.any(Object),
      }),
    )
  })
})
