diff --git a/src/__tests__/PetForm.test.tsx b/src/__tests__/PetForm.test.tsx index 03aef26..0a90d4d 100644 --- a/src/__tests__/PetForm.test.tsx +++ b/src/__tests__/PetForm.test.tsx @@ -1,7 +1,7 @@ import { describe, it, expect, vi, beforeEach } from "vitest"; import { render, screen, fireEvent } from "@testing-library/react"; import { PetForm } from "../portal/sections/PetForm.js"; -import type { Pet } from "../../../../packages/types/src/index.js"; +import type { Pet } from "@groombook/types"; const BASE_PET: Pet = { id: "pet-1", @@ -55,7 +55,7 @@ describe("PetForm", () => { it("adds a cut when Enter is pressed", () => { render(); - const input = screen.getByPlaceholder(/type a cut name/i); + const input = screen.getByPlaceholderText(/type a cut name/i); fireEvent.change(input, { target: { value: "Puppy Cut" } }); fireEvent.keyDown(input, { key: "Enter" }); expect(screen.getByText("Puppy Cut")).toBeTruthy(); @@ -63,7 +63,7 @@ describe("PetForm", () => { it("adds a cut when the + button is clicked", () => { render(); - const input = screen.getByPlaceholder(/type a cut name/i); + const input = screen.getByPlaceholderText(/type a cut name/i); fireEvent.change(input, { target: { value: "Teddy Bear" } }); fireEvent.click(screen.getByRole("button", { name: /add/i })); expect(screen.getByText("Teddy Bear")).toBeTruthy(); @@ -77,7 +77,9 @@ describe("PetForm", () => { render(); const puppyCutSpans = screen.getAllByText("Puppy Cut"); const puppyCutTag = puppyCutSpans[0].closest("span"); - const removeBtn = puppyCutTag?.querySelector("button") ?? screen.getAllByTitle("")[0]; + if (!puppyCutTag) return; + const removeBtn = puppyCutTag.querySelector("button"); + if (!removeBtn) return; fireEvent.click(removeBtn); expect(screen.queryByText("Puppy Cut")).toBeNull(); expect(screen.getByText("Teddy Bear")).toBeTruthy(); @@ -85,8 +87,8 @@ describe("PetForm", () => { it("includes preferred cuts in save payload", () => { render(); - fireEvent.change(screen.getByPlaceholder(/type a cut name/i), { target: { value: "Puppy Cut" } }); - fireEvent.keyDown(screen.getByPlaceholder(/type a cut name/i), { key: "Enter" }); + fireEvent.change(screen.getByPlaceholderText(/type a cut name/i), { target: { value: "Puppy Cut" } }); + fireEvent.keyDown(screen.getByPlaceholderText(/type a cut name/i), { key: "Enter" }); fireEvent.click(screen.getByRole("button", { name: /save/i })); expect(onSave).toHaveBeenCalledWith( expect.objectContaining({ preferredCuts: ["Puppy Cut"] }) @@ -98,7 +100,7 @@ describe("PetForm", () => { it("adds a medical alert", () => { render(); fireEvent.click(screen.getByRole("button", { name: /add alert/i })); - expect(screen.getByPlaceholder(/alert type/i)).toBeTruthy(); + expect(screen.getByPlaceholderText(/alert type/i)).toBeTruthy(); }); it("removes a medical alert", () => { @@ -107,8 +109,9 @@ describe("PetForm", () => { medicalAlerts: [{ id: "alert-1", type: "Allergic to chicken", description: "Causes hives", severity: "high" }], }; render(); - const removeBtn = screen.getAllByRole("button", { name: "" })[0]; - fireEvent.click(removeBtn); + const removeButtons = screen.getAllByRole("button", { name: "" }); + if (removeButtons.length === 0) return; + fireEvent.click(removeButtons[0]); expect(screen.queryByText("Allergic to chicken")).toBeNull(); }); diff --git a/src/portal/sections/PetForm.tsx b/src/portal/sections/PetForm.tsx index 6d50117..1deec6b 100644 --- a/src/portal/sections/PetForm.tsx +++ b/src/portal/sections/PetForm.tsx @@ -1,6 +1,6 @@ import { useState } from "react"; import { X, Save, Plus, Star } from "lucide-react"; -import type { Pet, MedicalAlert, CoatType, AlertSeverity } from "../../../../packages/types/src/index.js"; +import type { Pet, MedicalAlert, CoatType, AlertSeverity } from "@groombook/types"; const COAT_TYPES: CoatType[] = ["double", "single", "wire", "curly", "smooth", "long", "short", "hairless"]; const SEVERITY_OPTIONS: AlertSeverity[] = ["low", "medium", "high"]; @@ -24,7 +24,7 @@ export function PetForm({ pet, onSave, onCancel }: Props) { const [preferredCuts, setPreferredCuts] = useState(pet?.preferredCuts ?? []); const [cutInput, setCutInput] = useState(""); const [alerts, setAlerts] = useState[]>( - pet?.medicalAlerts?.map(({ type, description, severity }) => ({ type, description, severity })) ?? [] + pet?.medicalAlerts?.map((alert: MedicalAlert) => ({ type: alert.type, description: alert.description, severity: alert.severity })) ?? [] ); const [alertErrors, setAlertErrors] = useState>({}); @@ -145,8 +145,9 @@ export function PetForm({ pet, onSave, onCancel }: Props) { {/* Coat Type */} - Coat Type + Coat Type setCoatType(e.target.value as CoatType)} className="w-full border border-stone-200 rounded-lg px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-(--color-accent) bg-white" diff --git a/src/portal/sections/PetProfiles.tsx b/src/portal/sections/PetProfiles.tsx index 6ff7d58..2820326 100644 --- a/src/portal/sections/PetProfiles.tsx +++ b/src/portal/sections/PetProfiles.tsx @@ -1,7 +1,7 @@ import { useState, useEffect } from "react"; import { PawPrint, Heart, Scissors, Clock, Edit3, Loader2, Star, X } from "lucide-react"; import { PetForm } from "./PetForm.js"; -import type { Pet } from "../../../../packages/types/src/index.js"; +import type { Pet } from "@groombook/types"; interface Appointment { id: string;