mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-01-25 20:46:48 +00:00
jquery-ujs automatically disable submit button when submitting the form. If one choose cancel on the leaving page warning, then the submit buttons end up in a disable state, with no way to re enable them. This fix prevent the warning from being triggered when submitting the form, so we can't end up in the scenario described.
233 lines
6.7 KiB
JavaScript
233 lines
6.7 KiB
JavaScript
/**
|
|
* @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 = `
|
|
<form
|
|
id="test-form"
|
|
data-controller="unsaved-changes"
|
|
data-action="unsaved-changes#submit beforeunload@window->unsaved-changes#leavingPage turbolinks:before-visit@window->unsaved-changes#leavingPage"
|
|
data-unsaved-changes-changed="false"
|
|
>
|
|
<input id="test-checkbox" type="checkbox" data-action="change->unsaved-changes#formIsChanged"/>
|
|
<input id="test-submit" type="submit"/>
|
|
</form>
|
|
`
|
|
})
|
|
|
|
describe("#connect", () => {
|
|
describe("when disable-submit-button is true", () => {
|
|
beforeEach(() => {
|
|
document.body.innerHTML = `
|
|
<form
|
|
id="test-form"
|
|
data-controller="unsaved-changes"
|
|
data-action="unsaved-changes#submit beforeunload@window->unsaved-changes#leavingPage turbolinks:before-visit@window->unsaved-changes#leavingPage"
|
|
data-unsaved-changes-changed="false"
|
|
data-unsaved-changes-disable-submit-button="true"
|
|
>
|
|
<input id="test-checkbox" type="checkbox" data-action="change->unsaved-changes#formIsChanged"/>
|
|
<input id="test-submit" type="submit"/>
|
|
</form>
|
|
`
|
|
})
|
|
|
|
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 = `
|
|
<form
|
|
id="test-form"
|
|
data-controller="unsaved-changes"
|
|
data-action="unsaved-changes#submit beforeunload@window->unsaved-changes#leavingPage turbolinks:before-visit@window->unsaved-changes#leavingPage"
|
|
data-unsaved-changes-changed="false"
|
|
data-unsaved-changes-disable-submit-button="false"
|
|
>
|
|
<input id="test-checkbox" type="checkbox" data-action="change->unsaved-changes#formIsChanged"/>
|
|
<input id="test-submit" type="submit"/>
|
|
</form>
|
|
`
|
|
})
|
|
|
|
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('#submit', () => {
|
|
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")
|
|
})
|
|
})
|
|
})
|
|
})
|