Files
Psychotoxical-psysonic/src/utils/share/shareSearch.test.ts
T
Maxim Isaev e7431b94b8 feat(search): queue pasted share links from Live Search and mobile search
Implement share-link detection in search (track, queue, album, artist,
composer): enqueue tracks/queues without interrupting playback; preview
album/artist/composer without switching the active server; queue preview
modal with scrollable track list. Based on community PR #551.

Co-authored-by: Daniel Wagner <daniel.iuser@icloud.com>
2026-05-15 13:38:35 +03:00

126 lines
3.3 KiB
TypeScript

import { describe, expect, it } from 'vitest';
import { encodeServerMagicString } from '../server/serverMagicString';
import { encodeSharePayload } from './shareLink';
import { parseShareSearchText, sharePayloadTotal } from './shareSearch';
describe('share search parsing', () => {
it('detects track share links as queueable', () => {
const link = encodeSharePayload({
srv: 'https://music.example.com',
k: 'track',
id: 'song-1',
});
expect(parseShareSearchText(link)).toEqual({
type: 'queueable',
payload: {
srv: 'https://music.example.com',
k: 'track',
id: 'song-1',
},
});
});
it('detects queue share links as queueable and counts their tracks', () => {
const link = encodeSharePayload({
srv: 'https://music.example.com',
k: 'queue',
ids: ['a', 'b', 'c'],
});
const match = parseShareSearchText(`try this ${link}`);
expect(match).toEqual({
type: 'queueable',
payload: {
srv: 'https://music.example.com',
k: 'queue',
ids: ['a', 'b', 'c'],
},
});
if (match?.type === 'queueable') {
expect(sharePayloadTotal(match.payload)).toBe(3);
}
});
it('does not treat server magic strings as share-search links', () => {
const invite = encodeServerMagicString({
url: 'https://music.example.com',
username: 'user',
password: 'pass',
});
expect(parseShareSearchText(invite)).toBeNull();
});
it('detects album share links as album search results', () => {
const album = encodeSharePayload({
srv: 'https://music.example.com',
k: 'album',
id: 'album-1',
});
expect(parseShareSearchText(album)).toEqual({
type: 'album',
payload: {
srv: 'https://music.example.com',
k: 'album',
id: 'album-1',
},
});
});
it('detects artist share links as artist search results', () => {
const artist = encodeSharePayload({
srv: 'https://music.example.com',
k: 'artist',
id: 'artist-1',
});
expect(parseShareSearchText(artist)).toEqual({
type: 'artist',
payload: {
srv: 'https://music.example.com',
k: 'artist',
id: 'artist-1',
},
});
});
it('detects composer share links as composer search results', () => {
const composer = encodeSharePayload({
srv: 'https://music.example.com',
k: 'composer',
id: 'composer-1',
});
expect(parseShareSearchText(composer)).toEqual({
type: 'composer',
payload: {
srv: 'https://music.example.com',
k: 'composer',
id: 'composer-1',
},
});
});
it('returns unsupported for invalid psysonic2 payloads', () => {
expect(parseShareSearchText('psysonic2-not-valid-base64!!!')).toEqual({ type: 'unsupported' });
});
it('counts a single track in sharePayloadTotal', () => {
expect(
sharePayloadTotal({ srv: 'https://music.example.com', k: 'track', id: 'song-1' }),
).toBe(1);
});
it('marks orbit invites as unsupported in search', () => {
const orbit = encodeSharePayload({
srv: 'https://music.example.com',
k: 'orbit',
sid: '1234abcd',
});
expect(parseShareSearchText(orbit)).toEqual({ type: 'unsupported' });
});
});