DeleteBucketModal.test.tsx128 lines · main
1import { faker } from '@faker-js/faker'
2import { fireEvent, screen, waitFor } from '@testing-library/dom'
3import userEvent from '@testing-library/user-event'
4import { useState } from 'react'
5import { beforeEach, describe, expect, it, vi } from 'vitest'
6
7import { DeleteBucketModal } from '../DeleteBucketModal'
8import { ProjectContextProvider } from '@/components/layouts/ProjectLayout/ProjectContext'
9import { Bucket } from '@/data/storage/buckets-query'
10import { customRender } from '@/tests/lib/custom-render'
11import { addAPIMock } from '@/tests/lib/msw'
12import { routerMock } from '@/tests/lib/route-mock'
13
14const bucket: Bucket = {
15 id: 'test',
16 name: 'test',
17 owner: faker.string.uuid(),
18 public: faker.datatype.boolean(),
19 allowed_mime_types: faker.helpers.multiple(() => faker.system.mimeType(), {
20 count: { min: 1, max: 5 },
21 }),
22 file_size_limit: faker.number.int({ min: 0, max: 25165824 }),
23 type: 'STANDARD',
24 created_at: faker.date.recent().toISOString(),
25 updated_at: faker.date.recent().toISOString(),
26}
27
28const Page = ({ onClose }: { onClose: () => void }) => {
29 const [open, setOpen] = useState(false)
30 return (
31 <ProjectContextProvider projectRef="default">
32 <button onClick={() => setOpen(true)}>Open</button>
33
34 <DeleteBucketModal
35 visible={open}
36 bucket={bucket}
37 onClose={() => {
38 setOpen(false)
39 onClose()
40 }}
41 />
42 </ProjectContextProvider>
43 )
44}
45
46describe(`DeleteBucketModal`, () => {
47 beforeEach(() => {
48 // useParams
49 routerMock.setCurrentUrl(`/project/default/storage/files`)
50 // useProjectContext
51 addAPIMock({
52 method: `get`,
53 path: `/platform/projects/:ref`,
54 // @ts-expect-error
55 response: {
56 cloud_provider: 'localhost',
57 id: 1,
58 inserted_at: '2021-08-02T06:40:40.646Z',
59 name: 'Default Project',
60 organization_id: 1,
61 ref: 'default',
62 region: 'local',
63 status: 'ACTIVE_HEALTHY',
64 },
65 })
66 // usePaginatedBucketsQuery
67 addAPIMock({
68 method: `get`,
69 path: `/platform/storage/:ref/buckets`,
70 response: [bucket],
71 })
72 // useDatabasePoliciesQuery
73 addAPIMock({
74 method: `get`,
75 path: `/platform/pg-meta/:ref/policies`,
76 response: [
77 {
78 id: faker.number.int({ min: 1 }),
79 name: faker.word.noun(),
80 action: faker.helpers.arrayElement(['PERMISSIVE', 'RESTRICTIVE']),
81 command: faker.helpers.arrayElement(['SELECT', 'INSERT', 'UPDATE', 'DELETE', 'ALL']),
82 table: faker.word.noun(),
83 table_id: faker.number.int({ min: 1 }),
84 check: null,
85 definition: null,
86 schema: faker.lorem.sentence(),
87 roles: faker.helpers.multiple(() => faker.word.noun(), {
88 count: { min: 1, max: 5 },
89 }),
90 },
91 ],
92 })
93 // useBucketDeleteMutation - empty bucket
94 addAPIMock({
95 method: `post`,
96 path: `/platform/storage/:ref/buckets/:id/empty`,
97 })
98 // useBucketDeleteMutation - poll for empty bucket
99 addAPIMock({
100 method: `post`,
101 path: `/platform/storage/:ref/buckets/:id/objects/list`,
102 response: [], // Return empty array to indicate bucket is empty
103 })
104 // useBucketDeleteMutation - delete bucket
105 addAPIMock({
106 method: `delete`,
107 path: `/platform/storage/:ref/buckets/:id`,
108 })
109 })
110
111 it(`renders a confirmation dialog`, async () => {
112 const onClose = vi.fn()
113 customRender(<Page onClose={onClose} />)
114
115 const openButton = screen.getByRole(`button`, { name: `Open` })
116 await userEvent.click(openButton)
117 await screen.findByRole(`dialog`)
118
119 const input = screen.getByPlaceholderText(`Type bucket name`)
120 await userEvent.type(input, `test`)
121
122 const confirmButton = screen.getByRole(`button`, { name: `Delete bucket` })
123 fireEvent.click(confirmButton)
124
125 await waitFor(() => expect(onClose).toHaveBeenCalledOnce())
126 expect(routerMock.asPath).toStrictEqual(`/project/default/storage/files`)
127 })
128})