diff --git a/src/components/organisms/FormNews.unit.js b/src/components/organisms/FormNews.unit.js deleted file mode 100644 index 0db1f5a00e..0000000000 --- a/src/components/organisms/FormNews.unit.js +++ /dev/null @@ -1,148 +0,0 @@ -import FormNews from "./FormNews"; -import { notifierModule } from "@/store"; -import { DATETIME_FORMAT } from "@/plugins/datetime"; -import dayjs from "dayjs"; -import setupStores from "@@/tests/test-utils/setupStores"; -import EnvConfigModule from "@/store/env-config"; -import NotifierModule from "@/store/notifier"; -import { I18N_KEY } from "@/utils/inject"; - -const testDate = dayjs("2022-07-05T09:00:00.000Z"); - -const date = testDate.format(DATETIME_FORMAT.inputDate); -const time = testDate.format(DATETIME_FORMAT.inputTime); - -const validNews = { - title: "Hi", - content: "lalaland", - displayAt: `${testDate.toISOString()}`, -}; - -const validNewsDate = { - date, - time, -}; - -const invalidNews = { - title: "", // no title - content: "", // and no content -}; - -const getMockActions = () => ({ - create: jest.fn().mockReturnValue(Promise.resolve()), - patch: jest.fn().mockReturnValue(Promise.resolve()), - remove: jest.fn().mockReturnValue(Promise.resolve()), -}); - -const getMocks = ({ - actions = getMockActions(), - $route = { - name: "news-id", - params: { - id: "randomId", - }, - query: {}, - }, -} = {}) => - createComponentMocks({ - $route, - i18n: true, - user: true, - stubs: { - BaseInput: true, - }, - store: { - news: { - actions, - getters: { - getStatus: () => "completed", - }, - }, - }, - }); - -describe("@/components/organisms/FormNews", () => { - beforeEach(() => { - setupStores({ - envConfigModule: EnvConfigModule, - notifierModule: NotifierModule, - }); - jest.clearAllMocks(); - }); - - it("converts date correctly", async () => { - const mocks = getMocks(); - const wrapper = mount(FormNews, { - ...mocks, - propsData: { - news: { ...validNews }, - }, - provide: { - [I18N_KEY.valueOf()]: { t: (key) => key }, - }, - }); - expect(wrapper.vm.data.date.date).toStrictEqual(validNewsDate.date); - expect(wrapper.vm.data.date.time).toStrictEqual(validNewsDate.time); - - expect(wrapper.vm.displayAt).toStrictEqual(validNews.displayAt); - }); - - describe("save", () => { - it("emits save event on form submit", async () => { - const actions = getMockActions(); - const mock = getMocks({ actions }); - const wrapper = mount(FormNews, { - ...mock, - propsData: { - news: { ...validNews }, - }, - provide: { - [I18N_KEY.valueOf()]: { t: (key) => key }, - }, - }); - wrapper.find("form").trigger("submit"); - await wrapper.vm.$nextTick(); - const events = wrapper.emitted(); - expect(events.save).toHaveLength(1); - const saveEventPayload = events.save[0][0]; - expect(saveEventPayload).toMatchObject(validNews); - }); - - it("shows validation error before submiting", async () => { - const notifierMock = jest.spyOn(notifierModule, "show"); - - const actions = getMockActions(); - const mock = getMocks({ actions }); - const wrapper = mount(FormNews, { - ...mock, - propsData: { - news: invalidNews, - }, - }); - - wrapper.find("form").trigger("submit"); - expect(notifierMock).toHaveBeenCalled(); - expect(notifierMock.mock.calls[0][0].status).toStrictEqual("error"); - expect(actions.create.mock.calls).toHaveLength(0); // and no dispatch happend - }); - }); - - describe.skip("remove", () => { - it("confirming remove dispatches the news/remove action", async () => { - const actions = getMockActions(); - const mock = getMocks({ actions }); - const wrapper = mount(FormNews, { - ...mock, - propsData: { - news: { ...validNews }, - }, - }); - - await wrapper.vm.remove(); - - expect(actions.create.mock.calls).toHaveLength(0); - expect(actions.patch.mock.calls).toHaveLength(0); - expect(actions.remove.mock.calls).toHaveLength(1); - }); - }); -}); diff --git a/src/components/organisms/FormNews.unit.ts b/src/components/organisms/FormNews.unit.ts new file mode 100644 index 0000000000..a6ac84232e --- /dev/null +++ b/src/components/organisms/FormNews.unit.ts @@ -0,0 +1,147 @@ +import Vue from "vue"; +import { MountOptions, mount, Wrapper } from "@vue/test-utils"; +import createComponentMocks from "@@/tests/test-utils/componentMocks"; +import FormNews from "./FormNews.vue"; +import { notifierModule } from "@/store"; +import EnvConfigModule from "@/store/env-config"; +import NotifierModule from "@/store/notifier"; +import { DATETIME_FORMAT } from "@/plugins/datetime"; +import dayjs from "dayjs"; +import setupStores from "@@/tests/test-utils/setupStores"; +import { I18N_KEY } from "@/utils/inject"; + +const testDate = dayjs("2022-07-05T09:00:00.000Z"); + +type News = { + title: string; + content: string; + displayAt?: string; +}; + +const testNews: News = { + title: "Hi", + content: "lalaland", + displayAt: `${testDate.toISOString()}`, +}; + +describe("FormNews", () => { + let wrapper: Wrapper; + + const setup = (news: News) => { + wrapper = mount(FormNews as MountOptions, { + ...createComponentMocks({ + $route: { + name: "news-id", + params: { + id: "randomId", + }, + query: {}, + }, + i18n: true, + user: true, + stubs: { + BaseInput: true, + }, + store: { + news: { + state: "", + mutations: {}, + actions: {}, + getters: { + getStatus: () => "completed", + }, + }, + }, + }), + propsData: { + news: news, + }, + provide: { + [I18N_KEY.valueOf()]: { t: (key: string) => key }, + }, + }); + }; + + beforeEach(() => { + setupStores({ + envConfigModule: EnvConfigModule, + notifierModule: NotifierModule, + }); + }); + + it("should render component", () => { + setup(testNews); + expect(wrapper.findComponent(FormNews).exists()).toBe(true); + }); + + it("passes date and time to input fields", async () => { + setup(testNews); + + const dateInput = wrapper.find('[data-testid="news_date"]'); + expect(dateInput.attributes("vmodel")).toStrictEqual( + testDate.format(DATETIME_FORMAT.inputDate) + ); + + const timeInput = wrapper.find('[data-testid="news_time"]'); + expect(timeInput.attributes("vmodel")).toStrictEqual( + testDate.format(DATETIME_FORMAT.inputTime) + ); + }); + + describe("save", () => { + it("emits save event on submit with correct payload", async () => { + setup({ ...testNews }); + + wrapper.find("form").trigger("submit"); + await wrapper.vm.$nextTick(); + + const emitted = wrapper.emitted(); + expect(emitted["save"]).toHaveLength(1); + + if (emitted["save"] === undefined) { + throw new Error("Emitted should be defined"); + } + + const saveEventPayload = emitted["save"][0][0]; + expect(saveEventPayload).toMatchObject(testNews); + }); + + it("shows validation error on empty title", async () => { + const notifierMock = jest.spyOn(notifierModule, "show"); + + setup({ ...testNews, title: "" }); + + wrapper.find("form").trigger("submit"); + expect(notifierMock).toHaveBeenCalled(); + expect(notifierMock.mock.calls[0][0].status).toStrictEqual("error"); + }); + + it("shows validation error on empty content", async () => { + const notifierMock = jest.spyOn(notifierModule, "show"); + + setup({ ...testNews, content: "" }); + + wrapper.find("form").trigger("submit"); + expect(notifierMock).toHaveBeenCalled(); + expect(notifierMock.mock.calls[0][0].status).toStrictEqual("error"); + }); + + it("does not emit save event on empty title", async () => { + setup({ ...testNews, title: "" }); + + wrapper.find("form").trigger("submit"); + + const emitted = wrapper.emitted(); + expect(emitted["save"]).toBeUndefined(); + }); + + it("does not emit save event on empty content", async () => { + setup({ ...testNews, content: "" }); + + wrapper.find("form").trigger("submit"); + + const emitted = wrapper.emitted(); + expect(emitted["save"]).toBeUndefined(); + }); + }); +});