ui icon indicating copy to clipboard operation
ui copied to clipboard

[Bug] Undefined is not a function on Carousel Component while integration testing

Open louispelarrey opened this issue 1 year ago • 3 comments

Hello,

I'm having an error using your Carousel Component. When I'm using it on my dev server everything works as expected but when I'm trying to do some integration testing, CarouselContent throws an error which is "TypeError: undefined is not a function".

I have no idea if this concerns your implementation of the library or the library itself.

I'm using vite, react, typescript, and ts-jest.

My test file :

import { render, screen } from "@testing-library/react";
import "@testing-library/jest-dom";
import jsonMovies from "@/__mocks__/json/movies.json";
import MovieCarousel from "./MovieCarousel";
import { Provider } from "react-redux";
import { store } from "@/state/store";

jest.mock("@/fetchers/movies", () => ({
  fetchMovies: jest.fn(() => Promise.resolve(jsonMovies)),
}));

describe("MovieCarousel", () => {
  it("should render", () => {
    render(
      <Provider store={store}>
        <MovieCarousel />
      </Provider>
    );
    const welcomeMessage = screen.getByText(/Welcome to TV App!/i);
    expect(welcomeMessage).toBeDefined();
  });
});

My file where I'm getting the error :

import { Card } from "../ui/card";
import {
  Carousel,
  CarouselContent,
  CarouselItem,
  CarouselNext,
  CarouselPrevious,
} from "../ui/carousel";
import Autoplay from "embla-carousel-autoplay";
import useMovie from "@/hooks/useMovie";
import { useMemo } from "react";
import useWatchlist from "@/hooks/useWatchlist";
import LikeWatchlistIcon from "../LikeWatchlist/LikeWatchlistIcon";


export default function MovieCarousel() {
  const { movie } = useMovie();
  const { watchlist, toggleWatchlist } = useWatchlist();

  const topFiveMovies = useMemo(
    () => movie.data.results.slice(0, 3),
    [movie.data]
  );

  return (
    <Card className="m-4 p-8">
      <Carousel
        className="overflow-hidden"
        plugins={[
          Autoplay({
            delay: 3000,
            waitForUser: false,
          }),
        ]}
        opts={{
          loop: true,
        }}
      >
        <CarouselContent>
          {topFiveMovies.length ? (
            topFiveMovies.map((movie, index) => (
              <CarouselItem>
                <img
                  className="object-contain w-full h-96 rounded-lg"
                  src={`https://image.tmdb.org/t/p/original${movie.poster_path}`}
                />
                <p className="text-lg font-semibold mt-2">
                  [#{index + 1}] {movie.title}
                </p>
                <p className="text-sm text-gray-400">
                  {movie.overview.slice(0, 100)}...
                </p>
                <LikeWatchlistIcon
                  isLike={!!watchlist.data.find((m) => m.id === movie.id)}
                  toggleWatchlist={() => toggleWatchlist(movie)}
                />
              </CarouselItem>
            ))
          ) : (
            <p>Loading...</p>
          )}
        </CarouselContent>
        <CarouselPrevious />
        <CarouselNext />
      </Carousel>
    </Card>
  );
}

louispelarrey avatar Feb 22 '24 10:02 louispelarrey

I'm having a similar issue after upgrading to React 18 from 17. I used to use this fix https://stackoverflow.com/questions/39830580/jest-test-fails-typeerror-window-matchmedia-is-not-a-function/53449595#53449595 but now I get the error TypeError: i.disconnect is not a function Jest

Object.defineProperty(window, "matchMedia", {
    writable: true,
    value: jest.fn().mockImplementation((query) => ({
      matches: false,
      media: query,
      onchange: null,
      addListener: jest.fn(), // Deprecated
      removeListener: jest.fn(), // Deprecated
      addEventListener: jest.fn(),
      removeEventListener: jest.fn(),
      dispatchEvent: jest.fn(),
    })),
  });

MWhiteFearless avatar Feb 23 '24 19:02 MWhiteFearless

how can i get 2 images per slide for mobile

VesperQuartz avatar Mar 15 '24 01:03 VesperQuartz

@louispelarrey and @MWhiteFearless you need to mock the following API:s to solve the problem:

  • IntersectionObserver
  • matchMedia
  • resizeObserver

Maybe that's the culprit? Feel free to grab the mocks that the core library embla-carousel is using.

Best, David

davidjerleke avatar Apr 11 '24 07:04 davidjerleke

This issue has been automatically closed because it received no activity for a while. If you think it was closed by accident, please leave a comment. Thank you.

shadcn avatar Jun 10 '24 23:06 shadcn