Skip to content

Commit 2da908d

Browse files
committed
RequestUrlBar tests
1 parent c7fe6b2 commit 2da908d

File tree

1 file changed

+157
-0
lines changed

1 file changed

+157
-0
lines changed

src/test/RequestUrlBar.test.tsx

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
import { describe, it, expect, vi } from 'vitest'
2+
import { render, screen, fireEvent, createEvent } from '@testing-library/react'
3+
import userEvent from '@testing-library/user-event'
4+
import { RequestUrlBar } from '@/components/RequestUrlBar'
5+
6+
// Mock Radix UI's Select component
7+
vi.mock('@/components/ui/select', () => ({
8+
Select: ({ value, onValueChange, children }: any) => (
9+
<select
10+
value={value}
11+
onChange={(e) => onValueChange(e.target.value)}
12+
data-testid="method-select"
13+
>
14+
{children}
15+
</select>
16+
),
17+
SelectTrigger: ({ children }: any) => children,
18+
SelectValue: ({ placeholder }: any) => placeholder,
19+
SelectContent: ({ children }: any) => children,
20+
SelectItem: ({ value, children }: any) => (
21+
<option value={value}>{children}</option>
22+
),
23+
}))
24+
25+
describe('RequestUrlBar', () => {
26+
interface SetupOptions {
27+
method?: string
28+
url?: string
29+
loading?: boolean
30+
}
31+
32+
const setup = (options: SetupOptions = {}) => {
33+
const user = userEvent.setup()
34+
const props = {
35+
method: options.method || 'GET',
36+
url: options.url || '',
37+
loading: options.loading || false,
38+
onMethodChange: vi.fn(),
39+
onUrlChange: vi.fn(),
40+
onSend: vi.fn(),
41+
onSave: vi.fn(),
42+
}
43+
44+
const utils = render(<RequestUrlBar {...props} />)
45+
46+
return {
47+
user,
48+
...utils,
49+
...props,
50+
}
51+
}
52+
53+
it('renders with default props', () => {
54+
setup()
55+
56+
expect(screen.getByTestId('method-select')).toBeInTheDocument()
57+
expect(screen.getByPlaceholderText('Enter request URL')).toBeInTheDocument()
58+
expect(screen.getByRole('button', { name: /Save/i })).toBeInTheDocument()
59+
expect(screen.getByRole('button', { name: /Send/i })).toBeInTheDocument()
60+
})
61+
62+
it('displays the current method and URL', () => {
63+
setup({
64+
method: 'POST',
65+
url: 'https://api.example.com'
66+
})
67+
68+
expect(screen.getByTestId('method-select')).toHaveValue('POST')
69+
expect(screen.getByPlaceholderText('Enter request URL')).toHaveValue('https://api.example.com')
70+
})
71+
72+
it('calls onMethodChange when method is changed', () => {
73+
const { onMethodChange } = setup({ method: 'GET' })
74+
75+
const methodSelect = screen.getByTestId('method-select')
76+
fireEvent.change(methodSelect, { target: { value: 'POST' } })
77+
78+
expect(onMethodChange).toHaveBeenCalledWith('POST')
79+
})
80+
81+
it('calls onUrlChange when URL is changed', () => {
82+
const { onUrlChange } = setup()
83+
84+
const urlInput = screen.getByPlaceholderText('Enter request URL')
85+
fireEvent.change(urlInput, { target: { value: 'https://api.example.com' } })
86+
87+
expect(onUrlChange).toHaveBeenCalledWith('https://api.example.com')
88+
})
89+
90+
it('prevents default question mark behavior in URL input', () => {
91+
setup()
92+
93+
const urlInput = screen.getByPlaceholderText('Enter request URL')
94+
const event = createEvent.keyDown(urlInput, { key: '?' })
95+
event.stopPropagation = vi.fn()
96+
97+
fireEvent(urlInput, event)
98+
99+
expect(event.stopPropagation).toHaveBeenCalled()
100+
})
101+
102+
it('does not stop propagation for non-question mark keys', () => {
103+
setup()
104+
105+
const urlInput = screen.getByPlaceholderText('Enter request URL')
106+
const event = createEvent.keyDown(urlInput, { key: 'a' })
107+
event.stopPropagation = vi.fn()
108+
109+
fireEvent(urlInput, event)
110+
111+
expect(event.stopPropagation).not.toHaveBeenCalled()
112+
})
113+
114+
it('calls onSave when save button is clicked', async () => {
115+
const { user, onSave } = setup()
116+
117+
const saveButton = screen.getByRole('button', { name: /Save/i })
118+
await user.click(saveButton)
119+
120+
expect(onSave).toHaveBeenCalled()
121+
})
122+
123+
it('calls onSend when send button is clicked', async () => {
124+
const { user, onSend } = setup()
125+
126+
const sendButton = screen.getByRole('button', { name: /Send/i })
127+
await user.click(sendButton)
128+
129+
expect(onSend).toHaveBeenCalled()
130+
})
131+
132+
it('disables send button when loading', () => {
133+
setup({ loading: true })
134+
135+
const sendButton = screen.getByRole('button', { name: /Sending/i })
136+
expect(sendButton).toBeDisabled()
137+
})
138+
139+
it('changes send button text to "Sending..." when loading', () => {
140+
setup({ loading: true })
141+
142+
expect(screen.getByRole('button', { name: /Sending/i })).toBeInTheDocument()
143+
expect(screen.queryByRole('button', { name: /^Send$/i })).not.toBeInTheDocument()
144+
})
145+
146+
it('supports all HTTP methods', () => {
147+
const { onMethodChange } = setup()
148+
const methods = ["GET", "POST", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS"]
149+
150+
const methodSelect = screen.getByTestId('method-select')
151+
152+
for (const method of methods) {
153+
fireEvent.change(methodSelect, { target: { value: method } })
154+
expect(onMethodChange).toHaveBeenCalledWith(method)
155+
}
156+
})
157+
})

0 commit comments

Comments
 (0)