import { test } from '@japa/runner' import db from '@adonisjs/lucid/services/db' import FileStore from '#services/FileStore' import env from '#start/env' import testUtils from '@adonisjs/core/services/test_utils' let counter = 0 async function seed(name: string, opts: { fileTotal?: number; files?: number } = {}) { const now = new Date() const [release] = await db .table('releases') .insert({ release_key: `nz${++counter}`.padEnd(40, 'n'), name, source: 'stem', poster: 'poster@example.invalid', groups: '["alt.binaries.test"]', file_total: opts.fileTotal ?? null, posted_at: now, first_seen_at: now, last_seen_at: now }) .returning('id') for (let i = 0; i < (opts.files ?? 1); i++) { await FileStore.insert([{ filename: `${name}.part${i + 1}.rar`, poster: 'poster@example.invalid', date: now.getTime(), parts: 1, size: 1_000_000, release_id: release.id, groups: '["alt.binaries.test"]', segments: [{ number: 1, id: `${name}-${i}@test`, size: 1_000_000 }], created_at: now, updated_at: now, }]) } return Number(release.id) } const ids = (xml: string) => [...xml.matchAll(/(\d+)<\/guid>/g)].map((m) => Number(m[1])) test.group('Newznab API', (group) => { group.each.setup(() => testUtils.db().withGlobalTransaction()) test('caps lists search functions and categories', async ({ client, assert }) => { const response = await client.get('/api').qs({ t: 'caps' }) response.assertStatus(200) assert.include(response.text(), '') assert.include(response.text(), '') assert.include(response.text(), '') }) test('tvsearch matches show, season and episode, with Newznab attributes', async ({ client, assert }) => { const e02 = await seed('Nzbtest.Show.S01E02.1080p.WEB-DL-GRP') const e03 = await seed('Nzbtest.Show.S01E03.1080p.WEB-DL-GRP') const movie = await seed('Nzbtest.Show.The.Movie.2020.1080p.BluRay.x264-GRP') const response = await client.get('/api').qs({ t: 'tvsearch', q: 'nzbtest show', season: '1', ep: '2' }) response.assertStatus(200) const body = response.text() assert.deepEqual(ids(body), [e02]) assert.include(body, '') assert.include(body, '') assert.include(body, '') assert.include(body, `/api?t=get&id=${e02}`) assert.include(body, 'type="application/x-nzb"') const season = await client.get('/api').qs({ t: 'tvsearch', q: 'nzbtest show', season: '1' }) assert.sameMembers(ids(season.text()), [e02, e03]) const movies = await client.get('/api').qs({ t: 'movie', q: 'nzbtest show' }) assert.deepEqual(ids(movies.text()), [movie]) }) test('leaves out obfuscated names and releases known to be incomplete', async ({ client, assert }) => { const readable = await seed('Nzbtest.Other.2021.720p.WEB-DL-GRP') const incomplete = await seed('Nzbtest.Partial.2021.720p.WEB-DL-GRP', { fileTotal: 5, files: 2 }) const random = await seed('Xq8r2KdLm3Zw91PqA7nzbtest') const found = ids((await client.get('/api').qs({ t: 'search', q: 'nzbtest' })).text()) assert.include(found, readable) assert.notInclude(found, incomplete) assert.notInclude(found, random) }) test('get returns the NZB, errors use Newznab codes', async ({ client, assert }) => { const id = await seed('Nzbtest.Get.S02E01.720p.HDTV-GRP') const nzb = await client.get('/api').qs({ t: 'get', id: String(id) }) nzb.assertStatus(200) assert.include(nzb.header('content-type'), 'application/x-nzb') assert.include(nzb.text(), 'Nzbtest.Get.S02E01.720p.HDTV-GRP-0@test') assert.include((await client.get('/api').qs({ t: 'get', id: '999999999' })).text(), 'code="300"') assert.include((await client.get('/api').qs({ t: 'nonsense' })).text(), 'code="202"') }) test('requires the API key when one is configured', async ({ client, assert }) => { const previous = env.get('NEWZNAB_API_KEY') env.set('NEWZNAB_API_KEY', 'test-key' as any) try { assert.include((await client.get('/api').qs({ t: 'caps' })).text(), 'code="100"') assert.include((await client.get('/api').qs({ t: 'caps', apikey: 'test-key' })).text(), '') const id = await seed('Nzbtest.Key.S01E01.720p.HDTV-GRP') const search = await client.get('/api').qs({ t: 'search', q: 'nzbtest key', apikey: 'test-key' }) assert.include(search.text(), `id=${id}&apikey=test-key`) } finally { env.set('NEWZNAB_API_KEY', previous as any) } }) })