0

I have a Nuxt composable that fetches data from Contentful using the contentful client's getEntries function. It's working on the frontend of my website but when I run my tests i'm getting:

TypeError: Cannot read properties of undefined (reading 'getEntries')

So i'm gathering this means the test is saying my Contentful client from useNuxtApp() is undefined. Do I need to mock/spy on this? I have tried but I keep getting the same error

/composables/contentful-service.js

export const fetchEntriesByContentType = async ({
  contentType,
  title,
  variant,
  slug,
  tag
}) => {
    const nuxtApp = useNuxtApp()
    const { $contentfulClient } = nuxtApp

      return Promise.all([
        $contentfulClient.getEntries({
          content_type: contentType,
          "fields.title": title,
          "fields.slug": slug,
          "metadata.tags.sys.id[in]": tag,
          "fields.variant": variant,
          include: 10
        })
      ]).then(([entries]) => {
          return  entries.items
        })
        .catch(console.error);
}

index.nuxt.spec.js

import index from "./index.vue";
import * as ContentfulService from "../../../composables/contentful-service";
import { pageData } from "../assets/data/test-data";
import { mountSuspended, mockNuxtImport } from "@nuxt/test-utils/runtime";

const mockNavLinks = [
  {
    fields: {
      url: "/testUrl1",
      text: "testUrlText1",
    },
  },
  {
    fields: {
      url: "/testUrl2",
      text: "testUrlText2",
    },
  },
  {
    fields: {
      url: "/testUrl3",
      text: "testUrlText3",
    },
  },
];

describe("index page", () => {
  beforeEach(() => {
    vi.stubGlobal("useNuxtApp", () => ({
      $contentfulClient: { getEntries: vi.fn()}
    }));

     vi.spyOn(ContentfulService, "fetchEntriesByContentType")
      .mockResolvedValueOnce([pageData])
      .mockResolvedValueOnce([
        {
          fields: {
            title: "Navbar",
            navLinks: mockNavLinks,
          },
        },
      ]);
  });
  afterEach(() => {
    vi.clearAllMocks();
  });

  it("should render the correct header data from contentful", async () => {
    const wrapper = await mountSuspended(index);

    mockNuxtImport('useRoute', () => () => ({
      path: `pages/${pageData.fields.slug}`
    }));

    await wrapper.vm.getPageData()

    const htmlContent = wrapper.html();

    expect(wrapper.findAll(".nav-link").length).toBe(3);

    mockNavLinks.forEach((link) => {
      expect(htmlContent).toContain(link.fields.url);
    });

    expect(htmlContent).toContain(pageData.fields.title);
  });
});

the functions are being called in my index page here:

<template>
  <div>
    <Subpage
      :navLinks="navLinks"
      :childPage="true"
    />
  </div>
</template>

<script setup>
import { fetchEntriesByContentType } from "../../../composables/contentful-service";
import Subpage from "../../../components/header/Subpage.vue";

const pageData = ref({})
const navLinks = ref({})

async function getPageData () { 
  try {
    const route = useRoute()
    const path = route.path;
    const slug = path.split("/")[path.split("/").length - 1];

    const [page] = await fetchEntriesByContentType({
      contentType: "page",
      slug,
    });

    const [navbar] = await fetchEntriesByContentType({
      contentType: "navbar",
      title: "Navbar"
    });
    if (!page || !navbar) {
      throw `Error-Fetching page data - ${slug}`;
    } else {
      pageData.value = page?.fields;
      navLinks.value = navbar;
    }
  } catch (error) {
    if (process.env.ROLLBAR_ENABLED === true) {
      Vue.rollbar.error(error);
    }
    throw new Error(error);
  }
}

onMounted(() => {
  getPageData().then(console.log).catch(console.error);
})

</script>

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.