123import type { JSX } from "solid-js";4import { afterEach, describe, expect, it, vi } from "vitest";5import type { VaultEntry } from "../../shared/types";6import { renderView } from "../views/view-test-utils";7import { NoteRow } from "./NoteRow";89const note = {10 id: "note-1",11 type: "note",12 title: "Hybrid input",13 modifiedAt: Date.now(),14} as VaultEntry;1516function touchEvent(type: string, x: number, y: number): TouchEvent {17 const event = new Event(type, { bubbles: true, cancelable: true }) as TouchEvent;18 const touch = { clientX: x, clientY: y } as Touch;19 Object.defineProperties(event, {20 touches: { value: type === "touchend" ? [] : [touch] },21 changedTouches: { value: [touch] },22 });23 return event;24}2526describe("NoteRow input", () => {27 const cleanups: Array<() => void> = [];2829 afterEach(() => {30 while (cleanups.length) cleanups.pop()!();31 });3233 function mounted(props: { onTap: () => void; onArchive?: () => void }) {34 const view = renderView(() => (35 <NoteRow36 note={note}37 index={0}38 onTap={props.onTap}39 onDelete={() => {}}40 onArchive={props.onArchive ?? (() => {})}41 />42 ) as JSX.Element);43 cleanups.push(view.dispose);44 return view.container.querySelector(".peach-note-row") as HTMLDivElement;45 }4647 it("opens once when a touch tap produces its click", () => {48 const onTap = vi.fn();49 const row = mounted({ onTap });5051 row.dispatchEvent(touchEvent("touchstart", 20, 20));52 row.dispatchEvent(touchEvent("touchend", 20, 20));53 row.click();5455 expect(onTap).toHaveBeenCalledTimes(1);56 });5758 it("accepts a mouse click even when the browser supports touch", () => {59 const onTap = vi.fn();60 const row = mounted({ onTap });61 Object.defineProperty(window, "ontouchstart", { configurable: true, value: null });6263 row.click();6465 expect(onTap).toHaveBeenCalledTimes(1);66 });6768 it("does not open after a swipe click", () => {69 const onTap = vi.fn();70 const onArchive = vi.fn();71 const row = mounted({ onTap, onArchive });7273 row.dispatchEvent(touchEvent("touchstart", 10, 20));74 row.dispatchEvent(touchEvent("touchmove", 140, 20));75 row.dispatchEvent(touchEvent("touchmove", 140, 20));76 row.dispatchEvent(touchEvent("touchend", 140, 20));77 row.click();7879 expect(onArchive).toHaveBeenCalledTimes(1);80 expect(onTap).not.toHaveBeenCalled();81 });82});