Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Component Testing: Error: DialogClose must be used within Dialog #2997

Open
alamenai opened this issue Jul 4, 2024 · 0 comments
Open

Component Testing: Error: DialogClose must be used within Dialog #2997

alamenai opened this issue Jul 4, 2024 · 0 comments

Comments

@alamenai
Copy link

alamenai commented Jul 4, 2024

I'm using Shadcn Dialog in Next.js project which is implemented internally using Radix Dialog.

When I want to create a unit test ( component testing ) using Vitest and Testing Library for a component ( Form ) within by a Dialog component I go this issue:

 FAIL  src/features/solar-analytics/electricity-consumption/__tests__/form.spec.tsx > ElectricityConsumptionForm > should update electricity requirements value when a household total members carousel item is selected
Error: `DialogClose` must be used within `Dialog`
 ❯ useDialogContext node_modules/@radix-ui/react-context/dist/packages/react/context/src/createContext.tsx:72:13
 ❯ node_modules/@radix-ui/react-dialog/dist/packages/react/dialog/src/Dialog.tsx:476:21
 ❯ renderWithHooks node_modules/react-dom/cjs/react-dom.development.js:15486:18
 ❯ updateForwardRef node_modules/react-dom/cjs/react-dom.development.js:19245:20
 ❯ beginWork node_modules/react-dom/cjs/react-dom.development.js:21675:16
 ❯ beginWork$1 node_modules/react-dom/cjs/react-dom.development.js:27465:14
 ❯ performUnitOfWork node_modules/react-dom/cjs/react-dom.development.js:26599:12
 ❯ workLoopSync node_modules/react-dom/cjs/react-dom.development.js:26505:5
 ❯ renderRootSync node_modules/react-dom/cjs/react-dom.development.js:26473:7
 ❯ recoverFromConcurrentError node_modules/react-dom/cjs/react-dom.development.js:25889:20

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/1]⎯

 Test Files  1 failed (1)
      Tests  1 failed (1)
   Start at  09:16:00
   Duration  2.04s


 FAIL  Tests failed. Watching for file changes...
       press h to show help, press q to quit

Component Testing

import { render } from "@/__test-utils__/custom-render"
import { fireEvent, screen } from "@testing-library/react"
import mockRouter from "next-router-mock"
import { AppRouterContext } from "next/dist/shared/lib/app-router-context.shared-runtime"
import { describe, it } from "vitest"

import { ElectricityConsumptionForm } from "../components/form"

describe("ElectricityConsumptionForm", async () => {
  it("should update electricity requirements value when a household total members carousel item is selected", () => {
    render(
      <AppRouterContext.Provider value={mockRouter as any}>
        <ElectricityConsumptionForm />
      </AppRouterContext.Provider>
    )

    // Open the dialog by clicking the button
    const openButton = screen.getByText("Parameter ändern") // Adjust the text if necessary
    fireEvent.click(openButton)

    // // Select the first carousel item
    // Const firstCarouselItem = screen.getByText("1") // Assumes the text '1' is visible on the first item
    // FireEvent.click(firstCarouselItem)

    // // Get the electricity requirements input
    // Const electricityInput = screen.getByLabelText("Geben Sie Ihren jährlichen Stromverbrauch ein") // Adjust the label text as necessary

    // // Check if the value is updated according to the first carousel item selection
    // Expect(electricityInput).toHaveValue("2500")
  })
})

Component

// some code here

export const ElectricityConsumptionForm = () => {

// some code here


  const onDialogOpen = (isOpen: boolean | ((prevState: boolean) => boolean)): void => {
    if (!isOpen && !isChangesSaved) {
      form.reset({
        electricityAnnualConsumption: electricityAnnualConsumptionParam!,
        standardLoadProfile: standardLoadProfileParam!,
      })
      setSelectedHouseholdTotalMembers(lastSavedHouseholdTotalMembers)
    }
    setIsChangesSaved(false)
    setIsElectrictyDemandEditable(false)
    setOpen(isOpen)
  }

  return <ResponsiveDialog open={open} setOpen={(isOpen) => onDialogOpen(isOpen)}>
   // some code here
    </ResponsiveDialog>
}

Responsive Dialog

import { SlidersHorizontal, Zap } from "lucide-react"
import { Dispatch, ReactNode, SetStateAction } from "react"
import { useMediaQuery } from "usehooks-ts"

import { Button } from "../ui/button"
import { CardContent } from "../ui/card"
import {
  Dialog,
  DialogClose,
  DialogContent,
  DialogFooter,
  DialogHeader,
  DialogTitle,
  DialogTrigger,
} from "../ui/dialog"
import {
  Drawer,
  DrawerContent,
  DrawerDescription,
  DrawerFooter,
  DrawerHeader,
  DrawerTitle,
  DrawerTrigger,
} from "../ui/drawer"

type ResponsiveDialogProps = {
  children: ReactNode
  open: boolean
  setOpen: Dispatch<SetStateAction<boolean>>
}

export const ResponsiveDialog = ({ children, open, setOpen }: ResponsiveDialogProps) => {
  const isDesktop = useMediaQuery("(min-width: 768px)")

  if (isDesktop) {
    return (
      <Dialog open={open} onOpenChange={setOpen}>
        <DialogTrigger asChild>
          <Button className='rounded-full h-9'>
            <Zap size={16} className='mr-2' />
            Stromverbrauch anpassen
          </Button>
        </DialogTrigger>
        <DialogContent className='flex flex-col min-w-[600px] gap-0'>
          <DialogHeader>
            <DialogTitle className='text-2xl'>Strombedarf</DialogTitle>
            <DrawerDescription>
              Passen Sie Ihren Strombedarf individuell an und wählen Sie Ihre Analysetiefe.
            </DrawerDescription>
          </DialogHeader>
          {children}
          <DialogFooter>
            <DialogClose asChild>
              <Button type='button' variant='ghost' className='rounded-full h-12 w-full mt-2'>
                Abbrechen
              </Button>
            </DialogClose>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    )
  }

  return (
    <Drawer open={open} onOpenChange={setOpen}>
      <DrawerTrigger asChild>
        <Button variant='outline' className='rounded-full'>
          <SlidersHorizontal size={16} className='mr-2' /> Parameter ändern
        </Button>
      </DrawerTrigger>
      <DrawerContent>
        <DrawerHeader>
          <DrawerTitle>Strombedarf</DrawerTitle>
          <DrawerDescription>
            Passen Sie Ihren Strombedarf individuell an und wählen Sie Ihre Analysetiefe.
          </DrawerDescription>
        </DrawerHeader>
        <CardContent>{children}</CardContent>
        <DrawerFooter>
          <DialogClose asChild>
            <Button type='button' variant='ghost' className='h-12 rounded-full'>
              Abbrechen
            </Button>
          </DialogClose>
        </DrawerFooter>
      </DrawerContent>
    </Drawer>
  )
}

Screenshot

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant