1
0

feat: discogs client with barcode/text search and release fetch

This commit is contained in:
2026-08-29 16:13:43 +02:00
parent b79a72a81b
commit 3715bb7447
3 changed files with 302 additions and 0 deletions

108
server/test/discogs.test.ts Normal file
View File

@@ -0,0 +1,108 @@
import { describe, it, expect } from 'vitest'
import {
DiscogsClient,
DiscogsAuthError,
DiscogsRateLimitError,
mapSearchResult,
mapRelease,
} from '../src/discogs.js'
import { discogsSearchFixture, discogsReleaseFixture } from './fixtures.js'
function jsonResponse(body: unknown, status = 200): Response {
return new Response(JSON.stringify(body), {
status,
headers: { 'content-type': 'application/json' },
})
}
function stubFetch(routes: (url: string) => Response): typeof fetch {
return (async (input: any) => routes(String(input))) as typeof fetch
}
describe('DiscogsClient', () => {
it('searches by barcode with token and maps results', async () => {
const seen: string[] = []
const c = new DiscogsClient(
'testtoken',
stubFetch((url) => {
seen.push(url)
return jsonResponse(discogsSearchFixture)
})
)
const results = await c.searchByBarcode('5021592210629')
expect(seen[0]).toContain('/database/search')
expect(seen[0]).toContain('barcode=5021592210629')
expect(seen[0]).toContain('type=release')
expect(seen[0]).toContain('token=testtoken')
expect(results).toHaveLength(2)
expect(results[0]).toEqual({
id: 1001,
artist: 'The Cinematic Orchestra',
title: 'Motion',
year: 1999,
formats: ['CD', 'Album'],
labels: ['Ninja Tune'],
country: 'UK',
catno: 'ZENCD012',
thumbUrl: 'https://img.discogs.com/small1.jpg',
})
})
it('searches by text with optional format filter', async () => {
const seen: string[] = []
const c = new DiscogsClient(
't',
stubFetch((url) => {
seen.push(url)
return jsonResponse(discogsSearchFixture)
})
)
await c.searchByText('motion', 'Vinyl')
expect(seen[0]).toContain('q=motion')
expect(seen[0]).toContain('format=Vinyl')
})
it('throws DiscogsAuthError on 401', async () => {
const c = new DiscogsClient('bad', stubFetch(() => jsonResponse({ message: 'bad' }, 401)))
await expect(c.searchByBarcode('123')).rejects.toBeInstanceOf(DiscogsAuthError)
})
it('throws DiscogsRateLimitError on 429', async () => {
const c = new DiscogsClient('t', stubFetch(() => jsonResponse({}, 429)))
await expect(c.searchByBarcode('123')).rejects.toBeInstanceOf(DiscogsRateLimitError)
})
it('fetches full release with barcode identifiers', async () => {
const c = new DiscogsClient(
't',
stubFetch((url) => {
expect(url).toContain('/releases/1001')
return jsonResponse(discogsReleaseFixture)
})
)
const release = await c.getRelease(1001)
expect(release.title).toBe('Motion')
expect(release.barcodes).toEqual(['5021592210629'])
expect(release.coverUrl).toBe('https://img.discogs.com/full1.jpg')
})
})
describe('mappers', () => {
it('splits search title into artist/title and parses year', () => {
const first = discogsSearchFixture.results[0]!
const mapped = mapSearchResult(first)
expect(mapped.artist).toBe('The Cinematic Orchestra')
expect(mapped.title).toBe('Motion')
expect(mapped.year).toBe(1999)
})
it('maps full release', () => {
const mapped = mapRelease(discogsReleaseFixture)
expect(mapped.formats).toEqual(['CD'])
expect(mapped.labels).toEqual(['Ninja Tune'])
expect(mapped.tracklist).toEqual([
{ position: '1', title: 'Overture' },
{ position: '2', title: 'Theme de Yoyo' },
])
})
})

45
server/test/fixtures.ts Normal file
View File

@@ -0,0 +1,45 @@
export const discogsSearchFixture = {
results: [
{
id: 1001,
type: 'release',
title: 'The Cinematic Orchestra - Motion',
year: '1999',
format: ['CD', 'Album'],
label: ['Ninja Tune'],
country: 'UK',
catno: 'ZENCD012',
cover_image: 'https://img.discogs.com/big1.jpg',
thumb: 'https://img.discogs.com/small1.jpg',
},
{
id: 1002,
type: 'release',
title: 'The Cinematic Orchestra - Motion',
year: '1999',
format: ['Vinyl', '2xLP'],
label: ['Ninja Tune'],
country: 'UK',
catno: 'ZEN012',
cover_image: 'https://img.discogs.com/big2.jpg',
thumb: 'https://img.discogs.com/small2.jpg',
},
],
}
export const discogsReleaseFixture = {
id: 1001,
title: 'Motion',
artists: [{ name: 'The Cinematic Orchestra' }],
year: 1999,
formats: [{ name: 'CD', qty: '1' }],
labels: [{ name: 'Ninja Tune', catno: 'ZENCD012' }],
genres: ['Electronic', 'Jazz'],
country: 'UK',
images: [{ uri: 'https://img.discogs.com/full1.jpg' }],
tracklist: [
{ position: '1', title: 'Overture' },
{ position: '2', title: 'Theme de Yoyo' },
],
identifiers: [{ type: 'Barcode', value: '5021592210629' }],
}