mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-15 05:36:17 -08:00
test(downloads): cover Stalker adapter reactivity
This commit is contained in:
1 parent
2500b9015b
commit
e6cc9e5ff9
1 file changed
+90
-85
+90
-85
@@ -99,6 +99,11 @@ describe('StalkerSeriesViewComponent', () => {
|
||||
macAddress: '00:1A:79:12:34:56',
|
||||
});
|
||||
|
||||
async function stabilize(): Promise<void> {
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
}
|
||||
|
||||
beforeEach(async () => {
|
||||
selectedContentType.set('series');
|
||||
selectedItem.set({
|
||||
@@ -285,8 +290,7 @@ describe('StalkerSeriesViewComponent', () => {
|
||||
});
|
||||
|
||||
it('renders quick start for regular series and starts the first episode', async () => {
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
await stabilize();
|
||||
fixture.detectChanges();
|
||||
|
||||
const quickStartButton: HTMLButtonElement | null =
|
||||
@@ -322,8 +326,7 @@ describe('StalkerSeriesViewComponent', () => {
|
||||
it('keeps provider episodes playable while hiding download presentation', async () => {
|
||||
fixture.componentRef.setInput('providerOnly', true);
|
||||
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
await stabilize();
|
||||
|
||||
const seasonContainer = fixture.debugElement.query(
|
||||
By.directive(StubSeasonContainerComponent)
|
||||
@@ -347,21 +350,16 @@ describe('StalkerSeriesViewComponent', () => {
|
||||
id: '50001',
|
||||
is_series: true,
|
||||
category_id: '18',
|
||||
info: {
|
||||
name: 'Signal House',
|
||||
description: 'Parent series plot',
|
||||
movie_image:
|
||||
'https://images.example.test/posters/signal-house.jpg',
|
||||
},
|
||||
info: { name: 'Signal House' },
|
||||
});
|
||||
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
await stabilize();
|
||||
|
||||
const seasonContainer = fixture.debugElement.query(
|
||||
By.directive(StubSeasonContainerComponent)
|
||||
).componentInstance as StubSeasonContainerComponent;
|
||||
const candidate = seasonContainer.downloadAdapter()?.createCandidate(
|
||||
const initialAdapter = seasonContainer.downloadAdapter();
|
||||
const candidate = initialAdapter?.createCandidate(
|
||||
{
|
||||
id: '61001',
|
||||
episode_num: 3,
|
||||
@@ -387,24 +385,60 @@ describe('StalkerSeriesViewComponent', () => {
|
||||
expect(request).toEqual(
|
||||
expect.objectContaining({
|
||||
playlistId: 'stalker-1',
|
||||
playlistType: 'stalker',
|
||||
seriesXtreamId: 50001,
|
||||
xtreamId: 61001,
|
||||
seasonNumber: 2,
|
||||
episodeNumber: 3,
|
||||
title: 'Signal House - S02E03 - The Call',
|
||||
url: 'https://cdn.example.test/episode.mpg',
|
||||
playlistName: 'Living Room Portal',
|
||||
})
|
||||
);
|
||||
|
||||
currentPlaylist.set({
|
||||
_id: 'stalker-2',
|
||||
title: 'Bedroom Portal',
|
||||
portalUrl: 'https://bedroom.example.test',
|
||||
macAddress: '00:1A:79:65:43:21',
|
||||
});
|
||||
selectedItem.set({
|
||||
id: '40002:season-slice',
|
||||
category_id: '22',
|
||||
info: { name: 'Second Signal' },
|
||||
});
|
||||
await stabilize();
|
||||
|
||||
const updatedAdapter = seasonContainer.downloadAdapter();
|
||||
expect(updatedAdapter).not.toBe(initialAdapter);
|
||||
const updatedCandidate = updatedAdapter?.createCandidate(
|
||||
{
|
||||
id: '62001',
|
||||
episode_num: 1,
|
||||
title: 'Pilot',
|
||||
custom_sid: 'regular-series',
|
||||
season: 4,
|
||||
originalCmd: '/media/file_888.mpg',
|
||||
} as never,
|
||||
'4'
|
||||
);
|
||||
if (!updatedCandidate) {
|
||||
throw new Error('expected a refreshed Stalker download adapter');
|
||||
}
|
||||
const updatedRequest = await updatedCandidate.prepare();
|
||||
|
||||
expect(fetchLinkToPlay).toHaveBeenLastCalledWith(
|
||||
'https://bedroom.example.test',
|
||||
'00:1A:79:65:43:21',
|
||||
'/media/file_888.mpg',
|
||||
1
|
||||
);
|
||||
expect(updatedRequest).toEqual(
|
||||
expect.objectContaining({
|
||||
playlistId: 'stalker-2',
|
||||
seriesXtreamId: 40002,
|
||||
xtreamId: 62001,
|
||||
title: 'Second Signal - S04E01 - Pilot',
|
||||
portalUrl: 'https://bedroom.example.test',
|
||||
macAddress: '00:1A:79:65:43:21',
|
||||
metadataSnapshot: expect.objectContaining({
|
||||
language: 'en',
|
||||
mediaKind: 'series',
|
||||
title: 'Signal House',
|
||||
plot: 'Parent series plot',
|
||||
providerCategoryId: '18',
|
||||
episode: expect.objectContaining({
|
||||
seasonNumber: 2,
|
||||
episodeNumber: 3,
|
||||
}),
|
||||
title: 'Second Signal',
|
||||
providerCategoryId: '22',
|
||||
}),
|
||||
})
|
||||
);
|
||||
@@ -424,8 +458,7 @@ describe('StalkerSeriesViewComponent', () => {
|
||||
serialSeasonsResource.set([]);
|
||||
vodSeriesSeasonsResource.set([]);
|
||||
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
await stabilize();
|
||||
fixture.componentInstance.vodSeriesSeasons.set([
|
||||
{
|
||||
id: 'season-1',
|
||||
@@ -505,8 +538,7 @@ describe('StalkerSeriesViewComponent', () => {
|
||||
},
|
||||
]);
|
||||
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
await stabilize();
|
||||
fixture.detectChanges();
|
||||
|
||||
const quickStartButton: HTMLButtonElement | null =
|
||||
@@ -577,8 +609,7 @@ describe('StalkerSeriesViewComponent', () => {
|
||||
},
|
||||
]);
|
||||
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
await stabilize();
|
||||
|
||||
fixture.componentInstance.vodSeriesSeasons.set([
|
||||
{
|
||||
@@ -677,8 +708,7 @@ describe('StalkerSeriesViewComponent', () => {
|
||||
]);
|
||||
isEmbeddedPlayer.mockReturnValue(true);
|
||||
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
await stabilize();
|
||||
|
||||
fixture.componentInstance.vodSeriesSeasons.set([
|
||||
{
|
||||
@@ -820,8 +850,7 @@ describe('StalkerSeriesViewComponent', () => {
|
||||
]);
|
||||
isEmbeddedPlayer.mockReturnValue(true);
|
||||
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
await stabilize();
|
||||
|
||||
// Season 1 loaded, season 2 still empty — the state a user is in
|
||||
// right after opening the series and starting the first episode.
|
||||
@@ -855,8 +884,7 @@ describe('StalkerSeriesViewComponent', () => {
|
||||
const firstEpisode = fixture.componentInstance.mappedSeasons()['1'][0];
|
||||
fixture.componentInstance.onEpisodeClicked(firstEpisode);
|
||||
await fixture.whenStable();
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
await stabilize();
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(fetchVodSeriesEpisodes).toHaveBeenCalledWith(
|
||||
@@ -904,8 +932,7 @@ describe('StalkerSeriesViewComponent', () => {
|
||||
]);
|
||||
isEmbeddedPlayer.mockReturnValue(true);
|
||||
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
await stabilize();
|
||||
|
||||
fixture.componentInstance.vodSeriesSeasons.set([
|
||||
{
|
||||
@@ -938,8 +965,7 @@ describe('StalkerSeriesViewComponent', () => {
|
||||
const seasonOne = fixture.componentInstance.mappedSeasons()['1'];
|
||||
fixture.componentInstance.onEpisodeClicked(seasonOne[0]);
|
||||
await fixture.whenStable();
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
await stabilize();
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(fetchVodSeriesEpisodes).toHaveBeenCalledTimes(1);
|
||||
@@ -947,8 +973,7 @@ describe('StalkerSeriesViewComponent', () => {
|
||||
// Further playback activity in the same season must not retrigger it.
|
||||
fixture.componentInstance.onEpisodeClicked(seasonOne[1]);
|
||||
await fixture.whenStable();
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
await stabilize();
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(fetchVodSeriesEpisodes).toHaveBeenCalledTimes(1);
|
||||
@@ -982,8 +1007,7 @@ describe('StalkerSeriesViewComponent', () => {
|
||||
]);
|
||||
isEmbeddedPlayer.mockReturnValue(true);
|
||||
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
await stabilize();
|
||||
|
||||
fixture.componentInstance.vodSeriesSeasons.set([
|
||||
{
|
||||
@@ -1014,8 +1038,7 @@ describe('StalkerSeriesViewComponent', () => {
|
||||
const seasonOne = fixture.componentInstance.mappedSeasons()['1'];
|
||||
fixture.componentInstance.onEpisodeClicked(seasonOne[0]);
|
||||
await fixture.whenStable();
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
await stabilize();
|
||||
fixture.detectChanges();
|
||||
|
||||
// The failure must not loop while the same episode keeps playing.
|
||||
@@ -1027,8 +1050,7 @@ describe('StalkerSeriesViewComponent', () => {
|
||||
]);
|
||||
fixture.componentInstance.onEpisodeClicked(seasonOne[1]);
|
||||
await fixture.whenStable();
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
await stabilize();
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(fetchVodSeriesEpisodes).toHaveBeenCalledTimes(2);
|
||||
@@ -1079,8 +1101,7 @@ describe('StalkerSeriesViewComponent', () => {
|
||||
},
|
||||
]);
|
||||
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
await stabilize();
|
||||
|
||||
fixture.componentInstance.vodSeriesSeasons.set([
|
||||
{
|
||||
@@ -1151,8 +1172,7 @@ describe('StalkerSeriesViewComponent', () => {
|
||||
});
|
||||
|
||||
it('fetches the TMDB season once the show-level match arrives after auto-select', async () => {
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
await stabilize();
|
||||
fixture.detectChanges();
|
||||
|
||||
// Season tabs auto-select immediately — usually before the async
|
||||
@@ -1161,8 +1181,7 @@ describe('StalkerSeriesViewComponent', () => {
|
||||
By.directive(StubSeasonContainerComponent)
|
||||
).componentInstance as StubSeasonContainerComponent;
|
||||
seasonContainer.seasonSelected.emit('1');
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
await stabilize();
|
||||
expect(tmdbGetSeason).not.toHaveBeenCalled();
|
||||
|
||||
// The TMDB match lands afterwards — the fetch must run now.
|
||||
@@ -1176,8 +1195,7 @@ describe('StalkerSeriesViewComponent', () => {
|
||||
tmdb_id: 777,
|
||||
},
|
||||
} as never);
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
await stabilize();
|
||||
|
||||
expect(tmdbGetSeason).toHaveBeenCalledWith(777, 1);
|
||||
});
|
||||
@@ -1194,12 +1212,10 @@ describe('StalkerSeriesViewComponent', () => {
|
||||
tmdb_id: 777,
|
||||
},
|
||||
} as never);
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
await stabilize();
|
||||
|
||||
fixture.componentInstance.onSeasonSelected('1');
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
await stabilize();
|
||||
|
||||
// Season resource still loading — fetching now would pass a zero
|
||||
// season count, suppress the title-marker override and cache the
|
||||
@@ -1214,8 +1230,7 @@ describe('StalkerSeriesViewComponent', () => {
|
||||
series: [1, 2],
|
||||
},
|
||||
]);
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
await stabilize();
|
||||
|
||||
// Single-season slice whose provider season is renumbered to 1:
|
||||
// the title marker names the real TMDB season.
|
||||
@@ -1223,12 +1238,10 @@ describe('StalkerSeriesViewComponent', () => {
|
||||
});
|
||||
|
||||
it('gates the fetch on the reloading season resource during detail-to-detail navigation', async () => {
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
await stabilize();
|
||||
|
||||
fixture.componentInstance.onSeasonSelected('1');
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
await stabilize();
|
||||
// No show-level TMDB match yet — nothing fetched for the first item
|
||||
expect(tmdbGetSeason).not.toHaveBeenCalled();
|
||||
|
||||
@@ -1246,8 +1259,7 @@ describe('StalkerSeriesViewComponent', () => {
|
||||
tmdb_id: 888,
|
||||
},
|
||||
} as never);
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
await stabilize();
|
||||
|
||||
// The new tmdb_id must NOT pair with the previous series' season
|
||||
// context while the resource reloads.
|
||||
@@ -1266,17 +1278,14 @@ describe('StalkerSeriesViewComponent', () => {
|
||||
},
|
||||
]);
|
||||
isSerialSeasonsLoading.set(false);
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
await stabilize();
|
||||
expect(tmdbGetSeason).toHaveBeenCalledWith(888, 2);
|
||||
});
|
||||
|
||||
it('enriches after equal-id navigation once the season resource settles', async () => {
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
await stabilize();
|
||||
fixture.componentInstance.onSeasonSelected('1');
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
await stabilize();
|
||||
|
||||
// Distinct items can reuse a provider id; the loading gate (not an
|
||||
// id comparison) keeps the stale map from being used.
|
||||
@@ -1291,13 +1300,11 @@ describe('StalkerSeriesViewComponent', () => {
|
||||
tmdb_id: 999,
|
||||
},
|
||||
} as never);
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
await stabilize();
|
||||
expect(tmdbGetSeason).not.toHaveBeenCalled();
|
||||
|
||||
isSerialSeasonsLoading.set(false);
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
await stabilize();
|
||||
expect(tmdbGetSeason).toHaveBeenCalledWith(999, 3);
|
||||
});
|
||||
|
||||
@@ -1313,12 +1320,10 @@ describe('StalkerSeriesViewComponent', () => {
|
||||
tmdb_id: 777,
|
||||
},
|
||||
} as never);
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
await stabilize();
|
||||
|
||||
fixture.componentInstance.onSeasonSelected('1');
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
await stabilize();
|
||||
|
||||
expect(tmdbGetSeason).toHaveBeenCalledWith(777, 2);
|
||||
});
|
||||
|
||||
Reference in new issue
Block a user