UNPKG

bt-fetch

Version:

Interact with Bittorrent the same way you would websites via fetch()

274 lines (209 loc) 7.21 kB
import test from 'tape' import tmp from 'tmp' import FormData from 'form-data' import makeBTFetch from './index.js' tmp.setGracefulCleanup(true) const folder = tmp.dirSync({ prefix: 'btfetch_example' }).name const TEST_DATA = 'Hello World!' test('Create a torrent using FormData to bittorrent://localhost/, check files', async (t) => { const fetch = makeBTFetch({ folder }) try { const form = new FormData() form.append('name', 'TestTorrent') form.append('file2', TEST_DATA, { filename: 'example.txt' }) form.append('file', TEST_DATA, { filename: 'example2.txt' }) const body = form.getBuffer() const headers = form.getHeaders() const response = await fetch('bittorrent://localhost/', { method: 'POST', headers, body }) await checkOk(response, t, 'Able to create torrent') const createdURL = await response.text() t.ok(createdURL.startsWith('bittorrent://'), 'got new bittorrent URL back') t.equal(createdURL.length, 'bittorrent://'.length + 40 + 1, 'Bittorrent URL is expected length') const listResponse = await fetch(createdURL) await checkOk(listResponse, t, 'able to list directory') const files = await listResponse.json() const expectedFiles = ['example.txt', 'example2.txt'].sort() t.deepEqual(files.sort(), expectedFiles.sort(), 'Got listing of uploaded files') for (const fileName of files) { const fileURL = new URL(fileName, createdURL).href const getResponse = await fetch(fileURL) await checkOk(getResponse, t, `Able to GET ${fileName}`) const fileData = await getResponse.text() t.equal(fileData, TEST_DATA, 'Got expected file data ' + fileName) } } finally { await fetch.destroy() } }) test('Create a torrent using FormData to petname', async (t) => { const fetch = makeBTFetch({ folder }) try { const form = new FormData() form.append('name', 'TestTorrent') form.append('file2', TEST_DATA, { filename: 'example.txt' }) form.append('file', TEST_DATA, { filename: 'example2.txt' }) const body = form.getBuffer() const headers = form.getHeaders() const response = await fetch('bittorrent://example/', { method: 'POST', headers, body }) // Resolve public key from response headers t.ok(response.ok, 'Successful response') const createdURL = await response.text() t.equal(createdURL.length, 'bittorrent://'.length + 64 + 1, 'Bittorrent URL is expected length') t.ok(createdURL.startsWith('bittorrent://'), 'got new bittorrent URL back') const listResponse = await fetch(createdURL) t.ok(listResponse.ok, 'able to list directory') const files = await listResponse.json() const expectedFiles = ['example.txt', 'example2.txt'].sort() t.deepEqual(files.sort(), expectedFiles.sort(), 'Got listing of uploaded files') for (const fileName of files) { const fileURL = new URL(fileName, createdURL).href const getResponse = await fetch(fileURL) const fileData = await getResponse.text() t.equal(fileData, TEST_DATA, 'Got expected file data ' + fileName) } } finally { await fetch.destroy() } }) test('Upload to subfolder with petname', async (t) => { const fetch = makeBTFetch({ folder }) try { const form1 = new FormData() form1.append('file', TEST_DATA, { filename: 'example.txt' }) const body1 = form1.getBuffer() const headers1 = form1.getHeaders() const response1 = await fetch('bittorrent://example2/', { method: 'POST', headers: headers1, body: body1 }) // Resolve public key from response headers t.ok(response1.ok, 'Successful response') const createdURL1 = await response1.text() t.equal(createdURL1.length, 'bittorrent://'.length + 64 + 1, 'Bittorrent URL is expected length') t.ok(createdURL1.startsWith('bittorrent://'), 'got new bittorrent URL back') const form2 = new FormData() form2.append('file', TEST_DATA, { filename: 'index.md' }) const body2 = form2.getBuffer() const headers2 = form2.getHeaders() const response2 = await fetch('bittorrent://example2/subfolder/', { method: 'POST', headers: headers2, body: body2 }) // Resolve public key from response headers t.ok(response2.ok, 'Successful response') const createdURL2 = await response2.text() t.equal(createdURL2.length, 'bittorrent://'.length + 64 + 1, 'Bittorrent URL is expected length') t.ok(createdURL2.startsWith('bittorrent://'), 'got new bittorrent URL back') t.equal(createdURL1, createdURL2, 'URL consistent after uploads') const listResponse = await fetch(createdURL1) t.ok(listResponse.ok, 'able to list directory') const files = await listResponse.json() const expectedFiles = ['example.txt', 'subfolder/'].sort() t.deepEqual(files.sort(), expectedFiles.sort(), 'Got listing of uploaded files') } finally { await fetch.destroy() } }) test('Re-load petname torrent after closing it', async (t) => { let fetch = makeBTFetch({ folder }) try { const form = new FormData() form.append('file', TEST_DATA, { filename: 'example.txt' }) const body = form.getBuffer() const headers = form.getHeaders() const response = await fetch('bittorrent://examplereload/', { method: 'POST', headers, body }) // Resolve public key from response headers t.ok(response.ok, 'Successful response') await response.text() await fetch.destroy() fetch = makeBTFetch({ folder }) const response2 = await fetch('bittorrent://examplereload/example.txt') t.ok(response2, 'Able to load file back up') const text = await response2.text() t.equal(text, TEST_DATA, 'Data got loaded back') } finally { await fetch.destroy() } }) test('Test loading a well-seeded file', async (t) => { const fetch = makeBTFetch({ folder }) // InfoHash for the Sintel torrent // Taken from https://webtorrent.io/docs const url = 'bittorrent://08ada5a7a6183aae1e09d831df6748d566095a10/' try { const res = await fetch(url) t.ok(res.ok, 'Response successful') t.equal(res.status, 200, '200 OK') const files = await res.json() console.log(files) const resHTML = await fetch(url, { headers: { Accept: 'text/html' } }) console.log('As HTML', await resHTML.text()) const srtURL = url + 'Sintel.en.srt' console.log('Fetching subtitle track metadata') console.log(srtURL) const resHead = await fetch(srtURL, { method: 'head' }) const { headers, status } = resHead console.log({ headers: [...headers], status }) console.log('Getting contents of srt file') const resSRT = await fetch(srtURL) for await (const chunk of resSRT.body) { console.log('Chunk:', chunk) } } finally { await fetch.destroy() } }) async function checkOk (response, t, message = 'Response OK') { if (!response.ok) { t.error(await response.text()) } else { t.pass(message) } }