| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422 |
- import {
- ActionStateSetRemote,
- ActionTypeLocal,
- ActionTypeRemote,
- activeClientToggled,
- masterSet,
- playPaused,
- queueOrdered,
- queuePushed,
- queueRemoved,
- queueShifted,
- seeked,
- songInfoFetched,
- stateSet,
- } from '../actions';
- import { globalReducer, GlobalState, initialState } from '../reducer';
- import { Song } from '../types';
- import { MusicPlayer } from '../types/state';
- import { globalEffects } from './effects';
- describe(globalEffects.name, () => {
- describe(ActionTypeLocal.StateSet, () => {
- const state: GlobalState = {
- ...initialState,
- myClientName: 'my-client-name',
- };
- it('should create a remote state set action', () => {
- expect.assertions(1);
- const localPlayer: MusicPlayer = {
- songId: 123,
- playing: false,
- currentTime: 83,
- seekTime: 87,
- master: 'my-client-name',
- activeClients: [],
- queue: [],
- shuffleMode: false,
- };
- const action = stateSet(localPlayer);
- const result = globalEffects(globalReducer(state, action), action);
- expect(result).toStrictEqual<ActionStateSetRemote>({
- type: ActionTypeRemote.StateSet,
- payload: { ...localPlayer, seekTime: 83 },
- });
- });
- });
- describe(ActionTypeLocal.Seeked, () => {
- const stateMaster: GlobalState = {
- ...initialState,
- player: {
- songId: 123,
- playing: false,
- currentTime: 83,
- seekTime: 87,
- master: 'my-client-name',
- activeClients: [],
- queue: [],
- shuffleMode: false,
- },
- myClientName: 'my-client-name',
- };
- const stateSlave: GlobalState = {
- ...initialState,
- player: { ...initialState.player, master: 'some-master-client' },
- myClientName: 'some-slave-client',
- };
- const action = seeked(776);
- describe.each`
- clientType | state
- ${'master'} | ${stateMaster}
- ${'a slave'} | ${stateSlave}
- `('when the client is $clientType', ({ state }) => {
- it('should create a remote state set action', () => {
- expect.assertions(1);
- const result = globalEffects(state, action);
- expect(result).toStrictEqual<ActionStateSetRemote>({
- type: ActionTypeRemote.StateSet,
- payload: { ...state.player, seekTime: 776 },
- });
- });
- });
- });
- describe(ActionTypeLocal.MasterSet, () => {
- const stateMasterWentAway: GlobalState = {
- ...initialState,
- clientList: [{ name: 'my-client-name', lastPing: 0 }],
- player: {
- songId: 123,
- playing: true,
- currentTime: 83,
- seekTime: 5,
- master: 'some-master-went-away',
- activeClients: [],
- queue: [],
- shuffleMode: false,
- },
- myClientName: 'my-client-name',
- };
- const action = masterSet();
- it('should return a StateSet action informing other clients that we are the new master', () => {
- expect.assertions(1);
- const result = globalEffects(stateMasterWentAway, action);
- expect(result).toStrictEqual<ActionStateSetRemote>({
- type: ActionTypeRemote.StateSet,
- payload: {
- songId: 123,
- playing: false,
- currentTime: 83,
- seekTime: -1,
- master: 'my-client-name',
- activeClients: [],
- queue: [],
- shuffleMode: false,
- },
- });
- });
- describe('when the action specified a particular client', () => {
- it('should return a StateSet action informing the new client to resume playback', () => {
- expect.assertions(1);
- const result = globalEffects(stateMasterWentAway, masterSet('other-client'));
- expect(result).toStrictEqual<ActionStateSetRemote>({
- type: ActionTypeRemote.StateSet,
- payload: {
- songId: 123,
- playing: true,
- currentTime: 83,
- seekTime: 83,
- master: 'other-client',
- activeClients: [],
- queue: [],
- shuffleMode: false,
- },
- });
- });
- });
- });
- describe(ActionTypeLocal.ActiveClientToggled, () => {
- const action = activeClientToggled('some-client');
- describe('when the given client is active', () => {
- const stateWithGivenClientActive: GlobalState = {
- ...initialState,
- player: {
- ...initialState.player,
- activeClients: ['some-client', 'other-client'],
- },
- };
- it('should remove the given client from the active clients list', () => {
- expect.assertions(1);
- const result = globalEffects(stateWithGivenClientActive, action);
- expect(result).toStrictEqual<ActionStateSetRemote>({
- type: ActionTypeRemote.StateSet,
- payload: expect.objectContaining({
- activeClients: ['other-client'],
- }),
- });
- });
- });
- describe('when the given client is not active', () => {
- const stateWithGivenClientInactive: GlobalState = {
- ...initialState,
- player: {
- ...initialState.player,
- activeClients: ['other-client'],
- },
- };
- it('should add the given client to the active clients list', () => {
- expect.assertions(1);
- const result = globalEffects(stateWithGivenClientInactive, action);
- expect(result).toStrictEqual<ActionStateSetRemote>({
- type: ActionTypeRemote.StateSet,
- payload: expect.objectContaining({
- activeClients: expect.arrayContaining(['some-client', 'other-client']),
- }),
- });
- });
- });
- });
- describe(ActionTypeLocal.PlayPaused, () => {
- const action = playPaused();
- describe.each`
- currentClient | myClientName
- ${'master'} | ${'some-master-client'}
- ${'a slave'} | ${'my client'}
- `('when the current client is $currentClient', ({ myClientName }) => {
- const statePrior: GlobalState = {
- ...initialState,
- player: {
- songId: 123,
- playing: true,
- currentTime: 83,
- seekTime: 5,
- master: 'some-master-client',
- activeClients: [],
- queue: [],
- shuffleMode: false,
- },
- myClientName,
- };
- it('should return a StateSet action informing other clients of the updated playing state', () => {
- expect.assertions(1);
- const result = globalEffects(statePrior, action);
- expect(result).toStrictEqual<ActionStateSetRemote>({
- type: ActionTypeRemote.StateSet,
- payload: {
- songId: 123,
- playing: false,
- currentTime: 83,
- seekTime: 5,
- master: 'some-master-client',
- activeClients: [],
- queue: [],
- shuffleMode: false,
- },
- });
- });
- });
- });
- describe(ActionTypeLocal.SongInfoFetched, () => {
- const statePriorMaster: GlobalState = {
- ...initialState,
- player: {
- songId: 123,
- playing: true,
- currentTime: 83,
- seekTime: 5,
- master: 'some-master-client',
- activeClients: [],
- queue: [],
- shuffleMode: false,
- },
- myClientName: 'some-master-client',
- };
- const action = songInfoFetched({ id: 185 } as Song, true);
- describe('when the client is master', () => {
- it('should return null', () => {
- expect.assertions(1);
- expect(globalEffects(statePriorMaster, action)).toBeNull();
- });
- });
- describe('when the client is a slave', () => {
- const stateSlave: GlobalState = {
- ...statePriorMaster,
- myClientName: 'some-slave-client',
- };
- it('should return a StateSet action informing other clients of the changed song', () => {
- expect.assertions(1);
- const result = globalEffects(stateSlave, action);
- expect(result).toStrictEqual<ActionStateSetRemote>({
- type: ActionTypeRemote.StateSet,
- payload: {
- songId: 185,
- playing: true,
- currentTime: 0,
- seekTime: 0,
- master: 'some-master-client',
- activeClients: [],
- queue: [],
- shuffleMode: false,
- },
- });
- });
- describe('when the action is not set to replace the current song', () => {
- const actionNoReplace = songInfoFetched({ id: 185 } as Song, false);
- it('should return null', () => {
- expect.assertions(1);
- const result = globalEffects(stateSlave, actionNoReplace);
- expect(result).toBeNull();
- });
- });
- });
- });
- describe(ActionTypeLocal.QueuePushed, () => {
- const action = queuePushed([184, 79]);
- it('should add to the end of the queue', () => {
- expect.assertions(1);
- const result = globalEffects(
- {
- ...initialState,
- player: { ...initialState.player, master: 'some-master', queue: [23] },
- },
- action,
- );
- expect(result).toStrictEqual<ActionStateSetRemote>({
- type: ActionTypeRemote.StateSet,
- payload: {
- ...initialState.player,
- master: 'some-master',
- queue: [23, 184, 79],
- },
- });
- });
- describe('when the songs are already in the queue', () => {
- it('should not modify the queue', () => {
- expect.assertions(1);
- const result = globalEffects(
- {
- ...initialState,
- player: { ...initialState.player, queue: [184, 23, 79] },
- },
- action,
- );
- expect(result).toBeNull();
- });
- });
- });
- describe(ActionTypeLocal.QueueShifted, () => {
- const action = queueShifted();
- const stateWithQueue: GlobalState = {
- ...initialState,
- player: { ...initialState.player, master: 'some-master', queue: [8843, 23] },
- };
- it('should play the first song on the queue and remove it from the queue', () => {
- expect.assertions(1);
- const result = globalEffects(stateWithQueue, action);
- expect(result).toStrictEqual<ActionStateSetRemote>({
- type: ActionTypeRemote.StateSet,
- payload: {
- ...initialState.player,
- master: 'some-master',
- playing: true,
- songId: 8843,
- currentTime: 0,
- seekTime: 0,
- queue: [23],
- },
- });
- });
- });
- describe(ActionTypeLocal.QueueRemoved, () => {
- const action = queueRemoved(84);
- it('should remove the given song ID from the queue', () => {
- expect.assertions(1);
- const result = globalEffects(
- {
- ...initialState,
- player: { ...initialState.player, master: 'some-master', queue: [17, 84, 23] },
- },
- action,
- );
- expect(result).toStrictEqual<ActionStateSetRemote>({
- type: ActionTypeRemote.StateSet,
- payload: {
- ...initialState.player,
- master: 'some-master',
- queue: [17, 23],
- },
- });
- });
- });
- describe(ActionTypeLocal.QueueOrdered, () => {
- it.each`
- direction | delta | expectedResult
- ${'forwards'} | ${1} | ${[17, 23, 84]}
- ${'backwards'} | ${-1} | ${[84, 17, 23]}
- `('should reorder ($direction) the given song ID', ({ delta, expectedResult }) => {
- const action = queueOrdered(84, delta);
- expect.assertions(1);
- const result = globalEffects(
- {
- ...initialState,
- player: { ...initialState.player, master: 'some-master', queue: [17, 84, 23] },
- },
- action,
- );
- expect(result).toStrictEqual<ActionStateSetRemote>({
- type: ActionTypeRemote.StateSet,
- payload: {
- ...initialState.player,
- master: 'some-master',
- queue: expectedResult,
- },
- });
- });
- });
- });
|