95 lines
4.7 KiB
TypeScript
95 lines
4.7 KiB
TypeScript
import {QueryClient, QueryClientProvider} from '@tanstack/react-query'
|
|
import {render, screen, within} from '@testing-library/react'
|
|
import userEvent from '@testing-library/user-event'
|
|
import {beforeEach, expect, test, vi} from 'vitest'
|
|
import {Route53RecordsPanel} from './Route53RecordsPanel'
|
|
import type {CloudResource} from '@/types/resource'
|
|
|
|
const api = vi.hoisted(() => ({
|
|
deleteFlatItem: vi.fn(),
|
|
getCloudResource: vi.fn(),
|
|
listFlatItems: vi.fn(),
|
|
putFlatItem: vi.fn(),
|
|
}))
|
|
|
|
vi.mock('@/api/cloudProxyClient', () => api)
|
|
vi.mock('@/lib/accountStore', () => ({useAccountId: () => '000000000000'}))
|
|
|
|
const zone: CloudResource = {
|
|
id: 'ZG9PAE0M9KRWJ4F', name: 'example.test', cloud: 'aws', service: 'dns', type: 'hosted-zone',
|
|
region: null, createdAt: null, metadata: {visibility: 'public', recordCount: 3},
|
|
}
|
|
|
|
function item(id: string, body: Record<string, unknown>) {
|
|
return {id, collectionId: null, timestamp: null, metadata: {}, body: {ttl: 300, values: [], alias: null, setIdentifier: null, managed: false, editable: true, ...body}}
|
|
}
|
|
|
|
const records = [
|
|
item('example.test|NS', {name: 'example.test', type: 'NS', ttl: 172800, values: ['ns-1.awsdns-01.org.'], managed: true}),
|
|
item('www.example.test|A', {name: 'www.example.test', type: 'A', values: ['10.0.0.1']}),
|
|
item('example.test|TXT', {name: 'example.test', type: 'TXT', values: ['"v=spf1 -all"']}),
|
|
item('cdn.example.test|A', {name: 'cdn.example.test', type: 'A', ttl: null, alias: {dnsName: 'd111.cloudfront.net', hostedZoneId: 'Z2'}, editable: false}),
|
|
]
|
|
|
|
function renderPanel() {
|
|
const client = new QueryClient({defaultOptions: {queries: {retry: false}}})
|
|
return render(<QueryClientProvider client={client}><Route53RecordsPanel resource={zone} runtimeReachable/></QueryClientProvider>)
|
|
}
|
|
|
|
beforeEach(() => {
|
|
vi.clearAllMocks()
|
|
api.getCloudResource.mockResolvedValue({...zone, metadata: {...zone.metadata, nameServers: ['ns-1.awsdns-01.org', 'ns-2.awsdns-02.net']}})
|
|
api.listFlatItems.mockResolvedValue({items: records, nextCursor: null})
|
|
api.putFlatItem.mockImplementation(async (_cloud, _service, _zone, body) => item('x', {name: `${body.name}.example.test`, type: body.type}))
|
|
api.deleteFlatItem.mockResolvedValue(undefined)
|
|
})
|
|
|
|
test('shows the name servers and records, keeping the zone defaults read-only', async () => {
|
|
renderPanel()
|
|
|
|
expect(await screen.findByText('ns-2.awsdns-02.net')).toBeInTheDocument()
|
|
expect(await screen.findByText('10.0.0.1')).toBeInTheDocument()
|
|
expect(screen.getByText('Alias → d111.cloudfront.net')).toBeInTheDocument()
|
|
expect(screen.getByText('zone default')).toBeInTheDocument()
|
|
expect(screen.queryByRole('button', {name: 'Delete NS example.test'})).not.toBeInTheDocument()
|
|
expect(screen.queryByRole('button', {name: 'Edit A cdn.example.test'})).not.toBeInTheDocument()
|
|
expect(screen.getByRole('button', {name: 'Delete A cdn.example.test'})).toBeInTheDocument()
|
|
})
|
|
|
|
test('creates a record from a name inside the zone', async () => {
|
|
const user = userEvent.setup()
|
|
renderPanel()
|
|
|
|
const form = await screen.findByRole('form', {name: 'Create record'})
|
|
await user.type(within(form).getByLabelText(/Record name/), 'api')
|
|
await user.selectOptions(within(form).getByLabelText('Type'), 'CNAME')
|
|
await user.clear(within(form).getByLabelText(/TTL/))
|
|
await user.type(within(form).getByLabelText(/TTL/), '60')
|
|
await user.type(within(form).getByLabelText(/Values/), 'app.example.net')
|
|
await user.click(within(form).getByRole('button', {name: 'Create record'}))
|
|
|
|
expect(api.putFlatItem).toHaveBeenCalledWith('aws', 'dns', zone.id, {name: 'api', type: 'CNAME', ttl: 60, values: ['app.example.net']})
|
|
expect(await screen.findByText(/Created CNAME api.example.test/)).toBeInTheDocument()
|
|
})
|
|
|
|
test('edits a record with its name and type fixed, showing TXT text without quotes', async () => {
|
|
const user = userEvent.setup()
|
|
renderPanel()
|
|
|
|
await user.click(await screen.findByRole('button', {name: 'Edit TXT example.test'}))
|
|
const form = screen.getByRole('form', {name: 'Edit record'})
|
|
expect(within(form).getByLabelText(/Record name/)).toHaveValue('@')
|
|
expect(within(form).getByLabelText(/Record name/)).toBeDisabled()
|
|
expect(within(form).getByLabelText('Type')).toBeDisabled()
|
|
expect(within(form).getByLabelText(/Values/)).toHaveValue('v=spf1 -all')
|
|
})
|
|
|
|
test('deletes a record by its name and type', async () => {
|
|
const user = userEvent.setup()
|
|
renderPanel()
|
|
|
|
await user.click(await screen.findByRole('button', {name: 'Delete A www.example.test'}))
|
|
expect(api.deleteFlatItem).toHaveBeenCalledWith('aws', 'dns', zone.id, 'www.example.test|A')
|
|
expect(await screen.findByText('Deleted A www.example.test.')).toBeInTheDocument()
|
|
})
|