From aaf7077364e8c3f62c948b3c62a4faa69a14dc6c Mon Sep 17 00:00:00 2001 From: jj Date: Wed, 13 Nov 2024 16:08:43 +0000 Subject: [PATCH 1/4] api/test: split up tests into individual files --- api/src/util/test-ci.js | 20 +- api/src/util/tests.json | 1550 --------------------------- api/src/util/tests/bilibili.json | 60 ++ api/src/util/tests/bsky.json | 78 ++ api/src/util/tests/dailymotion.json | 29 + api/src/util/tests/facebook.json | 67 ++ api/src/util/tests/instagram.json | 123 +++ api/src/util/tests/loom.json | 33 + api/src/util/tests/ok.json | 11 + api/src/util/tests/pinterest.json | 87 ++ api/src/util/tests/reddit.json | 60 ++ api/src/util/tests/rutube.json | 90 ++ api/src/util/tests/snapchat.json | 29 + api/src/util/tests/soundcloud.json | 87 ++ api/src/util/tests/streamable.json | 51 + api/src/util/tests/tiktok.json | 38 + api/src/util/tests/tumblr.json | 49 + api/src/util/tests/twitch.json | 33 + api/src/util/tests/twitter.json | 213 ++++ api/src/util/tests/vimeo.json | 64 ++ api/src/util/tests/vine.json | 33 + api/src/util/tests/vk.json | 77 ++ api/src/util/tests/youtube.json | 240 +++++ 23 files changed, 1566 insertions(+), 1556 deletions(-) delete mode 100644 api/src/util/tests.json create mode 100644 api/src/util/tests/bilibili.json create mode 100644 api/src/util/tests/bsky.json create mode 100644 api/src/util/tests/dailymotion.json create mode 100644 api/src/util/tests/facebook.json create mode 100644 api/src/util/tests/instagram.json create mode 100644 api/src/util/tests/loom.json create mode 100644 api/src/util/tests/ok.json create mode 100644 api/src/util/tests/pinterest.json create mode 100644 api/src/util/tests/reddit.json create mode 100644 api/src/util/tests/rutube.json create mode 100644 api/src/util/tests/snapchat.json create mode 100644 api/src/util/tests/soundcloud.json create mode 100644 api/src/util/tests/streamable.json create mode 100644 api/src/util/tests/tiktok.json create mode 100644 api/src/util/tests/tumblr.json create mode 100644 api/src/util/tests/twitch.json create mode 100644 api/src/util/tests/twitter.json create mode 100644 api/src/util/tests/vimeo.json create mode 100644 api/src/util/tests/vine.json create mode 100644 api/src/util/tests/vk.json create mode 100644 api/src/util/tests/youtube.json diff --git a/api/src/util/test-ci.js b/api/src/util/test-ci.js index 3a0352cb8..5a1d6300c 100644 --- a/api/src/util/test-ci.js +++ b/api/src/util/test-ci.js @@ -1,3 +1,5 @@ +import path from "node:path"; + import { env } from "../config.js"; import { runTest } from "../misc/run-test.js"; import { loadJSON } from "../misc/load-from-fs.js"; @@ -6,7 +8,8 @@ import { randomizeCiphers } from "../misc/randomize-ciphers.js"; import { services } from "../processing/service-config.js"; -const tests = loadJSON('./src/util/tests.json'); +const getTestPath = service => path.join('./src/util/tests/', `./${service}.json`); +const getTests = (service) => loadJSON(getTestPath(service)); // services that are known to frequently fail due to external // factors (e.g. rate limiting) @@ -18,12 +21,14 @@ switch (action) { const fromConfig = Object.keys(services); const missingTests = fromConfig.filter( - service => !tests[service] || tests[service].length === 0 + service => { + const tests = getTests(service); + return !tests || tests.length === 0 + } ); if (missingTests.length) { console.error('services have no tests:', missingTests); - console.log('[]'); process.exitCode = 1; break; } @@ -34,16 +39,19 @@ switch (action) { case "run-tests-for": const service = process.argv[3]; let failed = false; + const tests = getTests(service); - if (!tests[service]) { + if (!tests) { console.error('no such service:', service); + process.exitCode = 1; + break; } - env.streamLifespan = 3; + env.streamLifespan = 10000; env.apiURL = 'http://x'; randomizeCiphers(); - for (const test of tests[service]) { + for (const test of tests) { const { name, url, params, expected } = test; const canFail = test.canFail || finnicky.has(service); diff --git a/api/src/util/tests.json b/api/src/util/tests.json deleted file mode 100644 index 72f00ad42..000000000 --- a/api/src/util/tests.json +++ /dev/null @@ -1,1550 +0,0 @@ -{ - "twitter": [ - { - "name": "regular video", - "url": "https://twitter.com/X/status/1697304622749086011", - "params": { - "audioFormat": "mp3" - }, - "expected": { - "code": 200, - "status": "redirect" - } - }, - { - "name": "video with mobile web mediaviewer", - "url": "https://twitter.com/X/status/1697304622749086011/mediaViewer?currentTweet=1697304622749086011¤tTweetUser=X¤tTweet=1697304622749086011¤tTweetUser=X", - "params": {}, - "expected": { - "code": 200, - "status": "redirect" - } - }, - { - "name": "embedded twitter video", - "url": "https://twitter.com/dustbin_nie/status/1624596567188717568?s=20", - "params": { - "audioFormat": "mp3" - }, - "expected": { - "code": 200, - "status": "redirect" - } - }, - { - "name": "mixed media (image + gif)", - "url": "https://twitter.com/sky_mj26/status/1807756010712428565", - "params": { - "audioFormat": "mp3" - }, - "expected": { - "code": 200, - "status": "picker" - } - }, - { - "name": "picker: mixed media (3 videos)", - "url": "https://twitter.com/DankGameAlert/status/1584726006094794774", - "params": { - "audioFormat": "mp3" - }, - "expected": { - "code": 200, - "status": "picker" - } - }, - { - "name": "audio from embedded twitter video (mp3, isAudioOnly)", - "url": "https://twitter.com/dustbin_nie/status/1624596567188717568?s=20", - "params": { - "downloadMode": "audio", - "audioFormat": "mp3" - }, - "expected": { - "code": 200, - "status": "tunnel" - } - }, - { - "name": "audio from embedded twitter video (best, isAudioOnly)", - "url": "https://twitter.com/dustbin_nie/status/1624596567188717568?s=20", - "params": { - "downloadMode": "audio", - "audioFormat": "best" - }, - "expected": { - "code": 200, - "status": "tunnel" - } - }, - { - "name": "audio from embedded twitter video (ogg, isAudioOnly, isAudioMuted)", - "url": "https://twitter.com/dustbin_nie/status/1624596567188717568?s=20", - "params": { - "downloadMode": "audio", - "audioFormat": "best" - }, - "expected": { - "code": 200, - "status": "tunnel" - } - }, - { - "name": "muted embedded twitter video", - "url": "https://twitter.com/dustbin_nie/status/1624596567188717568?s=20", - "params": { - "downloadMode": "mute", - "audioFormat": "mp3" - }, - "expected": { - "code": 200, - "status": "tunnel" - } - }, - { - "name": "retweeted video", - "url": "https://twitter.com/uwukko/status/1696901469633421344", - "params": {}, - "canFail": true, - "expected": { - "code": 200, - "status": "redirect" - } - }, - { - "name": "age restricted video", - "url": "https://x.com/XSpaces/status/1526955853743546372", - "params": {}, - "canFail": true, - "expected": { - "code": 200, - "status": "redirect" - } - }, - { - "name": "twitter voice + x.com link", - "url": "https://x.com/eggsaladscreams/status/1693089534886506756?s=46", - "params": {}, - "canFail": true, - "expected": { - "code": 200, - "status": "redirect" - } - }, - { - "name": "vxtwitter link", - "url": "https://vxtwitter.com/dustbin_nie/status/1624596567188717568?s=20", - "params": {}, - "expected": { - "code": 200, - "status": "redirect" - } - }, - { - "name": "post with 1 image", - "url": "https://x.com/PopCrave/status/1815960083475423235", - "params": {}, - "expected": { - "code": 200, - "status": "redirect" - } - }, - { - "name": "post with 4 images", - "url": "https://x.com/PopCrave/status/1816260887147114696", - "params": {}, - "expected": { - "code": 200, - "status": "picker" - } - }, - { - "name": "retweeted video, isAudioOnly", - "url": "https://twitter.com/hugekiwinuts/status/1618671150829309953?s=46&t=gItGzgwGQQJJaJrO6qc1Pg", - "params": { - "downloadMode": "mute", - "audioFormat": "mp3" - }, - "canFail": true, - "expected": { - "code": 200, - "status": "tunnel" - } - }, - { - "name": "inexistent post", - "url": "https://twitter.com/test/status/9487653", - "params": { - "audioFormat": "best" - }, - "expected": { - "code": 400, - "status": "error" - } - }, - { - "name": "post with no media content", - "url": "https://twitter.com/elonmusk/status/1604617643973124097?s=20", - "params": { - "audioFormat": "best" - }, - "expected": { - "code": 400, - "status": "error" - } - }, - { - "name": "bookmarked video", - "url": "https://twitter.com/i/bookmarks?post_id=1828099210220294314", - "params": {}, - "expected": { - "code": 200, - "status": "redirect" - } - }, - { - "name": "bookmarked photo", - "url": "https://twitter.com/i/bookmarks?post_id=1837430141179289876", - "params": {}, - "expected": { - "code": 200, - "status": "redirect" - } - } - ], - "soundcloud": [ - { - "name": "public song (best)", - "url": "https://soundcloud.com/l2share77/loona-butterfly?utm_source=clipboard&utm_medium=text&utm_campaign=social_sharing", - "params": { - "audioFormat": "best" - }, - "expected": { - "code": 200, - "status": "tunnel" - } - }, - { - "name": "public song (mp3, isAudioMuted)", - "url": "https://soundcloud.com/l2share77/loona-butterfly?utm_source=clipboard&utm_medium=text&utm_campaign=social_sharing", - "params": { - "downloadMode": "mute", - "audioFormat": "mp3" - }, - "expected": { - "code": 200, - "status": "tunnel" - } - }, - { - "name": "private song", - "url": "https://soundcloud.com/user-798052861/asdasdasdsdsd/s-9TqZ7edLJ90", - "params": { - "audioFormat": "mp3" - }, - "expected": { - "code": 200, - "status": "tunnel" - } - }, - { - "name": "private song (wav, isAudioMuted)", - "url": "https://soundcloud.com/user-798052861/asdasdasdsdsd/s-9TqZ7edLJ90", - "params": { - "downloadMode": "mute", - "audioFormat": "wav" - }, - "expected": { - "code": 200, - "status": "tunnel" - } - }, - { - "name": "private song (ogg, isAudioMuted, isAudioOnly)", - "url": "https://soundcloud.com/user-798052861/asdasdasdsdsd/s-9TqZ7edLJ90", - "params": { - "downloadMode": "audio", - "audioFormat": "ogg" - }, - "expected": { - "code": 200, - "status": "tunnel" - } - }, - { - "name": "on.soundcloud link", - "url": "https://on.soundcloud.com/wLZre", - "params": {}, - "expected": { - "code": 200, - "status": "tunnel" - } - }, - { - "name": "on.soundcloud link, different stream type", - "url": "https://on.soundcloud.com/AG4c", - "params": {}, - "expected": { - "code": 200, - "status": "tunnel" - } - }, - { - "name": "no opus audio, fallback to mp3", - "url": "https://soundcloud.com/frums/credits", - "params": {}, - "expected": { - "code": 200, - "status": "tunnel" - } - } - ], - "youtube": [ - { - "name": "4k video (h264, 1440)", - "url": "https://www.youtube.com/watch?v=vPwaXytZcgI", - "params": { - "youtubeVideoCodec": "h264", - "videoQuality": "1440" - }, - "expected": { - "code": 200, - "status": "tunnel" - } - }, - { - "name": "4k video (vp9, 720)", - "url": "https://www.youtube.com/watch?v=vPwaXytZcgI", - "params": { - "youtubeVideoCodec": "vp9", - "videoQuality": "720" - }, - "expected": { - "code": 200, - "status": "tunnel" - } - }, - { - "name": "4k video (av1, max)", - "url": "https://www.youtube.com/watch?v=vPwaXytZcgI", - "params": { - "youtubeVideoCodec": "av1", - "videoQuality": "max" - }, - "expected": { - "code": 200, - "status": "tunnel" - } - }, - { - "name": "4k video (h264, 720)", - "url": "https://www.youtube.com/watch?v=vPwaXytZcgI", - "params": { - "youtubeVideoCodec": "h264", - "videoQuality": "720" - }, - "expected": { - "code": 200, - "status": "tunnel" - } - }, - { - "name": "4k video (vp9, max, isAudioMuted)", - "url": "https://www.youtube.com/watch?v=vPwaXytZcgI", - "params": { - "downloadMode": "mute", - "youtubeVideoCodec": "vp9", - "videoQuality": "max" - }, - "expected": { - "code": 200, - "status": "tunnel" - } - }, - { - "name": "4k video (h264, max, isAudioMuted)", - "url": "https://www.youtube.com/watch?v=vPwaXytZcgI", - "params": { - "downloadMode": "mute", - "youtubeVideoCodec": "h264", - "videoQuality": "max" - }, - "expected": { - "code": 200, - "status": "tunnel" - } - }, - { - "name": "4k video (av1, max, isAudioMuted, isAudioOnly, mp3)", - "url": "https://www.youtube.com/watch?v=vPwaXytZcgI", - "params": { - "downloadMode": "audio", - "audioFormat": "mp3", - "youtubeVideoCodec": "av1", - "videoQuality": "max" - }, - "expected": { - "code": 200, - "status": "tunnel" - } - }, - { - "name": "4k video (av1, max, isAudioMuted, isAudioOnly, best)", - "url": "https://www.youtube.com/watch?v=vPwaXytZcgI", - "params": { - "downloadMode": "audio", - "audioFormat": "best", - "youtubeVideoCodec": "av1", - "videoQuality": "max" - }, - "expected": { - "code": 200, - "status": "tunnel" - } - }, - { - "name": "music (mp3, isAudioOnly, isAudioMuted)", - "url": "https://music.youtube.com/watch?v=5rGTsvZCEdk&feature=share", - "params": { - "downloadMode": "audio", - "audioFormat": "mp3" - }, - "expected": { - "code": 200, - "status": "tunnel" - } - }, - { - "name": "music (mp3)", - "url": "https://music.youtube.com/watch?v=5rGTsvZCEdk&feature=share", - "params": { - "audioFormat": "mp3" - }, - "expected": { - "code": 200, - "status": "tunnel" - } - }, - { - "name": "audio bitrate higher than video, no vp9 video in response (mp3, isAudioOnly)", - "url": "https://www.youtube.com/watch?v=t5nC_ucYBrc", - "params": { - "downloadMode": "audio", - "audioFormat": "mp3" - }, - "expected": { - "code": 200, - "status": "tunnel" - } - }, - { - "name": "short, defaults", - "url": "https://www.youtube.com/shorts/r5FpeOJItbw", - "params": {}, - "expected": { - "code": 200, - "status": "tunnel" - } - }, - { - "name": "vr 360, av1, max", - "url": "https://www.youtube.com/watch?v=hEdzv7D4CbQ", - "params": { - "youtubeVideoCodec": "vp9", - "videoQuality": "max" - }, - "expected": { - "code": 200, - "status": "tunnel" - } - }, - { - "name": "live link, defaults", - "url": "https://www.youtube.com/live/ENxZS6PUDuI?feature=shared", - "params": {}, - "expected": { - "code": 200, - "status": "tunnel" - } - }, - { - "name": "inexistent video", - "url": "https://youtube.com/watch?v=gnjuHYWGEW", - "params": {}, - "expected": { - "code": 400, - "status": "error" - } - }, - { - "name": "broken audioOnly download", - "url": "https://www.youtube.com/watch?v=ink80Al5nbw", - "params": { - "downloadMode": "audio" - }, - "expected": { - "code": 200, - "status": "tunnel" - } - }, { - "name": "hls video (h264, 1440p)", - "url": "https://www.youtube.com/watch?v=vPwaXytZcgI", - "params": { - "youtubeVideoCodec": "h264", - "videoQuality": "1440", - "youtubeHLS": true - }, - "expected": { - "code": 200, - "status": "tunnel" - } - }, { - "name": "hls video (vp9, 360p)", - "url": "https://www.youtube.com/watch?v=vPwaXytZcgI", - "params": { - "youtubeVideoCodec": "vp9", - "videoQuality": "360", - "youtubeHLS": true - }, - "expected": { - "code": 200, - "status": "tunnel" - } - }, { - "name": "hls video (audio mode)", - "url": "https://www.youtube.com/watch?v=vPwaXytZcgI", - "params": { - "downloadMode": "audio", - "youtubeHLS": true - }, - "expected": { - "code": 200, - "status": "tunnel" - } - }, { - "name": "hls video (audio mode, best format)", - "url": "https://www.youtube.com/watch?v=vPwaXytZcgI", - "params": { - "downloadMode": "audio", - "youtubeHLS": true, - "audioFormat": "best" - }, - "expected": { - "code": 200, - "status": "tunnel" - } - } - ], - "vk": [ - { - "name": "clip, defaults", - "canFail": true, - "url": "https://vk.com/clip-57274055_456239788", - "params": {}, - "expected": { - "code": 200, - "status": "tunnel" - } - }, - { - "name": "clip, 360", - "canFail": true, - "url": "https://vk.com/clip-57274055_456239788", - "params": { - "videoQuality": "360" - }, - "expected": { - "code": 200, - "status": "tunnel" - } - }, - { - "name": "clip different link, max", - "canFail": true, - "url": "https://vk.com/clips-57274055?z=clip-57274055_456239788", - "params": { - "videoQuality": "max" - }, - "expected": { - "code": 200, - "status": "tunnel" - } - }, - { - "name": "video, defaults", - "canFail": true, - "url": "https://vk.com/video-57274055_456239399", - "params": {}, - "expected": { - "code": 200, - "status": "tunnel" - } - }, - { - "name": "4k video", - "canFail": true, - "url": "https://vk.com/video-1112285_456248465", - "params": { - "videoQuality": "max" - }, - "expected": { - "code": 200, - "status": "tunnel" - } - }, - { - "name": "ancient video (fallback to 240p)", - "canFail": true, - "url": "https://vk.com/video-1959_28496479", - "params": {}, - "expected": { - "code": 200, - "status": "tunnel" - } - }, - { - "name": "inexistent video", - "url": "https://vk.com/video-53333333_456233333", - "params": {}, - "expected": { - "code": 400, - "status": "error" - } - } - ], - "tiktok": [ - { - "name": "long link video", - "url": "https://www.tiktok.com/@fatfatmillycat/video/7195741644585454894", - "params": {}, - "expected": { - "code": 200, - "status": "tunnel" - } - }, - { - "name": "images", - "url": "https://www.tiktok.com/@matryoshk4/video/7231234675476532526", - "params": {}, - "expected": { - "code": 200, - "status": "picker" - } - }, - { - "name": "long link inexistent", - "url": "https://www.tiktok.com/@blablabla/video/7120851458451417478", - "params": {}, - "expected": { - "code": 400, - "status": "error" - } - }, - { - "name": "short link inexistent", - "url": "https://vt.tiktok.com/2p4ewa7/", - "params": {}, - "expected": { - "code": 400, - "status": "error" - } - } - ], - "bilibili": [ - { - "name": "1080p video", - "url": "https://www.bilibili.com/video/BV18i4y1m7xV/", - "params": {}, - "expected": { - "code": 200, - "status": "tunnel" - } - }, - { - "name": "1080p video muted", - "url": "https://www.bilibili.com/video/BV18i4y1m7xV/", - "params": { - "downloadMode": "mute" - }, - "expected": { - "code": 200, - "status": "tunnel" - } - }, - { - "name": "1080p vertical video", - "url": "https://www.bilibili.com/video/BV1uu411z7VV/", - "params": {}, - "expected": { - "code": 200, - "status": "tunnel" - } - }, - { - "name": "1080p vertical video muted", - "url": "https://www.bilibili.com/video/BV1uu411z7VV/", - "params": { - "downloadMode": "mute" - }, - "expected": { - "code": 200, - "status": "tunnel" - } - }, - { - "name": "b23.tv shortlink", - "url": "https://b23.tv/lbMyOI9", - "params": {}, - "expected": { - "code": 200, - "status": "tunnel" - } - }, - { - "name": "bilibili.tv link", - "url": "https://www.bilibili.tv/en/video/4789599404426256", - "params": {}, - "expected": { - "code": 200, - "status": "tunnel" - } - } - ], - "tumblr": [ - { - "name": "at.tumblr link", - "url": "https://at.tumblr.com/music/704177038274281472/n7x7pr7x4w2b", - "params": {}, - "expected": { - "code": 200, - "status": "redirect" - } - }, - { - "name": "user subdomain link", - "url": "https://garfield-69.tumblr.com/post/696499862852780032", - "params": {}, - "expected": { - "code": 200, - "status": "redirect" - } - }, - { - "name": "web app link", - "url": "https://www.tumblr.com/rongzhi/707729381162958848/english-added-by-me?source=share", - "params": {}, - "expected": { - "code": 200, - "status": "redirect" - } - }, - { - "name": "tumblr audio", - "url": "https://www.tumblr.com/zedneon/737815079301562368/zedneon-ft-mr-sauceman-tech-n9ne-speed-of?source=share", - "params": {}, - "expected": { - "code": 200, - "status": "tunnel" - } - }, - { - "name": "tumblr video converted to audio", - "url": "https://garfield-69.tumblr.com/post/696499862852780032", - "params": { - "downloadMode": "audio" - }, - "expected": { - "code": 200, - "status": "tunnel" - } - } - ], - "vimeo": [ - { - "name": "4k progressive", - "url": "https://vimeo.com/288386543", - "params": { - "videoQuality": "2160" - }, - "expected": { - "code": 200, - "status": "redirect" - } - }, - { - "name": "720p progressive", - "url": "https://vimeo.com/288386543", - "params": { - "videoQuality": "720" - }, - "expected": { - "code": 200, - "status": "redirect" - } - }, - { - "name": "1080p dash parcel", - "url": "https://vimeo.com/967252742", - "params": { - "videoQuality": "1440" - }, - "expected": { - "code": 200, - "status": "redirect" - } - }, - { - "name": "720p dash parcel", - "url": "https://vimeo.com/967252742", - "params": { - "videoQuality": "360" - }, - "expected": { - "code": 200, - "status": "redirect" - } - }, - { - "name": "private video", - "url": "https://vimeo.com/903115595/f14d06da38", - "params": {}, - "expected": { - "code": 200, - "status": "redirect" - } - }, - { - "name": "mature video", - "url": "https://vimeo.com/973212054", - "params": {}, - "expected": { - "code": 200, - "status": "redirect" - } - } - ], - "reddit": [ - { - "name": "video with audio", - "url": "https://www.reddit.com/r/TikTokCringe/comments/wup1fg/id_be_escaping_at_the_first_chance_i_got/?utm_source=share&utm_medium=web2x&context=3", - "params": {}, - "expected": { - "code": 200, - "status": "tunnel" - } - }, - { - "name": "video with audio (isAudioOnly)", - "url": "https://www.reddit.com/r/TikTokCringe/comments/wup1fg/id_be_escaping_at_the_first_chance_i_got/?utm_source=share&utm_medium=web2x&context=3", - "params": { - "downloadMode": "audio" - }, - "expected": { - "code": 200, - "status": "tunnel" - } - }, - { - "name": "video with audio (isAudioMuted)", - "url": "https://www.reddit.com/r/TikTokCringe/comments/wup1fg/id_be_escaping_at_the_first_chance_i_got/?utm_source=share&utm_medium=web2x&context=3", - "params": { - "downloadMode": "mute" - }, - "expected": { - "code": 200, - "status": "tunnel" - } - }, - { - "name": "video without audio", - "url": "https://www.reddit.com/r/catvideos/comments/ftoeo7/luna_doesnt_want_to_be_bothered_while_shes_napping/?utm_source=share&utm_medium=web2x&context=3", - "params": {}, - "expected": { - "code": 200, - "status": "redirect" - } - }, - { - "name": "actual gif, not looping video", - "url": "https://www.reddit.com/r/whenthe/comments/109wqy1/god_really_did_some_trolling/?utm_source=share&utm_medium=web2x&context=3", - "params": {}, - "expected": { - "code": 200, - "status": "redirect" - } - }, - { - "name": "different audio link, live render", - "url": "https://www.reddit.com/r/TikTokCringe/comments/15hce91/asian_daddy_kink/", - "params": {}, - "expected": { - "code": 200, - "status": "tunnel" - } - } - ], - "instagram": [ - { - "name": "single photo post", - "url": "https://www.instagram.com/p/CwIgW8Yu5-I/", - "params": {}, - "expected": { - "code": 200, - "status": "redirect" - } - }, - { - "name": "various picker (photos + video)", - "url": "https://www.instagram.com/p/CvYrSgnsKjv/", - "params": {}, - "expected": { - "code": 200, - "status": "picker" - } - }, - { - "name": "reel", - "url": "https://www.instagram.com/reel/CoEBV3eM4QR/", - "params": {}, - "expected": { - "code": 200, - "status": "redirect" - } - }, - { - "name": "regular video", - "url": "https://www.instagram.com/p/CmCVWoIr9OH/", - "params": {}, - "expected": { - "code": 200, - "status": "redirect" - } - }, - { - "name": "reel (isAudioOnly)", - "url": "https://www.instagram.com/reel/CoEBV3eM4QR/", - "params": { - "downloadMode": "audio" - }, - "expected": { - "code": 200, - "status": "tunnel" - } - }, - { - "name": "reel (isAudioMuted)", - "url": "https://www.instagram.com/reel/CoEBV3eM4QR/", - "params": { - "downloadMode": "mute" - }, - "expected": { - "code": 200, - "status": "tunnel" - } - }, - { - "name": "inexistent reel", - "url": "https://www.instagram.com/reel/XXXXXXXXXX/", - "params": {}, - "expected": { - "code": 400, - "status": "error" - } - }, - { - "name": "inexistent post", - "url": "https://www.instagram.com/p/XXXXXXXXXX/", - "params": {}, - "expected": { - "code": 400, - "status": "error" - } - }, - { - "name": "post info in an array (for whatever reason??)", - "url": "https://www.instagram.com/reel/CrVB9tatUDv/?igshid=blaBlABALALbLABULLSHIT==", - "params": {}, - "expected": { - "code": 200, - "status": "redirect" - } - }, - { - "name": "prone to get rate limited", - "url": "https://www.instagram.com/reel/CrO-T7Qo6rq/?igshid=fuckYouNoTrackingIdForYou==", - "params": {}, - "expected": { - "code": 200, - "status": "redirect" - } - }, - { - "name": "ddinstagram link", - "url": "https://ddinstagram.com/p/CmCVWoIr9OH/", - "params": {}, - "expected": { - "code": 200, - "status": "redirect" - } - }, - { - "name": "d.ddinstagram.com link", - "url": "https://d.ddinstagram.com/p/CmCVWoIr9OH/", - "params": {}, - "expected": { - "code": 200, - "status": "redirect" - } - }, - { - "name": "g.ddinstagram.com link", - "url": "https://g.ddinstagram.com/p/CmCVWoIr9OH/", - "params": {}, - "expected": { - "code": 200, - "status": "redirect" - } - } - ], - "vine": [ - { - "name": "regular vine link (9+10=21)", - "url": "https://vine.co/v/huwVJIEJW50", - "params": {}, - "expected": { - "code": 200, - "status": "redirect" - } - }, - { - "name": "regular vine link (isAudioOnly)", - "url": "https://vine.co/v/huwVJIEJW50", - "params": { - "downloadMode": "audio" - }, - "expected": { - "code": 200, - "status": "tunnel" - } - }, - { - "name": "regular vine link (isAudioMuted)", - "url": "https://vine.co/v/huwVJIEJW50", - "params": { - "downloadMode": "mute" - }, - "expected": { - "code": 200, - "status": "tunnel" - } - } - ], - "pinterest": [ - { - "name": "regular video", - "url": "https://www.pinterest.com/pin/70437485604616/", - "params": {}, - "expected": { - "code": 200, - "status": "redirect" - } - }, - { - "name": "regular video (isAudioOnly)", - "url": "https://www.pinterest.com/pin/70437485604616/", - "params": { - "downloadMode": "audio" - }, - "expected": { - "code": 200, - "status": "tunnel" - } - }, - { - "name": "regular video (isAudioMuted)", - "url": "https://www.pinterest.com/pin/70437485604616/", - "params": { - "downloadMode": "mute" - }, - "expected": { - "code": 200, - "status": "tunnel" - } - }, - { - "name": "regular video (.ca TLD)", - "url": "https://www.pinterest.ca/pin/70437485604616/", - "params": {}, - "expected": { - "code": 200, - "status": "redirect" - } - }, - { - "name": "story", - "url": "https://www.pinterest.com/pin/gadget-cool-products-amazon-product-technology-kitchen-gadgets--1084663891475263837/", - "params": {}, - "expected": { - "code": 200, - "status": "redirect" - } - }, - { - "name": "regular picture", - "url": "https://www.pinterest.com/pin/412994228343400946/", - "params": {}, - "expected": { - "code": 200, - "status": "redirect" - } - }, - { - "name": "regular picture (.ca TLD)", - "url": "https://www.pinterest.ca/pin/412994228343400946/", - "params": {}, - "expected": { - "code": 200, - "status": "redirect" - } - }, - { - "name": "regular gif", - "url": "https://www.pinterest.com/pin/814447913881127862/", - "params": {}, - "expected": { - "code": 200, - "status": "redirect" - } - }, - { - "name": "regular gif (.ca TLD)", - "url": "https://www.pinterest.ca/pin/814447913881127862/", - "params": {}, - "expected": { - "code": 200, - "status": "redirect" - } - } - ], - "streamable": [ - { - "name": "regular video", - "url": "https://streamable.com/p9cln4", - "params": {}, - "expected": { - "code": 200, - "status": "redirect" - } - }, - { - "name": "embedded link", - "url": "https://streamable.com/e/rsmo56", - "params": {}, - "expected": { - "code": 200, - "status": "redirect" - } - }, - { - "name": "regular video (isAudioOnly)", - "url": "https://streamable.com/p9cln4", - "params": { - "downloadMode": "audio" - }, - "expected": { - "code": 200, - "status": "tunnel" - } - }, - { - "name": "regular video (isAudioMuted)", - "url": "https://streamable.com/p9cln4", - "params": { - "downloadMode": "mute" - }, - "expected": { - "code": 200, - "status": "tunnel" - } - }, - { - "name": "inexistent video", - "url": "https://streamable.com/XXXXXX", - "params": {}, - "expected": { - "code": 400, - "status": "error" - } - } - ], - "twitch": [ - { - "name": "clip", - "url": "https://twitch.tv/rtgame/clip/TubularInventiveSardineCorgiDerp-PM47mJQQ2vsL5B5G", - "params": {}, - "expected": { - "code": 200, - "status": "redirect" - } - }, - { - "name": "clip (isAudioOnly)", - "url": "https://twitch.tv/rtgame/clip/TubularInventiveSardineCorgiDerp-PM47mJQQ2vsL5B5G", - "params": { - "downloadMode": "audio" - }, - "expected": { - "code": 200, - "status": "tunnel" - } - }, - { - "name": "clip (isAudioMuted)", - "url": "https://twitch.tv/rtgame/clip/TubularInventiveSardineCorgiDerp-PM47mJQQ2vsL5B5G", - "params": { - "downloadMode": "mute" - }, - "expected": { - "code": 200, - "status": "tunnel" - } - } - ], - "rutube": [ - { - "name": "regular video", - "url": "https://rutube.ru/video/b2f6c27649907c2fde0af411b03825eb/", - "params": {}, - "expected": { - "code": 200, - "status": "tunnel" - } - }, - { - "name": "vertical video (isAudioMuted)", - "url": "https://rutube.ru/video/18a281399b96f9184c647455a86f6724/", - "params": { - "downloadMode": "mute" - }, - "expected": { - "code": 200, - "status": "tunnel" - } - }, - { - "name": "russian region lock", - "url": "https://rutube.ru/video/b521653b4f71ece57b8ff54e57ca9b82/", - "params": {}, - "expected": { - "code": 400, - "status": "error" - } - }, - { - "name": "vertical video", - "url": "https://rutube.ru/video/18a281399b96f9184c647455a86f6724/", - "params": {}, - "expected": { - "code": 200, - "status": "tunnel" - } - }, - { - "name": "yappy", - "url": "https://rutube.ru/yappy/c8c32bf7aee04412837656ea26c2b25b/", - "canFail": true, - "params": {}, - "expected": { - "code": 200, - "status": "tunnel" - } - }, - { - "name": "shorts", - "url": "https://rutube.ru/shorts/935c1afafd0e7d52836d671967d53dac/", - "params": {}, - "expected": { - "code": 200, - "status": "tunnel" - } - }, - { - "name": "vertical video (isAudioOnly)", - "url": "https://rutube.ru/video/18a281399b96f9184c647455a86f6724/", - "params": { - "downloadMode": "audio" - }, - "expected": { - "code": 200, - "status": "tunnel" - } - }, - { - "name": "vertical video (isAudioMuted)", - "url": "https://rutube.ru/video/18a281399b96f9184c647455a86f6724/", - "params": { - "downloadMode": "mute" - }, - "expected": { - "code": 200, - "status": "tunnel" - } - }, - { - "name": "private video", - "url": "https://rutube.ru/video/private/1161415be0e686214bb2a498165cab3e/?p=_IL1G8RSnKutunnTYwhZ5A", - "params": {}, - "expected": { - "code": 200, - "status": "tunnel" - } - } - ], - "ok": [ - { - "name": "regular video", - "url": "https://ok.ru/video/7204071410346", - "params": {}, - "expected": { - "code": 200, - "status": "tunnel" - } - } - ], - "dailymotion": [ - { - "name": "regular video", - "url": "https://www.dailymotion.com/video/x8t1eho", - "params": {}, - "expected": { - "code": 200, - "status": "tunnel" - } - }, - { - "name": "private video", - "url": "https://www.dailymotion.com/video/k41fZWpx2TaAORA2nok", - "params": {}, - "expected": { - "code": 200, - "status": "tunnel" - } - }, - { - "name": "dai.ly shortened link", - "url": "https://dai.ly/k41fZWpx2TaAORA2nok", - "params": {}, - "expected": { - "code": 200, - "status": "tunnel" - } - } - ], - "snapchat": [ - { - "name": "spotlight", - "url": "https://www.snapchat.com/spotlight/W7_EDlXWTBiXAEEniNoMPwAAYdWxucG9pZmNqAY46j0a5AY46j0YbAAAAAQ", - "params": {}, - "expected": { - "code": 200, - "status": "redirect" - } - }, - { - "name": "shortlinked spotlight", - "url": "https://t.snapchat.com/4ZsiBLDi", - "params": {}, - "expected": { - "code": 200, - "status": "redirect" - } - }, - { - "name": "story", - "url": "https://www.snapchat.com/add/bazerkmakane", - "params": {}, - "expected": { - "code": 200, - "status": "picker" - } - } - ], - "loom": [ - { - "name": "1080p video", - "url": "https://www.loom.com/share/313bf71d20ca47b2a35b6634cefdb761", - "params": {}, - "expected": { - "code": 200, - "status": "redirect" - } - }, - { - "name": "1080p video (muted)", - "url": "https://www.loom.com/share/313bf71d20ca47b2a35b6634cefdb761", - "params": { - "downloadMode": "mute" - }, - "expected": { - "code": 200, - "status": "tunnel" - } - }, - { - "name": "1080p video (audio only)", - "url": "https://www.loom.com/share/313bf71d20ca47b2a35b6634cefdb761", - "params": { - "downloadMode": "audio" - }, - "expected": { - "code": 400, - "status": "error" - } - } - ], - "facebook": [ - { - "name": "direct video with username and id", - "url": "https://web.facebook.com/100048111287134/videos/1157798148685638/", - "params": {}, - "expected": { - "code": 200, - "status": "redirect" - } - }, - { - "name": "direct video with id as query param", - "url": "https://web.facebook.com/watch/?v=883839773514682&ref=sharing", - "params": {}, - "expected": { - "code": 200, - "status": "redirect" - } - }, - { - "name": "direct video with caption", - "url": "https://web.facebook.com/wood57/videos/š’šžš›ššš¬š¤šØš¦-šŸš®š„š„/883839773514682", - "params": {}, - "expected": { - "code": 200, - "status": "redirect" - } - }, - { - "name": "shortlink video", - "url": "https://fb.watch/r1K6XHMfGT/", - "canFail": true, - "params": {}, - "expected": { - "code": 200, - "status": "redirect" - } - }, - { - "name": "reel video", - "url": "https://web.facebook.com/reel/730293269054758", - "canFail": true, - "params": {}, - "expected": { - "code": 200, - "status": "redirect" - } - }, - { - "name": "shared video link", - "url": "https://www.facebook.com/share/v/NEf87jbPTvFE8LsL/", - "params": {}, - "expected": { - "code": 200, - "status": "redirect" - } - }, - { - "name": "shared video link v2", - "url": "https://web.facebook.com/share/r/JFZfPVgLkiJQmWrr/", - "params": {}, - "expected": { - "code": 200, - "status": "redirect" - } - } - ], - "bsky": [ - { - "name": "horizontal video", - "url": "https://bsky.app/profile/did:plc:oisofpd7lj26yvgiivf3lxsi/post/3l3giwtwp222m", - "params": {}, - "expected": { - "code": 200, - "status": "tunnel" - } - }, - { - "name": "horizontal video, recordWithMedia", - "url": "https://bsky.app/profile/did:plc:ywbm3iywnhzep3ckt6efhoh7/post/3l3wonhk23g2i", - "params": {}, - "expected": { - "code": 200, - "status": "tunnel" - } - }, - { - "name": "vertical video", - "url": "https://bsky.app/profile/did:plc:oisofpd7lj26yvgiivf3lxsi/post/3l3jhpomhjk2m", - "params": {}, - "expected": { - "code": 200, - "status": "tunnel" - } - }, - { - "name": "vertical video (muted)", - "url": "https://bsky.app/profile/did:plc:oisofpd7lj26yvgiivf3lxsi/post/3l3jhpomhjk2m", - "params": { - "downloadMode": "mute" - }, - "expected": { - "code": 200, - "status": "tunnel" - } - }, - { - "name": "vertical video (audio)", - "url": "https://bsky.app/profile/did:plc:oisofpd7lj26yvgiivf3lxsi/post/3l3jhpomhjk2m", - "params": { - "downloadMode": "audio" - }, - "expected": { - "code": 200, - "status": "tunnel" - } - }, - { - "name": "single image", - "url": "https://bsky.app/profile/did:plc:k4a7d65fcyevbrnntjxh57go/post/3l33flpoygt26", - "params": {}, - "expected": { - "code": 200, - "status": "redirect" - } - }, - { - "name": "several images", - "url": "https://bsky.app/profile/did:plc:rai7s6su2sy22ss7skouedl7/post/3kzxuxbiul626", - "params": {}, - "expected": { - "code": 200, - "status": "picker" - } - }, - { - "name": "deleted post/invalid user", - "url": "https://bsky.app/profile/notreal.bsky.team/post/3l2udah76ch2c", - "params": {}, - "expected": { - "code": 400, - "status": "error" - } - } - ] -} diff --git a/api/src/util/tests/bilibili.json b/api/src/util/tests/bilibili.json new file mode 100644 index 000000000..61d601347 --- /dev/null +++ b/api/src/util/tests/bilibili.json @@ -0,0 +1,60 @@ +[ + { + "name": "1080p video", + "url": "https://www.bilibili.com/video/BV18i4y1m7xV/", + "params": {}, + "expected": { + "code": 200, + "status": "tunnel" + } + }, + { + "name": "1080p video muted", + "url": "https://www.bilibili.com/video/BV18i4y1m7xV/", + "params": { + "downloadMode": "mute" + }, + "expected": { + "code": 200, + "status": "tunnel" + } + }, + { + "name": "1080p vertical video", + "url": "https://www.bilibili.com/video/BV1uu411z7VV/", + "params": {}, + "expected": { + "code": 200, + "status": "tunnel" + } + }, + { + "name": "1080p vertical video muted", + "url": "https://www.bilibili.com/video/BV1uu411z7VV/", + "params": { + "downloadMode": "mute" + }, + "expected": { + "code": 200, + "status": "tunnel" + } + }, + { + "name": "b23.tv shortlink", + "url": "https://b23.tv/lbMyOI9", + "params": {}, + "expected": { + "code": 200, + "status": "tunnel" + } + }, + { + "name": "bilibili.tv link", + "url": "https://www.bilibili.tv/en/video/4789599404426256", + "params": {}, + "expected": { + "code": 200, + "status": "tunnel" + } + } +] \ No newline at end of file diff --git a/api/src/util/tests/bsky.json b/api/src/util/tests/bsky.json new file mode 100644 index 000000000..840f1169b --- /dev/null +++ b/api/src/util/tests/bsky.json @@ -0,0 +1,78 @@ +[ + { + "name": "horizontal video", + "url": "https://bsky.app/profile/did:plc:oisofpd7lj26yvgiivf3lxsi/post/3l3giwtwp222m", + "params": {}, + "expected": { + "code": 200, + "status": "tunnel" + } + }, + { + "name": "horizontal video, recordWithMedia", + "url": "https://bsky.app/profile/did:plc:ywbm3iywnhzep3ckt6efhoh7/post/3l3wonhk23g2i", + "params": {}, + "expected": { + "code": 200, + "status": "tunnel" + } + }, + { + "name": "vertical video", + "url": "https://bsky.app/profile/did:plc:oisofpd7lj26yvgiivf3lxsi/post/3l3jhpomhjk2m", + "params": {}, + "expected": { + "code": 200, + "status": "tunnel" + } + }, + { + "name": "vertical video (muted)", + "url": "https://bsky.app/profile/did:plc:oisofpd7lj26yvgiivf3lxsi/post/3l3jhpomhjk2m", + "params": { + "downloadMode": "mute" + }, + "expected": { + "code": 200, + "status": "tunnel" + } + }, + { + "name": "vertical video (audio)", + "url": "https://bsky.app/profile/did:plc:oisofpd7lj26yvgiivf3lxsi/post/3l3jhpomhjk2m", + "params": { + "downloadMode": "audio" + }, + "expected": { + "code": 200, + "status": "tunnel" + } + }, + { + "name": "single image", + "url": "https://bsky.app/profile/did:plc:k4a7d65fcyevbrnntjxh57go/post/3l33flpoygt26", + "params": {}, + "expected": { + "code": 200, + "status": "redirect" + } + }, + { + "name": "several images", + "url": "https://bsky.app/profile/did:plc:rai7s6su2sy22ss7skouedl7/post/3kzxuxbiul626", + "params": {}, + "expected": { + "code": 200, + "status": "picker" + } + }, + { + "name": "deleted post/invalid user", + "url": "https://bsky.app/profile/notreal.bsky.team/post/3l2udah76ch2c", + "params": {}, + "expected": { + "code": 400, + "status": "error" + } + } +] \ No newline at end of file diff --git a/api/src/util/tests/dailymotion.json b/api/src/util/tests/dailymotion.json new file mode 100644 index 000000000..4de9302c8 --- /dev/null +++ b/api/src/util/tests/dailymotion.json @@ -0,0 +1,29 @@ +[ + { + "name": "regular video", + "url": "https://www.dailymotion.com/video/x8t1eho", + "params": {}, + "expected": { + "code": 200, + "status": "tunnel" + } + }, + { + "name": "private video", + "url": "https://www.dailymotion.com/video/k41fZWpx2TaAORA2nok", + "params": {}, + "expected": { + "code": 200, + "status": "tunnel" + } + }, + { + "name": "dai.ly shortened link", + "url": "https://dai.ly/k41fZWpx2TaAORA2nok", + "params": {}, + "expected": { + "code": 200, + "status": "tunnel" + } + } +] \ No newline at end of file diff --git a/api/src/util/tests/facebook.json b/api/src/util/tests/facebook.json new file mode 100644 index 000000000..876ac7fe1 --- /dev/null +++ b/api/src/util/tests/facebook.json @@ -0,0 +1,67 @@ +[ + { + "name": "direct video with username and id", + "url": "https://web.facebook.com/100048111287134/videos/1157798148685638/", + "params": {}, + "expected": { + "code": 200, + "status": "redirect" + } + }, + { + "name": "direct video with id as query param", + "url": "https://web.facebook.com/watch/?v=883839773514682&ref=sharing", + "params": {}, + "expected": { + "code": 200, + "status": "redirect" + } + }, + { + "name": "direct video with caption", + "url": "https://web.facebook.com/wood57/videos/š’šžš›ššš¬š¤šØš¦-šŸš®š„š„/883839773514682", + "params": {}, + "expected": { + "code": 200, + "status": "redirect" + } + }, + { + "name": "shortlink video", + "url": "https://fb.watch/r1K6XHMfGT/", + "canFail": true, + "params": {}, + "expected": { + "code": 200, + "status": "redirect" + } + }, + { + "name": "reel video", + "url": "https://web.facebook.com/reel/730293269054758", + "canFail": true, + "params": {}, + "expected": { + "code": 200, + "status": "redirect" + } + }, + { + "name": "shared video link", + "url": "https://www.facebook.com/share/v/NEf87jbPTvFE8LsL/", + "params": {}, + "expected": { + "code": 200, + "status": "redirect" + } + }, + { + "name": "shared video link v2", + "url": "https://web.facebook.com/share/r/JFZfPVgLkiJQmWrr/", + "params": {}, + "expected": { + "code": 200, + "status": "redirect" + } + } +] \ No newline at end of file diff --git a/api/src/util/tests/instagram.json b/api/src/util/tests/instagram.json new file mode 100644 index 000000000..2ee421946 --- /dev/null +++ b/api/src/util/tests/instagram.json @@ -0,0 +1,123 @@ +[ + { + "name": "single photo post", + "url": "https://www.instagram.com/p/CwIgW8Yu5-I/", + "params": {}, + "expected": { + "code": 200, + "status": "redirect" + } + }, + { + "name": "various picker (photos + video)", + "url": "https://www.instagram.com/p/CvYrSgnsKjv/", + "params": {}, + "expected": { + "code": 200, + "status": "picker" + } + }, + { + "name": "reel", + "url": "https://www.instagram.com/reel/CoEBV3eM4QR/", + "params": {}, + "expected": { + "code": 200, + "status": "redirect" + } + }, + { + "name": "regular video", + "url": "https://www.instagram.com/p/CmCVWoIr9OH/", + "params": {}, + "expected": { + "code": 200, + "status": "redirect" + } + }, + { + "name": "reel (isAudioOnly)", + "url": "https://www.instagram.com/reel/CoEBV3eM4QR/", + "params": { + "downloadMode": "audio" + }, + "expected": { + "code": 200, + "status": "tunnel" + } + }, + { + "name": "reel (isAudioMuted)", + "url": "https://www.instagram.com/reel/CoEBV3eM4QR/", + "params": { + "downloadMode": "mute" + }, + "expected": { + "code": 200, + "status": "tunnel" + } + }, + { + "name": "inexistent reel", + "url": "https://www.instagram.com/reel/XXXXXXXXXX/", + "params": {}, + "expected": { + "code": 400, + "status": "error" + } + }, + { + "name": "inexistent post", + "url": "https://www.instagram.com/p/XXXXXXXXXX/", + "params": {}, + "expected": { + "code": 400, + "status": "error" + } + }, + { + "name": "post info in an array (for whatever reason??)", + "url": "https://www.instagram.com/reel/CrVB9tatUDv/?igshid=blaBlABALALbLABULLSHIT==", + "params": {}, + "expected": { + "code": 200, + "status": "redirect" + } + }, + { + "name": "prone to get rate limited", + "url": "https://www.instagram.com/reel/CrO-T7Qo6rq/?igshid=fuckYouNoTrackingIdForYou==", + "params": {}, + "expected": { + "code": 200, + "status": "redirect" + } + }, + { + "name": "ddinstagram link", + "url": "https://ddinstagram.com/p/CmCVWoIr9OH/", + "params": {}, + "expected": { + "code": 200, + "status": "redirect" + } + }, + { + "name": "d.ddinstagram.com link", + "url": "https://d.ddinstagram.com/p/CmCVWoIr9OH/", + "params": {}, + "expected": { + "code": 200, + "status": "redirect" + } + }, + { + "name": "g.ddinstagram.com link", + "url": "https://g.ddinstagram.com/p/CmCVWoIr9OH/", + "params": {}, + "expected": { + "code": 200, + "status": "redirect" + } + } +] \ No newline at end of file diff --git a/api/src/util/tests/loom.json b/api/src/util/tests/loom.json new file mode 100644 index 000000000..1849a0004 --- /dev/null +++ b/api/src/util/tests/loom.json @@ -0,0 +1,33 @@ +[ + { + "name": "1080p video", + "url": "https://www.loom.com/share/313bf71d20ca47b2a35b6634cefdb761", + "params": {}, + "expected": { + "code": 200, + "status": "redirect" + } + }, + { + "name": "1080p video (muted)", + "url": "https://www.loom.com/share/313bf71d20ca47b2a35b6634cefdb761", + "params": { + "downloadMode": "mute" + }, + "expected": { + "code": 200, + "status": "tunnel" + } + }, + { + "name": "1080p video (audio only)", + "url": "https://www.loom.com/share/313bf71d20ca47b2a35b6634cefdb761", + "params": { + "downloadMode": "audio" + }, + "expected": { + "code": 400, + "status": "error" + } + } +] \ No newline at end of file diff --git a/api/src/util/tests/ok.json b/api/src/util/tests/ok.json new file mode 100644 index 000000000..8eb103eb7 --- /dev/null +++ b/api/src/util/tests/ok.json @@ -0,0 +1,11 @@ +[ + { + "name": "regular video", + "url": "https://ok.ru/video/7204071410346", + "params": {}, + "expected": { + "code": 200, + "status": "tunnel" + } + } +] \ No newline at end of file diff --git a/api/src/util/tests/pinterest.json b/api/src/util/tests/pinterest.json new file mode 100644 index 000000000..2f15fb0b3 --- /dev/null +++ b/api/src/util/tests/pinterest.json @@ -0,0 +1,87 @@ +[ + { + "name": "regular video", + "url": "https://www.pinterest.com/pin/70437485604616/", + "params": {}, + "expected": { + "code": 200, + "status": "redirect" + } + }, + { + "name": "regular video (isAudioOnly)", + "url": "https://www.pinterest.com/pin/70437485604616/", + "params": { + "downloadMode": "audio" + }, + "expected": { + "code": 200, + "status": "tunnel" + } + }, + { + "name": "regular video (isAudioMuted)", + "url": "https://www.pinterest.com/pin/70437485604616/", + "params": { + "downloadMode": "mute" + }, + "expected": { + "code": 200, + "status": "tunnel" + } + }, + { + "name": "regular video (.ca TLD)", + "url": "https://www.pinterest.ca/pin/70437485604616/", + "params": {}, + "expected": { + "code": 200, + "status": "redirect" + } + }, + { + "name": "story", + "url": "https://www.pinterest.com/pin/gadget-cool-products-amazon-product-technology-kitchen-gadgets--1084663891475263837/", + "params": {}, + "expected": { + "code": 200, + "status": "redirect" + } + }, + { + "name": "regular picture", + "url": "https://www.pinterest.com/pin/412994228343400946/", + "params": {}, + "expected": { + "code": 200, + "status": "redirect" + } + }, + { + "name": "regular picture (.ca TLD)", + "url": "https://www.pinterest.ca/pin/412994228343400946/", + "params": {}, + "expected": { + "code": 200, + "status": "redirect" + } + }, + { + "name": "regular gif", + "url": "https://www.pinterest.com/pin/814447913881127862/", + "params": {}, + "expected": { + "code": 200, + "status": "redirect" + } + }, + { + "name": "regular gif (.ca TLD)", + "url": "https://www.pinterest.ca/pin/814447913881127862/", + "params": {}, + "expected": { + "code": 200, + "status": "redirect" + } + } +] \ No newline at end of file diff --git a/api/src/util/tests/reddit.json b/api/src/util/tests/reddit.json new file mode 100644 index 000000000..3afc61262 --- /dev/null +++ b/api/src/util/tests/reddit.json @@ -0,0 +1,60 @@ +[ + { + "name": "video with audio", + "url": "https://www.reddit.com/r/TikTokCringe/comments/wup1fg/id_be_escaping_at_the_first_chance_i_got/?utm_source=share&utm_medium=web2x&context=3", + "params": {}, + "expected": { + "code": 200, + "status": "tunnel" + } + }, + { + "name": "video with audio (isAudioOnly)", + "url": "https://www.reddit.com/r/TikTokCringe/comments/wup1fg/id_be_escaping_at_the_first_chance_i_got/?utm_source=share&utm_medium=web2x&context=3", + "params": { + "downloadMode": "audio" + }, + "expected": { + "code": 200, + "status": "tunnel" + } + }, + { + "name": "video with audio (isAudioMuted)", + "url": "https://www.reddit.com/r/TikTokCringe/comments/wup1fg/id_be_escaping_at_the_first_chance_i_got/?utm_source=share&utm_medium=web2x&context=3", + "params": { + "downloadMode": "mute" + }, + "expected": { + "code": 200, + "status": "tunnel" + } + }, + { + "name": "video without audio", + "url": "https://www.reddit.com/r/catvideos/comments/ftoeo7/luna_doesnt_want_to_be_bothered_while_shes_napping/?utm_source=share&utm_medium=web2x&context=3", + "params": {}, + "expected": { + "code": 200, + "status": "redirect" + } + }, + { + "name": "actual gif, not looping video", + "url": "https://www.reddit.com/r/whenthe/comments/109wqy1/god_really_did_some_trolling/?utm_source=share&utm_medium=web2x&context=3", + "params": {}, + "expected": { + "code": 200, + "status": "redirect" + } + }, + { + "name": "different audio link, live render", + "url": "https://www.reddit.com/r/TikTokCringe/comments/15hce91/asian_daddy_kink/", + "params": {}, + "expected": { + "code": 200, + "status": "tunnel" + } + } +] \ No newline at end of file diff --git a/api/src/util/tests/rutube.json b/api/src/util/tests/rutube.json new file mode 100644 index 000000000..967c52fb6 --- /dev/null +++ b/api/src/util/tests/rutube.json @@ -0,0 +1,90 @@ +[ + { + "name": "regular video", + "url": "https://rutube.ru/video/b2f6c27649907c2fde0af411b03825eb/", + "params": {}, + "expected": { + "code": 200, + "status": "tunnel" + } + }, + { + "name": "vertical video (isAudioMuted)", + "url": "https://rutube.ru/video/18a281399b96f9184c647455a86f6724/", + "params": { + "downloadMode": "mute" + }, + "expected": { + "code": 200, + "status": "tunnel" + } + }, + { + "name": "russian region lock", + "url": "https://rutube.ru/video/b521653b4f71ece57b8ff54e57ca9b82/", + "params": {}, + "expected": { + "code": 400, + "status": "error" + } + }, + { + "name": "vertical video", + "url": "https://rutube.ru/video/18a281399b96f9184c647455a86f6724/", + "params": {}, + "expected": { + "code": 200, + "status": "tunnel" + } + }, + { + "name": "yappy", + "url": "https://rutube.ru/yappy/c8c32bf7aee04412837656ea26c2b25b/", + "canFail": true, + "params": {}, + "expected": { + "code": 200, + "status": "tunnel" + } + }, + { + "name": "shorts", + "url": "https://rutube.ru/shorts/935c1afafd0e7d52836d671967d53dac/", + "params": {}, + "expected": { + "code": 200, + "status": "tunnel" + } + }, + { + "name": "vertical video (isAudioOnly)", + "url": "https://rutube.ru/video/18a281399b96f9184c647455a86f6724/", + "params": { + "downloadMode": "audio" + }, + "expected": { + "code": 200, + "status": "tunnel" + } + }, + { + "name": "vertical video (isAudioMuted)", + "url": "https://rutube.ru/video/18a281399b96f9184c647455a86f6724/", + "params": { + "downloadMode": "mute" + }, + "expected": { + "code": 200, + "status": "tunnel" + } + }, + { + "name": "private video", + "url": "https://rutube.ru/video/private/1161415be0e686214bb2a498165cab3e/?p=_IL1G8RSnKutunnTYwhZ5A", + "params": {}, + "expected": { + "code": 200, + "status": "tunnel" + } + } +] \ No newline at end of file diff --git a/api/src/util/tests/snapchat.json b/api/src/util/tests/snapchat.json new file mode 100644 index 000000000..44f764ce3 --- /dev/null +++ b/api/src/util/tests/snapchat.json @@ -0,0 +1,29 @@ +[ + { + "name": "spotlight", + "url": "https://www.snapchat.com/spotlight/W7_EDlXWTBiXAEEniNoMPwAAYdWxucG9pZmNqAY46j0a5AY46j0YbAAAAAQ", + "params": {}, + "expected": { + "code": 200, + "status": "redirect" + } + }, + { + "name": "shortlinked spotlight", + "url": "https://t.snapchat.com/4ZsiBLDi", + "params": {}, + "expected": { + "code": 200, + "status": "redirect" + } + }, + { + "name": "story", + "url": "https://www.snapchat.com/add/bazerkmakane", + "params": {}, + "expected": { + "code": 200, + "status": "picker" + } + } +] \ No newline at end of file diff --git a/api/src/util/tests/soundcloud.json b/api/src/util/tests/soundcloud.json new file mode 100644 index 000000000..ea705cb57 --- /dev/null +++ b/api/src/util/tests/soundcloud.json @@ -0,0 +1,87 @@ +[ + { + "name": "public song (best)", + "url": "https://soundcloud.com/l2share77/loona-butterfly?utm_source=clipboard&utm_medium=text&utm_campaign=social_sharing", + "params": { + "audioFormat": "best" + }, + "expected": { + "code": 200, + "status": "tunnel" + } + }, + { + "name": "public song (mp3, isAudioMuted)", + "url": "https://soundcloud.com/l2share77/loona-butterfly?utm_source=clipboard&utm_medium=text&utm_campaign=social_sharing", + "params": { + "downloadMode": "mute", + "audioFormat": "mp3" + }, + "expected": { + "code": 200, + "status": "tunnel" + } + }, + { + "name": "private song", + "url": "https://soundcloud.com/user-798052861/asdasdasdsdsd/s-9TqZ7edLJ90", + "params": { + "audioFormat": "mp3" + }, + "expected": { + "code": 200, + "status": "tunnel" + } + }, + { + "name": "private song (wav, isAudioMuted)", + "url": "https://soundcloud.com/user-798052861/asdasdasdsdsd/s-9TqZ7edLJ90", + "params": { + "downloadMode": "mute", + "audioFormat": "wav" + }, + "expected": { + "code": 200, + "status": "tunnel" + } + }, + { + "name": "private song (ogg, isAudioMuted, isAudioOnly)", + "url": "https://soundcloud.com/user-798052861/asdasdasdsdsd/s-9TqZ7edLJ90", + "params": { + "downloadMode": "audio", + "audioFormat": "ogg" + }, + "expected": { + "code": 200, + "status": "tunnel" + } + }, + { + "name": "on.soundcloud link", + "url": "https://on.soundcloud.com/wLZre", + "params": {}, + "expected": { + "code": 200, + "status": "tunnel" + } + }, + { + "name": "on.soundcloud link, different stream type", + "url": "https://on.soundcloud.com/AG4c", + "params": {}, + "expected": { + "code": 200, + "status": "tunnel" + } + }, + { + "name": "no opus audio, fallback to mp3", + "url": "https://soundcloud.com/frums/credits", + "params": {}, + "expected": { + "code": 200, + "status": "tunnel" + } + } +] \ No newline at end of file diff --git a/api/src/util/tests/streamable.json b/api/src/util/tests/streamable.json new file mode 100644 index 000000000..bf03c2282 --- /dev/null +++ b/api/src/util/tests/streamable.json @@ -0,0 +1,51 @@ +[ + { + "name": "regular video", + "url": "https://streamable.com/p9cln4", + "params": {}, + "expected": { + "code": 200, + "status": "redirect" + } + }, + { + "name": "embedded link", + "url": "https://streamable.com/e/rsmo56", + "params": {}, + "expected": { + "code": 200, + "status": "redirect" + } + }, + { + "name": "regular video (isAudioOnly)", + "url": "https://streamable.com/p9cln4", + "params": { + "downloadMode": "audio" + }, + "expected": { + "code": 200, + "status": "tunnel" + } + }, + { + "name": "regular video (isAudioMuted)", + "url": "https://streamable.com/p9cln4", + "params": { + "downloadMode": "mute" + }, + "expected": { + "code": 200, + "status": "tunnel" + } + }, + { + "name": "inexistent video", + "url": "https://streamable.com/XXXXXX", + "params": {}, + "expected": { + "code": 400, + "status": "error" + } + } +] \ No newline at end of file diff --git a/api/src/util/tests/tiktok.json b/api/src/util/tests/tiktok.json new file mode 100644 index 000000000..d23c0acc3 --- /dev/null +++ b/api/src/util/tests/tiktok.json @@ -0,0 +1,38 @@ +[ + { + "name": "long link video", + "url": "https://www.tiktok.com/@fatfatmillycat/video/7195741644585454894", + "params": {}, + "expected": { + "code": 200, + "status": "tunnel" + } + }, + { + "name": "images", + "url": "https://www.tiktok.com/@matryoshk4/video/7231234675476532526", + "params": {}, + "expected": { + "code": 200, + "status": "picker" + } + }, + { + "name": "long link inexistent", + "url": "https://www.tiktok.com/@blablabla/video/7120851458451417478", + "params": {}, + "expected": { + "code": 400, + "status": "error" + } + }, + { + "name": "short link inexistent", + "url": "https://vt.tiktok.com/2p4ewa7/", + "params": {}, + "expected": { + "code": 400, + "status": "error" + } + } +] \ No newline at end of file diff --git a/api/src/util/tests/tumblr.json b/api/src/util/tests/tumblr.json new file mode 100644 index 000000000..873522555 --- /dev/null +++ b/api/src/util/tests/tumblr.json @@ -0,0 +1,49 @@ +[ + { + "name": "at.tumblr link", + "url": "https://at.tumblr.com/music/704177038274281472/n7x7pr7x4w2b", + "params": {}, + "expected": { + "code": 200, + "status": "redirect" + } + }, + { + "name": "user subdomain link", + "url": "https://garfield-69.tumblr.com/post/696499862852780032", + "params": {}, + "expected": { + "code": 200, + "status": "redirect" + } + }, + { + "name": "web app link", + "url": "https://www.tumblr.com/rongzhi/707729381162958848/english-added-by-me?source=share", + "params": {}, + "expected": { + "code": 200, + "status": "redirect" + } + }, + { + "name": "tumblr audio", + "url": "https://www.tumblr.com/zedneon/737815079301562368/zedneon-ft-mr-sauceman-tech-n9ne-speed-of?source=share", + "params": {}, + "expected": { + "code": 200, + "status": "tunnel" + } + }, + { + "name": "tumblr video converted to audio", + "url": "https://garfield-69.tumblr.com/post/696499862852780032", + "params": { + "downloadMode": "audio" + }, + "expected": { + "code": 200, + "status": "tunnel" + } + } +] \ No newline at end of file diff --git a/api/src/util/tests/twitch.json b/api/src/util/tests/twitch.json new file mode 100644 index 000000000..fd6b84afc --- /dev/null +++ b/api/src/util/tests/twitch.json @@ -0,0 +1,33 @@ +[ + { + "name": "clip", + "url": "https://twitch.tv/rtgame/clip/TubularInventiveSardineCorgiDerp-PM47mJQQ2vsL5B5G", + "params": {}, + "expected": { + "code": 200, + "status": "redirect" + } + }, + { + "name": "clip (isAudioOnly)", + "url": "https://twitch.tv/rtgame/clip/TubularInventiveSardineCorgiDerp-PM47mJQQ2vsL5B5G", + "params": { + "downloadMode": "audio" + }, + "expected": { + "code": 200, + "status": "tunnel" + } + }, + { + "name": "clip (isAudioMuted)", + "url": "https://twitch.tv/rtgame/clip/TubularInventiveSardineCorgiDerp-PM47mJQQ2vsL5B5G", + "params": { + "downloadMode": "mute" + }, + "expected": { + "code": 200, + "status": "tunnel" + } + } +] \ No newline at end of file diff --git a/api/src/util/tests/twitter.json b/api/src/util/tests/twitter.json new file mode 100644 index 000000000..0024d0979 --- /dev/null +++ b/api/src/util/tests/twitter.json @@ -0,0 +1,213 @@ +[ + { + "name": "regular video", + "url": "https://twitter.com/X/status/1697304622749086011", + "params": { + "audioFormat": "mp3" + }, + "expected": { + "code": 200, + "status": "redirect" + } + }, + { + "name": "video with mobile web mediaviewer", + "url": "https://twitter.com/X/status/1697304622749086011/mediaViewer?currentTweet=1697304622749086011¤tTweetUser=X¤tTweet=1697304622749086011¤tTweetUser=X", + "params": {}, + "expected": { + "code": 200, + "status": "redirect" + } + }, + { + "name": "embedded twitter video", + "url": "https://twitter.com/dustbin_nie/status/1624596567188717568?s=20", + "params": { + "audioFormat": "mp3" + }, + "expected": { + "code": 200, + "status": "redirect" + } + }, + { + "name": "mixed media (image + gif)", + "url": "https://twitter.com/sky_mj26/status/1807756010712428565", + "params": { + "audioFormat": "mp3" + }, + "expected": { + "code": 200, + "status": "picker" + } + }, + { + "name": "picker: mixed media (3 videos)", + "url": "https://twitter.com/DankGameAlert/status/1584726006094794774", + "params": { + "audioFormat": "mp3" + }, + "expected": { + "code": 200, + "status": "picker" + } + }, + { + "name": "audio from embedded twitter video (mp3, isAudioOnly)", + "url": "https://twitter.com/dustbin_nie/status/1624596567188717568?s=20", + "params": { + "downloadMode": "audio", + "audioFormat": "mp3" + }, + "expected": { + "code": 200, + "status": "tunnel" + } + }, + { + "name": "audio from embedded twitter video (best, isAudioOnly)", + "url": "https://twitter.com/dustbin_nie/status/1624596567188717568?s=20", + "params": { + "downloadMode": "audio", + "audioFormat": "best" + }, + "expected": { + "code": 200, + "status": "tunnel" + } + }, + { + "name": "audio from embedded twitter video (ogg, isAudioOnly, isAudioMuted)", + "url": "https://twitter.com/dustbin_nie/status/1624596567188717568?s=20", + "params": { + "downloadMode": "audio", + "audioFormat": "best" + }, + "expected": { + "code": 200, + "status": "tunnel" + } + }, + { + "name": "muted embedded twitter video", + "url": "https://twitter.com/dustbin_nie/status/1624596567188717568?s=20", + "params": { + "downloadMode": "mute", + "audioFormat": "mp3" + }, + "expected": { + "code": 200, + "status": "tunnel" + } + }, + { + "name": "retweeted video", + "url": "https://twitter.com/uwukko/status/1696901469633421344", + "params": {}, + "canFail": true, + "expected": { + "code": 200, + "status": "redirect" + } + }, + { + "name": "age restricted video", + "url": "https://x.com/XSpaces/status/1526955853743546372", + "params": {}, + "canFail": true, + "expected": { + "code": 200, + "status": "redirect" + } + }, + { + "name": "twitter voice + x.com link", + "url": "https://x.com/eggsaladscreams/status/1693089534886506756?s=46", + "params": {}, + "canFail": true, + "expected": { + "code": 200, + "status": "redirect" + } + }, + { + "name": "vxtwitter link", + "url": "https://vxtwitter.com/dustbin_nie/status/1624596567188717568?s=20", + "params": {}, + "expected": { + "code": 200, + "status": "redirect" + } + }, + { + "name": "post with 1 image", + "url": "https://x.com/PopCrave/status/1815960083475423235", + "params": {}, + "expected": { + "code": 200, + "status": "redirect" + } + }, + { + "name": "post with 4 images", + "url": "https://x.com/PopCrave/status/1816260887147114696", + "params": {}, + "expected": { + "code": 200, + "status": "picker" + } + }, + { + "name": "retweeted video, isAudioOnly", + "url": "https://twitter.com/hugekiwinuts/status/1618671150829309953?s=46&t=gItGzgwGQQJJaJrO6qc1Pg", + "params": { + "downloadMode": "mute", + "audioFormat": "mp3" + }, + "canFail": true, + "expected": { + "code": 200, + "status": "tunnel" + } + }, + { + "name": "inexistent post", + "url": "https://twitter.com/test/status/9487653", + "params": { + "audioFormat": "best" + }, + "expected": { + "code": 400, + "status": "error" + } + }, + { + "name": "post with no media content", + "url": "https://twitter.com/elonmusk/status/1604617643973124097?s=20", + "params": { + "audioFormat": "best" + }, + "expected": { + "code": 400, + "status": "error" + } + }, + { + "name": "bookmarked video", + "url": "https://twitter.com/i/bookmarks?post_id=1828099210220294314", + "params": {}, + "expected": { + "code": 200, + "status": "redirect" + } + }, + { + "name": "bookmarked photo", + "url": "https://twitter.com/i/bookmarks?post_id=1837430141179289876", + "params": {}, + "expected": { + "code": 200, + "status": "redirect" + } + } +] \ No newline at end of file diff --git a/api/src/util/tests/vimeo.json b/api/src/util/tests/vimeo.json new file mode 100644 index 000000000..6c44a47d5 --- /dev/null +++ b/api/src/util/tests/vimeo.json @@ -0,0 +1,64 @@ +[ + { + "name": "4k progressive", + "url": "https://vimeo.com/288386543", + "params": { + "videoQuality": "2160" + }, + "expected": { + "code": 200, + "status": "redirect" + } + }, + { + "name": "720p progressive", + "url": "https://vimeo.com/288386543", + "params": { + "videoQuality": "720" + }, + "expected": { + "code": 200, + "status": "redirect" + } + }, + { + "name": "1080p dash parcel", + "url": "https://vimeo.com/967252742", + "params": { + "videoQuality": "1440" + }, + "expected": { + "code": 200, + "status": "redirect" + } + }, + { + "name": "720p dash parcel", + "url": "https://vimeo.com/967252742", + "params": { + "videoQuality": "360" + }, + "expected": { + "code": 200, + "status": "redirect" + } + }, + { + "name": "private video", + "url": "https://vimeo.com/903115595/f14d06da38", + "params": {}, + "expected": { + "code": 200, + "status": "redirect" + } + }, + { + "name": "mature video", + "url": "https://vimeo.com/973212054", + "params": {}, + "expected": { + "code": 200, + "status": "redirect" + } + } +] \ No newline at end of file diff --git a/api/src/util/tests/vine.json b/api/src/util/tests/vine.json new file mode 100644 index 000000000..f1bc1f77c --- /dev/null +++ b/api/src/util/tests/vine.json @@ -0,0 +1,33 @@ +[ + { + "name": "regular vine link (9+10=21)", + "url": "https://vine.co/v/huwVJIEJW50", + "params": {}, + "expected": { + "code": 200, + "status": "redirect" + } + }, + { + "name": "regular vine link (isAudioOnly)", + "url": "https://vine.co/v/huwVJIEJW50", + "params": { + "downloadMode": "audio" + }, + "expected": { + "code": 200, + "status": "tunnel" + } + }, + { + "name": "regular vine link (isAudioMuted)", + "url": "https://vine.co/v/huwVJIEJW50", + "params": { + "downloadMode": "mute" + }, + "expected": { + "code": 200, + "status": "tunnel" + } + } +] \ No newline at end of file diff --git a/api/src/util/tests/vk.json b/api/src/util/tests/vk.json new file mode 100644 index 000000000..b9b3fb3b9 --- /dev/null +++ b/api/src/util/tests/vk.json @@ -0,0 +1,77 @@ +[ + { + "name": "clip, defaults", + "canFail": true, + "url": "https://vk.com/clip-57274055_456239788", + "params": {}, + "expected": { + "code": 200, + "status": "tunnel" + } + }, + { + "name": "clip, 360", + "canFail": true, + "url": "https://vk.com/clip-57274055_456239788", + "params": { + "videoQuality": "360" + }, + "expected": { + "code": 200, + "status": "tunnel" + } + }, + { + "name": "clip different link, max", + "canFail": true, + "url": "https://vk.com/clips-57274055?z=clip-57274055_456239788", + "params": { + "videoQuality": "max" + }, + "expected": { + "code": 200, + "status": "tunnel" + } + }, + { + "name": "video, defaults", + "canFail": true, + "url": "https://vk.com/video-57274055_456239399", + "params": {}, + "expected": { + "code": 200, + "status": "tunnel" + } + }, + { + "name": "4k video", + "canFail": true, + "url": "https://vk.com/video-1112285_456248465", + "params": { + "videoQuality": "max" + }, + "expected": { + "code": 200, + "status": "tunnel" + } + }, + { + "name": "ancient video (fallback to 240p)", + "canFail": true, + "url": "https://vk.com/video-1959_28496479", + "params": {}, + "expected": { + "code": 200, + "status": "tunnel" + } + }, + { + "name": "inexistent video", + "url": "https://vk.com/video-53333333_456233333", + "params": {}, + "expected": { + "code": 400, + "status": "error" + } + } +] \ No newline at end of file diff --git a/api/src/util/tests/youtube.json b/api/src/util/tests/youtube.json new file mode 100644 index 000000000..0655e6833 --- /dev/null +++ b/api/src/util/tests/youtube.json @@ -0,0 +1,240 @@ +[ + { + "name": "4k video (h264, 1440)", + "url": "https://www.youtube.com/watch?v=vPwaXytZcgI", + "params": { + "youtubeVideoCodec": "h264", + "videoQuality": "1440" + }, + "expected": { + "code": 200, + "status": "tunnel" + } + }, + { + "name": "4k video (vp9, 720)", + "url": "https://www.youtube.com/watch?v=vPwaXytZcgI", + "params": { + "youtubeVideoCodec": "vp9", + "videoQuality": "720" + }, + "expected": { + "code": 200, + "status": "tunnel" + } + }, + { + "name": "4k video (av1, max)", + "url": "https://www.youtube.com/watch?v=vPwaXytZcgI", + "params": { + "youtubeVideoCodec": "av1", + "videoQuality": "max" + }, + "expected": { + "code": 200, + "status": "tunnel" + } + }, + { + "name": "4k video (h264, 720)", + "url": "https://www.youtube.com/watch?v=vPwaXytZcgI", + "params": { + "youtubeVideoCodec": "h264", + "videoQuality": "720" + }, + "expected": { + "code": 200, + "status": "tunnel" + } + }, + { + "name": "4k video (vp9, max, isAudioMuted)", + "url": "https://www.youtube.com/watch?v=vPwaXytZcgI", + "params": { + "downloadMode": "mute", + "youtubeVideoCodec": "vp9", + "videoQuality": "max" + }, + "expected": { + "code": 200, + "status": "tunnel" + } + }, + { + "name": "4k video (h264, max, isAudioMuted)", + "url": "https://www.youtube.com/watch?v=vPwaXytZcgI", + "params": { + "downloadMode": "mute", + "youtubeVideoCodec": "h264", + "videoQuality": "max" + }, + "expected": { + "code": 200, + "status": "tunnel" + } + }, + { + "name": "4k video (av1, max, isAudioMuted, isAudioOnly, mp3)", + "url": "https://www.youtube.com/watch?v=vPwaXytZcgI", + "params": { + "downloadMode": "audio", + "audioFormat": "mp3", + "youtubeVideoCodec": "av1", + "videoQuality": "max" + }, + "expected": { + "code": 200, + "status": "tunnel" + } + }, + { + "name": "4k video (av1, max, isAudioMuted, isAudioOnly, best)", + "url": "https://www.youtube.com/watch?v=vPwaXytZcgI", + "params": { + "downloadMode": "audio", + "audioFormat": "best", + "youtubeVideoCodec": "av1", + "videoQuality": "max" + }, + "expected": { + "code": 200, + "status": "tunnel" + } + }, + { + "name": "music (mp3, isAudioOnly, isAudioMuted)", + "url": "https://music.youtube.com/watch?v=5rGTsvZCEdk&feature=share", + "params": { + "downloadMode": "audio", + "audioFormat": "mp3" + }, + "expected": { + "code": 200, + "status": "tunnel" + } + }, + { + "name": "music (mp3)", + "url": "https://music.youtube.com/watch?v=5rGTsvZCEdk&feature=share", + "params": { + "audioFormat": "mp3" + }, + "expected": { + "code": 200, + "status": "tunnel" + } + }, + { + "name": "audio bitrate higher than video, no vp9 video in response (mp3, isAudioOnly)", + "url": "https://www.youtube.com/watch?v=t5nC_ucYBrc", + "params": { + "downloadMode": "audio", + "audioFormat": "mp3" + }, + "expected": { + "code": 200, + "status": "tunnel" + } + }, + { + "name": "short, defaults", + "url": "https://www.youtube.com/shorts/r5FpeOJItbw", + "params": {}, + "expected": { + "code": 200, + "status": "tunnel" + } + }, + { + "name": "vr 360, av1, max", + "url": "https://www.youtube.com/watch?v=hEdzv7D4CbQ", + "params": { + "youtubeVideoCodec": "vp9", + "videoQuality": "max" + }, + "expected": { + "code": 200, + "status": "tunnel" + } + }, + { + "name": "live link, defaults", + "url": "https://www.youtube.com/live/ENxZS6PUDuI?feature=shared", + "params": {}, + "expected": { + "code": 200, + "status": "tunnel" + } + }, + { + "name": "inexistent video", + "url": "https://youtube.com/watch?v=gnjuHYWGEW", + "params": {}, + "expected": { + "code": 400, + "status": "error" + } + }, + { + "name": "broken audioOnly download", + "url": "https://www.youtube.com/watch?v=ink80Al5nbw", + "params": { + "downloadMode": "audio" + }, + "expected": { + "code": 200, + "status": "tunnel" + } + }, + { + "name": "hls video (h264, 1440p)", + "url": "https://www.youtube.com/watch?v=vPwaXytZcgI", + "params": { + "youtubeVideoCodec": "h264", + "videoQuality": "1440", + "youtubeHLS": true + }, + "expected": { + "code": 200, + "status": "tunnel" + } + }, + { + "name": "hls video (vp9, 360p)", + "url": "https://www.youtube.com/watch?v=vPwaXytZcgI", + "params": { + "youtubeVideoCodec": "vp9", + "videoQuality": "360", + "youtubeHLS": true + }, + "expected": { + "code": 200, + "status": "tunnel" + } + }, + { + "name": "hls video (audio mode)", + "url": "https://www.youtube.com/watch?v=vPwaXytZcgI", + "params": { + "downloadMode": "audio", + "youtubeHLS": true + }, + "expected": { + "code": 200, + "status": "tunnel" + } + }, + { + "name": "hls video (audio mode, best format)", + "url": "https://www.youtube.com/watch?v=vPwaXytZcgI", + "params": { + "downloadMode": "audio", + "youtubeHLS": true, + "audioFormat": "best" + }, + "expected": { + "code": 200, + "status": "tunnel" + } + } +] \ No newline at end of file From 91e8ef8ab42baf08fbf5e8d5a99e435c6b8ac67b Mon Sep 17 00:00:00 2001 From: jj Date: Wed, 13 Nov 2024 17:24:51 +0000 Subject: [PATCH 2/4] api/test-ci: add functionality for running all tests --- api/src/misc/run-test.js | 2 +- api/src/util/test-ci.js | 119 ++++++++++++++++++++++++++------------- 2 files changed, 81 insertions(+), 40 deletions(-) diff --git a/api/src/misc/run-test.js b/api/src/misc/run-test.js index 10d19aef7..21d97d045 100644 --- a/api/src/misc/run-test.js +++ b/api/src/misc/run-test.js @@ -41,4 +41,4 @@ export async function runTest(url, params, expect) { if (result.body.status === 'tunnel') { // TODO: stream testing } -} \ No newline at end of file +} diff --git a/api/src/util/test-ci.js b/api/src/util/test-ci.js index 5a1d6300c..a8b70fd36 100644 --- a/api/src/util/test-ci.js +++ b/api/src/util/test-ci.js @@ -13,7 +13,56 @@ const getTests = (service) => loadJSON(getTestPath(service)); // services that are known to frequently fail due to external // factors (e.g. rate limiting) -const finnicky = new Set(['bilibili', 'instagram', 'facebook', 'youtube']) +const finnicky = new Set(['bilibili', 'instagram', 'facebook', 'youtube']); + +const runTestsFor = async (service) => { + const tests = getTests(service); + let softFails = 0, fails = 0; + + if (!tests) { + throw "no such service: " + service; + } + + for (const test of tests) { + const { name, url, params, expected } = test; + const canFail = test.canFail || finnicky.has(service); + + try { + await runTest(url, params, expected); + console.log(`${service}/${name}: ok`); + + } catch(e) { + softFails += !canFail; + fails++; + + let failText = canFail ? `${Red('FAIL')} (ignored)` : Bright(Red('FAIL')); + if (canFail && process.env.GITHUB_ACTION) { + console.log(`::warning title=${service}/${name.replace(/,/g, ';')}::failed and was ignored`); + } + + console.error(`${service}/${name}: ${failText}`); + const errorString = e.toString().split('\n'); + let c = 'ā”ƒ'; + errorString.forEach((line, index) => { + line = line.replace('!=', Red('!=')); + + if (index === errorString.length - 1) { + c = 'ā”—'; + } + + console.error(` ${c}`, line); + }); + } + } + + return { fails, softFails }; +} + +const printHeader = (service, padLen) => { + const padding = padLen - service.length; + service = service.padEnd(1 + service.length + padding, ' '); + console.log(service + '='.repeat(50)); +} const action = process.argv[2]; switch (action) { @@ -38,53 +87,45 @@ switch (action) { case "run-tests-for": const service = process.argv[3]; - let failed = false; - const tests = getTests(service); - if (!tests) { - console.error('no such service:', service); + env.streamLifespan = 10000; + env.apiURL = 'http://x/'; + randomizeCiphers(); + + try { + const { softFails } = await runTestsFor(service); + process.exitCode = Number(!!softFails); + } catch(e) { + console.error(e); process.exitCode = 1; break; } + break; + default: + const maxHeaderLen = Object.keys(services).reduce((n, v) => v.length > n ? v.length : n, 0); + const failCounters = {}; + env.streamLifespan = 10000; - env.apiURL = 'http://x'; + env.apiURL = 'http://x/'; randomizeCiphers(); - for (const test of tests) { - const { name, url, params, expected } = test; - const canFail = test.canFail || finnicky.has(service); - - try { - await runTest(url, params, expected); - console.log(`${service}/${name}: ok`); - - } catch(e) { - failed = !canFail; - - let failText = canFail ? `${Red('FAIL')} (ignored)` : Bright(Red('FAIL')); - if (canFail && process.env.GITHUB_ACTION) { - console.log(`::warning title=${service}/${name.replace(/,/g, ';')}::failed and was ignored`); - } - - console.error(`${service}/${name}: ${failText}`); - const errorString = e.toString().split('\n'); - let c = 'ā”ƒ'; - errorString.forEach((line, index) => { - line = line.replace('!=', Red('!=')); + for (const service in services) { + printHeader(service, maxHeaderLen); + const { fails, softFails } = await runTestsFor(service); + failCounters[service] = fails; + console.log(); - if (index === errorString.length - 1) { - c = 'ā”—'; - } - - console.error(` ${c}`, line); - }); - } + if (!process.exitCode && softFails) + process.exitCode = 1; } - process.exitCode = Number(failed); - break; - default: - console.error('invalid action:', action); - process.exitCode = 1; + console.log('='.repeat(50 + maxHeaderLen)); + console.log( + Bright('total fails:'), + Object.values(failCounters).reduce((a, b) => a + b) + ); + for (const [ service, fails ] of Object.entries(failCounters)) { + if (fails) console.log(`${Bright(service)} fails: ${fails}`); + } } From f6bffe543c9039846240a594c45d52b7993e0d1a Mon Sep 17 00:00:00 2001 From: jj Date: Wed, 13 Nov 2024 17:25:23 +0000 Subject: [PATCH 3/4] api/test: replace test.js with test-ci.js --- .github/workflows/test-services.yml | 4 +- api/src/util/test-ci.js | 131 ------------------- api/src/util/test.js | 191 +++++++++++++++++----------- 3 files changed, 121 insertions(+), 205 deletions(-) delete mode 100644 api/src/util/test-ci.js diff --git a/.github/workflows/test-services.yml b/.github/workflows/test-services.yml index 6291c7365..77242cb87 100644 --- a/.github/workflows/test-services.yml +++ b/.github/workflows/test-services.yml @@ -17,7 +17,7 @@ jobs: - uses: actions/checkout@v4 - uses: pnpm/action-setup@v4 - id: checkServices - run: pnpm i --frozen-lockfile && echo "service_list=$(node api/src/util/test-ci get-services)" >> "$GITHUB_OUTPUT" + run: pnpm i --frozen-lockfile && echo "service_list=$(node api/src/util/test get-services)" >> "$GITHUB_OUTPUT" test-services: needs: check-services @@ -30,4 +30,4 @@ jobs: steps: - uses: actions/checkout@v4 - uses: pnpm/action-setup@v4 - - run: pnpm i --frozen-lockfile && node api/src/util/test-ci run-tests-for ${{ matrix.service }} \ No newline at end of file + - run: pnpm i --frozen-lockfile && node api/src/util/test run-tests-for ${{ matrix.service }} diff --git a/api/src/util/test-ci.js b/api/src/util/test-ci.js deleted file mode 100644 index a8b70fd36..000000000 --- a/api/src/util/test-ci.js +++ /dev/null @@ -1,131 +0,0 @@ -import path from "node:path"; - -import { env } from "../config.js"; -import { runTest } from "../misc/run-test.js"; -import { loadJSON } from "../misc/load-from-fs.js"; -import { Red, Bright } from "../misc/console-text.js"; -import { randomizeCiphers } from "../misc/randomize-ciphers.js"; - -import { services } from "../processing/service-config.js"; - -const getTestPath = service => path.join('./src/util/tests/', `./${service}.json`); -const getTests = (service) => loadJSON(getTestPath(service)); - -// services that are known to frequently fail due to external -// factors (e.g. rate limiting) -const finnicky = new Set(['bilibili', 'instagram', 'facebook', 'youtube']); - -const runTestsFor = async (service) => { - const tests = getTests(service); - let softFails = 0, fails = 0; - - if (!tests) { - throw "no such service: " + service; - } - - for (const test of tests) { - const { name, url, params, expected } = test; - const canFail = test.canFail || finnicky.has(service); - - try { - await runTest(url, params, expected); - console.log(`${service}/${name}: ok`); - - } catch(e) { - softFails += !canFail; - fails++; - - let failText = canFail ? `${Red('FAIL')} (ignored)` : Bright(Red('FAIL')); - if (canFail && process.env.GITHUB_ACTION) { - console.log(`::warning title=${service}/${name.replace(/,/g, ';')}::failed and was ignored`); - } - - console.error(`${service}/${name}: ${failText}`); - const errorString = e.toString().split('\n'); - let c = 'ā”ƒ'; - errorString.forEach((line, index) => { - line = line.replace('!=', Red('!=')); - - if (index === errorString.length - 1) { - c = 'ā”—'; - } - - console.error(` ${c}`, line); - }); - } - } - - return { fails, softFails }; -} - -const printHeader = (service, padLen) => { - const padding = padLen - service.length; - service = service.padEnd(1 + service.length + padding, ' '); - console.log(service + '='.repeat(50)); -} - -const action = process.argv[2]; -switch (action) { - case "get-services": - const fromConfig = Object.keys(services); - - const missingTests = fromConfig.filter( - service => { - const tests = getTests(service); - return !tests || tests.length === 0 - } - ); - - if (missingTests.length) { - console.error('services have no tests:', missingTests); - process.exitCode = 1; - break; - } - - console.log(JSON.stringify(fromConfig)); - break; - - case "run-tests-for": - const service = process.argv[3]; - - env.streamLifespan = 10000; - env.apiURL = 'http://x/'; - randomizeCiphers(); - - try { - const { softFails } = await runTestsFor(service); - process.exitCode = Number(!!softFails); - } catch(e) { - console.error(e); - process.exitCode = 1; - break; - } - - break; - default: - const maxHeaderLen = Object.keys(services).reduce((n, v) => v.length > n ? v.length : n, 0); - const failCounters = {}; - - env.streamLifespan = 10000; - env.apiURL = 'http://x/'; - randomizeCiphers(); - - for (const service in services) { - printHeader(service, maxHeaderLen); - const { fails, softFails } = await runTestsFor(service); - failCounters[service] = fails; - console.log(); - - if (!process.exitCode && softFails) - process.exitCode = 1; - } - - console.log('='.repeat(50 + maxHeaderLen)); - console.log( - Bright('total fails:'), - Object.values(failCounters).reduce((a, b) => a + b) - ); - for (const [ service, fails ] of Object.entries(failCounters)) { - if (fails) console.log(`${Bright(service)} fails: ${fails}`); - } -} diff --git a/api/src/util/test.js b/api/src/util/test.js index 34afde7ef..a8b70fd36 100644 --- a/api/src/util/test.js +++ b/api/src/util/test.js @@ -1,84 +1,131 @@ -import "dotenv/config"; +import path from "node:path"; -import { services } from "../processing/service-config.js"; -import { extract } from "../processing/url.js"; -import match from "../processing/match.js"; -import { loadJSON } from "../misc/load-from-fs.js"; -import { normalizeRequest } from "../processing/request.js"; import { env } from "../config.js"; +import { runTest } from "../misc/run-test.js"; +import { loadJSON } from "../misc/load-from-fs.js"; +import { Red, Bright } from "../misc/console-text.js"; +import { randomizeCiphers } from "../misc/randomize-ciphers.js"; -env.apiURL = 'http://localhost:9000' -let tests = loadJSON('./src/util/tests.json'); - -let noTest = []; -let failed = []; -let success = 0; - -function addToFail(service, testName, url, status, response) { - failed.push({ - service: service, - name: testName, - url: url, - status: status, - response: response - }) -} -for (let i in services) { - if (tests[i]) { - console.log(`\nRunning tests for ${i}...\n`) - for (let k = 0; k < tests[i].length; k++) { - let test = tests[i][k]; - - console.log(`Running test ${k+1}: ${test.name}`); - console.log('params:'); - let params = {...{url: test.url}, ...test.params}; - console.log(params); - - let chck = await normalizeRequest(params); - if (chck.success) { - chck = chck.data; - - const parsed = extract(chck.url); - if (parsed === null) { - throw `Invalid URL: ${chck.url}` - } +import { services } from "../processing/service-config.js"; - let j = await match({ - host: parsed.host, - patternMatch: parsed.patternMatch, - params: chck, - }); - console.log('\nReceived:'); - console.log(j) - if (j.status === test.expected.code && j.body.status === test.expected.status) { - console.log("\nāœ… Success.\n"); - success++ - } else { - console.log(`\nāŒ Fail. Expected: ${test.expected.code} & ${test.expected.status}, received: ${j.status} & ${j.body.status}\n`); - addToFail(i, test.name, test.url, j.body.status, j) - } - } else { - console.log("\nāŒ couldn't validate the request JSON.\n"); - addToFail(i, test.name, test.url, "unknown", {}) +const getTestPath = service => path.join('./src/util/tests/', `./${service}.json`); +const getTests = (service) => loadJSON(getTestPath(service)); + +// services that are known to frequently fail due to external +// factors (e.g. rate limiting) +const finnicky = new Set(['bilibili', 'instagram', 'facebook', 'youtube']); + +const runTestsFor = async (service) => { + const tests = getTests(service); + let softFails = 0, fails = 0; + + if (!tests) { + throw "no such service: " + service; + } + + for (const test of tests) { + const { name, url, params, expected } = test; + const canFail = test.canFail || finnicky.has(service); + + try { + await runTest(url, params, expected); + console.log(`${service}/${name}: ok`); + + } catch(e) { + softFails += !canFail; + fails++; + + let failText = canFail ? `${Red('FAIL')} (ignored)` : Bright(Red('FAIL')); + if (canFail && process.env.GITHUB_ACTION) { + console.log(`::warning title=${service}/${name.replace(/,/g, ';')}::failed and was ignored`); } + + console.error(`${service}/${name}: ${failText}`); + const errorString = e.toString().split('\n'); + let c = 'ā”ƒ'; + errorString.forEach((line, index) => { + line = line.replace('!=', Red('!=')); + + if (index === errorString.length - 1) { + c = 'ā”—'; + } + + console.error(` ${c}`, line); + }); } - console.log("\n\n") - } else { - console.warn(`No tests found for ${i}.`); - noTest.push(i) } -} -console.log(`āœ… ${success} tests succeeded.`); -console.log(`āŒ ${failed.length} tests failed.`); -console.log(`ā” ${noTest.length} services weren't tested.`); + return { fails, softFails }; +} -if (failed.length > 0) { - console.log(`\nFailed tests:`); - console.log(failed) +const printHeader = (service, padLen) => { + const padding = padLen - service.length; + service = service.padEnd(1 + service.length + padding, ' '); + console.log(service + '='.repeat(50)); } -if (noTest.length > 0) { - console.log(`\nMissing tests:`); - console.log(noTest) +const action = process.argv[2]; +switch (action) { + case "get-services": + const fromConfig = Object.keys(services); + + const missingTests = fromConfig.filter( + service => { + const tests = getTests(service); + return !tests || tests.length === 0 + } + ); + + if (missingTests.length) { + console.error('services have no tests:', missingTests); + process.exitCode = 1; + break; + } + + console.log(JSON.stringify(fromConfig)); + break; + + case "run-tests-for": + const service = process.argv[3]; + + env.streamLifespan = 10000; + env.apiURL = 'http://x/'; + randomizeCiphers(); + + try { + const { softFails } = await runTestsFor(service); + process.exitCode = Number(!!softFails); + } catch(e) { + console.error(e); + process.exitCode = 1; + break; + } + + break; + default: + const maxHeaderLen = Object.keys(services).reduce((n, v) => v.length > n ? v.length : n, 0); + const failCounters = {}; + + env.streamLifespan = 10000; + env.apiURL = 'http://x/'; + randomizeCiphers(); + + for (const service in services) { + printHeader(service, maxHeaderLen); + const { fails, softFails } = await runTestsFor(service); + failCounters[service] = fails; + console.log(); + + if (!process.exitCode && softFails) + process.exitCode = 1; + } + + console.log('='.repeat(50 + maxHeaderLen)); + console.log( + Bright('total fails:'), + Object.values(failCounters).reduce((a, b) => a + b) + ); + for (const [ service, fails ] of Object.entries(failCounters)) { + if (fails) console.log(`${Bright(service)} fails: ${fails}`); + } } From cf40f0542f7ed4d1a924f8356de4d84aba08e91d Mon Sep 17 00:00:00 2001 From: jj Date: Wed, 13 Nov 2024 17:27:26 +0000 Subject: [PATCH 4/4] api/test: make deepsource happy --- api/src/util/test.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/api/src/util/test.js b/api/src/util/test.js index a8b70fd36..efb0f3a5c 100644 --- a/api/src/util/test.js +++ b/api/src/util/test.js @@ -86,14 +86,12 @@ switch (action) { break; case "run-tests-for": - const service = process.argv[3]; - env.streamLifespan = 10000; env.apiURL = 'http://x/'; randomizeCiphers(); try { - const { softFails } = await runTestsFor(service); + const { softFails } = await runTestsFor(process.argv[3]); process.exitCode = Number(!!softFails); } catch(e) { console.error(e);