import { test } from '@japa/runner' import { fileKey, parseSubject } from '#lib/subject/index' import { parseXrefGroups } from '#lib/nntp/xref' import { inferTotalParts } from '#lib/yenc/index' test.group('subject / parseSubject', () => { test('parses file counter, filename and segment counter', ({ assert }) => { assert.deepEqual(parseSubject('. - [09/51] - "obrMkrDeLmbhaouwYO34.part08.rar" yEnc (56/274)'), { name: 'obrMkrDeLmbhaouwYO34.part08.rar', segment: 56, totalSegments: 274, fileIndex: 9, fileTotal: 51, base: '. - [09/51] - "obrMkrDeLmbhaouwYO34.part08.rar" yEnc', }) }) test('handles a file size after the segment counter', ({ assert }) => { const subject = '[8/9] - "x.tar.zst.vol063+064.par2" yEnc (37/72) 51315352' const parsed = parseSubject(subject)! assert.equal(parsed.segment, 37) assert.equal(parsed.totalSegments, 72) assert.equal(parsed.base, '[8/9] - "x.tar.zst.vol063+064.par2" yEnc 51315352') }) test('ignores counters inside the filename', ({ assert }) => { const parsed = parseSubject('"Show (1/2) Special.mkv" yEnc (3/10)')! assert.equal(parsed.name, 'Show (1/2) Special.mkv') assert.equal(parsed.segment, 3) assert.equal(parsed.totalSegments, 10) }) test('the base is equal for all segments of one file', ({ assert }) => { const a = parseSubject('[1/9] - "a.tar.zst" yEnc (253/1000) 716554110')! const b = parseSubject('[1/9] - "a.tar.zst" yEnc (254/1000) 716554110')! assert.equal(a.base, b.base) }) test('returns null for obfuscated or invalid subjects', ({ assert }) => { assert.isNull(parseSubject('GZFDJc0hB3Y0FwwAznkk')) assert.isNull(parseSubject('"name.rar" yEnc')) assert.isNull(parseSubject('"name.rar" yEnc (0/5)')) assert.isNull(parseSubject('"name.rar" yEnc (6/5)')) assert.isNull(parseSubject('"" yEnc (1/5)')) }) }) test.group('subject / fileKey', () => { test('differs per poster and per segment count, is stable otherwise', ({ assert }) => { const key = fileKey('poster@a', '"x.rar" yEnc', 10) assert.lengthOf(key, 40) assert.equal(key, fileKey('poster@a', '"x.rar" yEnc', 10)) assert.notEqual(key, fileKey('poster@b', '"x.rar" yEnc', 10)) assert.notEqual(key, fileKey('poster@a', '"x.rar" yEnc', 11)) }) }) test.group('nntp / parseXrefGroups', () => { test('extracts crossposted groups', ({ assert }) => { assert.deepEqual( parseXrefGroups('news.eweka.nl alt.binaries.nl:35801424104 alt.binaries.test:27275430913'), ['alt.binaries.nl', 'alt.binaries.test'] ) assert.deepEqual(parseXrefGroups(undefined), []) }) }) test.group('yenc / inferTotalParts', () => { const size = 104857600 const partSize = 384000 test('uses total= when present', ({ assert }) => { assert.equal(inferTotalParts({ begin: { part: 2, total: 7, line: 128, size, name: 'a' } }), 7) }) test('derives the total from the part size for middle and last parts', ({ assert }) => { const expected = Math.ceil(size / partSize) // 274, as in the subject "(56/274)" assert.equal(expected, 274) assert.equal( inferTotalParts({ begin: { part: 56, line: 128, size, name: 'a' }, part: { begin: 21120001, end: 21504000 }, }), expected ) assert.equal( inferTotalParts({ begin: { part: 274, line: 128, size, name: 'a' }, part: { begin: 273 * partSize + 1, end: size }, }), 274 ) }) test('single-part posts have one part', ({ assert }) => { assert.equal(inferTotalParts({ begin: { line: 128, size: 10, name: 'a' } }), 1) }) }) test.group('indexer / skipBodyMessageIds', () => { test('matches the multi-group uploader, not other posts', async ({ assert }) => { const { default: indexerConfig } = await import('#config/indexer') const skip = (id: string) => indexerConfig.skipBodyMessageIds.some((re) => re.test(id)) assert.isTrue(skip('')) assert.isFalse(skip('')) assert.isFalse(skip('')) }) })