77 * - Temp directory for output files
88 *
99 * Run with: npm run test:integration
10- *
11- * Note: The actual download test is skipped by default in CI
12- * because it can take several minutes. Run locally with:
13- * INTEGRATION_DOWNLOAD=true npm run test:integration
1410 */
1511
1612import { existsSync , mkdirSync , rmSync , statSync } from "node:fs" ;
@@ -21,13 +17,13 @@ import { checkFfmpeg, downloadHLSVideo, fetchHLSQualities } from "./hlsDownloade
2117
2218// Test fixtures - public HLS streams for testing
2319const TEST_STREAMS = {
24- // Apple's bipbop test stream (shorter variant )
25- bipbop :
20+ // Apple's bipbop master playlist (for quality detection )
21+ bipbopMaster :
2622 "https://devstreaming-cdn.apple.com/videos/streaming/examples/bipbop_4x3/bipbop_4x3_variant.m3u8" ,
2723} ;
2824
29- // Skip download tests unless explicitly enabled (they're slow)
30- const SKIP_DOWNLOAD = ! process . env . INTEGRATION_DOWNLOAD ;
25+ // Full download tests are slow - skip in CI unless explicitly enabled
26+ const RUN_SLOW_TESTS = process . env . INTEGRATION_SLOW === "true" ;
3127
3228describe ( "HLS Downloader Integration" , ( ) => {
3329 let tempDir : string ;
@@ -48,65 +44,69 @@ describe("HLS Downloader Integration", () => {
4844 describe ( "checkFfmpeg" , ( ) => {
4945 it ( "should detect ffmpeg when installed" , async ( ) => {
5046 const result = await checkFfmpeg ( ) ;
51- // This test will fail if ffmpeg is not installed
5247 expect ( result ) . toBe ( true ) ;
5348 } ) ;
5449 } ) ;
5550
5651 describe ( "fetchHLSQualities" , ( ) => {
5752 it ( "should fetch qualities from a real HLS master playlist" , async ( ) => {
58- const qualities = await fetchHLSQualities ( TEST_STREAMS . bipbop ) ;
53+ const qualities = await fetchHLSQualities ( TEST_STREAMS . bipbopMaster ) ;
5954
6055 expect ( qualities . length ) . toBeGreaterThan ( 0 ) ;
6156 expect ( qualities [ 0 ] ) . toHaveProperty ( "url" ) ;
6257 expect ( qualities [ 0 ] ) . toHaveProperty ( "bandwidth" ) ;
6358 expect ( qualities [ 0 ] ) . toHaveProperty ( "label" ) ;
64- } , 30000 ) ;
59+
60+ // Bipbop should have multiple quality levels
61+ expect ( qualities . length ) . toBeGreaterThanOrEqual ( 4 ) ;
62+ } , 15000 ) ;
6563 } ) ;
6664
6765 describe ( "downloadHLSVideo" , ( ) => {
68- it . skipIf ( SKIP_DOWNLOAD ) (
69- "should download a short HLS stream (slow, set INTEGRATION_DOWNLOAD=true)" ,
66+ it ( "should return error for invalid URL" , async ( ) => {
67+ const outputPath = join ( tempDir , "invalid-test.mp4" ) ;
68+
69+ const result = await downloadHLSVideo (
70+ "https://invalid-url-that-does-not-exist.example.com/video.m3u8" ,
71+ outputPath
72+ ) ;
73+
74+ expect ( result . success ) . toBe ( false ) ;
75+ expect ( result . error ) . toBeDefined ( ) ;
76+ } , 15000 ) ;
77+
78+ it ( "should handle non-HLS URL gracefully" , async ( ) => {
79+ const outputPath = join ( tempDir , "not-hls.mp4" ) ;
80+
81+ const result = await downloadHLSVideo ( "https://example.com/not-a-playlist.txt" , outputPath ) ;
82+
83+ expect ( result . success ) . toBe ( false ) ;
84+ expect ( result . errorCode ) . toBeDefined ( ) ;
85+ } , 15000 ) ;
86+
87+ // Full download test - only run when INTEGRATION_SLOW=true
88+ it . skipIf ( ! RUN_SLOW_TESTS ) (
89+ "should download complete HLS stream (slow, set INTEGRATION_SLOW=true)" ,
7090 async ( ) => {
7191 const outputPath = join ( tempDir , "test-video.mp4" ) ;
7292
7393 const progressUpdates : number [ ] = [ ] ;
74- const result = await downloadHLSVideo ( TEST_STREAMS . bipbop , outputPath , ( progress ) => {
94+ const result = await downloadHLSVideo ( TEST_STREAMS . bipbopMaster , outputPath , ( progress ) => {
7595 progressUpdates . push ( progress . percent ) ;
7696 } ) ;
7797
7898 expect ( result . success ) . toBe ( true ) ;
7999 expect ( result . outputPath ) . toBe ( outputPath ) ;
80100 expect ( existsSync ( outputPath ) ) . toBe ( true ) ;
81101
82- // Check file size is reasonable (at least 100KB)
102+ // Check file size is reasonable
83103 const stats = statSync ( outputPath ) ;
84104 expect ( stats . size ) . toBeGreaterThan ( 100 * 1024 ) ;
85105
86106 // Should have received progress updates
87107 expect ( progressUpdates . length ) . toBeGreaterThan ( 0 ) ;
88108 } ,
89- 300000 // 5 minute timeout for actual download
109+ 300000 // 5 minute timeout
90110 ) ;
91-
92- it ( "should return error for invalid URL" , async ( ) => {
93- const outputPath = join ( tempDir , "invalid-test.mp4" ) ;
94-
95- const result = await downloadHLSVideo (
96- "https://invalid-url-that-does-not-exist.example.com/video.m3u8" ,
97- outputPath
98- ) ;
99-
100- expect ( result . success ) . toBe ( false ) ;
101- expect ( result . error ) . toBeDefined ( ) ;
102- } , 30000 ) ;
103-
104- it ( "should handle non-HLS URL gracefully" , async ( ) => {
105- const outputPath = join ( tempDir , "not-hls.mp4" ) ;
106-
107- const result = await downloadHLSVideo ( "https://example.com/not-a-playlist.txt" , outputPath ) ;
108-
109- expect ( result . success ) . toBe ( false ) ;
110- } , 30000 ) ;
111111 } ) ;
112112} ) ;
0 commit comments