Files
xtremflow/bin/test/epg_api_test.dart
T
MichaelandClaude Opus 5 537312908a fix(epg,ui): utiliser get_simple_data_table pour l'EPG et recaler la sidebar sur le thème
EPG — les trois chemins (backend /api/epg, XtreamService.getShortEpg et
getShortEPG) n'utilisaient que get_epg et get_short_epg. Beaucoup de
panneaux Xtream ne connaissent pas get_epg : ils répondent 200 avec le
bloc d'authentification, sans epg_listings, ce qui produisait un guide
vide indiscernable d'une chaîne sans programme. get_short_epg y renvoie
epg_listings vide en permanence.

- backend : get_simple_data_table en premier, get_short_epg en repli
- client : bascule automatique et mémorisée vers le tableau complet dès
  qu'un panneau est muet sur l'action légère, pour ne pas doubler les
  requêtes sur chaque tuile de grille
- dates dérivées des *_timestamp epoch et émises en ISO-8601 UTC : les
  champs texte sont dans le fuseau du panneau, sans indicateur de zone,
  et étaient relus comme de l'heure locale — le guide était décalé et
  les enregistrements planifiés depuis le guide l'étaient aussi
- cache backend : la clé incluait seulement le channelId, deux playlists
  partageant un stream_id se servaient mutuellement leur guide

UI — les deux halos d'ambiance du dashboard étaient restés de l'ancien
thème : primary (#FFB68C) à 40 % posé sur le coin haut-gauche, donc pile
derrière la sidebar, et info (#A3B8C4, bleu-gris) à 35 % dans une palette
entièrement chaude. Ramenés à des braises ember à 8 % / 6 %.

- fond via AppColors.backgroundGradient
- onglet actif rempli en primaryContainer (surface) et non primary
  (teinte claire réservée au texte/icônes)
- sidebar en niveau flottant : en niveau 1 son fond #181310 se confondait
  avec le haut du dégradé #1A1310

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-11 09:53:17 +02:00

75 lines
2.6 KiB
Dart

import 'package:test/test.dart';
import '../api/epg_api.dart';
/// Extrait réel d'une réponse `get_simple_data_table` (panneau Xtream) :
/// titres/descriptions en base64, horodatages epoch UTC doublés d'une chaîne
/// exprimée dans le fuseau du panneau — ici Europe/Amsterdam (UTC+2).
const _sampleListing = {
'epg_listings': [
{
'id': '336987829',
'epg_id': '104',
'title': 'Sm91cm5hbCBkZSAyMGg=', // "Journal de 20h"
'lang': '',
'start': '2026-08-11 20:00:00',
'end': '2026-08-11 20:35:00',
'description': 'TCdpbmZvIGR1IHNvaXI=', // "L'info du soir"
'channel_id': 'TF1.fr',
'start_timestamp': '1786471200', // 2026-08-11T18:00:00Z
'stop_timestamp': '1786473300', // 2026-08-11T18:35:00Z
},
],
};
void main() {
final api = EpgApi((_) async => null);
group('transformEpgData', () {
test('convertit les horodatages epoch en ISO-8601 UTC', () {
final result = api.transformEpgData(_sampleListing, '845452');
final programme = (result['programmes'] as List).single as Map;
// Sans cette conversion, le client relisait « 2026-08-11T20:00:00 »
// comme de l'heure locale et décalait tout le guide de 2 h.
expect(programme['start'], '2026-08-11T18:00:00.000Z');
expect(programme['end'], '2026-08-11T18:35:00.000Z');
});
test('décode les titres et descriptions base64', () {
final result = api.transformEpgData(_sampleListing, '845452');
final programme = (result['programmes'] as List).single as Map;
expect(programme['title'], 'Journal de 20h');
expect(programme['description'], "L'info du soir");
expect(programme['channel_id'], '845452');
});
test('retombe sur les champs texte quand les epoch manquent', () {
final result = api.transformEpgData({
'epg_listings': [
{
'title': 'Sm91cm5hbCBkZSAyMGg=',
'start': '2026-08-11 20:00:00',
'stop': '2026-08-11 20:35:00',
},
],
}, '845452');
final programme = (result['programmes'] as List).single as Map;
expect(programme['start'], '2026-08-11T20:00:00');
expect(programme['end'], '2026-08-11T20:35:00');
});
test('rend une liste vide sur un payload sans epg_listings', () {
// Ce que renvoie un panneau qui ne connaît pas l'action demandée :
// un 200 contenant le bloc d'authentification.
final result = api.transformEpgData({
'user_info': {'auth': 1},
'server_info': {'url': 'tit.example'},
}, '845452');
expect(result['programmes'], isEmpty);
});
});
}