Files
lyssnarr/backend/test/search.test.js
claude 9874d383ea
All checks were successful
build-and-push / build (push) Successful in 14s
Inbäddad mini-spelare: ▶ på korten spelar direkt i appen
- GET /api/play?q=: slår upp spelbart videoId via YouTube Data API
  (kategori musik, YOUTUBE_API_KEY i stackens .env)
- MiniPlayer: fast spelare nere till höger (YouTube-embed, autoplay),
  ligger kvar medan man bläddrar; stängs med ✕
- MusicCard: ▶-knapp på artist/album/låt/sångare (genrer behåller sina
  två knappar); YT-länken heter nu 'YT ↗'
- 2 nya tester, totalt 31

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01824ZrvG2mDYYrmwqypLNup
2026-08-01 04:38:33 +02:00

180 lines
5.8 KiB
JavaScript

import test from 'node:test'
import assert from 'node:assert/strict'
import { buildApp } from '../src/app.js'
import { mapLidarrSearch } from '../src/mapping.js'
const config = {
appPassword: 'testlösen',
sessionSecret: 'x'.repeat(32),
lidarr: { url: 'http://stub', apiKey: 'k', qualityProfileId: 3, metadataProfileId: 1, rootFolder: '/music' },
jellyfin: { url: '', apiKey: '' },
gemini: { apiKey: '', model: '' },
}
const powerwolf = {
foreignArtistId: 'mbid-artist-1',
artistName: 'Powerwolf',
disambiguation: 'tysk powermetal',
images: [{ coverType: 'poster', remoteUrl: 'http://img/poster.jpg' }],
}
const album = {
foreignAlbumId: 'mbid-album-1',
title: 'The Sacrament of Sin',
releaseDate: '2018-07-20',
images: [],
artist: { ...powerwolf },
}
async function loggedIn(app) {
const login = await app.inject({ method: 'POST', url: '/api/login', payload: { password: 'testlösen' } })
return login.headers['set-cookie']
}
test('mapLidarrSearch formar artist- och albumkort', () => {
const results = [{ artist: powerwolf }, { album }]
const artists = mapLidarrSearch(results, 'artist')
assert.equal(artists.length, 1)
assert.deepEqual(artists[0], {
kind: 'artist',
name: 'Powerwolf',
secondary: 'tysk powermetal',
year: '',
mbid: 'mbid-artist-1',
poster: 'http://img/poster.jpg',
inLibrary: false,
})
const albums = mapLidarrSearch(results, 'album')
assert.equal(albums[0].year, '2018')
assert.equal(albums[0].secondary, 'Powerwolf')
})
test('GET /api/search kräver inloggning', async () => {
const app = buildApp(config, { lidarr: {}, musicbrainz: {} })
const res = await app.inject({ method: 'GET', url: '/api/search?q=powerwolf' })
assert.equal(res.statusCode, 401)
await app.close()
})
test('GET /api/search returnerar mappade träffar', async () => {
const app = buildApp(config, {
lidarr: { search: async () => [{ artist: powerwolf }] },
musicbrainz: {},
})
const cookie = await loggedIn(app)
const res = await app.inject({ method: 'GET', url: '/api/search?q=powerwolf&type=artist', headers: { cookie } })
assert.equal(res.statusCode, 200)
assert.equal(res.json()[0].name, 'Powerwolf')
await app.close()
})
test('GET /api/search ger 503 när källan är nere', async () => {
const app = buildApp(config, {
lidarr: { search: async () => { throw new Error('nere') } },
musicbrainz: {},
})
const cookie = await loggedIn(app)
const res = await app.inject({ method: 'GET', url: '/api/search?q=x&type=artist', headers: { cookie } })
assert.equal(res.statusCode, 503)
await app.close()
})
test('POST /api/add lägger till artist med profiler och bevakning', async () => {
let sent = null
const app = buildApp(config, {
lidarr: {
search: async (term) => {
assert.equal(term, 'lidarr:mbid-artist-1')
return [{ artist: { ...powerwolf } }]
},
addArtist: async (payload) => { sent = payload; return { id: 7 } },
},
musicbrainz: {},
})
const cookie = await loggedIn(app)
const res = await app.inject({
method: 'POST',
url: '/api/add',
headers: { cookie },
payload: { kind: 'artist', mbid: 'mbid-artist-1' },
})
assert.equal(res.statusCode, 200)
assert.deepEqual(res.json(), { ok: true, already: false })
assert.equal(sent.qualityProfileId, 3)
assert.equal(sent.rootFolderPath, '/music')
assert.equal(sent.monitored, true)
assert.equal(sent.addOptions.searchForMissingAlbums, true)
await app.close()
})
test('POST /api/add med låt går via albumet', async () => {
let sent = null
const app = buildApp(config, {
lidarr: {
search: async () => [{ album: { ...album } }],
addAlbum: async (payload) => { sent = payload; return { id: 9 } },
},
musicbrainz: {},
})
const cookie = await loggedIn(app)
const res = await app.inject({
method: 'POST',
url: '/api/add',
headers: { cookie },
payload: { kind: 'track', mbid: 'rec-1', artistMbid: 'mbid-artist-1', albumMbid: 'mbid-album-1' },
})
assert.equal(res.statusCode, 200)
assert.equal(sent.monitored, true)
assert.equal(sent.artist.rootFolderPath, '/music')
assert.equal(sent.addOptions.searchForNewAlbum, true)
await app.close()
})
test('GET /api/play slår upp videoId via YouTube Data API', async () => {
const playConfig = { ...config, youtube: { apiKey: 'yt-nyckel' } }
const app = buildApp(playConfig, {
lidarr: {},
musicbrainz: {},
playFetch: async (url) => {
assert.match(url, /videoCategoryId=10/)
assert.match(url, /q=Powerwolf%20Sanctified/)
return {
ok: true,
json: async () => ({
items: [{ id: { videoId: 'abc123' }, snippet: { title: 'Sanctified with Dynamite', channelTitle: 'Powerwolf - Topic' } }],
}),
}
},
})
const cookie = await loggedIn(app)
const res = await app.inject({ method: 'GET', url: '/api/play?q=Powerwolf%20Sanctified', headers: { cookie } })
assert.equal(res.statusCode, 200)
assert.equal(res.json().videoId, 'abc123')
await app.close()
})
test('GET /api/play utan nyckel ger begripligt fel', async () => {
const app = buildApp({ ...config, youtube: { apiKey: '' } }, { lidarr: {}, musicbrainz: {} })
const cookie = await loggedIn(app)
const res = await app.inject({ method: 'GET', url: '/api/play?q=x', headers: { cookie } })
assert.equal(res.statusCode, 500)
assert.match(res.json().error, /YOUTUBE_API_KEY/)
await app.close()
})
test('POST /api/add svarar already för befintlig artist', async () => {
const app = buildApp(config, {
lidarr: { search: async () => [{ artist: { ...powerwolf, id: 12 } }] },
musicbrainz: {},
})
const cookie = await loggedIn(app)
const res = await app.inject({
method: 'POST',
url: '/api/add',
headers: { cookie },
payload: { kind: 'artist', mbid: 'mbid-artist-1' },
})
assert.deepEqual(res.json(), { ok: true, already: true })
await app.close()
})