fix(rumble): le lien de nav /videos n'est plus pris pour une vidéo
CI / build-and-test (push) Canceled after 0s

Le scan générique acceptait tout href /^\/v/ dont le regex d'id
matchait : `/videos` donnait `videoId: "videos"` — une fausse carte en
tête du flux /shorts (pré-validée puis retirée, mais visible le temps
du résolve). Probe live : 32/32 vrais ids rumble portent au moins un
chiffre, seul /videos n'en a pas. Garde « >=1 chiffre » dans l'id,
plafond documenté (un id sans chiffre ferait sauter sa carte).

Effet de bord heureux : la branche /video/123 (isLegacy) était morte
depuis toujours — le regex capturait « video » avant elle — elle
redevient accessible.

Tests : lien /videos ajouté au fixture du flux, 64 assertions vertes.
This commit is contained in:
2026-10-02 08:57:41 -04:00
parent 7fc1e1096d
commit 4e44d85717
2 changed files with 11 additions and 2 deletions
+7 -1
View File
@@ -626,8 +626,14 @@ export function parseCardsHtml(html, { mode = 'browse' } = {}) {
$(linkSelector).each((_idx, el) => { $(linkSelector).each((_idx, el) => {
const href = ($(el).attr('href') || '').split('?')[0]; const href = ($(el).attr('href') || '').split('?')[0];
// On préfère STRICTEMENT l’ID /vXXXX (aussi après /shorts/). // On préfère STRICTEMENT l’ID /vXXXX (aussi après /shorts/).
// ≥1 chiffre exigé : les vrais ids en portent toujours (probe 2026-10 :
// 32/32 sur /shorts + /videos), alors que les liens de nav (`/videos`)
// passeraient le regex et sortiraient une fausse carte « videoId: videos ».
// La branche /video/123 (isLegacy) ne devient accessible que grâce à ça :
// sans ce garde-fou, le regex capturait 'video' et l'ID s'échappait jamais.
// ponytail: si Rumble émettait un id sans chiffre, sa carte est sautée.
const m = /\/(v[0-9A-Za-z]+)(?:[-/.]|$)/.exec(href); const m = /\/(v[0-9A-Za-z]+)(?:[-/.]|$)/.exec(href);
const id = m?.[1] || null; const id = m && /[0-9]/.test(m[1]) ? m[1] : null;
// Fallback /video/123 : on ne convertit pas ici, /video/:id normalise par parse de page. // Fallback /video/123 : on ne convertit pas ici, /video/:id normalise par parse de page.
const isLegacy = !id && /^\/video\//.test(href); const isLegacy = !id && /^\/video\//.test(href);
if (!id && !isLegacy) return; if (!id && !isLegacy) return;
+4 -1
View File
@@ -146,13 +146,16 @@ const cardsHtml = `<html><body>
<a href="/vBBB22-autre-titre.html"><img src="https://i.rumble.com/b.jpg"></a> <a href="/vBBB22-autre-titre.html"><img src="https://i.rumble.com/b.jpg"></a>
<h3>Titre B</h3><span class="video-item--views" data-views="3456"></span> <h3>Titre B</h3><span class="video-item--views" data-views="3456"></span>
</div> </div>
<div class="video-item">
<a href="/videos"><h3>Featured Channels</h3></a>
</div>
<div class="video-item"> <div class="video-item">
<a href="/shorts/vCCC33"><h3>Titre C</h3></a> <a href="/shorts/vCCC33"><h3>Titre C</h3></a>
</div> </div>
</body></html>`; </body></html>`;
const browseCards = parseCardsHtml(cardsHtml, { mode: 'browse' }); const browseCards = parseCardsHtml(cardsHtml, { mode: 'browse' });
eq(browseCards.length, 2, 'cards browse: /vXXXX lu, /shorts/ ignoré'); eq(browseCards.length, 2, 'cards browse: /vXXXX lu, /shorts/ et /videos (nav) ignorés');
eq(browseCards[0].id, 'vAAA11', 'cards: id = vXXXX avant le slug -titre'); eq(browseCards[0].id, 'vAAA11', 'cards: id = vXXXX avant le slug -titre');
eq(browseCards[0].views, 1200, 'cards: vues « 1,2K » -> 1200 (bug parseur legacy corrigé)'); eq(browseCards[0].views, 1200, 'cards: vues « 1,2K » -> 1200 (bug parseur legacy corrigé)');
eq(browseCards[0].duration, 90, 'cards: durée depuis data-value'); eq(browseCards[0].duration, 90, 'cards: durée depuis data-value');