Ver Fonte

test: add tests for tasks import dialog

satnaing há 2 meses atrás
pai
commit
58b5228bc2

+ 123 - 0
src/features/tasks/components/tasks-import-dialog.test.tsx

@@ -0,0 +1,123 @@
+import { useState } from 'react'
+import { beforeEach, describe, expect, it, vi } from 'vitest'
+import { render } from 'vitest-browser-react'
+import { userEvent } from 'vitest/browser'
+import { showSubmittedData } from '@/lib/show-submitted-data'
+import { TasksImportDialog } from './tasks-import-dialog'
+
+vi.mock('@/lib/show-submitted-data', () => ({ showSubmittedData: vi.fn() }))
+
+describe('TasksImportDialog', () => {
+  beforeEach(() => vi.clearAllMocks())
+
+  it('renders the dialog with the correct title, description, file input and buttons', async () => {
+    const onOpenChange = vi.fn()
+    const { getByRole, getByText, getByLabelText } = await render(
+      <TasksImportDialog open onOpenChange={onOpenChange} />
+    )
+
+    const title = getByRole('heading', {
+      level: 2,
+      name: /Import Tasks/i,
+    })
+    const desc = getByText('Import tasks quickly from a CSV file')
+    const fileInput = getByLabelText('File')
+    const closeButtons = getByRole('dialog')
+      .getByRole('button', { name: 'Close' })
+      .elements()
+
+    const importButton = getByRole('button', { name: /^Import$/i })
+
+    expect(title).toBeInTheDocument()
+    expect(desc).toBeInTheDocument()
+    expect(fileInput).toBeInTheDocument()
+    expect(closeButtons).toHaveLength(2)
+    expect(importButton).toBeInTheDocument()
+  })
+
+  it('shows validation when submitting without a file', async () => {
+    const onOpenChange = vi.fn()
+    const { getByRole, getByText } = await render(
+      <TasksImportDialog open onOpenChange={onOpenChange} />
+    )
+
+    const importButton = getByRole('button', { name: /^Import$/i })
+    await userEvent.click(importButton)
+
+    expect(getByText('Please upload a file.')).toBeInTheDocument()
+    expect(onOpenChange).not.toHaveBeenCalled()
+    expect(showSubmittedData).not.toHaveBeenCalled()
+  })
+
+  it('calls showSubmittedData and closes when a CSV file is imported', async () => {
+    const onOpenChange = vi.fn()
+    const { getByRole, getByLabelText } = await render(
+      <TasksImportDialog open onOpenChange={onOpenChange} />
+    )
+
+    const csv = new File(['a,b'], 'tasks.csv', { type: 'text/csv' })
+    await userEvent.upload(getByLabelText('File'), csv)
+
+    const importButton = getByRole('button', { name: /^Import$/i })
+    await userEvent.click(importButton)
+
+    expect(showSubmittedData).toHaveBeenCalledOnce()
+    expect(showSubmittedData).toHaveBeenCalledWith(
+      {
+        name: 'tasks.csv',
+        size: csv.size,
+        type: 'text/csv',
+      },
+      'You have imported the following file:'
+    )
+    expect(onOpenChange).toHaveBeenCalledOnce()
+    expect(onOpenChange).toHaveBeenCalledWith(false)
+  })
+
+  it('closes the dialog when Close is clicked', async () => {
+    const onOpenChange = vi.fn()
+
+    function Harness() {
+      const [open, setOpen] = useState(true)
+      return (
+        <>
+          <button type='button' onClick={() => setOpen(true)}>
+            Reopen
+          </button>
+          <TasksImportDialog
+            open={open}
+            onOpenChange={(val) => {
+              onOpenChange(val)
+              setOpen(val)
+            }}
+          />
+        </>
+      )
+    }
+
+    const { getByRole } = await render(<Harness />)
+
+    const closeButtonX = getByRole('dialog')
+      .getByRole('button', {
+        name: /Close/i,
+      })
+      .nth(0)
+    await userEvent.click(closeButtonX)
+
+    expect(onOpenChange).toHaveBeenCalledOnce()
+    expect(onOpenChange).toHaveBeenCalledWith(false)
+    expect(showSubmittedData).not.toHaveBeenCalled()
+
+    await userEvent.click(getByRole('button', { name: /Reopen/i }))
+    const closeButton = getByRole('dialog')
+      .getByRole('button', {
+        name: /Close/i,
+      })
+      .nth(1)
+    await userEvent.click(closeButton)
+
+    expect(onOpenChange).toHaveBeenCalledTimes(2)
+    expect(onOpenChange).toHaveBeenCalledWith(false)
+    expect(showSubmittedData).not.toHaveBeenCalled()
+  })
+})

+ 7 - 2
src/features/tasks/components/tasks-import-dialog.tsx

@@ -26,7 +26,7 @@ const formSchema = z.object({
   file: z
     .instanceof(FileList)
     .refine((files) => files.length > 0, {
-      message: 'Please upload a file',
+      message: 'Please upload a file.',
     })
     .refine(
       (files) => ['text/csv'].includes(files?.[0]?.type),
@@ -88,7 +88,12 @@ export function TasksImportDialog({
                 <FormItem className='my-2'>
                   <FormLabel>File</FormLabel>
                   <FormControl>
-                    <Input type='file' {...fileRef} className='h-8 py-0' />
+                    <Input
+                      type='file'
+                      accept='text/csv'
+                      {...fileRef}
+                      className='h-8 py-0'
+                    />
                   </FormControl>
                   <FormMessage />
                 </FormItem>