ErrorMatcher.test.tsx101 lines · main
1import { render, screen } from '@testing-library/react'
2import { beforeEach, describe, expect, it, vi } from 'vitest'
3
4import { ErrorMatcher } from './ErrorMatcher'
5import { ConnectionTimeoutError } from '@/types/api-errors'
6import { ResponseError } from '@/types/base'
7
8vi.mock('@/lib/telemetry/track', () => ({ useTrack: () => vi.fn() }))
9vi.mock('@/state/ai-assistant-state', () => ({
10 useAiAssistantStateSnapshot: () => ({ newChat: vi.fn() }),
11}))
12vi.mock('@/state/sidebar-manager-state', () => ({
13 useSidebarManagerSnapshot: () => ({ openSidebar: vi.fn() }),
14}))
15vi.mock('@/components/layouts/ProjectLayout/LayoutSidebar/LayoutSidebarProvider', () => ({
16 SIDEBAR_KEYS: { AI_ASSISTANT: 'ai-assistant' },
17}))
18vi.mock('./RestartProjectDialog', () => ({
19 RestartProjectDialog: () => null,
20}))
21
22describe('ErrorMatcher', () => {
23 beforeEach(() => vi.clearAllMocks())
24
25 it('renders the provided title and error message', () => {
26 render(
27 <ErrorMatcher
28 title="Failed to load tables"
29 error="ERROR: FAILED TO RUN SQL QUERY: CONNECTION TERMINATED DUE TO CONNECTION TIMEOUT."
30 supportFormParams={{}}
31 />
32 )
33 expect(screen.getByText('Failed to load tables')).toBeInTheDocument()
34 expect(
35 screen.getByText(
36 'ERROR: FAILED TO RUN SQL QUERY: CONNECTION TERMINATED DUE TO CONNECTION TIMEOUT.'
37 )
38 ).toBeInTheDocument()
39 })
40
41 it('renders troubleshooting steps for classified errors', () => {
42 const error = new ConnectionTimeoutError('CONNECTION TERMINATED DUE TO CONNECTION TIMEOUT')
43 render(<ErrorMatcher title="Failed to load tables" error={error} supportFormParams={{}} />)
44 expect(screen.getByText('Try restarting your project')).toBeInTheDocument()
45 expect(screen.getByText('Try our troubleshooting guide')).toBeInTheDocument()
46 expect(screen.getByText('Debug with AI')).toBeInTheDocument()
47 })
48
49 it('renders fallback for plain ResponseError (not a classified subclass)', () => {
50 render(
51 <ErrorMatcher
52 title="Failed to load tables"
53 error={new ResponseError('CONNECTION TERMINATED DUE TO CONNECTION TIMEOUT')}
54 supportFormParams={{}}
55 />
56 )
57 expect(screen.getByText('Failed to load tables')).toBeInTheDocument()
58 expect(screen.queryByText('Try restarting your project')).not.toBeInTheDocument()
59 })
60
61 it('renders fallback with provided title for unmatched errors', () => {
62 render(
63 <ErrorMatcher title="Failed to load tables" error="UNKNOWN ERROR" supportFormParams={{}} />
64 )
65 expect(screen.getByText('Failed to load tables')).toBeInTheDocument()
66 expect(screen.getByText('UNKNOWN ERROR')).toBeInTheDocument()
67 })
68
69 it('accepts error as object with message property', () => {
70 render(
71 <ErrorMatcher
72 title="Failed to load tables"
73 error={{ message: 'UNKNOWN ERROR' }}
74 supportFormParams={{}}
75 />
76 )
77 expect(screen.getByText('UNKNOWN ERROR')).toBeInTheDocument()
78 })
79
80 it('builds support link with projectRef param', () => {
81 render(
82 <ErrorMatcher
83 title="Failed to load tables"
84 error="UNKNOWN ERROR"
85 supportFormParams={{ projectRef: 'my-project' }}
86 />
87 )
88 expect(screen.getByRole('link', { name: /contact support/i })).toHaveAttribute(
89 'href',
90 '/support/new?projectRef=my-project'
91 )
92 })
93
94 it('builds support link with no params when supportFormParams is omitted', () => {
95 render(<ErrorMatcher title="Failed to load tables" error="UNKNOWN ERROR" />)
96 expect(screen.getByRole('link', { name: /contact support/i })).toHaveAttribute(
97 'href',
98 '/support/new'
99 )
100 })
101})