/** * @jest-environment jsdom */ import { Application } from "stimulus"; import unsaved_changes_controller from "../../../app/webpacker/controllers/unsaved_changes_controller"; describe("UnsavedChangesController", () => { beforeAll(() => { const application = Application.start(); application.register("unsaved-changes", unsaved_changes_controller); }); beforeEach(() => { document.body.innerHTML = `
`; }); describe("#connect", () => { describe("when disable-submit-button is true", () => { beforeEach(() => { document.body.innerHTML = `
`; }); it("disables any submit button", () => { const submit = document.getElementById("test-submit"); expect(submit.disabled).toBe(true); }); }); describe("when disable-submit-button is false", () => { beforeEach(() => { document.body.innerHTML = `
`; }); it("doesn't disable any submit button", () => { const submit = document.getElementById("test-submit"); expect(submit.disabled).toBe(false); }); }); describe("when disable-submit-button is not set", () => { it("doesn't disable any submit button", () => { const submit = document.getElementById("test-submit"); expect(submit.disabled).toBe(false); }); }); }); describe("#formIsChanged", () => { let checkbox; let submit; beforeEach(() => { checkbox = document.getElementById("test-checkbox"); submit = document.getElementById("test-submit"); }); it("changed is set to true", () => { const form = document.getElementById("test-form"); checkbox.click(); expect(form.dataset.unsavedChangesChanged).toBe("true"); }); describe("when disable-submit-button is true", () => { it("enables any submit button", () => { checkbox.click(); expect(submit.disabled).toBe(false); }); }); describe("when disable-submit-button is false", () => { it("does nothing", () => { expect(submit.disabled).toBe(false); checkbox.click(); expect(submit.disabled).toBe(false); }); }); }); describe("#leavingPage", () => { let checkbox; beforeEach(() => { // Add a mock I18n object to const mockedT = jest.fn(); mockedT.mockImplementation((string) => string); global.I18n = { t: mockedT, }; checkbox = document.getElementById("test-checkbox"); }); afterEach(() => { delete global.I18n; }); describe("when triggering a beforeunload event", () => { it("triggers leave page pop up when leaving page and form has been interacted with", () => { // interact with the form checkbox.click(); // trigger beforeunload to simulate leaving the page const beforeunloadEvent = new Event("beforeunload"); window.dispatchEvent(beforeunloadEvent); // Test the event returnValue has been set, we don't really care about the value as // the brower will ignore it expect(beforeunloadEvent.returnValue).toBeTruthy(); }); }); describe("when triggering a turbolinks:before-visit event", () => { let confirmSpy; beforeEach(() => { confirmSpy = jest.spyOn(window, "confirm"); }); afterEach(() => { // cleanup confirmSpy.mockRestore(); }); it("triggers a confirm popup up when leaving page and form has been interacted with", () => { confirmSpy.mockImplementation((msg) => {}); // interact with the form checkbox.click(); // trigger turbolinks:before-visit to simulate leaving the page const turbolinkEv = new Event("turbolinks:before-visit"); window.dispatchEvent(turbolinkEv); expect(confirmSpy).toHaveBeenCalled(); }); it("stays on the page if user clicks cancel on the confirm popup", () => { // return false to simulate a user clicking on cancel confirmSpy.mockImplementation((msg) => false); // interact with the form checkbox.click(); // trigger turbolinks:before-visit to simulate leaving the page const turbolinkEv = new Event("turbolinks:before-visit"); const preventDefaultSpy = jest.spyOn(turbolinkEv, "preventDefault"); window.dispatchEvent(turbolinkEv); expect(confirmSpy).toHaveBeenCalled(); expect(preventDefaultSpy).toHaveBeenCalled(); }); }); }); describe("#handleSubmit", () => { let checkbox; beforeEach(() => { // Add a mock I18n object to const mockedT = jest.fn(); mockedT.mockImplementation((string) => string); global.I18n = { t: mockedT, }; checkbox = document.getElementById("test-checkbox"); }); afterEach(() => { delete global.I18n; }); describe("when submiting the form", () => { it("changed is set to true", () => { const form = document.getElementById("test-form"); // interact with the form checkbox.click(); // submit the form const submitEvent = new Event("submit"); form.dispatchEvent(submitEvent); expect(form.dataset.unsavedChangesChanged).toBe("false"); }); }); }); });