/** * @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") }) }) }) })