import {QueryClient, QueryClientProvider} from '@tanstack/react-query' import {render, screen, waitFor} from '@testing-library/react' import userEvent from '@testing-library/user-event' import {expect, test, vi} from 'vitest' import {StorageObjectBrowser} from './StorageObjectBrowser' import type {CloudResource} from '@/types/resource' const apiMocks = vi.hoisted(() => ({ copyStorageObject: vi.fn(), createCloudResource: vi.fn(), deleteStorageObject: vi.fn(), listCloudResources: vi.fn(), listStorageObjects: vi.fn(), storageObjectDownloadUrl: vi.fn(), uploadStorageObject: vi.fn(), })) vi.mock('@/api/cloudProxyClient', () => apiMocks) const bucket: CloudResource = { id: 'incoming-orders', name: 'incoming-orders', cloud: 'aws', service: 'storage', type: 'bucket', region: null, createdAt: null, metadata: {}, } test('deletes a folder and all nested objects', async () => { apiMocks.listStorageObjects.mockImplementation((_cloud: string, _bucket: string, prefix: string) => { if (prefix === 'orders/') { return Promise.resolve({prefix, objects: [{ key: 'orders/order.json', name: 'order.json', type: 'object', size: 10, lastModified: null, metadata: {}, }]}) } return Promise.resolve({prefix, objects: [{ key: 'orders/', name: 'orders', type: 'folder', size: null, lastModified: null, metadata: {}, }]}) }) apiMocks.deleteStorageObject.mockResolvedValue(undefined) const user = userEvent.setup() const queryClient = new QueryClient({defaultOptions: {queries: {retry: false}}}) render( {}}/> , ) await user.click(await screen.findByRole('button', {name: 'Delete orders folder'})) await user.click(screen.getByRole('button', {name: 'Delete folder'})) await waitFor(() => { expect(apiMocks.deleteStorageObject).toHaveBeenCalledWith('aws', 'incoming-orders', 'orders/order.json') expect(apiMocks.deleteStorageObject).toHaveBeenCalledWith('aws', 'incoming-orders', 'orders/') }) }) test('requires the bucket name before emptying all folder contents', async () => { apiMocks.listStorageObjects.mockImplementation((_cloud: string, _bucket: string, prefix: string) => { if (prefix === 'orders/') { return Promise.resolve({prefix, objects: [{ key: 'orders/order.json', name: 'order.json', type: 'object', size: 10, lastModified: null, metadata: {}, }]}) } return Promise.resolve({prefix, objects: [{ key: 'orders/', name: 'orders', type: 'folder', size: null, lastModified: null, metadata: {}, }]}) }) apiMocks.deleteStorageObject.mockResolvedValue(undefined) const user = userEvent.setup() const queryClient = new QueryClient({defaultOptions: {queries: {retry: false}}}) render( {}}/> , ) await user.click(await screen.findByRole('button', {name: 'Empty bucket'})) expect(screen.getAllByRole('button', {name: /^Empty bucket$/})[1]).toBeDisabled() await user.type(screen.getByPlaceholderText('incoming-orders'), 'incoming-orders') await user.click(screen.getAllByRole('button', {name: /^Empty bucket$/})[1]) await waitFor(() => { expect(apiMocks.deleteStorageObject).toHaveBeenCalledWith('aws', 'incoming-orders', 'orders/order.json') expect(apiMocks.deleteStorageObject).toHaveBeenCalledWith('aws', 'incoming-orders', 'orders/') }) }) test('shows an object extension instead of a generic object type', async () => { apiMocks.listStorageObjects.mockResolvedValue({prefix: '', objects: [{ key: 'orders/order.json', name: 'order.json', type: 'object', size: 10, lastModified: null, metadata: {}, }]}) const queryClient = new QueryClient({defaultOptions: {queries: {retry: false}}}) render( {}}/> , ) expect(await screen.findByText('JSON file')).toBeInTheDocument() }) test('offers a copy action for the AWS bucket name', async () => { apiMocks.listStorageObjects.mockResolvedValue({prefix: '', objects: []}) const queryClient = new QueryClient({defaultOptions: {queries: {retry: false}}}) render( {}}/> , ) expect(await screen.findByRole('button', {name: 'Copy Bucket name'})).toBeInTheDocument() }) test('opens the object action with copy selected', async () => { apiMocks.listStorageObjects.mockResolvedValue({prefix: '', objects: [{ key: 'orders/order.json', name: 'order.json', type: 'object', size: 10, lastModified: null, metadata: {}, }]}) apiMocks.listCloudResources.mockResolvedValue([bucket]) const user = userEvent.setup() const queryClient = new QueryClient({defaultOptions: {queries: {retry: false}}}) render( {}}/> , ) await user.click(await screen.findByRole('button', {name: 'Copy or move order.json'})) const copyTab = screen.getAllByRole('button', {name: 'Copy'}).find((button) => button.classList.contains('drawer-tab')) expect(copyTab).toHaveClass('active') })