|
1 | 1 | import Pattern, { parser } from "./validation";
|
2 |
| -import utils from "../../core/utils"; |
3 | 2 | import events from "../../core/events";
|
| 3 | +import utils from "../../core/utils"; |
| 4 | +import { jest } from "@jest/globals"; |
4 | 5 |
|
5 | 6 | describe("pat-validation", function () {
|
6 | 7 | let orig_delay;
|
@@ -287,6 +288,153 @@ describe("pat-validation", function () {
|
287 | 288 | expect(el.querySelectorAll("em.warning").length).toBe(0);
|
288 | 289 | });
|
289 | 290 |
|
| 291 | + it("1.13 - Prevents other event handlers when invalid.", async function () { |
| 292 | + document.body.innerHTML = ` |
| 293 | + <form class="pat-validation"> |
| 294 | + <input name="ok" required /> |
| 295 | + <button>submit</button> |
| 296 | + </form> |
| 297 | + `; |
| 298 | + const el = document.querySelector(".pat-validation"); |
| 299 | + |
| 300 | + new Pattern(el); |
| 301 | + |
| 302 | + let submit_called = false; |
| 303 | + let click_called = false; |
| 304 | + |
| 305 | + // Note: the handlers must be registered after Pattern initialization. |
| 306 | + // Otherwise the pattern will not be able to prevent the event. |
| 307 | + // In case of other patterns, the validation pattern will be reordered |
| 308 | + // first and submit prevention does work. |
| 309 | + el.addEventListener("submit", () => (submit_called = true)); |
| 310 | + el.addEventListener("click", () => (click_called = true)); |
| 311 | + |
| 312 | + el.querySelector("button").click(); |
| 313 | + await utils.timeout(1); // wait a tick for async to settle. |
| 314 | + |
| 315 | + expect(el.querySelectorAll("em.warning").length).toBe(1); |
| 316 | + expect(submit_called).toBe(false); |
| 317 | + expect(click_called).toBe(true); |
| 318 | + }); |
| 319 | + |
| 320 | + it("1.14 - Prevents pat-inject form submission when invalid.", async function () { |
| 321 | + const pat_inject = (await import("../inject/inject")).default; |
| 322 | + const registry = (await import("../../core/registry")).default; |
| 323 | + |
| 324 | + document.body.innerHTML = ` |
| 325 | + <form action="." class="pat-inject pat-validation"> |
| 326 | + <input name="ok" required /> |
| 327 | + <button>submit</button> |
| 328 | + </form> |
| 329 | + `; |
| 330 | + const el = document.querySelector(".pat-validation"); |
| 331 | + |
| 332 | + const spy_inject_submit = jest.spyOn(pat_inject, "onTrigger"); |
| 333 | + |
| 334 | + registry.scan(document.body); |
| 335 | + await utils.timeout(1); // wait a tick for async to settle. |
| 336 | + |
| 337 | + el.querySelector("button").click(); |
| 338 | + await utils.timeout(1); // wait a tick for async to settle. |
| 339 | + |
| 340 | + expect(el.querySelectorAll("em.warning").length).toBe(1); |
| 341 | + expect(spy_inject_submit).not.toHaveBeenCalled(); |
| 342 | + }); |
| 343 | + |
| 344 | + it("1.15 - Prevents pat-modal closing with a pat-inject when invalid.", async function () { |
| 345 | + await import("../close-panel/close-panel"); |
| 346 | + const pat_inject = (await import("../inject/inject")).default; |
| 347 | + const pat_modal = (await import("../modal/modal")).default; |
| 348 | + const registry = (await import("../../core/registry")).default; |
| 349 | + |
| 350 | + document.body.innerHTML = ` |
| 351 | + <div class="pat-modal"> |
| 352 | + <form action="." class="pat-inject pat-validation"> |
| 353 | + <input name="ok" required /> |
| 354 | + <button class="close-panel">submit</button> |
| 355 | + </form> |
| 356 | + </div> |
| 357 | + `; |
| 358 | + const el = document.querySelector("form"); |
| 359 | + |
| 360 | + const spy_inject_submit = jest.spyOn(pat_inject, "onTrigger"); |
| 361 | + const spy_destroy_modal = jest.spyOn(pat_modal.prototype, "destroy"); |
| 362 | + |
| 363 | + registry.scan(document.body); |
| 364 | + await utils.timeout(1); // wait a tick for async to settle. |
| 365 | + |
| 366 | + el.querySelector("button").click(); |
| 367 | + await utils.timeout(1); // wait a tick for async to settle. |
| 368 | + |
| 369 | + expect(el.querySelectorAll("em.warning").length).toBe(1); |
| 370 | + expect(spy_inject_submit).not.toHaveBeenCalled(); |
| 371 | + expect(spy_destroy_modal).not.toHaveBeenCalled(); |
| 372 | + }); |
| 373 | + |
| 374 | + it("1.16 - Prevents pat-modal closing when invalid.", async function () { |
| 375 | + await import("../close-panel/close-panel"); |
| 376 | + const pat_modal = (await import("../modal/modal")).default; |
| 377 | + const registry = (await import("../../core/registry")).default; |
| 378 | + |
| 379 | + document.body.innerHTML = ` |
| 380 | + <div class="pat-modal"> |
| 381 | + <form action="." class="pat-validation"> |
| 382 | + <input name="ok" required /> |
| 383 | + <button class="close-panel">submit</button> |
| 384 | + </form> |
| 385 | + </div> |
| 386 | + `; |
| 387 | + const el = document.querySelector("form"); |
| 388 | + |
| 389 | + const spy_destroy_modal = jest.spyOn(pat_modal.prototype, "destroy"); |
| 390 | + |
| 391 | + registry.scan(document.body); |
| 392 | + await utils.timeout(1); // wait a tick for async to settle. |
| 393 | + |
| 394 | + el.querySelector("button").click(); |
| 395 | + await utils.timeout(1); // wait a tick for async to settle. |
| 396 | + |
| 397 | + expect(el.querySelectorAll("em.warning").length).toBe(1); |
| 398 | + expect(spy_destroy_modal).not.toHaveBeenCalled(); |
| 399 | + }); |
| 400 | + |
| 401 | + it("1.17 - Prevents pat-modal closing when invalid with custom validation rule.", async function () { |
| 402 | + await import("../close-panel/close-panel"); |
| 403 | + const pat_modal = (await import("../modal/modal")).default; |
| 404 | + const registry = (await import("../../core/registry")).default; |
| 405 | + |
| 406 | + const spy_destroy_modal = jest.spyOn(pat_modal.prototype, "destroy"); |
| 407 | + |
| 408 | + document.body.innerHTML = ` |
| 409 | + <div class="pat-modal"> |
| 410 | + <form action="." class="pat-validation"> |
| 411 | + <input name="ok" /> |
| 412 | + <input name="nok" data-pat-validation="equality: ok" /> |
| 413 | + <button class="close-panel submit">submit</button> |
| 414 | + <button class="close-panel cancel" type="button">cancel</button> |
| 415 | + </form> |
| 416 | + </div> |
| 417 | + `; |
| 418 | + const el = document.querySelector("form"); |
| 419 | + const inp_ok = document.querySelector("input[name=ok]"); |
| 420 | + inp_ok.value = "foo"; |
| 421 | + |
| 422 | + registry.scan(document.body); |
| 423 | + await utils.timeout(1); // wait a tick for async to settle. |
| 424 | + |
| 425 | + el.querySelector("button.submit").click(); |
| 426 | + await utils.timeout(1); // wait a tick for async to settle. |
| 427 | + |
| 428 | + expect(el.querySelectorAll("em.warning").length).toBe(1); |
| 429 | + expect(spy_destroy_modal).not.toHaveBeenCalled(); |
| 430 | + |
| 431 | + // A non-submit close-panel button does not check for validity. |
| 432 | + el.querySelector("button.cancel").click(); |
| 433 | + await utils.timeout(1); // wait a tick for async to settle. |
| 434 | + |
| 435 | + expect(spy_destroy_modal).toHaveBeenCalled(); |
| 436 | + }); |
| 437 | + |
290 | 438 | it("2.1 - validates required inputs", async function () {
|
291 | 439 | document.body.innerHTML = `
|
292 | 440 | <form class="pat-validation">
|
|
0 commit comments