import 'package:flutter_test/flutter_test.dart'; import 'package:mocktail/mocktail.dart'; import 'package:http/http.dart' as http; import 'dart:convert'; import 'package:yommi_ff/services/m3u_service.dart'; import 'package:yommi_ff/models/stream_entry.dart'; class _MockClient extends Mock implements http.Client {} void main() { group('M3UService', () { test('parses simple m3u content', () { final content = '''#EXTM3U #EXTINF:-1,Channel One http://example.com/stream1.m3u8 #EXTINF:-1,Second Channel http://example.com/stream2.m3u8 '''; final svc = M3UService(client: http.Client()); final entries = svc.parse(content); expect(entries, [ StreamEntry( title: 'Channel One', url: 'http://example.com/stream1.m3u8'), StreamEntry( title: 'Second Channel', url: 'http://example.com/stream2.m3u8'), ]); }); test('fetches and caches', () async { final mock = _MockClient(); final url = 'http://mock/m3u'; final body = '#EXTM3U\n#EXTINF:-1,Mock\nhttp://mock/stream\n'; when(() => mock.get(Uri.parse(url))) .thenAnswer((_) async => http.Response(body, 200)); final svc = M3UService(client: mock); final first = await svc.fetch(url); expect(first.length, 1); // second fetch should use cache — we verify by changing mock to throw if called again when(() => mock.get(Uri.parse(url))) .thenThrow(Exception('should not be called')); final second = await svc.fetch(url); expect(second.length, 1); }); test('throws on empty', () { final svc = M3UService(); expect(() => svc.parse(''), throwsA(isA())); }); }); }