e48d84cde1
Click on the For-You tile's play button now triggers a synchronous refresh, then enqueues + auto-plays the freshly-built playlist. Two-click-target tile pattern: tile BODY click still navigates to the playlist detail page (existing behavior); the play button is the new generate-and-play action. Behavior is gated on playlist.system_variant === 'for_you' — every other playlist (user, Discover, Songs-like-X) keeps the existing "fetch detail, enqueue, play" flow. The atomic-replace BuildSystem- Playlists creates a new playlist_id, so the play handler uses the refresh response's id for the follow-up getPlaylist call rather than the stale tile prop's id. Empty-library response (playlist_id: null) is a no-op — clicking play in a degenerate-empty library doesn't error, it just doesn't start playback. Caches are invalidated post-refresh so the home view re-fetches and the tile re-renders with the new id, avoiding the corner case of a click-then-tile-body 404. Tests cover the refresh-and-play happy path, the empty-library no-op, and that non-For-You playlists keep the existing flow. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
32 lines
1.1 KiB
TypeScript
32 lines
1.1 KiB
TypeScript
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
import { refreshForYou } from './playlists';
|
|
|
|
vi.mock('./client', () => ({
|
|
apiFetch: vi.fn()
|
|
}));
|
|
|
|
import { apiFetch } from './client';
|
|
|
|
describe('refreshForYou', () => {
|
|
beforeEach(() => vi.clearAllMocks());
|
|
|
|
it('POSTs the correct path and returns the response', async () => {
|
|
const sample = { playlist_id: 'pl-abc', track_count: 25, track_ids: ['t1', 't2'] };
|
|
(apiFetch as unknown as ReturnType<typeof vi.fn>).mockResolvedValueOnce(sample);
|
|
const got = await refreshForYou();
|
|
expect(apiFetch).toHaveBeenCalledWith(
|
|
'/api/playlists/system/for-you/refresh',
|
|
expect.objectContaining({ method: 'POST' })
|
|
);
|
|
expect(got).toEqual(sample);
|
|
});
|
|
|
|
it('handles empty-library response', async () => {
|
|
const sample = { playlist_id: null, track_count: 0, track_ids: [] };
|
|
(apiFetch as unknown as ReturnType<typeof vi.fn>).mockResolvedValueOnce(sample);
|
|
const got = await refreshForYou();
|
|
expect(got.playlist_id).toBe(null);
|
|
expect(got.track_ids).toEqual([]);
|
|
});
|
|
});
|