mirror of
https://github.com/Psychotoxical/psysonic.git
synced 2026-07-22 15:25:46 +00:00
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>
This commit is contained in:
@@ -0,0 +1,125 @@
|
||||
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' });
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user