import { test } from '@japa/runner' import db from '@adonisjs/lucid/services/db' import FileStore from '#services/FileStore' import type { Segment } from '#lib/nzb/index' import testUtils from '@adonisjs/core/services/test_utils' import NzbImportService, { nzbFileName } from '#services/NzbImportService' import SearchService from '#services/SearchService' const XML = ` Real.Name.2026.1080p.WEB-DL-GRPhunter2 alt.binaries.bloaf known-1@xknown-2@x alt.binaries.cores new-1@x ` async function file(fields: Record & { segments: Segment[] }) { const now = new Date() const [{ id }] = await FileStore.insert([{ poster: 'p@x', date: now.getTime(), parts: 1, size: 100, groups: '[]', created_at: now, updated_at: now, ...fields }]) return db.from('files').where('id', id).first() } test.group('NzbImportService', (group) => { group.each.setup(() => testUtils.db().withGlobalTransaction()) test('names entries despite odd quoting', ({ assert }) => { assert.equal(nzbFileName('Wond40 "Nachbe" Nachchbee2025bebeSD.part1.rar" yEnc (0001/1849)'), 'Nachchbee2025bebeSD.part1.rar') assert.equal(nzbFileName('"x.par2" yEnc (1/1)'), 'x.par2') // Spot NZBs without quotes. assert.equal(nzbFileName('Adventure.part0055.rar - [056/175] (1/1)'), 'Adventure.part0055.rar') assert.equal(nzbFileName('LegalPorno.26.03.01.XXX.1080p.MP4-P2P.vol007+008.par2 (1/0) (1/0)'), 'LegalPorno.26.03.01.XXX.1080p.MP4-P2P.vol007+008.par2') assert.equal(nzbFileName('Reacher.S04.vol001+02.par2 yEnc'), 'Reacher.S04.vol001+02.par2') assert.equal(nzbFileName('06 - A New Land, a New Music.flac Mehmet Ali Sanlikol - The Rise Up (2020) (01/35)'), '06 - A New Land, a New Music.flac') assert.equal(nzbFileName('[01/10] - Some.Release.2026.part01.rar yEnc (1/50) 35000000'), 'Some.Release.2026.part01.rar') assert.equal(nzbFileName('Mozart Zauberfloete 2026 mp4 720p.zip.001'), 'Mozart Zauberfloete 2026 mp4 720p.zip.001') assert.equal(nzbFileName('LibreOffice_7.6.4_Win_x86-64.msi.vol0000'), 'LibreOffice_7.6.4_Win_x86-64.msi.vol0000') }) test('joins the release of known files, adds the rest, keeps name and password', async ({ assert }) => { const now = new Date() const [release] = await db .table('releases') .insert({ release_key: 'z'.repeat(40), name: 'Xq8r2KdLm3Zw91PqA7', source: 'stem', groups: '[]', first_seen_at: now, last_seen_at: now }) .returning('id') await file({ filename: 'Xq8r2KdLm3Zw91PqA7.part1.rar', release_id: release.id, segments: [{ number: 1, id: 'known-1@x', size: 700 }] }) const posted = await file({ filename: 'Xq8r2KdLm3Zw91PqA7.nzb', segments: [{ number: 1, id: 'nzb-1@x', size: 2000 }] }) const result = (await NzbImportService.import(posted, XML))! assert.equal(result.releaseId, Number(release.id)) assert.include(result, { listed: 2, known: 1, added: 1, password: true }) const updated = await db.from('releases').where('id', release.id).first() assert.equal(updated.name, 'Real.Name.2026.1080p.WEB-DL-GRP') assert.equal(updated.password, 'hunter2') assert.equal(updated.file_total, 2) const files = await db.from('files').where('release_id', release.id).orderBy('filename').select('filename', 'groups') assert.deepEqual(files.map((f) => f.filename), ['Xq8r2KdLm3Zw91PqA7.nzb', 'Xq8r2KdLm3Zw91PqA7.part1.rar', 'Xq8r2KdLm3Zw91PqA7.part2.rar']) // Our own NZB passes the password on. const nzb = await SearchService.nzb(Number(release.id)) assert.include(nzb!.xml, 'hunter2') // Importing again changes nothing. const again = (await NzbImportService.import(posted, XML))! assert.equal(again.added, 0) }) test('NZBs from one archive become separate releases named after their entries', async ({ assert }) => { const nzbXml = (id: string) => ` alt.binaries.x ${id}@x ` const archive = await file({ filename: 'JOCpLxSgyzOPhBWXL5riLy.rar', segments: [{ number: 1, id: 'rar-1@x', size: 2000 }] }) const a = (await NzbImportService.import(archive, nzbXml('a'), { entryName: 'The Kinks - Misfits-LP-1978.nzb', moveContainer: false }))! const b = (await NzbImportService.import(archive, nzbXml('b'), { entryName: 'The Kinks - Sleepwalker-LP-1977.nzb', moveContainer: false }))! assert.notEqual(a.releaseId, b.releaseId) assert.equal(a.releaseName, 'The Kinks - Misfits-LP-1978') assert.equal(b.releaseName, 'The Kinks - Sleepwalker-LP-1977') const container = await db.from('files').where('id', archive.id).first() assert.isNull(container.release_id) }) test('a posted NZB alone in its own release moves to the release it describes', async ({ assert }) => { const now = new Date() const insert = async (key: string, name: string) => (await db.table('releases').insert({ release_key: key.padEnd(40, 'r'), name, source: 'stem', groups: '[]', first_seen_at: now, last_seen_at: now }).returning('id'))[0].id const target = await insert('target', 'Backbeat.1994.1080p.BluRay.x264-OFT') const lonely = await insert('lonely', '.nzb') await file({ filename: 'x.part1.rar', release_id: target, segments: [{ number: 1, id: 'known-1@x', size: 700 }] }) const posted = await file({ filename: '.nzb', release_id: lonely, segments: [{ number: 1, id: 'nzb-2@x', size: 2000 }] }) await NzbImportService.import(posted, XML) assert.equal(Number((await db.from('files').where('id', posted.id).first()).release_id), Number(target)) assert.notExists(await db.from('releases').where('id', lonely).first()) }) test('a trusted NZB (a spot) takes its files into its own release, named after it', async ({ assert }) => { const now = new Date() const insertRelease = async (key: string, name: string, source: string) => ( await db .table('releases') .insert({ release_key: key.repeat(40).slice(0, 40), name, source, groups: '[]', first_seen_at: now, last_seen_at: now }) .returning('id') )[0].id // Name rules had put the spot's first volume into a season release with another episode. const season = await insertRelease('s', 'zxcvvbgnhgjytygf', 'stem') await file({ filename: 'Xq8r2KdLm3Zw91PqA7.part1.rar', release_id: season, segments: [{ number: 1, id: 'known-1@x', size: 700 }] }) await file({ filename: 'other.episode.rar', release_id: season, segments: [{ number: 1, id: 'other-1@x', size: 700 }] }) const spotFile = { id: null, filename: 'x.nzb', poster: 'Bart', groups: [], date: now.getTime(), first_message_id: 'spot1@spot.net' } const result = (await NzbImportService.import(spotFile, XML, { name: 'De.Bondgenoten.S03E285.DUTCH.1080p.WEB.H264', source: 'spot', moveContainer: false, trusted: true }))! assert.notEqual(result.releaseId, Number(season)) const own = await db.from('releases').where('id', result.releaseId).first() assert.include(own, { name: 'De.Bondgenoten.S03E285.DUTCH.1080p.WEB.H264', source: 'spot', file_count: 2 }) const left = await db.from('files').where('release_id', season).select('filename') assert.deepEqual(left.map((f) => f.filename), ['other.episode.rar']) // A par2 or archive name no longer replaces a spot's title. const { isBetterName } = await import('#services/NameService') assert.isTrue(isBetterName('zxcvvbgnhgjytygf', 'Better.Name.S03E285')) // Another spot for the same files (a repost) joins the first one's release instead of taking them. const repost = { ...spotFile, first_message_id: 'spot2@spot.net' } const second = (await NzbImportService.import(repost, XML, { name: 'Repost', source: 'spot', moveContainer: false, trusted: true }))! assert.equal(second.releaseId, result.releaseId) assert.equal(second.releaseName, 'De.Bondgenoten.S03E285.DUTCH.1080p.WEB.H264') }) })