learn and share notes on atproto (wip) 🦉 malfestio.stormlightlabs.org/
readability solid axum atproto srs
at main 120 lines 4.0 kB view raw
1import type { ReviewCard } from "$lib/model"; 2import { cleanup, fireEvent, render, screen } from "@solidjs/testing-library"; 3import { afterEach, describe, expect, it, vi } from "vitest"; 4import { StudySession } from "../StudySession"; 5 6vi.mock( 7 "$lib/api", 8 () => ({ api: { submitReview: vi.fn().mockResolvedValue({ ok: true, json: () => Promise.resolve({}) }) } }), 9); 10 11const mockCards: ReviewCard[] = [{ 12 review_id: "review-1", 13 card_id: "card-1", 14 deck_id: "deck-1", 15 deck_title: "Test Deck", 16 front: "What is 2+2?", 17 back: "4", 18 media_url: undefined, 19 hints: [], 20 due_at: new Date().toISOString(), 21}, { 22 review_id: "review-2", 23 card_id: "card-2", 24 deck_id: "deck-1", 25 deck_title: "Test Deck", 26 front: "What is the capital of France?", 27 back: "Paris", 28 media_url: undefined, 29 hints: ["It's a famous city"], 30 due_at: new Date().toISOString(), 31}]; 32 33describe("StudySession", () => { 34 afterEach(cleanup); 35 36 it("renders card front initially", () => { 37 const onComplete = vi.fn(); 38 const onExit = vi.fn(); 39 40 render(() => <StudySession cards={mockCards} onComplete={onComplete} onExit={onExit} />); 41 42 expect(screen.getByText("What is 2+2?")).toBeInTheDocument(); 43 expect(screen.getByText("Press Space or click to reveal")).toBeInTheDocument(); 44 }); 45 46 it("shows progress indicator", () => { 47 const onComplete = vi.fn(); 48 const onExit = vi.fn(); 49 50 render(() => <StudySession cards={mockCards} onComplete={onComplete} onExit={onExit} />); 51 52 expect(screen.getByText(/Card 1 of 2/i)).toBeInTheDocument(); 53 }); 54 55 it("flips card on click", async () => { 56 const onComplete = vi.fn(); 57 const onExit = vi.fn(); 58 59 render(() => <StudySession cards={mockCards} onComplete={onComplete} onExit={onExit} />); 60 61 expect(screen.getByText("What is 2+2?")).toBeInTheDocument(); 62 63 const cardElement = screen.getByText("What is 2+2?").closest("div[class*='cursor-pointer']"); 64 if (cardElement) { 65 fireEvent.click(cardElement); 66 } 67 68 expect(await screen.findByText("How well did you know this?")).toBeInTheDocument(); 69 }); 70 71 it("flips back to front on second click", async () => { 72 const onComplete = vi.fn(); 73 const onExit = vi.fn(); 74 75 render(() => <StudySession cards={mockCards} onComplete={onComplete} onExit={onExit} />); 76 77 const cardElement = screen.getByText("What is 2+2?").closest("div[class*='cursor-pointer']"); 78 if (cardElement) fireEvent.click(cardElement); 79 80 expect(await screen.findByText("How well did you know this?")).toBeInTheDocument(); 81 82 if (cardElement) fireEvent.click(cardElement); 83 expect(await screen.findByText("Press Space or click to reveal")).toBeInTheDocument(); 84 expect(screen.queryByText("How well did you know this?")).not.toBeInTheDocument(); 85 }); 86 87 it("shows keyboard hints conditionally", async () => { 88 const onComplete = vi.fn(); 89 const onExit = vi.fn(); 90 91 render(() => <StudySession cards={mockCards} onComplete={onComplete} onExit={onExit} />); 92 93 expect(screen.getByText("Space: Flip")).toBeInTheDocument(); 94 expect(screen.getByText("Esc: Exit")).toBeInTheDocument(); 95 96 // Initially hidden 97 expect(screen.queryByText("1-6: Grade")).not.toBeInTheDocument(); 98 expect(screen.queryByText("E: Edit")).not.toBeInTheDocument(); 99 100 // Flip card 101 const cardElement = screen.getByText("What is 2+2?").closest("div[class*='cursor-pointer']"); 102 if (cardElement) fireEvent.click(cardElement); 103 104 // Now visible 105 expect(await screen.findByText("1-6: Grade")).toBeInTheDocument(); 106 expect(screen.getByText("E: Edit")).toBeInTheDocument(); 107 }); 108 109 it("calls onExit when exit button is clicked", () => { 110 const onComplete = vi.fn(); 111 const onExit = vi.fn(); 112 113 render(() => <StudySession cards={mockCards} onComplete={onComplete} onExit={onExit} />); 114 115 const exitButton = screen.getByRole("button", { name: /✕ Exit/i }); 116 fireEvent.click(exitButton); 117 118 expect(onExit).toHaveBeenCalled(); 119 }); 120});