2026-07-26 20:22:05 +04:00
|
|
|
<?php
|
|
|
|
|
/**
|
|
|
|
|
* Tests unitaires pour les fonctions de formatage de includes/config.php
|
|
|
|
|
* (formatDuration, formatViewCount, formatDate, formatVideosData)
|
|
|
|
|
* et truncateText de includes/structured-data.php
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
// --- formatDuration ---------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
assertEquals('0:00', formatDuration(0), 'formatDuration(0) donne 0:00');
|
|
|
|
|
assertEquals('0:59', formatDuration(59), 'formatDuration formate les secondes');
|
|
|
|
|
assertEquals('1:05', formatDuration(65), 'formatDuration formate minutes:secondes avec zéro');
|
|
|
|
|
assertEquals('1:00:00', formatDuration(3600), 'formatDuration passe au format heures');
|
|
|
|
|
assertEquals('1:01:01', formatDuration(3661), 'formatDuration formate heures:minutes:secondes');
|
|
|
|
|
|
|
|
|
|
// --- formatViewCount --------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
assertEquals(999, formatViewCount(999), 'formatViewCount laisse les valeurs < 1000 intactes');
|
|
|
|
|
assertEquals('1K', formatViewCount(1000), 'formatViewCount abrège en K à partir de 1000');
|
|
|
|
|
assertEquals('1.5K', formatViewCount(1500), 'formatViewCount arrondit les K à une décimale');
|
|
|
|
|
assertEquals('1M', formatViewCount(1000000), 'formatViewCount abrège en M à partir de 1 million');
|
|
|
|
|
assertEquals('2.5M', formatViewCount(2500000), 'formatViewCount arrondit les M à une décimale');
|
|
|
|
|
|
|
|
|
|
// --- formatDate -------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
assertEquals('Aujourd\'hui', formatDate(date('Y-m-d H:i:s')), 'formatDate affiche Aujourd\'hui');
|
|
|
|
|
assertEquals('Hier', formatDate(date('Y-m-d H:i:s', time() - 86400)), 'formatDate affiche Hier');
|
|
|
|
|
assertEquals(
|
|
|
|
|
'Il y a 3 jours',
|
|
|
|
|
formatDate(date('Y-m-d H:i:s', time() - 3 * 86400)),
|
|
|
|
|
'formatDate affiche les jours sous une semaine'
|
|
|
|
|
);
|
|
|
|
|
assertEquals(
|
|
|
|
|
'Il y a 1 semaine',
|
|
|
|
|
formatDate(date('Y-m-d H:i:s', time() - 10 * 86400)),
|
|
|
|
|
'formatDate affiche la semaine au singulier'
|
|
|
|
|
);
|
|
|
|
|
assertEquals(
|
|
|
|
|
'Il y a 2 semaines',
|
|
|
|
|
formatDate(date('Y-m-d H:i:s', time() - 20 * 86400)),
|
|
|
|
|
'formatDate affiche les semaines au pluriel'
|
|
|
|
|
);
|
|
|
|
|
assertEquals(
|
|
|
|
|
'Il y a 2 mois',
|
|
|
|
|
formatDate(date('Y-m-d H:i:s', time() - 60 * 86400)),
|
|
|
|
|
'formatDate affiche les mois'
|
|
|
|
|
);
|
|
|
|
|
assertEquals(
|
|
|
|
|
'Il y a 1 an',
|
|
|
|
|
formatDate(date('Y-m-d H:i:s', time() - 400 * 86400)),
|
|
|
|
|
'formatDate affiche l\'année au singulier'
|
|
|
|
|
);
|
|
|
|
|
assertEquals(
|
|
|
|
|
'Il y a 2 ans',
|
|
|
|
|
formatDate(date('Y-m-d H:i:s', time() - 800 * 86400)),
|
|
|
|
|
'formatDate affiche les années au pluriel'
|
|
|
|
|
);
|
|
|
|
|
|
2026-07-27 01:55:21 +04:00
|
|
|
// --- formatDate : dates malformées (repli sur la chaîne brute) ---------------
|
|
|
|
|
|
|
|
|
|
assertEquals(
|
|
|
|
|
'pas une date',
|
|
|
|
|
formatDate('pas une date'),
|
|
|
|
|
'formatDate retourne la chaîne brute si la date est invalide'
|
|
|
|
|
);
|
|
|
|
|
assertEquals(
|
|
|
|
|
'2024-13-45T99:99:99Z',
|
|
|
|
|
formatDate('2024-13-45T99:99:99Z'),
|
|
|
|
|
'formatDate retourne une date ISO malformée telle quelle'
|
|
|
|
|
);
|
|
|
|
|
assertEquals('', formatDate(''), 'formatDate retourne une chaîne vide telle quelle');
|
|
|
|
|
assertEquals(' ', formatDate(' '), 'formatDate retourne une chaîne blanche telle quelle');
|
|
|
|
|
|
2026-07-26 20:22:05 +04:00
|
|
|
// --- formatVideosData -------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
$rawVideos = [
|
|
|
|
|
[
|
|
|
|
|
'uuid' => 'abc-123',
|
|
|
|
|
'name' => 'Ma vidéo',
|
|
|
|
|
'previewPath' => '/lazy/abc.jpg',
|
|
|
|
|
'duration' => 125,
|
|
|
|
|
'channel' => [
|
|
|
|
|
'displayName' => 'Chaîne',
|
|
|
|
|
'avatars' => [['path' => '/avatars/a.png']]
|
|
|
|
|
],
|
|
|
|
|
'views' => 42,
|
|
|
|
|
'publishedAt' => '2024-01-01T00:00:00.000Z',
|
|
|
|
|
'aspectRatio' => 1.78,
|
|
|
|
|
'description' => 'Une description',
|
|
|
|
|
'tags' => ['musique'],
|
|
|
|
|
'isLive' => true,
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
// Vidéo minimale : sans vignette, avatar, description, tags ni isLive
|
|
|
|
|
'uuid' => 'def-456',
|
|
|
|
|
'name' => 'Minimale',
|
|
|
|
|
'duration' => 5,
|
|
|
|
|
'channel' => ['displayName' => 'Autre chaîne'],
|
|
|
|
|
'views' => 0,
|
|
|
|
|
'publishedAt' => '2024-01-02T00:00:00.000Z',
|
|
|
|
|
'aspectRatio' => 1.78,
|
|
|
|
|
],
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
$videos = formatVideosData($rawVideos);
|
|
|
|
|
|
|
|
|
|
assertEquals(2, count($videos), 'formatVideosData retourne une entrée par vidéo');
|
|
|
|
|
|
|
|
|
|
assertEquals('abc-123', $videos[0]['id'], 'formatVideosData mappe uuid vers id');
|
|
|
|
|
assertEquals('Ma vidéo', $videos[0]['title'], 'formatVideosData mappe name vers title');
|
|
|
|
|
assertEquals(
|
|
|
|
|
PEERTUBE_URL . '/lazy/abc.jpg',
|
|
|
|
|
$videos[0]['thumbnail'],
|
|
|
|
|
'formatVideosData préfixe la vignette avec PEERTUBE_URL'
|
|
|
|
|
);
|
|
|
|
|
assertEquals(
|
|
|
|
|
PEERTUBE_URL . '/avatars/a.png',
|
|
|
|
|
$videos[0]['channelAvatar'],
|
|
|
|
|
'formatVideosData préfixe l\'avatar avec PEERTUBE_URL'
|
|
|
|
|
);
|
|
|
|
|
assertEquals(125, $videos[0]['duration'], 'formatVideosData conserve la durée');
|
|
|
|
|
assertEquals('Chaîne', $videos[0]['channel'], 'formatVideosData mappe le nom de la chaîne');
|
|
|
|
|
assertEquals(42, $videos[0]['views'], 'formatVideosData conserve les vues');
|
|
|
|
|
assertEquals('2024-01-01T00:00:00.000Z', $videos[0]['date'], 'formatVideosData mappe publishedAt vers date');
|
|
|
|
|
assertEquals('Une description', $videos[0]['description'], 'formatVideosData conserve la description');
|
|
|
|
|
assertEquals(['musique'], $videos[0]['tags'], 'formatVideosData conserve les tags');
|
|
|
|
|
assertTrue($videos[0]['isLive'], 'formatVideosData conserve isLive');
|
|
|
|
|
|
|
|
|
|
assertEquals(
|
|
|
|
|
'img/default-thumbnail.jpg',
|
|
|
|
|
$videos[1]['thumbnail'],
|
|
|
|
|
'formatVideosData utilise une vignette par défaut si absente'
|
|
|
|
|
);
|
|
|
|
|
assertEquals(
|
|
|
|
|
'img/default-avatar.png',
|
|
|
|
|
$videos[1]['channelAvatar'],
|
|
|
|
|
'formatVideosData utilise un avatar par défaut si absent'
|
|
|
|
|
);
|
|
|
|
|
assertEquals('', $videos[1]['description'], 'formatVideosData met une description vide par défaut');
|
|
|
|
|
assertEquals([], $videos[1]['tags'], 'formatVideosData met des tags vides par défaut');
|
|
|
|
|
assertFalse($videos[1]['isLive'], 'formatVideosData met isLive à false par défaut');
|
|
|
|
|
|
2026-07-27 01:55:21 +04:00
|
|
|
// --- formatVideosData : données API incomplètes -------------------------------
|
|
|
|
|
|
|
|
|
|
$incompleteVideos = formatVideosData([
|
|
|
|
|
[
|
|
|
|
|
// Sans uuid : doit être ignorée
|
|
|
|
|
'name' => 'Sans uuid',
|
|
|
|
|
'duration' => 10,
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
// uuid vide : doit être ignorée aussi
|
|
|
|
|
'uuid' => '',
|
|
|
|
|
'name' => 'Uuid vide',
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
// uuid seul : valeurs par défaut partout ailleurs
|
|
|
|
|
'uuid' => 'ghi-789',
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
// channel présent mais sans displayName ni avatars
|
|
|
|
|
'uuid' => 'jkl-012',
|
|
|
|
|
'channel' => ['name' => 'compte'],
|
|
|
|
|
],
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
assertEquals(2, count($incompleteVideos), 'formatVideosData ignore les entrées sans uuid');
|
|
|
|
|
|
|
|
|
|
assertEquals('ghi-789', $incompleteVideos[0]['id'], 'formatVideosData conserve l\'uuid seul');
|
|
|
|
|
assertEquals('', $incompleteVideos[0]['title'], 'formatVideosData met un titre vide par défaut');
|
|
|
|
|
assertEquals(0, $incompleteVideos[0]['duration'], 'formatVideosData met une durée à 0 par défaut');
|
|
|
|
|
assertEquals('', $incompleteVideos[0]['channel'], 'formatVideosData met une chaîne vide par défaut');
|
|
|
|
|
assertEquals(0, $incompleteVideos[0]['views'], 'formatVideosData met les vues à 0 par défaut');
|
|
|
|
|
assertEquals('', $incompleteVideos[0]['date'], 'formatVideosData met une date vide par défaut');
|
|
|
|
|
assertNull($incompleteVideos[0]['aspectRatio'], 'formatVideosData met aspectRatio à null par défaut');
|
|
|
|
|
assertFalse($incompleteVideos[0]['isLive'], 'formatVideosData met isLive à false par défaut');
|
|
|
|
|
assertEquals(
|
|
|
|
|
'img/default-thumbnail.jpg',
|
|
|
|
|
$incompleteVideos[0]['thumbnail'],
|
|
|
|
|
'formatVideosData met la vignette par défaut pour une entrée minimale'
|
|
|
|
|
);
|
|
|
|
|
assertEquals(
|
|
|
|
|
'img/default-avatar.png',
|
|
|
|
|
$incompleteVideos[0]['channelAvatar'],
|
|
|
|
|
'formatVideosData met l\'avatar par défaut pour une entrée minimale'
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
assertEquals('', $incompleteVideos[1]['channel'], 'formatVideosData met une chaîne vide si displayName absent');
|
|
|
|
|
assertEquals(
|
|
|
|
|
'img/default-avatar.png',
|
|
|
|
|
$incompleteVideos[1]['channelAvatar'],
|
|
|
|
|
'formatVideosData met l\'avatar par défaut si le tableau avatars est absent'
|
|
|
|
|
);
|
|
|
|
|
|
2026-07-26 20:22:05 +04:00
|
|
|
// --- truncateText (includes/structured-data.php) ----------------------------
|
|
|
|
|
|
|
|
|
|
assertEquals('court', truncateText('court', 200), 'truncateText laisse un texte court intact');
|
|
|
|
|
assertEquals('exact', truncateText('exact', 5), 'truncateText laisse un texte à la limite exacte intact');
|
|
|
|
|
|
|
|
|
|
$textWithSpace = str_repeat('a', 150) . ' ' . str_repeat('b', 100); // 251 caractères
|
|
|
|
|
assertEquals(
|
|
|
|
|
str_repeat('a', 150) . '...',
|
|
|
|
|
truncateText($textWithSpace, 200),
|
|
|
|
|
'truncateText coupe au dernier espace avant la limite'
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
$textNoSpace = str_repeat('a', 250);
|
|
|
|
|
assertEquals(
|
|
|
|
|
str_repeat('a', 200) . '...',
|
|
|
|
|
truncateText($textNoSpace, 200),
|
|
|
|
|
'truncateText coupe à la limite quand il n\'y a pas d\'espace'
|
|
|
|
|
);
|