2026-07-06 19:48:12 -04:00
|
|
|
import { test } from 'node:test';
|
|
|
|
|
import assert from 'node:assert/strict';
|
|
|
|
|
import {
|
|
|
|
|
getYouTubeVideoId,
|
|
|
|
|
getYoutubeShortsId,
|
|
|
|
|
isYouTubeShorts,
|
|
|
|
|
getVimeoVideoId,
|
2026-07-06 23:56:47 -04:00
|
|
|
getVimeoParts,
|
2026-07-07 00:08:51 -04:00
|
|
|
extractEmbedHeight,
|
2026-07-06 20:01:05 -04:00
|
|
|
getTikTokVideoId,
|
2026-07-06 23:03:44 -04:00
|
|
|
isTikTokLink,
|
|
|
|
|
tiktokIdFromOembed,
|
|
|
|
|
tiktokPlayerEmbedUrl,
|
2026-07-06 20:01:05 -04:00
|
|
|
getDailymotionId,
|
|
|
|
|
getStreamableId,
|
|
|
|
|
getTwitchTarget,
|
|
|
|
|
getSpotifyEmbedTarget,
|
|
|
|
|
isSoundCloudTrack,
|
2026-07-06 20:14:53 -04:00
|
|
|
getAppleMusicEmbed,
|
|
|
|
|
getTweetId,
|
2026-07-06 20:55:47 -04:00
|
|
|
getTidalEmbed,
|
|
|
|
|
getInstagramEmbed,
|
|
|
|
|
getRedditPostEmbed,
|
2026-07-06 19:48:12 -04:00
|
|
|
buildVideoEmbedUrl,
|
2026-07-06 20:01:05 -04:00
|
|
|
spotifyEmbedHeight,
|
|
|
|
|
parseMediaEmbed,
|
2026-07-06 19:48:12 -04:00
|
|
|
} from './videoEmbed';
|
|
|
|
|
|
2026-07-06 20:01:05 -04:00
|
|
|
const HOST = 'chat.lotusguild.org';
|
|
|
|
|
|
|
|
|
|
test('YouTube: watch / youtu.be / embed / shorts', () => {
|
2026-07-06 19:48:12 -04:00
|
|
|
assert.equal(getYouTubeVideoId('https://www.youtube.com/watch?v=dQw4w9WgXcQ'), 'dQw4w9WgXcQ');
|
|
|
|
|
assert.equal(getYouTubeVideoId('https://youtu.be/dQw4w9WgXcQ?t=42'), 'dQw4w9WgXcQ');
|
|
|
|
|
assert.equal(getYouTubeVideoId('https://www.youtube.com/embed/dQw4w9WgXcQ'), 'dQw4w9WgXcQ');
|
|
|
|
|
assert.equal(getYouTubeVideoId('https://youtube.com/shorts/abc123DEF_-'), 'abc123DEF_-');
|
2026-07-06 23:56:47 -04:00
|
|
|
assert.equal(getYouTubeVideoId('https://www.youtube.com/live/abcLIVE123'), 'abcLIVE123');
|
|
|
|
|
assert.equal(getYouTubeVideoId('https://music.youtube.com/watch?v=musicId12'), 'musicId12');
|
2026-07-06 19:48:12 -04:00
|
|
|
assert.equal(getYouTubeVideoId('https://vimeo.com/123'), null);
|
|
|
|
|
assert.equal(isYouTubeShorts('https://www.youtube.com/shorts/abc123'), true);
|
|
|
|
|
assert.equal(getYoutubeShortsId('https://youtube.com/shorts/abc123'), 'abc123');
|
|
|
|
|
});
|
|
|
|
|
|
2026-07-07 00:08:51 -04:00
|
|
|
test('Vimeo (incl. unlisted hash + channel/group/album forms)', () => {
|
2026-07-06 19:48:12 -04:00
|
|
|
assert.equal(getVimeoVideoId('https://vimeo.com/123456789'), '123456789');
|
|
|
|
|
assert.equal(getVimeoVideoId('https://vimeo.com/channels/staffpicks'), null);
|
2026-07-06 23:56:47 -04:00
|
|
|
assert.deepEqual(getVimeoParts('https://vimeo.com/123456789/abc123'), {
|
|
|
|
|
id: '123456789',
|
|
|
|
|
hash: 'abc123',
|
|
|
|
|
});
|
|
|
|
|
assert.ok(parseMediaEmbed('https://vimeo.com/123456789/abc123', 'h')?.embedUrl.includes('h=abc123'));
|
2026-07-07 00:08:51 -04:00
|
|
|
// channel / group / album share a trailing numeric video id
|
|
|
|
|
assert.equal(getVimeoParts('https://vimeo.com/channels/staffpicks/76979871')?.id, '76979871');
|
|
|
|
|
assert.equal(getVimeoParts('https://vimeo.com/groups/motion/videos/12345')?.id, '12345');
|
|
|
|
|
assert.equal(getVimeoParts('https://vimeo.com/album/99/video/54321')?.id, '54321');
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('extractEmbedHeight: Instagram / Reddit / Twitter shapes', () => {
|
|
|
|
|
assert.equal(extractEmbedHeight({ type: 'MEASURE', details: { height: 640 } }), 640);
|
|
|
|
|
assert.equal(extractEmbedHeight({ type: 'resize.embed', data: 812 }), 812); // Reddit
|
|
|
|
|
assert.equal(
|
|
|
|
|
extractEmbedHeight({ 'twttr.embed': [{ method: 'twttr.private.resize', params: [{ height: 500 }] }] }),
|
|
|
|
|
500,
|
|
|
|
|
);
|
|
|
|
|
assert.equal(extractEmbedHeight({ height: 300 }), 300); // generic fallback
|
|
|
|
|
assert.equal(extractEmbedHeight({ type: 'other' }), undefined);
|
|
|
|
|
assert.equal(extractEmbedHeight('not-an-object'), undefined);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('mobile Shorts (m.youtube.com) → portrait', () => {
|
|
|
|
|
assert.equal(parseMediaEmbed('https://m.youtube.com/shorts/abc123', 'h')?.kind, 'portrait');
|
2026-07-06 19:48:12 -04:00
|
|
|
});
|
|
|
|
|
|
2026-07-06 20:01:05 -04:00
|
|
|
test('TikTok: canonical /video/<id> only', () => {
|
|
|
|
|
assert.equal(getTikTokVideoId('https://www.tiktok.com/@user/video/7234567890123456789'), '7234567890123456789');
|
2026-07-06 23:03:44 -04:00
|
|
|
assert.equal(getTikTokVideoId('https://vm.tiktok.com/ZMabc/'), null); // short link → oEmbed
|
2026-07-06 20:01:05 -04:00
|
|
|
assert.equal(getTikTokVideoId('https://www.tiktok.com/@user'), null);
|
|
|
|
|
});
|
|
|
|
|
|
2026-07-06 23:03:44 -04:00
|
|
|
test('isTikTokLink: canonical + short + vm/vt', () => {
|
|
|
|
|
assert.equal(isTikTokLink('https://www.tiktok.com/@user/video/123'), true);
|
|
|
|
|
assert.equal(isTikTokLink('https://www.tiktok.com/t/ZTSHuuXWq/'), true);
|
|
|
|
|
assert.equal(isTikTokLink('https://vm.tiktok.com/ZMabc/'), true);
|
|
|
|
|
assert.equal(isTikTokLink('https://www.tiktok.com/@user'), false); // profile, not a video
|
|
|
|
|
assert.equal(isTikTokLink('https://youtube.com/watch?v=x'), false);
|
|
|
|
|
assert.equal(parseMediaEmbed('https://www.tiktok.com/@u/video/123', 'h'), null); // handled by its own card
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('tiktokIdFromOembed + player url', () => {
|
|
|
|
|
assert.equal(tiktokIdFromOembed({ embed_product_id: '7659555276823006478' }), '7659555276823006478');
|
|
|
|
|
assert.equal(tiktokIdFromOembed({ html: '<blockquote data-video-id="123456">' }), '123456');
|
|
|
|
|
assert.equal(tiktokIdFromOembed({}), null);
|
2026-07-07 00:32:09 -04:00
|
|
|
assert.equal(tiktokPlayerEmbedUrl('999'), 'https://www.tiktok.com/player/v1/999?autoplay=1&rel=0');
|
2026-07-06 23:03:44 -04:00
|
|
|
});
|
|
|
|
|
|
2026-07-06 20:01:05 -04:00
|
|
|
test('Dailymotion + Streamable', () => {
|
|
|
|
|
assert.equal(getDailymotionId('https://www.dailymotion.com/video/x8abcde'), 'x8abcde');
|
|
|
|
|
assert.equal(getDailymotionId('https://dai.ly/x8abcde'), 'x8abcde');
|
|
|
|
|
assert.equal(getStreamableId('https://streamable.com/abc12'), 'abc12');
|
|
|
|
|
assert.equal(getStreamableId('https://streamable.com/e/abc12'), null); // already an embed path
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('Twitch: channel / video / clip', () => {
|
|
|
|
|
assert.deepEqual(getTwitchTarget('https://www.twitch.tv/somestreamer'), {
|
|
|
|
|
type: 'channel',
|
|
|
|
|
value: 'somestreamer',
|
2026-07-06 19:48:12 -04:00
|
|
|
});
|
2026-07-06 20:01:05 -04:00
|
|
|
assert.deepEqual(getTwitchTarget('https://www.twitch.tv/videos/123456789'), {
|
|
|
|
|
type: 'video',
|
|
|
|
|
value: '123456789',
|
|
|
|
|
});
|
|
|
|
|
assert.deepEqual(getTwitchTarget('https://clips.twitch.tv/FunnyClipSlug'), {
|
|
|
|
|
type: 'clip',
|
|
|
|
|
value: 'FunnyClipSlug',
|
|
|
|
|
});
|
|
|
|
|
assert.deepEqual(getTwitchTarget('https://www.twitch.tv/streamer/clip/CoolSlug'), {
|
|
|
|
|
type: 'clip',
|
|
|
|
|
value: 'CoolSlug',
|
2026-07-06 19:48:12 -04:00
|
|
|
});
|
2026-07-06 20:01:05 -04:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('Spotify target + height', () => {
|
|
|
|
|
assert.deepEqual(getSpotifyEmbedTarget('https://open.spotify.com/track/4cOdK2wGLETKBW3PvgPWqT'), {
|
|
|
|
|
type: 'track',
|
|
|
|
|
id: '4cOdK2wGLETKBW3PvgPWqT',
|
|
|
|
|
});
|
|
|
|
|
assert.deepEqual(getSpotifyEmbedTarget('https://open.spotify.com/intl-de/album/xyz'), {
|
|
|
|
|
type: 'album',
|
|
|
|
|
id: 'xyz',
|
2026-07-06 19:48:12 -04:00
|
|
|
});
|
2026-07-06 20:01:05 -04:00
|
|
|
assert.equal(getSpotifyEmbedTarget('https://open.spotify.com/'), null);
|
|
|
|
|
assert.equal(spotifyEmbedHeight('track'), 152);
|
|
|
|
|
assert.equal(spotifyEmbedHeight('album'), 352);
|
2026-07-06 19:48:12 -04:00
|
|
|
});
|
|
|
|
|
|
2026-07-07 00:32:09 -04:00
|
|
|
test('SoundCloud track detection (+ on. short link)', () => {
|
2026-07-06 20:01:05 -04:00
|
|
|
assert.equal(isSoundCloudTrack('https://soundcloud.com/artist/some-track'), true);
|
|
|
|
|
assert.equal(isSoundCloudTrack('https://soundcloud.com/artist'), false); // bare profile
|
2026-07-07 00:32:09 -04:00
|
|
|
assert.equal(isSoundCloudTrack('https://on.soundcloud.com/abc123'), true); // share short link
|
|
|
|
|
assert.equal(parseMediaEmbed('https://on.soundcloud.com/abc123', 'h')?.provider, 'soundcloud');
|
2026-07-06 20:01:05 -04:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('buildVideoEmbedUrl: cookie-less YouTube + Vimeo', () => {
|
2026-07-06 19:48:12 -04:00
|
|
|
assert.equal(
|
|
|
|
|
buildVideoEmbedUrl('youtube', 'dQw4w9WgXcQ'),
|
2026-07-06 23:56:47 -04:00
|
|
|
'https://www.youtube-nocookie.com/embed/dQw4w9WgXcQ?autoplay=1&rel=0&playsinline=1',
|
|
|
|
|
);
|
|
|
|
|
assert.equal(
|
|
|
|
|
buildVideoEmbedUrl('vimeo', '42'),
|
|
|
|
|
'https://player.vimeo.com/video/42?autoplay=1&dnt=1',
|
|
|
|
|
);
|
|
|
|
|
assert.equal(
|
|
|
|
|
buildVideoEmbedUrl('vimeo', '42', 'h4sh'),
|
|
|
|
|
'https://player.vimeo.com/video/42?autoplay=1&dnt=1&h=h4sh',
|
2026-07-06 19:48:12 -04:00
|
|
|
);
|
2026-07-06 20:01:05 -04:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('parseMediaEmbed: routes provider + kind, builds embed URLs', () => {
|
|
|
|
|
assert.deepEqual(parseMediaEmbed('https://youtube.com/shorts/abc', HOST), {
|
|
|
|
|
provider: 'youtube',
|
|
|
|
|
kind: 'portrait',
|
2026-07-06 23:56:47 -04:00
|
|
|
embedUrl: 'https://www.youtube-nocookie.com/embed/abc?autoplay=1&rel=0&playsinline=1',
|
2026-07-06 20:01:05 -04:00
|
|
|
});
|
|
|
|
|
assert.equal(parseMediaEmbed('https://www.youtube.com/watch?v=xyz', HOST)?.kind, 'landscape');
|
|
|
|
|
assert.equal(parseMediaEmbed('https://streamable.com/abc', HOST)?.provider, 'streamable');
|
|
|
|
|
const spotify = parseMediaEmbed('https://open.spotify.com/track/abc', HOST);
|
|
|
|
|
assert.equal(spotify?.kind, 'audio');
|
|
|
|
|
assert.equal(spotify?.height, 152);
|
|
|
|
|
assert.equal(parseMediaEmbed('https://soundcloud.com/a/b', HOST)?.provider, 'soundcloud');
|
|
|
|
|
assert.equal(parseMediaEmbed('https://example.com/x', HOST), null);
|
|
|
|
|
});
|
|
|
|
|
|
2026-07-06 20:14:53 -04:00
|
|
|
test('Apple Music: album vs single song height, embed host swap', () => {
|
|
|
|
|
const album = getAppleMusicEmbed('https://music.apple.com/us/album/some-album/123456');
|
|
|
|
|
assert.equal(album?.embedUrl, 'https://embed.music.apple.com/us/album/some-album/123456');
|
|
|
|
|
assert.equal(album?.height, 450);
|
|
|
|
|
const song = getAppleMusicEmbed('https://music.apple.com/us/album/some-album/123456?i=789');
|
|
|
|
|
assert.equal(song?.height, 175);
|
|
|
|
|
assert.ok(song?.embedUrl.includes('?i=789'));
|
|
|
|
|
assert.equal(getAppleMusicEmbed('https://music.apple.com/us/browse'), null);
|
|
|
|
|
assert.equal(getAppleMusicEmbed('https://example.com/album/x/1'), null);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('getTweetId', () => {
|
|
|
|
|
assert.equal(getTweetId('https://x.com/user/status/1799999999999999999'), '1799999999999999999');
|
|
|
|
|
assert.equal(getTweetId('https://twitter.com/user/status/12345'), '12345');
|
|
|
|
|
assert.equal(getTweetId('https://x.com/user'), null);
|
|
|
|
|
assert.equal(getTweetId('https://youtube.com/watch?v=x'), null);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('parseMediaEmbed: Apple Music → audio', () => {
|
|
|
|
|
const m = parseMediaEmbed('https://music.apple.com/us/album/x/1?i=2', 'chat.lotusguild.org');
|
|
|
|
|
assert.equal(m?.provider, 'applemusic');
|
|
|
|
|
assert.equal(m?.kind, 'audio');
|
|
|
|
|
assert.equal(m?.height, 175);
|
|
|
|
|
});
|
|
|
|
|
|
2026-07-06 20:55:47 -04:00
|
|
|
test('Tidal: track (audio) vs video (landscape)', () => {
|
|
|
|
|
assert.deepEqual(getTidalEmbed('https://tidal.com/browse/track/12345'), {
|
|
|
|
|
kind: 'audio',
|
|
|
|
|
embedUrl: 'https://embed.tidal.com/tracks/12345',
|
|
|
|
|
height: 120,
|
|
|
|
|
});
|
2026-07-06 23:56:47 -04:00
|
|
|
assert.equal(getTidalEmbed('https://listen.tidal.com/album/999')?.embedUrl, 'https://embed.tidal.com/albums/999?layout=gridify');
|
|
|
|
|
assert.equal(getTidalEmbed('https://listen.tidal.com/album/999')?.height, 275);
|
2026-07-06 20:55:47 -04:00
|
|
|
assert.equal(getTidalEmbed('https://tidal.com/video/555')?.kind, 'landscape');
|
|
|
|
|
assert.equal(getTidalEmbed('https://tidal.com/browse'), null);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('Instagram: p / reel / tv → embed path', () => {
|
|
|
|
|
assert.equal(getInstagramEmbed('https://www.instagram.com/p/AbC123_-/'), 'https://www.instagram.com/p/AbC123_-/embed/');
|
|
|
|
|
assert.equal(getInstagramEmbed('https://instagram.com/reel/XyZ/'), 'https://www.instagram.com/reel/XyZ/embed/');
|
|
|
|
|
assert.equal(getInstagramEmbed('https://www.instagram.com/reels/XyZ/'), 'https://www.instagram.com/reel/XyZ/embed/');
|
|
|
|
|
assert.equal(getInstagramEmbed('https://www.instagram.com/someuser/'), null);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('Reddit post embed → redditmedia', () => {
|
|
|
|
|
assert.equal(
|
|
|
|
|
getRedditPostEmbed('https://www.reddit.com/r/aww/comments/abc123/cute_cat/'),
|
2026-07-06 23:56:47 -04:00
|
|
|
'https://embed.reddit.com/r/aww/comments/abc123/?ref_source=embed&ref=share&embed=true&theme=dark',
|
2026-07-06 20:55:47 -04:00
|
|
|
);
|
2026-07-06 23:56:47 -04:00
|
|
|
assert.equal(getRedditPostEmbed('https://old.reddit.com/r/aww/comments/xyz/'), 'https://embed.reddit.com/r/aww/comments/xyz/?ref_source=embed&ref=share&embed=true&theme=dark');
|
2026-07-06 20:55:47 -04:00
|
|
|
assert.equal(getRedditPostEmbed('https://www.reddit.com/r/aww/'), null); // subreddit, not a post
|
2026-07-07 00:32:09 -04:00
|
|
|
// redd.it short link → comments-only embed (no subreddit in the redirect)
|
|
|
|
|
assert.equal(getRedditPostEmbed('https://redd.it/1abc23'), 'https://embed.reddit.com/comments/1abc23/?ref_source=embed&ref=share&embed=true&theme=dark');
|
2026-07-06 20:55:47 -04:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('parseMediaEmbed: Instagram/Reddit → rich, Tidal → audio', () => {
|
|
|
|
|
assert.equal(parseMediaEmbed('https://www.instagram.com/p/abc/', 'h')?.kind, 'rich');
|
|
|
|
|
assert.equal(parseMediaEmbed('https://www.reddit.com/r/x/comments/y/z/', 'h')?.provider, 'reddit');
|
|
|
|
|
assert.equal(parseMediaEmbed('https://tidal.com/browse/track/1', 'h')?.provider, 'tidal');
|
|
|
|
|
});
|
|
|
|
|
|
2026-07-06 20:01:05 -04:00
|
|
|
test('parseMediaEmbed: Twitch embed carries the parent host', () => {
|
|
|
|
|
const chan = parseMediaEmbed('https://twitch.tv/streamer', HOST);
|
|
|
|
|
assert.equal(chan?.provider, 'twitch');
|
|
|
|
|
assert.ok(chan?.embedUrl.includes('channel=streamer'));
|
|
|
|
|
assert.ok(chan?.embedUrl.includes(`parent=${HOST}`));
|
|
|
|
|
const clip = parseMediaEmbed('https://clips.twitch.tv/Slug', HOST);
|
|
|
|
|
assert.ok(clip?.embedUrl.startsWith('https://clips.twitch.tv/embed?clip=Slug'));
|
2026-07-06 19:48:12 -04:00
|
|
|
});
|