layout improvements
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
/**
|
||||
* Tests for `shouldShowAudioMiniPlayer` visibility invariant.
|
||||
*
|
||||
* The mini player must NOT flicker out while advancing between tracks. The
|
||||
* backend can momentarily report an idle/stopped state mid-transition, so the
|
||||
* bar stays visible as long as a queue item still exists, and only hides once
|
||||
* playback has genuinely ended and the queue has been cleared.
|
||||
*
|
||||
* TRACES: UR-005 | DR-009
|
||||
*/
|
||||
|
||||
import { describe, it, expect, beforeEach, vi } from "vitest";
|
||||
import { writable } from "svelte/store";
|
||||
import { get } from "svelte/store";
|
||||
import type { MediaItem } from "$lib/api/types";
|
||||
|
||||
// Mock the dependency stores so we can drive remote mode and the current queue
|
||||
// item independently of the real backend listeners.
|
||||
const isRemoteMode = writable(false);
|
||||
const selectedSession = writable<any>(null);
|
||||
const currentQueueItem = writable<MediaItem | null>(null);
|
||||
|
||||
vi.mock("./playbackMode", () => ({ isRemoteMode }));
|
||||
vi.mock("./sessions", () => ({ selectedSession }));
|
||||
vi.mock("./queue", () => ({ currentQueueItem }));
|
||||
|
||||
// Imported after the mocks so player.ts picks up the mocked stores.
|
||||
const { player, shouldShowAudioMiniPlayer } = await import("./player");
|
||||
|
||||
const audioItem = { id: "a1", type: "Audio" } as unknown as MediaItem;
|
||||
const videoItem = { id: "v1", type: "Movie" } as unknown as MediaItem;
|
||||
|
||||
describe("shouldShowAudioMiniPlayer", () => {
|
||||
beforeEach(() => {
|
||||
isRemoteMode.set(false);
|
||||
selectedSession.set(null);
|
||||
currentQueueItem.set(null);
|
||||
player.setIdle();
|
||||
});
|
||||
|
||||
it("shows while an audio track is playing", () => {
|
||||
player.setPlaying(audioItem, 0, 100);
|
||||
expect(get(shouldShowAudioMiniPlayer)).toBe(true);
|
||||
});
|
||||
|
||||
it("stays visible through a transient idle blip while still queued", () => {
|
||||
// A track is queued (e.g. mid-transition the backend emits idle but the
|
||||
// next track is already in the queue).
|
||||
currentQueueItem.set(audioItem);
|
||||
player.setIdle();
|
||||
expect(get(shouldShowAudioMiniPlayer)).toBe(true);
|
||||
});
|
||||
|
||||
it("stays visible through loading/seeking transitions", () => {
|
||||
currentQueueItem.set(audioItem);
|
||||
player.setLoading(audioItem);
|
||||
expect(get(shouldShowAudioMiniPlayer)).toBe(true);
|
||||
player.setSeeking(audioItem, 10);
|
||||
expect(get(shouldShowAudioMiniPlayer)).toBe(true);
|
||||
});
|
||||
|
||||
it("hides once playback ends and the queue is cleared", () => {
|
||||
currentQueueItem.set(null);
|
||||
player.setIdle();
|
||||
expect(get(shouldShowAudioMiniPlayer)).toBe(false);
|
||||
});
|
||||
|
||||
it("hides for video content even while playing", () => {
|
||||
player.setPlaying(videoItem, 0, 100);
|
||||
expect(get(shouldShowAudioMiniPlayer)).toBe(false);
|
||||
});
|
||||
|
||||
it("hides for video content reported only via the queue item", () => {
|
||||
currentQueueItem.set(videoItem);
|
||||
player.setIdle();
|
||||
expect(get(shouldShowAudioMiniPlayer)).toBe(false);
|
||||
});
|
||||
|
||||
it("shows in remote mode when the session has a now-playing item", () => {
|
||||
isRemoteMode.set(true);
|
||||
selectedSession.set({ nowPlayingItem: { id: "r1" } });
|
||||
expect(get(shouldShowAudioMiniPlayer)).toBe(true);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user