EdgeFunctionRenderer.test.tsx136 lines · main
1import { screen } from '@testing-library/react'
2import userEvent from '@testing-library/user-event'
3import { beforeEach, describe, expect, it, vi } from 'vitest'
4
5import { EdgeFunctionRenderer } from './EdgeFunctionRenderer'
6import { render } from '@/tests/helpers'
7
8const {
9 mockSendEvent,
10 mockUseEdgeFunctionQuery,
11 mockUseParams,
12 mockUseProjectSettingsV2Query,
13 mockUseSelectedOrganizationQuery,
14} = vi.hoisted(() => ({
15 mockSendEvent: vi.fn(),
16 mockUseEdgeFunctionQuery: vi.fn(),
17 mockUseParams: vi.fn(),
18 mockUseProjectSettingsV2Query: vi.fn(),
19 mockUseSelectedOrganizationQuery: vi.fn(),
20}))
21
22vi.mock('common', async () => {
23 const actual = await vi.importActual<typeof import('common')>('common')
24
25 return {
26 ...actual,
27 useParams: mockUseParams,
28 }
29})
30
31vi.mock('@/data/config/project-settings-v2-query', () => ({
32 useProjectSettingsV2Query: mockUseProjectSettingsV2Query,
33}))
34
35vi.mock('@/data/edge-functions/edge-function-query', () => ({
36 useEdgeFunctionQuery: mockUseEdgeFunctionQuery,
37}))
38
39vi.mock('@/data/telemetry/send-event-mutation', () => ({
40 useSendEventMutation: () => ({ mutate: mockSendEvent }),
41}))
42
43vi.mock('@/hooks/misc/useSelectedOrganization', () => ({
44 useSelectedOrganizationQuery: mockUseSelectedOrganizationQuery,
45}))
46
47vi.mock('../EdgeFunctionBlock/EdgeFunctionBlock', () => ({
48 EdgeFunctionBlock: ({
49 showReplaceWarning,
50 onCancelReplace,
51 onConfirmReplace,
52 }: {
53 showReplaceWarning?: boolean
54 onCancelReplace?: () => void
55 onConfirmReplace?: () => void
56 }) => (
57 <div>
58 {showReplaceWarning && (
59 <div>
60 <p>An edge function with this name already exists.</p>
61 <button onClick={onCancelReplace}>Cancel</button>
62 <button onClick={onConfirmReplace}>Replace function</button>
63 </div>
64 )}
65 </div>
66 ),
67}))
68
69vi.mock('./ConfirmFooter', () => ({
70 ConfirmFooter: ({
71 confirmLabel,
72 onConfirm,
73 }: {
74 confirmLabel?: string
75 onConfirm?: () => void
76 }) => <button onClick={onConfirm}>{confirmLabel ?? 'Confirm'}</button>,
77}))
78
79describe('EdgeFunctionRenderer', () => {
80 beforeEach(() => {
81 mockSendEvent.mockReset()
82 mockUseEdgeFunctionQuery.mockReset()
83 mockUseParams.mockReturnValue({ ref: 'project-ref' })
84 mockUseProjectSettingsV2Query.mockReturnValue({ data: undefined })
85 mockUseSelectedOrganizationQuery.mockReturnValue({ data: { slug: 'org-slug' } })
86 })
87
88 it('only deploys an existing function from the replace warning confirmation', async () => {
89 const user = userEvent.setup()
90 const onApprove = vi.fn()
91
92 mockUseEdgeFunctionQuery.mockReturnValue({ data: { slug: 'hello-world' } })
93
94 render(
95 <EdgeFunctionRenderer
96 label="Deploy Edge Function"
97 code="Deno.serve(() => new Response('ok'))"
98 functionName="hello-world"
99 onApprove={onApprove}
100 />
101 )
102
103 await user.click(screen.getByRole('button', { name: 'Deploy' }))
104 expect(screen.getByText('An edge function with this name already exists.')).toBeInTheDocument()
105 expect(onApprove).not.toHaveBeenCalled()
106
107 await user.click(screen.getByRole('button', { name: 'Deploy' }))
108 expect(onApprove).not.toHaveBeenCalled()
109 expect(mockSendEvent).not.toHaveBeenCalled()
110
111 await user.click(screen.getByRole('button', { name: 'Replace function' }))
112 expect(onApprove).toHaveBeenCalledTimes(1)
113 expect(mockSendEvent).toHaveBeenCalledTimes(1)
114 })
115
116 it('deploys immediately when no existing function is found', async () => {
117 const user = userEvent.setup()
118 const onApprove = vi.fn()
119
120 mockUseEdgeFunctionQuery.mockReturnValue({ data: undefined })
121
122 render(
123 <EdgeFunctionRenderer
124 label="Deploy Edge Function"
125 code="Deno.serve(() => new Response('ok'))"
126 functionName="hello-world"
127 onApprove={onApprove}
128 />
129 )
130
131 await user.click(screen.getByRole('button', { name: 'Deploy' }))
132
133 expect(onApprove).toHaveBeenCalledTimes(1)
134 expect(mockSendEvent).toHaveBeenCalledTimes(1)
135 })
136})