Ctrl K
ComunidadGuías…

src/renderer/store/player-queue-actions.test.ts

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
import { afterEach, describe, expect, it, vi } from 'vitest';

import {
    applyAddToQueueLast,
    applyAddToQueueNext,
    applyAddToQueueNow,
    applyAddToQueueShuffle,
    applyShuffleQueue,
    applyUnshuffleQueue,
    type PlayerQueueMutationState,
    registerQueueSongs,
} from './player-queue-actions';

import { QueueSong } from '/@/shared/types/domain-types';
import { PlayerShuffle } from '/@/shared/types/types';

vi.mock('/@/renderer/utils/shuffle', () => ({
    shuffleInPlace: <T>(items: T[]) => {
        const next = [...items];
        next.reverse();
        return next;
    },
}));

const song = (id: string): QueueSong =>
    ({
        _uniqueId: `uid-${id}`,
        id,
        name: id,
    }) as QueueSong;

const emptyState = (): PlayerQueueMutationState => ({
    player: { index: 0, shuffle: PlayerShuffle.NONE },
    queue: { default: [], songs: {}, unshuffled: null },
});

describe('registerQueueSongs + applyAddToQueueLast', () => {
    it('appends track ids to the queue', () => {
        const state = emptyState();
        const items = [song('a'), song('b')];
        const ids = registerQueueSongs(state, items);
        applyAddToQueueLast(state, ids);
        expect(state.queue.default).toEqual(['uid-a', 'uid-b']);
        expect(Object.keys(state.queue.songs)).toHaveLength(2);
    });

    it('shuffles the appended tracks into a shuffled queue', () => {
        const state = emptyState();
        state.player.shuffle = PlayerShuffle.TRACK;
        state.queue.default = ['uid-existing'];
        const ids = registerQueueSongs(state, [song('n'), song('o')]);
        applyAddToQueueLast(state, ids);
        expect(state.queue.default).toEqual(['uid-existing', 'uid-o', 'uid-n']);
    });
});

describe('applyAddToQueueNext', () => {
    it('inserts after the current index', () => {
        const state = emptyState();
        state.queue.default = ['uid-a', 'uid-b'];
        state.player.index = 0;
        registerQueueSongs(state, [song('x')]);
        applyAddToQueueNext(state, ['uid-x']);
        expect(state.queue.default).toEqual(['uid-a', 'uid-x', 'uid-b']);
    });

    it('inserts after the current index of a shuffled queue too', () => {
        const state = emptyState();
        state.player.shuffle = PlayerShuffle.TRACK;
        state.queue.default = ['uid-a', 'uid-b'];
        state.player.index = 0;
        registerQueueSongs(state, [song('x'), song('y')]);
        applyAddToQueueNext(state, ['uid-x', 'uid-y']);
        expect(state.queue.default).toEqual(['uid-a', 'uid-y', 'uid-x', 'uid-b']);
    });
});

describe('applyAddToQueueNow', () => {
    it('replaces the queue in source order when shuffle is off', () => {
        const state = emptyState();
        registerQueueSongs(state, [song('a'), song('b'), song('c')]);
        applyAddToQueueNow(state, ['uid-a', 'uid-b', 'uid-c'], 'uid-b');
        expect(state.queue.default).toEqual(['uid-a', 'uid-b', 'uid-c']);
        expect(state.queue.unshuffled).toBeNull();
        expect(state.player.index).toBe(0);
    });

    it('shuffles the queue with the clicked track first when shuffle is on', () => {
        const state = emptyState();
        state.player.shuffle = PlayerShuffle.TRACK;
        registerQueueSongs(state, [song('a'), song('b'), song('c')]);
        applyAddToQueueNow(state, ['uid-a', 'uid-b', 'uid-c'], 'uid-b');
        expect(state.queue.default).toEqual(['uid-b', 'uid-c', 'uid-a']);
        expect(state.queue.unshuffled).toEqual(['uid-a', 'uid-b', 'uid-c']);
        expect(state.player.index).toBe(0);
    });
});

describe('applyAddToQueueShuffle', () => {
    it('replaces the queue with the shuffled order', () => {
        const state = emptyState();
        registerQueueSongs(state, [song('a'), song('b')]);
        applyAddToQueueShuffle(state, ['uid-b', 'uid-a'], ['uid-a', 'uid-b']);
        expect(state.queue.default).toEqual(['uid-b', 'uid-a']);
        expect(state.queue.unshuffled).toBeNull();
    });

    it('remembers the source order when shuffle is on so it can be restored', () => {
        const state = emptyState();
        state.player.shuffle = PlayerShuffle.TRACK;
        registerQueueSongs(state, [song('a'), song('b')]);
        applyAddToQueueShuffle(state, ['uid-b', 'uid-a'], ['uid-a', 'uid-b']);
        expect(state.queue.default).toEqual(['uid-b', 'uid-a']);
        expect(state.queue.unshuffled).toEqual(['uid-a', 'uid-b']);
    });
});

describe('applyShuffleQueue / applyUnshuffleQueue', () => {
    const queued = (ids: string[], index: number): PlayerQueueMutationState => ({
        player: { index, shuffle: PlayerShuffle.TRACK },
        queue: { default: [...ids], songs: {}, unshuffled: null },
    });

    it('reorders the queue itself and keeps the playing track playing', () => {
        const state = queued(['a', 'b', 'c', 'd'], 2);

        applyShuffleQueue(state);

        expect(state.queue.default[0]).toBe('c');
        expect(state.player.index).toBe(0);
        expect([...state.queue.default].sort()).toEqual(['a', 'b', 'c', 'd']);
        expect(state.queue.unshuffled).toEqual(['a', 'b', 'c', 'd']);
    });

    it('puts the queue back and follows the playing track when shuffle goes off', () => {
        const state = queued(['a', 'b', 'c', 'd'], 2);

        applyShuffleQueue(state);
        applyUnshuffleQueue(state);

        expect(state.queue.default).toEqual(['a', 'b', 'c', 'd']);
        expect(state.player.index).toBe(2);
        expect(state.queue.unshuffled).toBeNull();
    });

    it('keeps the original order as the restore point when re-shuffling', () => {
        const state = queued(['a', 'b', 'c', 'd'], 0);

        applyShuffleQueue(state);
        applyShuffleQueue(state, { keepRestorePoint: true });
        applyUnshuffleQueue(state);

        expect(state.queue.default).toEqual(['a', 'b', 'c', 'd']);
    });

    it('restores an order that tracks were added to and removed from while shuffled', () => {
        const state = queued(['a', 'b', 'c'], 0);

        applyShuffleQueue(state);
        state.queue.default = state.queue.default.filter((id) => id !== 'b');
        state.queue.default.push('x');
        state.player.index = 0;

        applyUnshuffleQueue(state);

        expect(state.queue.default).toEqual(['a', 'c', 'x']);
    });

    it('leaves an empty queue alone', () => {
        const state = queued([], -1);

        applyShuffleQueue(state);

        expect(state.queue.default).toEqual([]);
        expect(state.queue.unshuffled).toBeNull();
        expect(state.player.index).toBe(-1);
    });
});

afterEach(() => {
    vi.clearAllMocks();
});