@@ -195,6 +195,138 @@ func TestRewriteYoutubeShortLinkUsingInvidious(t *testing.T) {
195195 }
196196}
197197
198+ func TestAddYoutubeVideoFromId (t * testing.T ) {
199+ config .Opts = config .NewOptions ()
200+
201+ scenarios := map [string ]string {
202+ // Test with single YouTube ID
203+ `Some content with youtube ID <script type="text/javascript" data-reactid="6">window.__APOLLO_STATE__ = {youtube_id: "9uASADiYe_8"}</script>` : `<iframe width="650" height="350" frameborder="0" src="https://www.youtube-nocookie.com/embed/9uASADiYe_8" allowfullscreen></iframe><br>Some content with youtube ID <script type="text/javascript" data-reactid="6">window.__APOLLO_STATE__ = {youtube_id: "9uASADiYe_8"}</script>` ,
204+
205+ // Test with multiple YouTube IDs
206+ `Content with youtube_id: "dQw4w9WgXcQ" and youtube_id: "jNQXAC9IVRw"` : `<iframe width="650" height="350" frameborder="0" src="https://www.youtube-nocookie.com/embed/dQw4w9WgXcQ" allowfullscreen></iframe><br><iframe width="650" height="350" frameborder="0" src="https://www.youtube-nocookie.com/embed/jNQXAC9IVRw" allowfullscreen></iframe><br>Content with youtube_id: "dQw4w9WgXcQ" and youtube_id: "jNQXAC9IVRw"` ,
207+
208+ // Test with YouTube ID using equals sign
209+ `Some content with youtube_id = "dQw4w9WgXcQ"` : `<iframe width="650" height="350" frameborder="0" src="https://www.youtube-nocookie.com/embed/dQw4w9WgXcQ" allowfullscreen></iframe><br>Some content with youtube_id = "dQw4w9WgXcQ"` ,
210+
211+ // Test with spaces around delimiters
212+ `Some content with youtube_id : "dQw4w9WgXcQ"` : `<iframe width="650" height="350" frameborder="0" src="https://www.youtube-nocookie.com/embed/dQw4w9WgXcQ" allowfullscreen></iframe><br>Some content with youtube_id : "dQw4w9WgXcQ"` ,
213+
214+ // Test with YouTube ID without quotes (regex requires quotes)
215+ `Some content with youtube_id: dQw4w9WgXcQ and more` : `Some content with youtube_id: dQw4w9WgXcQ and more` ,
216+
217+ // Test with no YouTube ID
218+ `Some regular content without any video ID` : `Some regular content without any video ID` ,
219+
220+ // Test with invalid YouTube ID (wrong length)
221+ `Some content with youtube_id: "invalid"` : `Some content with youtube_id: "invalid"` ,
222+
223+ // Test with empty content
224+ `` : `` ,
225+ }
226+
227+ for input , expected := range scenarios {
228+ actual := addYoutubeVideoFromId (input )
229+ if actual != expected {
230+ t .Errorf (`addYoutubeVideoFromId test failed for input "%s"` , input )
231+ t .Errorf (`Expected: "%s"` , expected )
232+ t .Errorf (`Actual: "%s"` , actual )
233+ }
234+ }
235+ }
236+
237+ func TestAddYoutubeVideoFromIdWithCustomEmbedURL (t * testing.T ) {
238+ os .Clearenv ()
239+ os .Setenv ("YOUTUBE_EMBED_URL_OVERRIDE" , "https://invidious.custom/embed/" )
240+
241+ var err error
242+ parser := config .NewParser ()
243+ config .Opts , err = parser .ParseEnvironmentVariables ()
244+
245+ if err != nil {
246+ t .Fatalf (`Parsing failure: %v` , err )
247+ }
248+
249+ input := `Some content with youtube_id: "dQw4w9WgXcQ"`
250+ expected := `<iframe width="650" height="350" frameborder="0" src="https://invidious.custom/embed/dQw4w9WgXcQ" allowfullscreen></iframe><br>Some content with youtube_id: "dQw4w9WgXcQ"`
251+
252+ actual := addYoutubeVideoFromId (input )
253+ if actual != expected {
254+ t .Errorf (`addYoutubeVideoFromId with custom embed URL failed` )
255+ t .Errorf (`Expected: "%s"` , expected )
256+ t .Errorf (`Actual: "%s"` , actual )
257+ }
258+ }
259+
260+ func TestAddInvidiousVideo (t * testing.T ) {
261+ scenarios := map [string ][]string {
262+ // Test with various Invidious instances
263+ "https://invidious.io/watch?v=dQw4w9WgXcQ" : {
264+ "Some video content" ,
265+ `<iframe width="650" height="350" frameborder="0" src="https://invidious.io/embed/dQw4w9WgXcQ" allowfullscreen></iframe><br>Some video content` ,
266+ },
267+ "https://yewtu.be/watch?v=jNQXAC9IVRw" : {
268+ "Another video description" ,
269+ `<iframe width="650" height="350" frameborder="0" src="https://yewtu.be/embed/jNQXAC9IVRw" allowfullscreen></iframe><br>Another video description` ,
270+ },
271+ "http://invidious.snopyta.org/watch?v=dQw4w9WgXcQ" : {
272+ "HTTP instance test" ,
273+ `<iframe width="650" height="350" frameborder="0" src="https://invidious.snopyta.org/embed/dQw4w9WgXcQ" allowfullscreen></iframe><br>HTTP instance test` ,
274+ },
275+ "https://youtube.com/watch?v=dQw4w9WgXcQ" : {
276+ "YouTube URL (also matches regex)" ,
277+ `<iframe width="650" height="350" frameborder="0" src="https://youtube.com/embed/dQw4w9WgXcQ" allowfullscreen></iframe><br>YouTube URL (also matches regex)` ,
278+ },
279+ "https://example.org/watch?v=dQw4w9WgXcQ" : {
280+ "Any domain with watch pattern" ,
281+ `<iframe width="650" height="350" frameborder="0" src="https://example.org/embed/dQw4w9WgXcQ" allowfullscreen></iframe><br>Any domain with watch pattern` ,
282+ },
283+
284+ // Test with query parameters
285+ "https://invidious.io/watch?v=dQw4w9WgXcQ&t=30s" : {
286+ "Video with timestamp" ,
287+ `<iframe width="650" height="350" frameborder="0" src="https://invidious.io/embed/dQw4w9WgXcQ&t=30s" allowfullscreen></iframe><br>Video with timestamp` ,
288+ },
289+
290+ // Test with more complex query parameters
291+ "https://invidious.io/watch?v=dQw4w9WgXcQ&t=30s&autoplay=1" : {
292+ "Video with multiple parameters" ,
293+ `<iframe width="650" height="350" frameborder="0" src="https://invidious.io/embed/dQw4w9WgXcQ&t=30s&autoplay=1" allowfullscreen></iframe><br>Video with multiple parameters` ,
294+ },
295+
296+ // Test with non-matching URLs (should return content unchanged)
297+ "https://invidious.io/" : {
298+ "Invidious homepage" ,
299+ "Invidious homepage" ,
300+ },
301+ "https://invidious.io/some-other-page" : {
302+ "Other page" ,
303+ "Other page" ,
304+ },
305+ "https://invidious.io/search?q=test" : {
306+ "Search page" ,
307+ "Search page" ,
308+ },
309+
310+ // Test with empty content
311+ "https://empty.invidious.io/watch?v=dQw4w9WgXcQ" : {
312+ "" ,
313+ `<iframe width="650" height="350" frameborder="0" src="https://empty.invidious.io/embed/dQw4w9WgXcQ" allowfullscreen></iframe><br>` ,
314+ },
315+ }
316+
317+ for entryURL , testData := range scenarios {
318+ entryContent := testData [0 ]
319+ expected := testData [1 ]
320+
321+ actual := addInvidiousVideo (entryURL , entryContent )
322+ if actual != expected {
323+ t .Errorf (`addInvidiousVideo test failed for URL "%s" and content "%s"` , entryURL , entryContent )
324+ t .Errorf (`Expected: "%s"` , expected )
325+ t .Errorf (`Actual: "%s"` , actual )
326+ }
327+ }
328+ }
329+
198330func TestRewriteWithInexistingCustomRule (t * testing.T ) {
199331 controlEntry := & model.Entry {
200332 URL : "https://www.youtube.com/watch?v=1234" ,
0 commit comments