All checks were successful
build-and-push / build (push) Successful in 12s
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01824ZrvG2mDYYrmwqypLNup
183 lines
6.0 KiB
JavaScript
183 lines
6.0 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: 'video99' }, snippet: { title: 'Official Video', channelTitle: 'Metal Blade Records' } },
|
|
{ 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()
|
|
})
|