mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-16 06:06:18 -08:00
fix(xtream): preserve favorites across catalog refreshes
This commit is contained in:
1 parent
ec4b9286a7
commit
8ccfcb68cc
121 files changed
+4000
-398
No files matched your search
@@ -77,6 +77,7 @@ describe('XtreamRefreshFlowService', () => {
|
||||
let confirmPromise: Promise<void> | undefined;
|
||||
let order: string[];
|
||||
let databaseService: {
|
||||
restoreXtreamFavoriteSnapshots: jest.Mock;
|
||||
createOperationId: jest.Mock;
|
||||
deleteXtreamPlaylistContent: jest.Mock;
|
||||
updateXtreamPlaylistDetails: jest.Mock;
|
||||
@@ -94,6 +95,10 @@ describe('XtreamRefreshFlowService', () => {
|
||||
order = [];
|
||||
|
||||
databaseService = {
|
||||
restoreXtreamFavoriteSnapshots: jest.fn(() => {
|
||||
order.push('save-favorites');
|
||||
return Promise.resolve();
|
||||
}),
|
||||
createOperationId: jest.fn((prefix: string) => `${prefix}-op`),
|
||||
deleteXtreamPlaylistContent: jest.fn(() => {
|
||||
order.push('delete');
|
||||
@@ -154,6 +159,53 @@ describe('XtreamRefreshFlowService', () => {
|
||||
localStorage.clear();
|
||||
});
|
||||
|
||||
it('converts legacy pending favorites before deleting or replacing the old catalog', async () => {
|
||||
localStorage.setItem(
|
||||
'xtream-restore-playlist-1',
|
||||
JSON.stringify({
|
||||
favorites: [{ contentType: 'movie', xtreamId: 7 }],
|
||||
hiddenCategories: [],
|
||||
recentlyViewed: [],
|
||||
playbackPositions: [],
|
||||
})
|
||||
);
|
||||
service.confirmAndRefresh(
|
||||
createPlaylistMeta(),
|
||||
createReporter().reporter
|
||||
);
|
||||
await confirmPromise;
|
||||
expect(
|
||||
databaseService.restoreXtreamFavoriteSnapshots
|
||||
).toHaveBeenCalledWith(
|
||||
'playlist-1',
|
||||
[{ contentType: 'movie', xtreamId: 7 }],
|
||||
undefined
|
||||
);
|
||||
expect(order.indexOf('save-favorites')).toBeLessThan(
|
||||
order.indexOf('delete')
|
||||
);
|
||||
});
|
||||
|
||||
it('preserves legacy pending state and the catalog when durable conversion fails', async () => {
|
||||
const pending = JSON.stringify({
|
||||
favorites: [{ contentType: 'movie', xtreamId: 7 }],
|
||||
});
|
||||
localStorage.setItem('xtream-restore-playlist-1', pending);
|
||||
databaseService.restoreXtreamFavoriteSnapshots.mockRejectedValue(
|
||||
new Error('SQLite unavailable')
|
||||
);
|
||||
jest.spyOn(console, 'error').mockImplementation(() => undefined);
|
||||
service.confirmAndRefresh(
|
||||
createPlaylistMeta(),
|
||||
createReporter().reporter
|
||||
);
|
||||
await confirmPromise;
|
||||
expect(
|
||||
databaseService.deleteXtreamPlaylistContent
|
||||
).not.toHaveBeenCalled();
|
||||
expect(localStorage.getItem('xtream-restore-playlist-1')).toBe(pending);
|
||||
});
|
||||
|
||||
it('ignores a confirmation that arrives while the playlist is already busy', async () => {
|
||||
const { reporter, calls } = createReporter({ isBusy: () => true });
|
||||
|
||||
|
||||
@@ -152,6 +152,17 @@ export class XtreamRefreshFlowService {
|
||||
);
|
||||
await reporter.waitForVisibleProgress?.();
|
||||
|
||||
// Migrate an older parked favorite list before replacing its state.
|
||||
// A durable receipt prevents replay after an explicit user removal.
|
||||
const pending = this.pendingRestoreService.getOrThrow(item._id);
|
||||
if (pending) {
|
||||
await this.databaseService.restoreXtreamFavoriteSnapshots(
|
||||
item._id,
|
||||
pending.favorites,
|
||||
pending.favoritesRestoreId
|
||||
);
|
||||
}
|
||||
|
||||
// Delete content/categories and update the timestamp in parallel —
|
||||
// all three operations are fully independent.
|
||||
const updateDate = Date.now();
|
||||
|
||||
Reference in new issue
Block a user