import { config, shallowMount, VueWrapper } from "@vue/test-utils"; import CommentTree from "@/components/Comment/CommentTree.vue"; import { createMockClient, MockApolloClient, RequestHandler, } from "mock-apollo-client"; import { COMMENTS_THREADS_WITH_REPLIES, CREATE_COMMENT_FROM_EVENT, } from "@/graphql/comment"; import { CommentModeration } from "@/types/enums"; import { IEvent } from "@/types/event.model"; import { eventCommentThreadsMock, eventNoCommentThreadsMock, newCommentForEventMock, newCommentForEventResponse, } from "../../mocks/event"; import flushPromises from "flush-promises"; import { defaultResolvers } from "../../common"; import { afterEach, describe, vi, it, expect, beforeEach } from "vitest"; import { DefaultApolloClient } from "@vue/apollo-composable"; import Oruga from "@oruga-ui/oruga-next"; import { notifierPlugin } from "@/plugins/notifier"; import { InMemoryCache } from "@apollo/client/cache"; import { createRouter, createWebHistory, Router } from "vue-router"; import { routes } from "@/router"; import { dialogPlugin } from "@/plugins/dialog"; config.global.plugins.push(Oruga); config.global.plugins.push(notifierPlugin); config.global.plugins.push(dialogPlugin); let router: Router; const eventData = { id: "1", uuid: "e37910ea-fd5a-4756-7634-00971f3f4107", options: { commentModeration: CommentModeration.ALLOW_ALL, }, }; describe("CommentTree", () => { let wrapper: VueWrapper; let mockClient: MockApolloClient | null; let requestHandlers: Record; const generateWrapper = (handlers = {}, extraProps = {}) => { const cache = new InMemoryCache({ addTypename: true }); mockClient = createMockClient({ cache, resolvers: defaultResolvers, }); requestHandlers = { eventCommentThreadsQueryHandler: vi .fn() .mockResolvedValue(eventCommentThreadsMock), createCommentForEventMutationHandler: vi .fn() .mockResolvedValue(newCommentForEventResponse), ...handlers, }; mockClient.setRequestHandler( COMMENTS_THREADS_WITH_REPLIES, requestHandlers.eventCommentThreadsQueryHandler ); mockClient.setRequestHandler( CREATE_COMMENT_FROM_EVENT, requestHandlers.createCommentForEventMutationHandler ); wrapper = shallowMount(CommentTree, { props: { event: { ...eventData }, ...extraProps, }, global: { provide: { [DefaultApolloClient]: mockClient, }, plugins: [router], }, }); }; beforeEach(async () => { router = createRouter({ history: createWebHistory(), routes: routes, }); // await router.isReady(); }); afterEach(() => { mockClient = null; requestHandlers = {}; wrapper.unmount(); }); it("renders a loading comment tree", async () => { generateWrapper(); expect(wrapper.find("p.text-center").text()).toBe("Loading comments…"); expect(wrapper.html()).toMatchSnapshot(); }); it("renders a comment tree with comments", async () => { generateWrapper(); expect(wrapper.exists()).toBe(true); expect( requestHandlers.eventCommentThreadsQueryHandler ).toHaveBeenCalledWith({ eventUUID: eventData.uuid }); await flushPromises(); expect(wrapper.find("p.text-center").exists()).toBe(false); expect(wrapper.findAllComponents("comment-stub").length).toBe(2); expect(wrapper.html()).toMatchSnapshot(); }); it("renders the form if we can comment", async () => { generateWrapper( {}, { newComment: { text: newCommentForEventMock.text, isAnnouncement: false, }, } ); await flushPromises(); expect(wrapper.find("form").isVisible()).toBe(true); expect(wrapper.findAllComponents("comment-stub").length).toBe(2); wrapper.getComponent({ ref: "commenteditor" }); wrapper.find("form").trigger("submit"); await flushPromises(); expect( requestHandlers.createCommentForEventMutationHandler ).toHaveBeenCalledWith({ ...newCommentForEventMock, }); if (mockClient) { const cachedData = mockClient.cache.readQuery<{ event: IEvent }>({ query: COMMENTS_THREADS_WITH_REPLIES, variables: { eventUUID: eventData.uuid, }, }); if (cachedData) { const { event } = cachedData; expect(event.comments).toHaveLength(3); } } }); it("renders an empty comment tree", async () => { generateWrapper({ eventCommentThreadsQueryHandler: vi .fn() .mockResolvedValue(eventNoCommentThreadsMock), }); await flushPromises(); expect( requestHandlers.eventCommentThreadsQueryHandler ).toHaveBeenCalledWith({ eventUUID: eventData.uuid }); expect(wrapper.findComponent({ name: "EmptyContent" }).exists()); expect(wrapper.html()).toMatchSnapshot(); }); });