diff --git a/client/src/components/songbook/PracticeLogger.jsx b/client/src/components/songbook/PracticeLogger.jsx index 3688bced8e..38b143b07c 100644 --- a/client/src/components/songbook/PracticeLogger.jsx +++ b/client/src/components/songbook/PracticeLogger.jsx @@ -59,17 +59,17 @@ export default function PracticeLogger({ song, onLogged, className = '' }) { -
+
{SONG_PRACTICE_RATINGS.map((rating) => ( ))}
diff --git a/client/src/components/songbook/PracticeLogger.test.jsx b/client/src/components/songbook/PracticeLogger.test.jsx index 02fe38b0fe..8d2c42525c 100644 --- a/client/src/components/songbook/PracticeLogger.test.jsx +++ b/client/src/components/songbook/PracticeLogger.test.jsx @@ -47,13 +47,21 @@ describe('PracticeLogger', () => { expect(screen.getByText(/1 session ·/)).toBeTruthy(); }); + it('renders each rating hint visibly for touch users, not hover-only', () => { + render(); + expect(screen.getByText('Fell apart — regress a stage and practice again today')).toBeTruthy(); + expect(screen.getByText('Got through it — hold the stage, review sooner')).toBeTruthy(); + expect(screen.getByText('Played it with hesitation — advance a stage')).toBeTruthy(); + expect(screen.getByText('Played it clean — advance a stage, review later')).toBeTruthy(); + }); + it('posts the grade and hands the updated record back — no client-side scheduling', async () => { const updated = { ...song(), stage: 'learned', practice: { nextReview: future(), sessions: 1 } }; practiceSong.mockResolvedValue(updated); const onLogged = vi.fn(); render(); - fireEvent.click(screen.getByRole('button', { name: 'Solid' })); + fireEvent.click(screen.getByRole('button', { name: /Solid/ })); await waitFor(() => expect(onLogged).toHaveBeenCalledWith(updated)); // The grade is the ONLY thing sent; the server owns stage + schedule. @@ -64,7 +72,7 @@ describe('PracticeLogger', () => { it('sends the low grade for a failed run', async () => { practiceSong.mockResolvedValue({ ...song(), stage: 'learning', practice: { nextReview: new Date().toISOString() } }); render(); - fireEvent.click(screen.getByRole('button', { name: 'Struggled' })); + fireEvent.click(screen.getByRole('button', { name: /Struggled/ })); await waitFor(() => expect(practiceSong).toHaveBeenCalledWith('song-1', 0, { silent: true })); }); @@ -73,7 +81,7 @@ describe('PracticeLogger', () => { const onLogged = vi.fn(); render(); - fireEvent.click(screen.getByRole('button', { name: 'Clean' })); + fireEvent.click(screen.getByRole('button', { name: /Clean/ })); await waitFor(() => expect(toast.error).toHaveBeenCalled()); expect(onLogged).not.toHaveBeenCalled();