Skip to content

Commit f3ac4da

Browse files
committed
test(rewrite): add unit tests for addYoutubeVideoFromId and addInvidiousVideo functions
1 parent 13986e9 commit f3ac4da

File tree

2 files changed

+142
-11
lines changed

2 files changed

+142
-11
lines changed

internal/reader/rewrite/content_rewrite_functions.go

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -273,9 +273,12 @@ func getYoutubVideoIDFromURL(entryURL string) string {
273273
return ""
274274
}
275275

276+
func buildVideoPlayerIframe(absoluteVideoURL string) string {
277+
return `<iframe width="650" height="350" frameborder="0" src="` + absoluteVideoURL + `" allowfullscreen></iframe>`
278+
}
279+
276280
func addVideoPlayerIframe(absoluteVideoURL, entryContent string) string {
277-
video := `<iframe width="650" height="350" frameborder="0" src="` + absoluteVideoURL + `" allowfullscreen></iframe>`
278-
return video + `<br>` + entryContent
281+
return buildVideoPlayerIframe(absoluteVideoURL) + `<br>` + entryContent
279282
}
280283

281284
func addYoutubeVideoRewriteRule(entryURL, entryContent string) string {
@@ -292,29 +295,25 @@ func addYoutubeVideoUsingInvidiousPlayer(entryURL, entryContent string) string {
292295
return entryContent
293296
}
294297

298+
// For reference: https://github.com/miniflux/v2/pull/1314
295299
func addYoutubeVideoFromId(entryContent string) string {
296300
matches := youtubeIdRegex.FindAllStringSubmatch(entryContent, -1)
297301
if matches == nil {
298302
return entryContent
299303
}
300-
sb := strings.Builder{}
304+
videoPlayerHTML := ""
301305
for _, match := range matches {
302306
if len(match) == 2 {
303-
sb.WriteString(`<iframe width="650" height="350" frameborder="0" src="`)
304-
sb.WriteString(config.Opts.YouTubeEmbedUrlOverride())
305-
sb.WriteString(match[1])
306-
sb.WriteString(`" allowfullscreen></iframe><br>`)
307+
videoPlayerHTML += buildVideoPlayerIframe(config.Opts.YouTubeEmbedUrlOverride()+match[1]) + "<br>"
307308
}
308309
}
309-
sb.WriteString(entryContent)
310-
return sb.String()
310+
return videoPlayerHTML + entryContent
311311
}
312312

313313
func addInvidiousVideo(entryURL, entryContent string) string {
314314
matches := invidioRegex.FindStringSubmatch(entryURL)
315315
if len(matches) == 3 {
316-
video := `<iframe width="650" height="350" frameborder="0" src="https://` + matches[1] + `/embed/` + matches[2] + `" allowfullscreen></iframe>`
317-
return video + `<br>` + entryContent
316+
return addVideoPlayerIframe(`https://`+matches[1]+`/embed/`+matches[2], entryContent)
318317
}
319318
return entryContent
320319
}

internal/reader/rewrite/content_rewrite_test.go

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
198330
func TestRewriteWithInexistingCustomRule(t *testing.T) {
199331
controlEntry := &model.Entry{
200332
URL: "https://www.youtube.com/watch?v=1234",

0 commit comments

Comments
 (0)