OverviewFilesCommitsIssuesDocsReleasesPeers

pearbrowser-desktop / test / p2p-first-fetch.test.js

85 lines · javascript ref:
// Tests for backend/p2p-first-fetch.js — the P2P-first hybrid fetch (privacy):
// the relay must not be contacted when P2P can serve the content.
import test from 'node:test'
import assert from 'node:assert/strict'
import mod from '../backend/p2p-first-fetch.js'
const { p2pFirstFetch } = mod

const delay = (ms, val) => () => new Promise((r) => setTimeout(() => r(val), ms))
const immediate = (val) => () => Promise.resolve(val)

test('a P2P hit within the grace window never contacts the relay (privacy)', async () => {
  let relayCalls = 0
  const out = await p2pFirstFetch({
    fetchP2P: delay(5, { body: 'p2p' }),
    fetchRelay: () => { relayCalls++; return Promise.resolve({ body: 'relay' }) },
    graceMs: 50,
  })
  assert.equal(out.source, 'p2p')
  assert.equal(out.result.body, 'p2p')
  assert.equal(out.relayContacted, false)
  assert.equal(relayCalls, 0) // the relay was never even invoked
})

test('a P2P miss falls back to the relay', async () => {
  const out = await p2pFirstFetch({
    fetchP2P: immediate(null),
    fetchRelay: immediate({ body: 'relay' }),
    graceMs: 50,
  })
  assert.equal(out.source, 'relay')
  assert.equal(out.result.body, 'relay')
  assert.equal(out.relayContacted, true)
})

test('a slow P2P still wins the fallback race against a relay miss', async () => {
  let relayCalls = 0
  const out = await p2pFirstFetch({
    fetchP2P: delay(80, { body: 'p2p-late' }), // arrives after the grace window
    fetchRelay: () => { relayCalls++; return Promise.resolve(null) }, // relay miss
    graceMs: 20,
  })
  assert.equal(relayCalls, 1) // relay WAS contacted (P2P was slow)
  assert.equal(out.relayContacted, true)
  assert.equal(out.source, 'p2p') // ...but the late P2P result still won
  assert.equal(out.result.body, 'p2p-late')
})

test('relayFirst kill-switch restores the parallel race (relay can win)', async () => {
  const out = await p2pFirstFetch({
    fetchP2P: delay(40, { body: 'p2p' }),
    fetchRelay: delay(5, { body: 'relay' }),
    relayFirst: true,
  })
  assert.equal(out.source, 'relay') // the faster relay wins
  assert.equal(out.relayContacted, true)
})

test('both sources missing yields a null result', async () => {
  const out = await p2pFirstFetch({
    fetchP2P: immediate(null),
    fetchRelay: immediate(null),
    graceMs: 20,
  })
  assert.equal(out.result, null)
  assert.equal(out.source, null)
})

test('no relay configured → P2P-only, relay never contacted', async () => {
  const out = await p2pFirstFetch({
    fetchP2P: immediate({ body: 'p2p' }),
    fetchRelay: null,
  })
  assert.equal(out.source, 'p2p')
  assert.equal(out.relayContacted, false)
})

test('a fetchP2P that throws is treated as a miss (relay fallback)', async () => {
  const out = await p2pFirstFetch({
    fetchP2P: () => { throw new Error('p2p boom') },
    fetchRelay: immediate({ body: 'relay' }),
    graceMs: 20,
  })
  assert.equal(out.source, 'relay')
})