Règle partagée front/back : flag natif, verticale stricte (ratio ≤ 0.8, ≤ 90 s), verticale sans durée jamais short, repli durée (70 YT / 75 autres). Dimensions alimentées par Dailymotion/Odysee/PeerTube, flag maison Rumble supprimé, condition innertube morte simplifiée. Shorts : langues utilisateur (UI + transcripts) via relevanceLanguage/languageOneOf/Twitch language, son activé par défaut.
This commit is contained in:
@@ -7,6 +7,7 @@ import {
|
||||
normalizeFilters, parseSearchFilters, activeFilters, filtersCacheKey,
|
||||
periodMs, durationBounds, matchesFilters, applySearchFilters,
|
||||
innertubeSearchFilters, apiSearchParams, itemDurationSec, itemPublishedTs,
|
||||
isShortItem, SHORT_MAX_SECONDS, VERTICAL_SHORT_MAX_SECONDS, VERTICAL_MAX_RATIO,
|
||||
} from '../search-filters.mjs';
|
||||
|
||||
function expect(cond, msg) {
|
||||
@@ -186,4 +187,74 @@ expect(
|
||||
);
|
||||
logOk('innertubeSearchFilters / apiSearchParams');
|
||||
|
||||
// ---------- Détection Short par orientation ----------
|
||||
|
||||
eq(typeof SHORT_MAX_SECONDS, 'number', 'seuils exportés');
|
||||
eq(VERTICAL_SHORT_MAX_SECONDS, 90, 'verticale short jusqu’à 90 s');
|
||||
eq(VERTICAL_MAX_RATIO, 0.8, 'ratio vertical max 0.8');
|
||||
|
||||
// Règle 2 : verticale 60 s (ex. repost TikTok 608x1080) ⇒ short.
|
||||
expect(
|
||||
isShortItem({ title: 'repost', duration: 60, width: 608, height: 1080, type: 'video' }),
|
||||
'vertical 60s is a short',
|
||||
);
|
||||
// Règle 2 : verticale 200 s ⇒ PAS short (vidéo verticale, pas short).
|
||||
expect(
|
||||
!isShortItem({ title: 'vlog', duration: 200, width: 720, height: 1280, type: 'video' }),
|
||||
'vertical 200s is not a short',
|
||||
);
|
||||
// Règle 2 : un carré 80 s (> 75 s) n'est PAS short : l'orientation seule
|
||||
// (ratio ~1) ne suffit pas ET le repli durée ne s'applique plus.
|
||||
expect(
|
||||
!isShortItem({ title: 'clip carré', duration: 80, width: 1080, height: 1080, type: 'video' }),
|
||||
'square 80s is not a short (orientation alone is not enough)',
|
||||
);
|
||||
// …mais à 30 s, la règle 4 (durée seule) le garde : non-régression historique.
|
||||
expect(
|
||||
matchesFilters({ id: 'a', title: 'clip carré', duration: 30, width: 1080, height: 1080, type: 'video' }, { type: 'shorts' }),
|
||||
'square 30s still matches shorts via duration fallback',
|
||||
);
|
||||
// Règle 4 : horizontale 50 s ⇒ short (non-régression durée seule).
|
||||
expect(
|
||||
isShortItem({ title: 'paysage', duration: 50, width: 1280, height: 720, type: 'video' }),
|
||||
'horizontal 50s is a short (duration fallback)',
|
||||
);
|
||||
// Règle 3 : verticale SANS durée connue ⇒ PAS short.
|
||||
expect(
|
||||
!isShortItem({ title: 'inconnu', width: 608, height: 1080, type: 'video' }),
|
||||
'vertical without duration is not a short',
|
||||
);
|
||||
// Règle 1 : flag contredit par une durée > 75 s ⇒ PAS short.
|
||||
expect(
|
||||
!isShortItem({ title: 'faux short', duration: 300, isShort: true, type: 'video' }),
|
||||
'native flag contradicted by duration is not a short',
|
||||
);
|
||||
// Règle 1 : un vrai Short titré « …shorts » n'est plus exclu (ancien bug
|
||||
// `!/short/i.test(title)`).
|
||||
expect(
|
||||
isShortItem({ title: 'mon voyage #shorts', duration: 40, type: 'video' }),
|
||||
'title containing shorts is kept',
|
||||
);
|
||||
// Seuil YouTube (70) vs autres (75) : 72 s.
|
||||
expect(
|
||||
!isShortItem({ title: 'yt', duration: 72, type: 'video', provider: 'youtube' }, 'yt'),
|
||||
'youtube 72s is not a short',
|
||||
);
|
||||
expect(
|
||||
isShortItem({ title: 'dm', duration: 72, type: 'video' }, 'dm'),
|
||||
'dailymotion 72s is a short',
|
||||
);
|
||||
// §4 : une verticale 60 s ne remonte jamais dans le filtre « vidéos »…
|
||||
expect(
|
||||
!matchesFilters({ id: 'b', title: 'v', duration: 60, width: 608, height: 1080, type: 'video' }, { type: 'video' }),
|
||||
'vertical 60s excluded from video filter',
|
||||
);
|
||||
// …et les dimensions comptent comme signal : l'item n'est plus "muet",
|
||||
// donc le filtre `live` l'exclut (une verticale n'est pas un direct).
|
||||
expect(
|
||||
!matchesFilters({ id: 'c', title: 'v', duration: 0, width: 608, height: 1080 }, { type: 'live' }),
|
||||
'dimensions are a signal: vertical without live flag is dropped from live',
|
||||
);
|
||||
logOk('isShortItem (orientation + durée)');
|
||||
|
||||
console.log('\nAll search-filters tests passed.');
|
||||
|
||||
Reference in New Issue
Block a user