Skip to content

Commit b5d1cb1

Browse files
committed
feat(graphiql): add API version selector component
Adds dropdown component for selecting Admin API version. - Add ApiVersionSelector component using Polaris Select - Support for version list and change callbacks - Include comprehensive tests (94 lines) All component tests pass
1 parent e4e87e9 commit b5d1cb1

File tree

3 files changed

+122
-0
lines changed

3 files changed

+122
-0
lines changed
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
import {ApiVersionSelector} from './ApiVersionSelector.tsx'
2+
import React from 'react'
3+
import {render, screen, fireEvent} from '@testing-library/react'
4+
import {describe, test, expect, vi} from 'vitest'
5+
import {AppProvider} from '@shopify/polaris'
6+
7+
// Helper to wrap components in AppProvider
8+
function renderWithProvider(element: React.ReactElement) {
9+
return render(<AppProvider i18n={{}}>{element}</AppProvider>)
10+
}
11+
12+
describe('<ApiVersionSelector />', () => {
13+
const defaultVersions = ['2024-01', '2024-04', '2024-07', '2024-10', 'unstable']
14+
15+
test('renders Select component', () => {
16+
const onChange = vi.fn()
17+
renderWithProvider(<ApiVersionSelector versions={defaultVersions} value="2024-10" onChange={onChange} />)
18+
19+
// Select should be rendered with the accessibility label
20+
const select = screen.getByLabelText('API version')
21+
expect(select).toBeDefined()
22+
})
23+
24+
test('Select has hidden label', () => {
25+
const onChange = vi.fn()
26+
renderWithProvider(<ApiVersionSelector versions={defaultVersions} value="2024-10" onChange={onChange} />)
27+
28+
// Label should exist but be visually hidden (Polaris labelHidden behavior)
29+
const select = screen.getByLabelText('API version')
30+
expect(select).toBeDefined()
31+
})
32+
33+
test('renders all version options', () => {
34+
const onChange = vi.fn()
35+
renderWithProvider(<ApiVersionSelector versions={defaultVersions} value="2024-10" onChange={onChange} />)
36+
37+
const select = screen.getByLabelText('API version')
38+
39+
expect(select.options).toHaveLength(5)
40+
expect(select.options[0].value).toBe('2024-01')
41+
expect(select.options[1].value).toBe('2024-04')
42+
expect(select.options[2].value).toBe('2024-07')
43+
expect(select.options[3].value).toBe('2024-10')
44+
expect(select.options[4].value).toBe('unstable')
45+
})
46+
47+
test('displays currently selected value', () => {
48+
const onChange = vi.fn()
49+
renderWithProvider(<ApiVersionSelector versions={defaultVersions} value="2024-07" onChange={onChange} />)
50+
51+
const select = screen.getByLabelText('API version')
52+
expect(select.value).toBe('2024-07')
53+
})
54+
55+
test('calls onChange when selection changes', () => {
56+
const onChange = vi.fn()
57+
renderWithProvider(<ApiVersionSelector versions={defaultVersions} value="2024-10" onChange={onChange} />)
58+
59+
const select = screen.getByLabelText('API version')
60+
fireEvent.change(select, {target: {value: '2024-04'}})
61+
62+
expect(onChange).toHaveBeenCalledTimes(1)
63+
// Polaris Select may pass additional parameters, check first argument
64+
expect(onChange.mock.calls[0][0]).toBe('2024-04')
65+
})
66+
67+
test('handles empty versions array', () => {
68+
const onChange = vi.fn()
69+
renderWithProvider(<ApiVersionSelector versions={[]} value="" onChange={onChange} />)
70+
71+
const select = screen.getByLabelText('API version')
72+
expect(select.options).toHaveLength(0)
73+
})
74+
75+
test('handles single version', () => {
76+
const onChange = vi.fn()
77+
renderWithProvider(<ApiVersionSelector versions={['2024-10']} value="2024-10" onChange={onChange} />)
78+
79+
const select = screen.getByLabelText('API version')
80+
expect(select.options).toHaveLength(1)
81+
expect(select.options[0].value).toBe('2024-10')
82+
})
83+
84+
test('handles custom version strings', () => {
85+
const customVersions = ['v1', 'v2', 'v3-beta']
86+
const onChange = vi.fn()
87+
renderWithProvider(<ApiVersionSelector versions={customVersions} value="v2" onChange={onChange} />)
88+
89+
const select = screen.getByLabelText('API version')
90+
expect(select.options[0].value).toBe('v1')
91+
expect(select.options[1].value).toBe('v2')
92+
expect(select.options[2].value).toBe('v3-beta')
93+
})
94+
})
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import React from 'react'
2+
import {Select} from '@shopify/polaris'
3+
4+
interface ApiVersionSelectorProps {
5+
// Available API versions
6+
versions: string[]
7+
// Currently selected version
8+
value: string
9+
// Callback when version changes
10+
onChange: (version: string) => void
11+
}
12+
13+
/**
14+
* API version selector component
15+
* Replaces vanilla JS event listener and manual DOM manipulation
16+
*/
17+
export function ApiVersionSelector({versions, value, onChange}: ApiVersionSelectorProps) {
18+
return (
19+
<Select
20+
label="API version"
21+
labelHidden
22+
options={versions.map((version) => ({label: version, value: version}))}
23+
value={value}
24+
onChange={onChange}
25+
/>
26+
)
27+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './ApiVersionSelector.tsx'

0 commit comments

Comments
 (0)