Files
usenet-indexer/tests/functional/newznab.spec.ts
T

91 lines
4.6 KiB
TypeScript

import { test } from '@japa/runner'
import db from '@adonisjs/lucid/services/db'
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 db.table('files').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"]', message_ids: JSON.stringify({ '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(/<guid isPermaLink="false">(\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(), '<tv-search available="yes" supportedParams="q,season,ep"/>')
assert.include(response.text(), '<category id="5000" name="TV">')
assert.include(response.text(), '<subcat id="5040" name="HD"/>')
})
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, '<newznab:attr name="category" value="5000"/>')
assert.include(body, '<newznab:attr name="category" value="5040"/>')
assert.include(body, '<newznab:attr name="season" value="S01"/>')
assert.include(body, `/api?t=get&amp;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(), '<caps>')
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}&amp;apikey=test-key`)
} finally {
env.set('NEWZNAB_API_KEY', previous as any)
}
})
})