fix(xtream): keep sparse VOD details playable

This commit is contained in:
4gray committed 2026-07-29 00:17:59 +02:00
1 parent 3c342bc555
commit ec6df196f5
27 files changed
+1367 -239

No files matched your search

@@ -25,6 +25,7 @@ export type XtreamLiveStream = {
export type XtreamVodStream = {
added?: string;
category_id?: string;
container_extension?: string;
name?: string;
stream_id?: number | string;
};
@@ -8,6 +8,7 @@ import {
resetMockServers,
test,
waitForXtreamWorkspaceReady,
xtreamMockServer,
} from './electron-test-fixtures';
import {
fetchXtreamVodFixture,
@@ -21,7 +22,7 @@ const emptyMetadataCredentials = {
};
test.describe('Xtream VOD Details', () => {
test('shows a curated fallback when the portal returns empty VOD metadata', async ({
test('keeps a sparse VOD playable inside the curated fallback', async ({
dataDir,
request,
}) => {
@@ -30,7 +31,29 @@ test.describe('Xtream VOD Details', () => {
request,
emptyMetadataCredentials
);
const [movieTitle] = pickDistinctTitles(vodFixture.items, getXtreamTitle);
const [movieTitle] = pickDistinctTitles(
vodFixture.items,
getXtreamTitle
);
const movieItem = vodFixture.items.find(
(item) => getXtreamTitle(item) === movieTitle
);
const streamId = Number(movieItem?.stream_id);
const containerExtension = movieItem?.container_extension?.trim();
if (
!Number.isInteger(streamId) ||
streamId <= 0 ||
!containerExtension
) {
throw new Error(
'Xtream VOD fixture returned an invalid playback source.'
);
}
const expectedMovieUrl =
`${xtreamMockServer}/movie/` +
`${emptyMetadataCredentials.username}/` +
`${emptyMetadataCredentials.password}/` +
`${streamId}.${containerExtension}`;
const app = await launchElectronApp(dataDir);
try {
@@ -43,17 +66,22 @@ test.describe('Xtream VOD Details', () => {
await app.mainWindow
.getByRole('link', { name: 'Movies', exact: true })
.click();
await clickCategoryByNameExact(app.mainWindow, vodFixture.categoryName);
await clickCategoryByNameExact(
app.mainWindow,
vodFixture.categoryName
);
await clickGridListCardByTitle(app.mainWindow, movieTitle);
await app.mainWindow.waitForURL(
/\/workspace\/xtreams\/[^/]+\/vod\/[^/]+\/[^/]+$/
);
await expect(app.mainWindow.locator('app-content-hero')).toContainText(
movieTitle
);
await expect(
app.mainWindow.locator('[data-testid="xtream-vod-fallback-status"]')
app.mainWindow.locator('app-content-hero')
).toContainText(movieTitle);
await expect(
app.mainWindow.locator(
'[data-testid="xtream-vod-fallback-status"]'
)
).toContainText('Portal metadata unavailable');
await expect(
app.mainWindow.locator('[data-testid="xtream-vod-fallback"]')
@@ -61,13 +89,40 @@ test.describe('Xtream VOD Details', () => {
'Extended metadata was not provided by this portal.'
);
await expect(app.mainWindow.locator('button.play-btn')).toHaveCount(0);
await expect(app.mainWindow.locator('button.favorite-btn')).toHaveCount(
0
);
await expect(app.mainWindow.locator('button.download-btn')).toHaveCount(
0
const playButton = app.mainWindow
.locator('button.play-btn')
.first();
await expect(playButton).toBeVisible();
await expect(
app.mainWindow.locator('button.favorite-btn').first()
).toBeVisible();
await expect(
app.mainWindow.locator('button.download-btn').first()
).toBeVisible();
const movieResponsePromise = app.mainWindow.waitForResponse(
(response) =>
response.url() === expectedMovieUrl &&
response.request().method() === 'GET',
{ timeout: 20_000 }
);
await playButton.click();
const movieResponse = await movieResponsePromise;
expect(movieResponse.status()).toBe(302);
await expect(
app.mainWindow.locator('app-portal-detail-shell')
).toHaveClass(/shell-host--watch/);
await expect(
app.mainWindow
.locator('app-portal-inline-player app-web-player-view')
.first()
).toBeVisible({ timeout: 20_000 });
await expect(
app.mainWindow.locator(
'app-portal-inline-player .player-shell__title'
)
).toContainText(movieTitle);
} finally {
await closeElectronApp(app);
}