From 0ec9b29993943eb034849f285113d6ee37982e04 Mon Sep 17 00:00:00 2001 From: 4gray <4gray@users.noreply.github.com> Date: Fri, 15 May 2026 23:10:35 +0200 Subject: [PATCH] fix(playlist): preserve auto-refresh on manual refresh (#947) * fix(playlist): preserve auto-refresh on manual refresh * test(playlist): cover disabled auto-refresh preservation --- .../lib/reducers/playlist.reducers.spec.ts | 68 +++++++++++++++++++ .../src/lib/reducers/playlist.reducers.ts | 7 +- .../src/lib/playlists.service.spec.ts | 43 ++++++++++++ libs/services/src/lib/playlists.service.ts | 3 + 4 files changed, 119 insertions(+), 2 deletions(-) diff --git a/libs/m3u-state/src/lib/reducers/playlist.reducers.spec.ts b/libs/m3u-state/src/lib/reducers/playlist.reducers.spec.ts index 9b1341292..89b9e61a0 100644 --- a/libs/m3u-state/src/lib/reducers/playlist.reducers.spec.ts +++ b/libs/m3u-state/src/lib/reducers/playlist.reducers.spec.ts @@ -130,4 +130,72 @@ describe('playlistReducers', () => { nextState.playlists.entities['playlist-1']?.hiddenGroupTitles ).toEqual(['Radio-de']); }); + + it('keeps autoRefresh enabled on playlist refresh when the parser payload defaults it to false', () => { + const existingPlaylist: PlaylistMeta = { + _id: 'playlist-1', + autoRefresh: true, + count: 1, + importDate: '2026-03-28T00:00:00.000Z', + title: 'Playlist One', + } as PlaylistMeta; + const state = { + ...initialState, + playlists: playlistsAdapter.addOne(existingPlaylist, { + ...initialState.playlists, + selectedId: 'playlist-1', + }), + }; + + const nextState = reducer( + state, + PlaylistActions.updatePlaylist({ + playlist: { + autoRefresh: false, + playlist: { + items: [], + }, + } as Playlist, + playlistId: 'playlist-1', + }) + ); + + expect( + nextState.playlists.entities['playlist-1']?.autoRefresh + ).toBe(true); + }); + + it('keeps autoRefresh disabled on playlist refresh when the existing playlist has it disabled', () => { + const existingPlaylist: PlaylistMeta = { + _id: 'playlist-1', + autoRefresh: false, + count: 1, + importDate: '2026-03-28T00:00:00.000Z', + title: 'Playlist One', + } as PlaylistMeta; + const state = { + ...initialState, + playlists: playlistsAdapter.addOne(existingPlaylist, { + ...initialState.playlists, + selectedId: 'playlist-1', + }), + }; + + const nextState = reducer( + state, + PlaylistActions.updatePlaylist({ + playlist: { + autoRefresh: true, + playlist: { + items: [], + }, + } as Playlist, + playlistId: 'playlist-1', + }) + ); + + expect( + nextState.playlists.entities['playlist-1']?.autoRefresh + ).toBe(false); + }); }); diff --git a/libs/m3u-state/src/lib/reducers/playlist.reducers.ts b/libs/m3u-state/src/lib/reducers/playlist.reducers.ts index 9c694cc1a..1ed089d32 100644 --- a/libs/m3u-state/src/lib/reducers/playlist.reducers.ts +++ b/libs/m3u-state/src/lib/reducers/playlist.reducers.ts @@ -33,6 +33,7 @@ export const playlistReducers = [ on(PlaylistActions.updatePlaylist, (state, action): PlaylistState => { const isActivePlaylist = state.playlists.selectedId === action.playlistId; + const currentPlaylist = state.playlists.entities[action.playlistId]; return { ...state, channels: isActivePlaylist @@ -49,8 +50,10 @@ export const playlistReducers = [ count: action.playlist.playlist.items.length, userAgent: action.playlist.userAgent, favorites: - state.playlists.entities[action.playlistId] - ?.favorites ?? [], + currentPlaylist?.favorites ?? [], + autoRefresh: + currentPlaylist?.autoRefresh ?? + action.playlist.autoRefresh, }, }, state.playlists diff --git a/libs/services/src/lib/playlists.service.spec.ts b/libs/services/src/lib/playlists.service.spec.ts index 637f44e73..7ca08e8b8 100644 --- a/libs/services/src/lib/playlists.service.spec.ts +++ b/libs/services/src/lib/playlists.service.spec.ts @@ -411,4 +411,47 @@ describe('PlaylistsService', () => { }) ); }); + + it('keeps autoRefresh enabled when refreshing a playlist payload with the parser default disabled', async () => { + const existingPlaylist: Playlist = { + _id: 'playlist-3', + title: 'Playlist Three', + count: 1, + importDate: new Date('2026-04-12T00:00:00.000Z').toISOString(), + lastUsage: new Date('2026-04-12T00:00:00.000Z').toISOString(), + autoRefresh: true, + playlist: { + items: [{ id: 'channel-1' }], + }, + } as Playlist; + const dbService = { + getAll: jest.fn(() => of([])), + getByID: jest.fn(() => of(existingPlaylist)), + update: jest.fn((_storeName: string, playlist: Playlist) => + of(playlist) + ), + }; + testWindow.electron = undefined; + + const service = createService(dbService); + + await firstValueFrom( + service.updatePlaylist('playlist-3', { + _id: 'playlist-3', + autoRefresh: false, + playlist: { + items: [], + }, + } as Playlist) + ); + + expect(dbService.update).toHaveBeenCalledWith( + DbStores.Playlists, + expect.objectContaining({ + _id: 'playlist-3', + autoRefresh: true, + count: 0, + }) + ); + }); }); diff --git a/libs/services/src/lib/playlists.service.ts b/libs/services/src/lib/playlists.service.ts index c76acc1b2..29fb2685c 100644 --- a/libs/services/src/lib/playlists.service.ts +++ b/libs/services/src/lib/playlists.service.ts @@ -436,6 +436,9 @@ export class PlaylistsService { updateDate: Date.now(), updateState: PlaylistUpdateState.UPDATED, favorites: currentPlaylist.favorites, + autoRefresh: + currentPlaylist.autoRefresh ?? + updatedPlaylist.autoRefresh, }; if (this.isElectronStorageAvailable) {