@@ -114,7 +114,8 @@ describe("fetchSubtitles", () => {
114114 vssId : ".fr" ,
115115 } ,
116116 ] ) ;
117- mockYoutubeFetch . mockImplementation (
117+ mockYoutubeFetch . mockImplementationOnce ( async ( ) => new Response ( "" , { status : 403 } ) ) ;
118+ mockYoutubeFetch . mockImplementationOnce (
118119 async ( ) => new Response ( "WEBVTT\n\n00:00.000 --> 00:01.000\nBonjour" ) ,
119120 ) ;
120121 const { fetchSubtitleContent } = await import ( "../src/subtitle-content.ts" ) ;
@@ -126,6 +127,7 @@ describe("fetchSubtitles", () => {
126127 const requestHeaders = new Headers ( mockYoutubeFetch . mock . calls . at ( - 1 ) ?. [ 1 ] ?. headers ) ;
127128
128129 expect ( new TextDecoder ( ) . decode ( bytes ) . startsWith ( "WEBVTT" ) ) . toBe ( true ) ;
130+ expect ( mockYoutubeFetch ) . toHaveBeenCalledTimes ( 2 ) ;
129131 expect ( requested . searchParams . get ( "expire" ) ) . toBe ( "999" ) ;
130132 expect ( requested . searchParams . get ( "fmt" ) ) . toBe ( "vtt" ) ;
131133 expect ( requested . searchParams . get ( "tlang" ) ) . toBe ( "es" ) ;
@@ -139,7 +141,8 @@ describe("fetchSubtitles", () => {
139141 { ...frTrack , languageCode : "en" , vssId : ".en" } ,
140142 asrTrack ,
141143 ] ) ;
142- mockYoutubeFetch . mockImplementation ( async ( ) => new Response ( "WEBVTT\n\nAutomatic" ) ) ;
144+ mockYoutubeFetch . mockImplementationOnce ( async ( ) => new Response ( "" , { status : 403 } ) ) ;
145+ mockYoutubeFetch . mockImplementationOnce ( async ( ) => new Response ( "WEBVTT\n\nAutomatic" ) ) ;
143146 const { fetchSubtitleContent } = await import ( "../src/subtitle-content.ts" ) ;
144147 await fetchSubtitleContent (
145148 "https://www.youtube.com/api/timedtext?v=video&lang=en&kind=asr&expire=1" ,
@@ -151,6 +154,26 @@ describe("fetchSubtitles", () => {
151154 expect ( requested . searchParams . get ( "expire" ) ) . toBe ( "999" ) ;
152155 } ) ;
153156
157+ it ( "uses a current WEB track without replacing it through MWEB" , async ( ) => {
158+ mockFetchCaptionTracks . mockClear ( ) ;
159+ mockYoutubeFetch . mockClear ( ) ;
160+ mockYoutubeFetch . mockImplementationOnce (
161+ async ( ) => new Response ( "WEBVTT\n\n00:00.000 --> 00:01.000\nCurrent" ) ,
162+ ) ;
163+ const { fetchSubtitleContent } = await import ( "../src/subtitle-content.ts" ) ;
164+ const bytes = await fetchSubtitleContent (
165+ "https://www.youtube.com/api/timedtext?v=video&lang=en&expire=999&fmt=ttml" ,
166+ mockYoutubeFetch ,
167+ ) ;
168+ const requested = new URL ( String ( mockYoutubeFetch . mock . calls [ 0 ] ?. [ 0 ] ) ) ;
169+
170+ expect ( new TextDecoder ( ) . decode ( bytes ) . startsWith ( "WEBVTT" ) ) . toBe ( true ) ;
171+ expect ( requested . hostname ) . toBe ( "www.youtube.com" ) ;
172+ expect ( requested . searchParams . get ( "fmt" ) ) . toBe ( "vtt" ) ;
173+ expect ( mockFetchCaptionTracks ) . not . toHaveBeenCalled ( ) ;
174+ expect ( mockYoutubeFetch ) . toHaveBeenCalledTimes ( 1 ) ;
175+ } ) ;
176+
154177 it ( "returns a typed throttling failure without retrying" , async ( ) => {
155178 mockFetchCaptionTracks . mockImplementation ( async ( ) => [ asrTrack ] ) ;
156179 mockYoutubeFetch . mockClear ( ) ;
0 commit comments