import { describe, it, expect } from 'vitest'; import { parseM3U, isValidM3U } from '../parsers/m3u'; describe('M3U Parser', () => { it('should parse basic M3U playlist', () => { const m3u = `#EXTM3U #EXTINF:-1 tvg-id="hbo" tvg-name="HBO" tvg-logo="http://example.com/hbo.png" group-title="Movies",HBO http://example.com/stream/hbo.m3u8 #EXTINF:-1 tvg-id="espn" tvg-name="ESPN" group-title="Sports",ESPN http://example.com/stream/espn.m3u8`; const channels = parseM3U(m3u, 'test-provider'); expect(channels).toHaveLength(2); // Check first channel (HBO) expect(channels[0].name).toBe('HBO'); expect(channels[0].category).toBe('Movies'); expect(channels[0].streamUrl).toBe('http://example.com/stream/hbo.m3u8'); expect(channels[0].logoUrl).toBe('http://example.com/hbo.png'); expect(channels[0].tvgId).toBe('hbo'); expect(channels[0].tvgName).toBe('HBO'); expect(channels[0].providerId).toBe('test-provider'); // Check second channel (ESPN) expect(channels[1].name).toBe('ESPN'); expect(channels[1].category).toBe('Sports'); expect(channels[1].streamUrl).toBe('http://example.com/stream/espn.m3u8'); }); it('should handle M3U without attributes', () => { const m3u = `#EXTM3U #EXTINF:-1,Channel 1 http://example.com/stream1.m3u8 #EXTINF:-1,Channel 2 http://example.com/stream2.m3u8`; const channels = parseM3U(m3u, 'test-provider'); expect(channels).toHaveLength(2); expect(channels[0].name).toBe('Channel 1'); expect(channels[0].streamUrl).toBe('http://example.com/stream1.m3u8'); expect(channels[0].logoUrl).toBeUndefined(); expect(channels[0].category).toBeUndefined(); }); it('should handle M3U with empty lines', () => { const m3u = `#EXTM3U #EXTINF:-1,Channel 1 http://example.com/stream1.m3u8 #EXTINF:-1,Channel 2 http://example.com/stream2.m3u8 `; const channels = parseM3U(m3u, 'test-provider'); expect(channels).toHaveLength(2); }); it('should skip malformed entries', () => { const m3u = `#EXTM3U #EXTINF:-1,Channel 1 http://example.com/stream1.m3u8 #EXTINF:-1,Channel without URL #EXTINF:-1,Channel 2 http://example.com/stream2.m3u8`; const channels = parseM3U(m3u, 'test-provider'); // Should only get 2 valid channels (skips the one without URL) expect(channels).toHaveLength(2); expect(channels[0].name).toBe('Channel 1'); expect(channels[1].name).toBe('Channel 2'); }); it('should validate M3U content', () => { expect(isValidM3U('#EXTM3U')).toBe(true); expect(isValidM3U('#EXTM3U\n#EXTINF:-1,Test\nhttp://test.com')).toBe(true); expect(isValidM3U(' #EXTM3U ')).toBe(true); expect(isValidM3U('Not M3U')).toBe(false); expect(isValidM3U('')).toBe(false); }); it('should handle special characters in channel names', () => { const m3u = `#EXTM3U #EXTINF:-1,HBO & Showtime [HD] http://example.com/stream.m3u8`; const channels = parseM3U(m3u, 'test-provider'); expect(channels[0].name).toBe('HBO & Showtime [HD]'); }); it('should return empty array for invalid M3U', () => { const channels = parseM3U('Not an M3U file', 'test-provider'); expect(channels).toHaveLength(0); }); });