import { test } from '@japa/runner' import { randomBytes } from 'node:crypto' import { zstdCompressSync, constants } from 'node:zlib' import { NICOVIDEO_FILE, nicovideoInfo, nicovideoReleaseName, zstdPrefix } from '#lib/content/index' function tarEntry(name: string, data: Buffer): Buffer { const header = Buffer.alloc(512) header.write(name, 0, 'utf8') header.write(data.length.toString(8).padStart(11, '0') + '\0', 124, 'latin1') header.write('ustar\0', 257, 'latin1') return Buffer.concat([header, data, Buffer.alloc((512 - (data.length % 512)) % 512)]) } test.group('nicovideo captures', () => { test('reads the title from the start of a capture, even a truncated one', async ({ assert }) => { const dir = '1790720489_nicovideo_jp_watch_sm27965722' const response = { data: { metadata: { jsonLds: [{ author: { name: 'まふまふ' } }] }, response: { video: { id: 'sm27965722', title: '桜花ニ月夜ト袖シグレ/After the Rain【そらる×まふまふ】', registeredAt: '2016-01-08T20:00:00+09:00' }, owner: { nickname: 'まふまふ' }, tag: { items: [{ name: '音楽' }, { name: 'After_the_Rain' }] }, }, }, } const tar = Buffer.concat([ tarEntry(`${dir}/`, Buffer.alloc(0)), tarEntry(`${dir}/server_response.metadata`, Buffer.from(JSON.stringify(response, null, 2))), tarEntry(`${dir}/01.cmfa`, randomBytes(300_000)), ]) const compressed = zstdCompressSync(tar, { params: { [constants.ZSTD_c_compressionLevel]: 3 } }) // Only the first part of the stream, as in the file's first article. const info = nicovideoInfo(await zstdPrefix(compressed.subarray(0, Math.floor(compressed.length * 0.6))))! assert.deepEqual(info, { id: 'sm27965722', title: '桜花ニ月夜ト袖シグレ/After the Rain【そらる×まふまふ】', owner: 'まふまふ', registeredAt: '2016-01-08T20:00:00+09:00', tags: ['音楽', 'After_the_Rain'], }) assert.equal(nicovideoReleaseName(info, 'sm1'), '桜花ニ月夜ト袖シグレ/After the Rain【そらる×まふまふ】 - まふまふ (nicovideo sm27965722)') assert.equal(NICOVIDEO_FILE.exec(`${dir}.tar.zst`)![1], 'sm27965722') assert.isNull(nicovideoInfo(await zstdPrefix(Buffer.from('not zstd')))) }) })