2023-08-16 19:22:50 +02:00
|
|
|
import {RichText} from '@atproto/api'
|
2024-04-20 00:31:20 +02:00
|
|
|
|
|
|
|
import {parseEmbedPlayerFromUrl} from 'lib/strings/embed-player'
|
|
|
|
import {cleanError} from '../../src/lib/strings/errors'
|
|
|
|
import {createFullHandle, makeValidHandle} from '../../src/lib/strings/handles'
|
2024-05-07 01:55:57 +02:00
|
|
|
import {enforceLen} from '../../src/lib/strings/helpers'
|
2024-04-20 00:31:20 +02:00
|
|
|
import {detectLinkables} from '../../src/lib/strings/rich-text-detection'
|
|
|
|
import {shortenLinks} from '../../src/lib/strings/rich-text-manip'
|
|
|
|
import {ago} from '../../src/lib/strings/time'
|
2022-11-23 23:29:17 +01:00
|
|
|
import {
|
2022-12-22 16:32:39 +01:00
|
|
|
makeRecordUri,
|
|
|
|
toNiceDomain,
|
|
|
|
toShareUrl,
|
2024-04-20 00:31:20 +02:00
|
|
|
toShortUrl,
|
2023-02-22 21:23:57 +01:00
|
|
|
} from '../../src/lib/strings/url-helpers'
|
2022-10-04 17:15:35 +02:00
|
|
|
|
2022-11-22 21:30:35 +01:00
|
|
|
describe('detectLinkables', () => {
|
|
|
|
const inputs = [
|
|
|
|
'no linkable',
|
2022-10-04 17:15:35 +02:00
|
|
|
'@start middle end',
|
|
|
|
'start @middle end',
|
|
|
|
'start middle @end',
|
|
|
|
'@start @middle @end',
|
|
|
|
'@full123.test-of-chars',
|
|
|
|
'not@right',
|
|
|
|
'@bad!@#$chars',
|
|
|
|
'@newline1\n@newline2',
|
2022-11-29 17:01:57 +01:00
|
|
|
'parenthetical (@handle)',
|
2022-11-22 21:30:35 +01:00
|
|
|
'start https://middle.com end',
|
|
|
|
'start https://middle.com/foo/bar end',
|
|
|
|
'start https://middle.com/foo/bar?baz=bux end',
|
|
|
|
'start https://middle.com/foo/bar?baz=bux#hash end',
|
|
|
|
'https://start.com/foo/bar?baz=bux#hash middle end',
|
|
|
|
'start middle https://end.com/foo/bar?baz=bux#hash',
|
|
|
|
'https://newline1.com\nhttps://newline2.com',
|
|
|
|
'start middle.com end',
|
|
|
|
'start middle.com/foo/bar end',
|
|
|
|
'start middle.com/foo/bar?baz=bux end',
|
|
|
|
'start middle.com/foo/bar?baz=bux#hash end',
|
|
|
|
'start.com/foo/bar?baz=bux#hash middle end',
|
|
|
|
'start middle end.com/foo/bar?baz=bux#hash',
|
|
|
|
'newline1.com\nnewline2.com',
|
2022-11-23 20:15:38 +01:00
|
|
|
'not.. a..url ..here',
|
2022-11-28 17:22:08 +01:00
|
|
|
'e.g.',
|
|
|
|
'e.g. real.com fake.notreal',
|
|
|
|
'something-cool.jpg',
|
|
|
|
'website.com.jpg',
|
|
|
|
'e.g./foo',
|
|
|
|
'website.com.jpg/foo',
|
2022-11-29 17:01:57 +01:00
|
|
|
'Classic article https://socket3.wordpress.com/2018/02/03/designing-windows-95s-user-interface/',
|
|
|
|
'Classic article https://socket3.wordpress.com/2018/02/03/designing-windows-95s-user-interface/ ',
|
|
|
|
'https://foo.com https://bar.com/whatever https://baz.com',
|
|
|
|
'punctuation https://foo.com, https://bar.com/whatever; https://baz.com.',
|
2023-05-30 21:46:43 +02:00
|
|
|
'parenthetical (https://foo.com)',
|
2022-11-29 17:01:57 +01:00
|
|
|
'except for https://foo.com/thing_(cool)',
|
2022-10-04 17:15:35 +02:00
|
|
|
]
|
|
|
|
const outputs = [
|
2022-11-22 21:30:35 +01:00
|
|
|
['no linkable'],
|
|
|
|
[{link: '@start'}, ' middle end'],
|
|
|
|
['start ', {link: '@middle'}, ' end'],
|
|
|
|
['start middle ', {link: '@end'}],
|
|
|
|
[{link: '@start'}, ' ', {link: '@middle'}, ' ', {link: '@end'}],
|
|
|
|
[{link: '@full123.test-of-chars'}],
|
|
|
|
['not@right'],
|
|
|
|
[{link: '@bad'}, '!@#$chars'],
|
|
|
|
[{link: '@newline1'}, '\n', {link: '@newline2'}],
|
2022-11-29 17:01:57 +01:00
|
|
|
['parenthetical (', {link: '@handle'}, ')'],
|
2022-11-22 21:30:35 +01:00
|
|
|
['start ', {link: 'https://middle.com'}, ' end'],
|
|
|
|
['start ', {link: 'https://middle.com/foo/bar'}, ' end'],
|
|
|
|
['start ', {link: 'https://middle.com/foo/bar?baz=bux'}, ' end'],
|
|
|
|
['start ', {link: 'https://middle.com/foo/bar?baz=bux#hash'}, ' end'],
|
|
|
|
[{link: 'https://start.com/foo/bar?baz=bux#hash'}, ' middle end'],
|
|
|
|
['start middle ', {link: 'https://end.com/foo/bar?baz=bux#hash'}],
|
|
|
|
[{link: 'https://newline1.com'}, '\n', {link: 'https://newline2.com'}],
|
|
|
|
['start ', {link: 'middle.com'}, ' end'],
|
|
|
|
['start ', {link: 'middle.com/foo/bar'}, ' end'],
|
|
|
|
['start ', {link: 'middle.com/foo/bar?baz=bux'}, ' end'],
|
|
|
|
['start ', {link: 'middle.com/foo/bar?baz=bux#hash'}, ' end'],
|
|
|
|
[{link: 'start.com/foo/bar?baz=bux#hash'}, ' middle end'],
|
|
|
|
['start middle ', {link: 'end.com/foo/bar?baz=bux#hash'}],
|
|
|
|
[{link: 'newline1.com'}, '\n', {link: 'newline2.com'}],
|
2022-11-23 20:15:38 +01:00
|
|
|
['not.. a..url ..here'],
|
2022-11-28 17:22:08 +01:00
|
|
|
['e.g.'],
|
|
|
|
['e.g. ', {link: 'real.com'}, ' fake.notreal'],
|
|
|
|
['something-cool.jpg'],
|
|
|
|
['website.com.jpg'],
|
|
|
|
['e.g./foo'],
|
|
|
|
['website.com.jpg/foo'],
|
2022-11-29 17:01:57 +01:00
|
|
|
[
|
|
|
|
'Classic article ',
|
|
|
|
{
|
|
|
|
link: 'https://socket3.wordpress.com/2018/02/03/designing-windows-95s-user-interface/',
|
|
|
|
},
|
|
|
|
],
|
|
|
|
[
|
|
|
|
'Classic article ',
|
|
|
|
{
|
|
|
|
link: 'https://socket3.wordpress.com/2018/02/03/designing-windows-95s-user-interface/',
|
|
|
|
},
|
|
|
|
' ',
|
|
|
|
],
|
|
|
|
[
|
|
|
|
{link: 'https://foo.com'},
|
|
|
|
' ',
|
|
|
|
{link: 'https://bar.com/whatever'},
|
|
|
|
' ',
|
|
|
|
{link: 'https://baz.com'},
|
|
|
|
],
|
|
|
|
[
|
|
|
|
'punctuation ',
|
|
|
|
{link: 'https://foo.com'},
|
|
|
|
', ',
|
|
|
|
{link: 'https://bar.com/whatever'},
|
|
|
|
'; ',
|
|
|
|
{link: 'https://baz.com'},
|
|
|
|
'.',
|
|
|
|
],
|
2023-05-30 21:46:43 +02:00
|
|
|
['parenthetical (', {link: 'https://foo.com'}, ')'],
|
2022-11-29 17:01:57 +01:00
|
|
|
['except for ', {link: 'https://foo.com/thing_(cool)'}],
|
2022-10-04 17:15:35 +02:00
|
|
|
]
|
|
|
|
it('correctly handles a set of text inputs', () => {
|
|
|
|
for (let i = 0; i < inputs.length; i++) {
|
|
|
|
const input = inputs[i]
|
2022-11-22 21:30:35 +01:00
|
|
|
const output = detectLinkables(input)
|
2022-10-04 17:15:35 +02:00
|
|
|
expect(output).toEqual(outputs[i])
|
|
|
|
}
|
|
|
|
})
|
|
|
|
})
|
2022-11-23 23:29:17 +01:00
|
|
|
|
2022-12-22 16:32:39 +01:00
|
|
|
describe('makeRecordUri', () => {
|
|
|
|
const inputs: [string, string, string][] = [
|
|
|
|
['alice.test', 'app.bsky.feed.post', '3jk7x4irgv52r'],
|
|
|
|
]
|
|
|
|
const outputs = ['at://alice.test/app.bsky.feed.post/3jk7x4irgv52r']
|
|
|
|
|
|
|
|
it('correctly builds a record URI', () => {
|
|
|
|
for (let i = 0; i < inputs.length; i++) {
|
|
|
|
const input = inputs[i]
|
|
|
|
const result = makeRecordUri(...input)
|
|
|
|
expect(result).toEqual(outputs[i])
|
|
|
|
}
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
2024-05-31 05:09:23 +02:00
|
|
|
// FIXME: Reenable after fixing non-deterministic test.
|
|
|
|
describe.skip('ago', () => {
|
2024-05-13 17:39:34 +02:00
|
|
|
const oneYearDate = new Date(
|
|
|
|
new Date().setMonth(new Date().getMonth() - 11),
|
|
|
|
).setDate(new Date().getDate() - 28)
|
|
|
|
|
2022-12-22 16:32:39 +01:00
|
|
|
const inputs = [
|
|
|
|
1671461038,
|
|
|
|
'04 Dec 1995 00:12:00 GMT',
|
|
|
|
new Date(),
|
2023-09-08 17:57:22 +02:00
|
|
|
new Date().setSeconds(new Date().getSeconds() - 10),
|
2022-12-22 16:32:39 +01:00
|
|
|
new Date().setMinutes(new Date().getMinutes() - 10),
|
|
|
|
new Date().setHours(new Date().getHours() - 1),
|
|
|
|
new Date().setDate(new Date().getDate() - 1),
|
2024-05-13 17:39:34 +02:00
|
|
|
new Date().setDate(new Date().getDate() - 20),
|
|
|
|
new Date().setDate(new Date().getDate() - 25),
|
|
|
|
new Date().setDate(new Date().getDate() - 28),
|
|
|
|
new Date().setDate(new Date().getDate() - 29),
|
|
|
|
new Date().setDate(new Date().getDate() - 30),
|
2022-12-22 16:32:39 +01:00
|
|
|
new Date().setMonth(new Date().getMonth() - 1),
|
2024-05-13 17:39:34 +02:00
|
|
|
new Date(new Date().setMonth(new Date().getMonth() - 1)).setDate(
|
|
|
|
new Date().getDate() - 20,
|
|
|
|
),
|
|
|
|
new Date(new Date().setMonth(new Date().getMonth() - 1)).setDate(
|
|
|
|
new Date().getDate() - 25,
|
|
|
|
),
|
|
|
|
new Date(new Date().setMonth(new Date().getMonth() - 1)).setDate(
|
|
|
|
new Date().getDate() - 28,
|
|
|
|
),
|
|
|
|
new Date(new Date().setMonth(new Date().getMonth() - 1)).setDate(
|
|
|
|
new Date().getDate() - 29,
|
|
|
|
),
|
|
|
|
new Date().setMonth(new Date().getMonth() - 11),
|
|
|
|
new Date(new Date().setMonth(new Date().getMonth() - 11)).setDate(
|
|
|
|
new Date().getDate() - 20,
|
|
|
|
),
|
|
|
|
new Date(new Date().setMonth(new Date().getMonth() - 11)).setDate(
|
|
|
|
new Date().getDate() - 25,
|
|
|
|
),
|
|
|
|
oneYearDate,
|
2022-12-22 16:32:39 +01:00
|
|
|
]
|
|
|
|
const outputs = [
|
2023-06-08 18:32:56 +02:00
|
|
|
new Date(1671461038).toLocaleDateString(),
|
|
|
|
new Date('04 Dec 1995 00:12:00 GMT').toLocaleDateString(),
|
2023-09-08 17:57:22 +02:00
|
|
|
'now',
|
|
|
|
'10s',
|
2022-12-22 16:32:39 +01:00
|
|
|
'10m',
|
|
|
|
'1h',
|
|
|
|
'1d',
|
2024-05-13 17:39:34 +02:00
|
|
|
'20d',
|
|
|
|
'25d',
|
|
|
|
'28d',
|
|
|
|
'29d',
|
|
|
|
'1mo',
|
|
|
|
'1mo',
|
|
|
|
'1mo',
|
2023-06-08 18:32:56 +02:00
|
|
|
'1mo',
|
2024-05-13 17:39:34 +02:00
|
|
|
'2mo',
|
|
|
|
'2mo',
|
|
|
|
'11mo',
|
|
|
|
'11mo',
|
|
|
|
'11mo',
|
|
|
|
new Date(oneYearDate).toLocaleDateString(),
|
2022-12-22 16:32:39 +01:00
|
|
|
]
|
|
|
|
|
|
|
|
it('correctly calculates how much time passed, in a string', () => {
|
|
|
|
for (let i = 0; i < inputs.length; i++) {
|
|
|
|
const result = ago(inputs[i])
|
|
|
|
expect(result).toEqual(outputs[i])
|
|
|
|
}
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
describe('makeValidHandle', () => {
|
|
|
|
const inputs = [
|
|
|
|
'test-handle-123',
|
|
|
|
'test!"#$%&/()=?_',
|
|
|
|
'this-handle-should-be-too-big',
|
|
|
|
]
|
|
|
|
const outputs = ['test-handle-123', 'test', 'this-handle-should-b']
|
|
|
|
|
|
|
|
it('correctly parses and corrects handles', () => {
|
|
|
|
for (let i = 0; i < inputs.length; i++) {
|
|
|
|
const result = makeValidHandle(inputs[i])
|
|
|
|
expect(result).toEqual(outputs[i])
|
|
|
|
}
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
describe('createFullHandle', () => {
|
|
|
|
const inputs: [string, string][] = [
|
|
|
|
['test-handle-123', 'test'],
|
|
|
|
['.test.handle', 'test.test.'],
|
|
|
|
['test.handle.', '.test.test'],
|
|
|
|
]
|
|
|
|
const outputs = [
|
|
|
|
'test-handle-123.test',
|
|
|
|
'.test.handle.test.test.',
|
|
|
|
'test.handle.test.test',
|
|
|
|
]
|
|
|
|
|
|
|
|
it('correctly parses and corrects handles', () => {
|
|
|
|
for (let i = 0; i < inputs.length; i++) {
|
|
|
|
const input = inputs[i]
|
|
|
|
const result = createFullHandle(...input)
|
|
|
|
expect(result).toEqual(outputs[i])
|
|
|
|
}
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
describe('enforceLen', () => {
|
|
|
|
const inputs: [string, number][] = [
|
|
|
|
['Hello World!', 5],
|
|
|
|
['Hello World!', 20],
|
|
|
|
['', 5],
|
|
|
|
]
|
|
|
|
const outputs = ['Hello', 'Hello World!', '']
|
|
|
|
|
|
|
|
it('correctly enforces defined length on a given string', () => {
|
|
|
|
for (let i = 0; i < inputs.length; i++) {
|
|
|
|
const input = inputs[i]
|
|
|
|
const result = enforceLen(...input)
|
|
|
|
expect(result).toEqual(outputs[i])
|
|
|
|
}
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
describe('cleanError', () => {
|
|
|
|
const inputs = [
|
|
|
|
'TypeError: Network request failed',
|
|
|
|
'Error: Aborted',
|
|
|
|
'Error: TypeError "x" is not a function',
|
|
|
|
'Error: SyntaxError unexpected token "export"',
|
|
|
|
'Some other error',
|
|
|
|
]
|
|
|
|
const outputs = [
|
|
|
|
'Unable to connect. Please check your internet connection and try again.',
|
|
|
|
'Unable to connect. Please check your internet connection and try again.',
|
|
|
|
'TypeError "x" is not a function',
|
|
|
|
'SyntaxError unexpected token "export"',
|
|
|
|
'Some other error',
|
|
|
|
]
|
|
|
|
|
|
|
|
it('removes extra content from error message', () => {
|
|
|
|
for (let i = 0; i < inputs.length; i++) {
|
|
|
|
const result = cleanError(inputs[i])
|
|
|
|
expect(result).toEqual(outputs[i])
|
|
|
|
}
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
describe('toNiceDomain', () => {
|
|
|
|
const inputs = [
|
|
|
|
'https://example.com/index.html',
|
|
|
|
'https://bsky.app',
|
|
|
|
'https://bsky.social',
|
|
|
|
'#123123123',
|
|
|
|
]
|
|
|
|
const outputs = ['example.com', 'bsky.app', 'Bluesky Social', '#123123123']
|
|
|
|
|
|
|
|
it("displays the url's host in a easily readable manner", () => {
|
|
|
|
for (let i = 0; i < inputs.length; i++) {
|
|
|
|
const result = toNiceDomain(inputs[i])
|
|
|
|
expect(result).toEqual(outputs[i])
|
|
|
|
}
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
describe('toShortUrl', () => {
|
|
|
|
const inputs = [
|
|
|
|
'https://bsky.app',
|
|
|
|
'https://bsky.app/3jk7x4irgv52r',
|
|
|
|
'https://bsky.app/3jk7x4irgv52r2313y182h9',
|
2023-08-16 19:22:50 +02:00
|
|
|
'https://very-long-domain-name.com/foo',
|
|
|
|
'https://very-long-domain-name.com/foo?bar=baz#andsomemore',
|
2022-12-22 16:32:39 +01:00
|
|
|
]
|
|
|
|
const outputs = [
|
|
|
|
'bsky.app',
|
|
|
|
'bsky.app/3jk7x4irgv52r',
|
2023-08-16 19:22:50 +02:00
|
|
|
'bsky.app/3jk7x4irgv52...',
|
|
|
|
'very-long-domain-name.com/foo',
|
|
|
|
'very-long-domain-name.com/foo?bar=baz#...',
|
2022-12-22 16:32:39 +01:00
|
|
|
]
|
|
|
|
|
|
|
|
it('shortens the url', () => {
|
|
|
|
for (let i = 0; i < inputs.length; i++) {
|
|
|
|
const result = toShortUrl(inputs[i])
|
|
|
|
expect(result).toEqual(outputs[i])
|
|
|
|
}
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
describe('toShareUrl', () => {
|
|
|
|
const inputs = ['https://bsky.app', '/3jk7x4irgv52r', 'item/test/123']
|
|
|
|
const outputs = [
|
|
|
|
'https://bsky.app',
|
|
|
|
'https://bsky.app/3jk7x4irgv52r',
|
|
|
|
'https://bsky.app/item/test/123',
|
|
|
|
]
|
|
|
|
|
|
|
|
it('appends https, when not present', () => {
|
|
|
|
for (let i = 0; i < inputs.length; i++) {
|
|
|
|
const result = toShareUrl(inputs[i])
|
|
|
|
expect(result).toEqual(outputs[i])
|
|
|
|
}
|
|
|
|
})
|
|
|
|
})
|
2023-02-22 21:23:57 +01:00
|
|
|
|
2023-08-16 19:22:50 +02:00
|
|
|
describe('shortenLinks', () => {
|
|
|
|
const inputs = [
|
|
|
|
'start https://middle.com/foo/bar?baz=bux#hash end',
|
|
|
|
'https://start.com/foo/bar?baz=bux#hash middle end',
|
|
|
|
'start middle https://end.com/foo/bar?baz=bux#hash',
|
|
|
|
'https://newline1.com/very/long/url/here\nhttps://newline2.com/very/long/url/here',
|
|
|
|
'Classic article https://socket3.wordpress.com/2018/02/03/designing-windows-95s-user-interface/',
|
|
|
|
]
|
|
|
|
const outputs = [
|
|
|
|
[
|
|
|
|
'start middle.com/foo/bar?baz=... end',
|
|
|
|
['https://middle.com/foo/bar?baz=bux#hash'],
|
|
|
|
],
|
|
|
|
[
|
|
|
|
'start.com/foo/bar?baz=... middle end',
|
|
|
|
['https://start.com/foo/bar?baz=bux#hash'],
|
|
|
|
],
|
|
|
|
[
|
|
|
|
'start middle end.com/foo/bar?baz=...',
|
|
|
|
['https://end.com/foo/bar?baz=bux#hash'],
|
|
|
|
],
|
|
|
|
[
|
|
|
|
'newline1.com/very/long/ur...\nnewline2.com/very/long/ur...',
|
|
|
|
[
|
|
|
|
'https://newline1.com/very/long/url/here',
|
|
|
|
'https://newline2.com/very/long/url/here',
|
|
|
|
],
|
|
|
|
],
|
|
|
|
[
|
|
|
|
'Classic article socket3.wordpress.com/2018/02/03/d...',
|
|
|
|
[
|
|
|
|
'https://socket3.wordpress.com/2018/02/03/designing-windows-95s-user-interface/',
|
|
|
|
],
|
|
|
|
],
|
|
|
|
]
|
2023-12-21 23:33:46 +01:00
|
|
|
|
2023-08-16 19:22:50 +02:00
|
|
|
it('correctly shortens rich text while preserving facet URIs', () => {
|
|
|
|
for (let i = 0; i < inputs.length; i++) {
|
|
|
|
const input = inputs[i]
|
|
|
|
const inputRT = new RichText({text: input})
|
|
|
|
inputRT.detectFacetsWithoutResolution()
|
|
|
|
const outputRT = shortenLinks(inputRT)
|
|
|
|
expect(outputRT.text).toEqual(outputs[i][0])
|
|
|
|
expect(outputRT.facets?.length).toEqual(outputs[i][1].length)
|
|
|
|
for (let j = 0; j < outputs[i][1].length; j++) {
|
|
|
|
expect(outputRT.facets![j].features[0].uri).toEqual(outputs[i][1][j])
|
|
|
|
}
|
|
|
|
}
|
|
|
|
})
|
|
|
|
})
|
2023-12-21 23:33:46 +01:00
|
|
|
|
|
|
|
describe('parseEmbedPlayerFromUrl', () => {
|
|
|
|
const inputs = [
|
|
|
|
'https://youtu.be/videoId',
|
|
|
|
'https://www.youtube.com/watch?v=videoId',
|
|
|
|
'https://www.youtube.com/watch?v=videoId&feature=share',
|
|
|
|
'https://youtube.com/watch?v=videoId',
|
|
|
|
'https://youtube.com/watch?v=videoId&feature=share',
|
|
|
|
'https://youtube.com/shorts/videoId',
|
2024-01-05 02:37:36 +01:00
|
|
|
'https://m.youtube.com/watch?v=videoId',
|
2024-04-28 07:11:08 +02:00
|
|
|
'https://music.youtube.com/watch?v=videoId',
|
2023-12-21 23:33:46 +01:00
|
|
|
|
|
|
|
'https://youtube.com/shorts/',
|
|
|
|
'https://youtube.com/',
|
|
|
|
'https://youtube.com/random',
|
|
|
|
|
|
|
|
'https://twitch.tv/channelName',
|
|
|
|
'https://www.twitch.tv/channelName',
|
2024-01-05 02:37:36 +01:00
|
|
|
'https://m.twitch.tv/channelName',
|
|
|
|
|
|
|
|
'https://twitch.tv/channelName/clip/clipId',
|
|
|
|
'https://twitch.tv/videos/videoId',
|
2023-12-21 23:33:46 +01:00
|
|
|
|
|
|
|
'https://open.spotify.com/playlist/playlistId',
|
|
|
|
'https://open.spotify.com/playlist/playlistId?param=value',
|
2024-01-05 02:37:36 +01:00
|
|
|
'https://open.spotify.com/locale/playlist/playlistId',
|
2023-12-21 23:33:46 +01:00
|
|
|
|
|
|
|
'https://open.spotify.com/track/songId',
|
|
|
|
'https://open.spotify.com/track/songId?param=value',
|
2024-01-05 02:37:36 +01:00
|
|
|
'https://open.spotify.com/locale/track/songId',
|
2023-12-21 23:33:46 +01:00
|
|
|
|
|
|
|
'https://open.spotify.com/album/albumId',
|
|
|
|
'https://open.spotify.com/album/albumId?param=value',
|
2024-01-05 02:37:36 +01:00
|
|
|
'https://open.spotify.com/locale/album/albumId',
|
2023-12-21 23:33:46 +01:00
|
|
|
|
|
|
|
'https://soundcloud.com/user/track',
|
|
|
|
'https://soundcloud.com/user/sets/set',
|
|
|
|
'https://soundcloud.com/user/',
|
2024-01-05 02:37:36 +01:00
|
|
|
|
|
|
|
'https://music.apple.com/us/playlist/playlistName/playlistId',
|
|
|
|
'https://music.apple.com/us/album/albumName/albumId',
|
|
|
|
'https://music.apple.com/us/album/albumName/albumId?i=songId',
|
|
|
|
|
|
|
|
'https://vimeo.com/videoId',
|
|
|
|
'https://vimeo.com/videoId?autoplay=0',
|
|
|
|
|
|
|
|
'https://giphy.com/gifs/some-random-gif-name-gifId',
|
|
|
|
'https://giphy.com/gif/some-random-gif-name-gifId',
|
|
|
|
'https://giphy.com/gifs/',
|
|
|
|
|
2024-04-20 00:31:20 +02:00
|
|
|
'https://giphy.com/gifs/39248209509382934029?hh=100&ww=100',
|
|
|
|
|
2024-01-05 02:37:36 +01:00
|
|
|
'https://media.giphy.com/media/gifId/giphy.webp',
|
|
|
|
'https://media0.giphy.com/media/gifId/giphy.webp',
|
|
|
|
'https://media1.giphy.com/media/gifId/giphy.gif',
|
|
|
|
'https://media2.giphy.com/media/gifId/giphy.webp',
|
|
|
|
'https://media3.giphy.com/media/gifId/giphy.mp4',
|
|
|
|
'https://media4.giphy.com/media/gifId/giphy.webp',
|
|
|
|
'https://media5.giphy.com/media/gifId/giphy.mp4',
|
|
|
|
'https://media0.giphy.com/media/gifId/giphy.mp3',
|
|
|
|
'https://media1.google.com/media/gifId/giphy.webp',
|
|
|
|
|
|
|
|
'https://media.giphy.com/media/trackingId/gifId/giphy.webp',
|
|
|
|
|
|
|
|
'https://i.giphy.com/media/gifId/giphy.webp',
|
|
|
|
'https://i.giphy.com/media/gifId/giphy.webp',
|
|
|
|
'https://i.giphy.com/gifId.gif',
|
|
|
|
'https://i.giphy.com/gifId.gif',
|
|
|
|
|
|
|
|
'https://tenor.com/view/gifId',
|
|
|
|
'https://tenor.com/notView/gifId',
|
|
|
|
'https://tenor.com/view',
|
|
|
|
'https://tenor.com/view/gifId.gif',
|
2024-01-08 22:55:48 +01:00
|
|
|
'https://tenor.com/intl/view/gifId.gif',
|
2024-04-23 03:54:15 +02:00
|
|
|
|
|
|
|
'https://media.tenor.com/someID_AAAAC/someName.gif?hh=100&ww=100',
|
|
|
|
'https://media.tenor.com/someID_AAAAC/someName.gif',
|
|
|
|
'https://media.tenor.com/someID/someName.gif',
|
|
|
|
'https://media.tenor.com/someID',
|
|
|
|
'https://media.tenor.com',
|
2023-12-21 23:33:46 +01:00
|
|
|
]
|
|
|
|
|
|
|
|
const outputs = [
|
|
|
|
{
|
|
|
|
type: 'youtube_video',
|
2024-01-05 02:37:36 +01:00
|
|
|
source: 'youtube',
|
2024-02-06 20:05:17 +01:00
|
|
|
playerUri: 'https://bsky.app/iframe/youtube.html?videoId=videoId&start=0',
|
2023-12-21 23:33:46 +01:00
|
|
|
},
|
|
|
|
{
|
|
|
|
type: 'youtube_video',
|
2024-01-05 02:37:36 +01:00
|
|
|
source: 'youtube',
|
2024-02-06 20:05:17 +01:00
|
|
|
playerUri: 'https://bsky.app/iframe/youtube.html?videoId=videoId&start=0',
|
2023-12-21 23:33:46 +01:00
|
|
|
},
|
|
|
|
{
|
|
|
|
type: 'youtube_video',
|
2024-01-05 02:37:36 +01:00
|
|
|
source: 'youtube',
|
2024-02-06 20:05:17 +01:00
|
|
|
playerUri: 'https://bsky.app/iframe/youtube.html?videoId=videoId&start=0',
|
2023-12-21 23:33:46 +01:00
|
|
|
},
|
|
|
|
{
|
|
|
|
type: 'youtube_video',
|
2024-01-05 02:37:36 +01:00
|
|
|
source: 'youtube',
|
2024-02-06 20:05:17 +01:00
|
|
|
playerUri: 'https://bsky.app/iframe/youtube.html?videoId=videoId&start=0',
|
2023-12-21 23:33:46 +01:00
|
|
|
},
|
|
|
|
{
|
|
|
|
type: 'youtube_video',
|
2024-01-05 02:37:36 +01:00
|
|
|
source: 'youtube',
|
2024-02-06 20:05:17 +01:00
|
|
|
playerUri: 'https://bsky.app/iframe/youtube.html?videoId=videoId&start=0',
|
2024-01-05 02:37:36 +01:00
|
|
|
},
|
|
|
|
{
|
|
|
|
type: 'youtube_short',
|
|
|
|
source: 'youtubeShorts',
|
|
|
|
hideDetails: true,
|
2024-02-06 20:05:17 +01:00
|
|
|
playerUri: 'https://bsky.app/iframe/youtube.html?videoId=videoId&start=0',
|
2023-12-21 23:33:46 +01:00
|
|
|
},
|
|
|
|
{
|
|
|
|
type: 'youtube_video',
|
2024-01-05 02:37:36 +01:00
|
|
|
source: 'youtube',
|
2024-02-06 20:05:17 +01:00
|
|
|
playerUri: 'https://bsky.app/iframe/youtube.html?videoId=videoId&start=0',
|
2023-12-21 23:33:46 +01:00
|
|
|
},
|
2024-04-28 07:11:08 +02:00
|
|
|
{
|
|
|
|
type: 'youtube_video',
|
|
|
|
source: 'youtube',
|
|
|
|
playerUri: 'https://bsky.app/iframe/youtube.html?videoId=videoId&start=0',
|
|
|
|
},
|
2024-01-05 02:37:36 +01:00
|
|
|
|
2023-12-21 23:33:46 +01:00
|
|
|
undefined,
|
|
|
|
undefined,
|
|
|
|
undefined,
|
|
|
|
|
|
|
|
{
|
2024-01-05 02:37:36 +01:00
|
|
|
type: 'twitch_video',
|
|
|
|
source: 'twitch',
|
2023-12-21 23:33:46 +01:00
|
|
|
playerUri: `https://player.twitch.tv/?volume=0.5&!muted&autoplay&channel=channelName&parent=localhost`,
|
|
|
|
},
|
|
|
|
{
|
2024-01-05 02:37:36 +01:00
|
|
|
type: 'twitch_video',
|
|
|
|
source: 'twitch',
|
2023-12-21 23:33:46 +01:00
|
|
|
playerUri: `https://player.twitch.tv/?volume=0.5&!muted&autoplay&channel=channelName&parent=localhost`,
|
|
|
|
},
|
2024-01-05 02:37:36 +01:00
|
|
|
{
|
|
|
|
type: 'twitch_video',
|
|
|
|
source: 'twitch',
|
|
|
|
playerUri: `https://player.twitch.tv/?volume=0.5&!muted&autoplay&channel=channelName&parent=localhost`,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
type: 'twitch_video',
|
|
|
|
source: 'twitch',
|
|
|
|
playerUri: `https://clips.twitch.tv/embed?volume=0.5&autoplay=true&clip=clipId&parent=localhost`,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
type: 'twitch_video',
|
|
|
|
source: 'twitch',
|
|
|
|
playerUri: `https://player.twitch.tv/?volume=0.5&!muted&autoplay&video=videoId&parent=localhost`,
|
|
|
|
},
|
2023-12-21 23:33:46 +01:00
|
|
|
|
|
|
|
{
|
|
|
|
type: 'spotify_playlist',
|
2024-01-05 02:37:36 +01:00
|
|
|
source: 'spotify',
|
2023-12-21 23:33:46 +01:00
|
|
|
playerUri: `https://open.spotify.com/embed/playlist/playlistId`,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
type: 'spotify_playlist',
|
2024-01-05 02:37:36 +01:00
|
|
|
source: 'spotify',
|
|
|
|
playerUri: `https://open.spotify.com/embed/playlist/playlistId`,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
type: 'spotify_playlist',
|
|
|
|
source: 'spotify',
|
2023-12-21 23:33:46 +01:00
|
|
|
playerUri: `https://open.spotify.com/embed/playlist/playlistId`,
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
type: 'spotify_song',
|
2024-01-05 02:37:36 +01:00
|
|
|
source: 'spotify',
|
|
|
|
playerUri: `https://open.spotify.com/embed/track/songId`,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
type: 'spotify_song',
|
|
|
|
source: 'spotify',
|
2023-12-21 23:33:46 +01:00
|
|
|
playerUri: `https://open.spotify.com/embed/track/songId`,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
type: 'spotify_song',
|
2024-01-05 02:37:36 +01:00
|
|
|
source: 'spotify',
|
2023-12-21 23:33:46 +01:00
|
|
|
playerUri: `https://open.spotify.com/embed/track/songId`,
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
type: 'spotify_album',
|
2024-01-05 02:37:36 +01:00
|
|
|
source: 'spotify',
|
|
|
|
playerUri: `https://open.spotify.com/embed/album/albumId`,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
type: 'spotify_album',
|
|
|
|
source: 'spotify',
|
2023-12-21 23:33:46 +01:00
|
|
|
playerUri: `https://open.spotify.com/embed/album/albumId`,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
type: 'spotify_album',
|
2024-01-05 02:37:36 +01:00
|
|
|
source: 'spotify',
|
2023-12-21 23:33:46 +01:00
|
|
|
playerUri: `https://open.spotify.com/embed/album/albumId`,
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
type: 'soundcloud_track',
|
2024-01-05 02:37:36 +01:00
|
|
|
source: 'soundcloud',
|
2023-12-21 23:33:46 +01:00
|
|
|
playerUri: `https://w.soundcloud.com/player/?url=https://soundcloud.com/user/track&auto_play=true&visual=false&hide_related=true`,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
type: 'soundcloud_set',
|
2024-01-05 02:37:36 +01:00
|
|
|
source: 'soundcloud',
|
2023-12-21 23:33:46 +01:00
|
|
|
playerUri: `https://w.soundcloud.com/player/?url=https://soundcloud.com/user/sets/set&auto_play=true&visual=false&hide_related=true`,
|
|
|
|
},
|
|
|
|
undefined,
|
2024-01-05 02:37:36 +01:00
|
|
|
|
|
|
|
{
|
|
|
|
type: 'apple_music_playlist',
|
|
|
|
source: 'appleMusic',
|
|
|
|
playerUri:
|
|
|
|
'https://embed.music.apple.com/us/playlist/playlistName/playlistId',
|
|
|
|
},
|
|
|
|
{
|
|
|
|
type: 'apple_music_album',
|
|
|
|
source: 'appleMusic',
|
|
|
|
playerUri: 'https://embed.music.apple.com/us/album/albumName/albumId',
|
|
|
|
},
|
|
|
|
{
|
|
|
|
type: 'apple_music_song',
|
|
|
|
source: 'appleMusic',
|
|
|
|
playerUri:
|
|
|
|
'https://embed.music.apple.com/us/album/albumName/albumId?i=songId',
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
type: 'vimeo_video',
|
|
|
|
source: 'vimeo',
|
|
|
|
playerUri: 'https://player.vimeo.com/video/videoId?autoplay=1',
|
|
|
|
},
|
|
|
|
{
|
|
|
|
type: 'vimeo_video',
|
|
|
|
source: 'vimeo',
|
|
|
|
playerUri: 'https://player.vimeo.com/video/videoId?autoplay=1',
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
type: 'giphy_gif',
|
|
|
|
source: 'giphy',
|
|
|
|
isGif: true,
|
|
|
|
hideDetails: true,
|
|
|
|
metaUri: 'https://giphy.com/gifs/gifId',
|
2024-04-20 00:31:20 +02:00
|
|
|
playerUri: 'https://i.giphy.com/media/gifId/200.webp',
|
2024-01-05 02:37:36 +01:00
|
|
|
},
|
|
|
|
undefined,
|
|
|
|
undefined,
|
2024-04-20 00:31:20 +02:00
|
|
|
{
|
|
|
|
type: 'giphy_gif',
|
|
|
|
source: 'giphy',
|
|
|
|
isGif: true,
|
|
|
|
hideDetails: true,
|
|
|
|
metaUri: 'https://giphy.com/gifs/39248209509382934029',
|
2024-04-23 03:54:15 +02:00
|
|
|
playerUri: 'https://i.giphy.com/media/39248209509382934029/200.webp',
|
2024-04-20 00:31:20 +02:00
|
|
|
},
|
2024-01-05 02:37:36 +01:00
|
|
|
{
|
|
|
|
type: 'giphy_gif',
|
|
|
|
source: 'giphy',
|
|
|
|
isGif: true,
|
|
|
|
hideDetails: true,
|
|
|
|
metaUri: 'https://giphy.com/gifs/gifId',
|
2024-04-20 00:31:20 +02:00
|
|
|
playerUri: 'https://i.giphy.com/media/gifId/200.webp',
|
2024-01-05 02:37:36 +01:00
|
|
|
},
|
|
|
|
{
|
|
|
|
type: 'giphy_gif',
|
|
|
|
source: 'giphy',
|
|
|
|
isGif: true,
|
|
|
|
hideDetails: true,
|
|
|
|
metaUri: 'https://giphy.com/gifs/gifId',
|
2024-04-20 00:31:20 +02:00
|
|
|
playerUri: 'https://i.giphy.com/media/gifId/200.webp',
|
2024-01-05 02:37:36 +01:00
|
|
|
},
|
|
|
|
{
|
|
|
|
type: 'giphy_gif',
|
|
|
|
source: 'giphy',
|
|
|
|
isGif: true,
|
|
|
|
hideDetails: true,
|
|
|
|
metaUri: 'https://giphy.com/gifs/gifId',
|
2024-04-20 00:31:20 +02:00
|
|
|
playerUri: 'https://i.giphy.com/media/gifId/200.webp',
|
2024-01-05 02:37:36 +01:00
|
|
|
},
|
|
|
|
{
|
|
|
|
type: 'giphy_gif',
|
|
|
|
source: 'giphy',
|
|
|
|
isGif: true,
|
|
|
|
hideDetails: true,
|
|
|
|
metaUri: 'https://giphy.com/gifs/gifId',
|
2024-04-20 00:31:20 +02:00
|
|
|
playerUri: 'https://i.giphy.com/media/gifId/200.webp',
|
2024-01-05 02:37:36 +01:00
|
|
|
},
|
|
|
|
{
|
|
|
|
type: 'giphy_gif',
|
|
|
|
source: 'giphy',
|
|
|
|
isGif: true,
|
|
|
|
hideDetails: true,
|
|
|
|
metaUri: 'https://giphy.com/gifs/gifId',
|
2024-04-20 00:31:20 +02:00
|
|
|
playerUri: 'https://i.giphy.com/media/gifId/200.webp',
|
2024-01-05 02:37:36 +01:00
|
|
|
},
|
|
|
|
{
|
|
|
|
type: 'giphy_gif',
|
|
|
|
source: 'giphy',
|
|
|
|
isGif: true,
|
|
|
|
hideDetails: true,
|
|
|
|
metaUri: 'https://giphy.com/gifs/gifId',
|
2024-04-20 00:31:20 +02:00
|
|
|
playerUri: 'https://i.giphy.com/media/gifId/200.webp',
|
2024-01-05 02:37:36 +01:00
|
|
|
},
|
|
|
|
undefined,
|
|
|
|
undefined,
|
|
|
|
undefined,
|
|
|
|
|
|
|
|
{
|
|
|
|
type: 'giphy_gif',
|
|
|
|
source: 'giphy',
|
|
|
|
isGif: true,
|
|
|
|
hideDetails: true,
|
|
|
|
metaUri: 'https://giphy.com/gifs/gifId',
|
2024-04-20 00:31:20 +02:00
|
|
|
playerUri: 'https://i.giphy.com/media/gifId/200.webp',
|
2024-01-05 02:37:36 +01:00
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
type: 'giphy_gif',
|
|
|
|
source: 'giphy',
|
|
|
|
isGif: true,
|
|
|
|
hideDetails: true,
|
|
|
|
metaUri: 'https://giphy.com/gifs/gifId',
|
2024-04-20 00:31:20 +02:00
|
|
|
playerUri: 'https://i.giphy.com/media/gifId/200.webp',
|
2024-01-05 02:37:36 +01:00
|
|
|
},
|
|
|
|
{
|
|
|
|
type: 'giphy_gif',
|
|
|
|
source: 'giphy',
|
|
|
|
isGif: true,
|
|
|
|
hideDetails: true,
|
|
|
|
metaUri: 'https://giphy.com/gifs/gifId',
|
2024-04-20 00:31:20 +02:00
|
|
|
playerUri: 'https://i.giphy.com/media/gifId/200.webp',
|
2024-01-05 02:37:36 +01:00
|
|
|
},
|
|
|
|
{
|
|
|
|
type: 'giphy_gif',
|
|
|
|
source: 'giphy',
|
|
|
|
isGif: true,
|
|
|
|
hideDetails: true,
|
|
|
|
metaUri: 'https://giphy.com/gifs/gifId',
|
2024-04-20 00:31:20 +02:00
|
|
|
playerUri: 'https://i.giphy.com/media/gifId/200.webp',
|
2024-01-05 02:37:36 +01:00
|
|
|
},
|
|
|
|
{
|
|
|
|
type: 'giphy_gif',
|
|
|
|
source: 'giphy',
|
|
|
|
isGif: true,
|
|
|
|
hideDetails: true,
|
|
|
|
metaUri: 'https://giphy.com/gifs/gifId',
|
2024-04-20 00:31:20 +02:00
|
|
|
playerUri: 'https://i.giphy.com/media/gifId/200.webp',
|
2024-01-05 02:37:36 +01:00
|
|
|
},
|
|
|
|
|
|
|
|
undefined,
|
|
|
|
undefined,
|
2024-04-23 03:54:15 +02:00
|
|
|
undefined,
|
|
|
|
undefined,
|
|
|
|
undefined,
|
|
|
|
|
2024-01-05 02:37:36 +01:00
|
|
|
{
|
|
|
|
type: 'tenor_gif',
|
|
|
|
source: 'tenor',
|
|
|
|
isGif: true,
|
|
|
|
hideDetails: true,
|
2024-04-23 03:54:15 +02:00
|
|
|
playerUri: 'https://t.gifs.bsky.app/someID_AAAAM/someName.gif',
|
|
|
|
dimensions: {
|
|
|
|
width: 100,
|
|
|
|
height: 100,
|
|
|
|
},
|
2024-01-08 22:55:48 +01:00
|
|
|
},
|
2024-04-23 03:54:15 +02:00
|
|
|
undefined,
|
|
|
|
undefined,
|
|
|
|
undefined,
|
|
|
|
undefined,
|
2023-12-21 23:33:46 +01:00
|
|
|
]
|
|
|
|
|
|
|
|
it('correctly grabs the correct id from uri', () => {
|
|
|
|
for (let i = 0; i < inputs.length; i++) {
|
|
|
|
const input = inputs[i]
|
|
|
|
const output = outputs[i]
|
|
|
|
|
|
|
|
const res = parseEmbedPlayerFromUrl(input)
|
|
|
|
|
|
|
|
expect(res).toEqual(output)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
})
|