OverviewFilesCommitsIssuesDocsReleasesPeers

hyper-note / test / multiwriter-manager.test.js

120 lines · javascript ref:
import test from 'brittle'
import fs from 'bare-fs'
import path from 'bare-path'
import os from 'bare-os'
import Corestore from 'corestore'
import { MultiwriterManager } from '../lib/multiwriter/manager.js'

function tmpDir () {
  const dir = path.join(os.tmpdir(), 'hn-mgr-' + Date.now() + '-' + Math.random().toString(36).slice(2))
  fs.mkdirSync(dir, { recursive: true })
  return dir
}

function rmrf (dir) {
  try {
    for (const f of fs.readdirSync(dir)) {
      const fp = path.join(dir, f)
      const stat = fs.statSync(fp)
      if (stat.isDirectory()) rmrf(fp)
      else fs.unlinkSync(fp)
    }
    fs.rmdirSync(dir)
  } catch {}
}

test('initialize and check status', async (t) => {
  const dir = tmpDir()
  const store = new Corestore(dir)
  const mgr = new MultiwriterManager(store)
  await mgr.ready()

  const status = mgr.getStatus()
  t.is(status.linked, false, 'not linked initially')
  t.is(status.sharedNotebooks, 0, 'no shared notebooks')
  t.ok(status.registryKey, 'registryKey exists')
  t.is(status.registryKey.length, 32, 'registryKey is 32 bytes')
  t.alike(status.sharedSlugs, [], 'no shared slugs')

  await mgr.close()
  await store.close()
  rmrf(dir)
})

test('share and unshare notebook', async (t) => {
  const dir = tmpDir()
  const store = new Corestore(dir)
  const mgr = new MultiwriterManager(store)
  await mgr.ready()

  // Share a notebook
  const snb = await mgr.shareNotebook('my-notes')
  t.ok(snb, 'shared notebook returned')
  t.ok(snb.bootstrapKey, 'shared notebook has bootstrapKey')

  let status = mgr.getStatus()
  t.is(status.sharedNotebooks, 1, 'one shared notebook')
  t.alike(status.sharedSlugs, ['my-notes'])
  t.is(mgr.isShared('my-notes'), true)

  // Verify registry was updated
  const nb = await mgr.registry.getNotebookBySlug('my-notes')
  t.ok(nb, 'notebook exists in registry')
  t.is(nb.shared, true, 'notebook marked as shared in registry')
  t.ok(nb.autobaseKey, 'autobaseKey stored in registry')

  // Unshare
  await mgr.unshareNotebook('my-notes')

  status = mgr.getStatus()
  t.is(status.sharedNotebooks, 0, 'no shared notebooks after unshare')
  t.is(mgr.isShared('my-notes'), false)

  // Registry should reflect unshare
  const nb2 = await mgr.registry.getNotebookBySlug('my-notes')
  t.ok(nb2, 'notebook still exists in registry')
  t.is(nb2.shared, false, 'notebook marked as not shared')

  await mgr.close()
  await store.close()
  rmrf(dir)
})

test('getSharedNotebook returns shared notebook or null', async (t) => {
  const dir = tmpDir()
  const store = new Corestore(dir)
  const mgr = new MultiwriterManager(store)
  await mgr.ready()

  t.is(mgr.getSharedNotebook('nonexistent'), null, 'returns null for unknown slug')

  await mgr.shareNotebook('test-nb')
  const snb = mgr.getSharedNotebook('test-nb')
  t.ok(snb, 'returns SharedNotebook after sharing')
  t.ok(snb.bootstrapKey, 'has bootstrapKey')
  t.is(snb.slug, 'test-nb', 'correct slug')

  await mgr.close()
  await store.close()
  rmrf(dir)
})

test('create invite returns inviteHex', async (t) => {
  const dir = tmpDir()
  const store = new Corestore(dir)
  const mgr = new MultiwriterManager(store)
  await mgr.ready()

  const result = await mgr.createLinkInvite()
  t.ok(result.inviteHex, 'inviteHex exists')
  t.is(typeof result.inviteHex, 'string', 'inviteHex is a string')
  t.ok(result.inviteHex.length > 0, 'inviteHex is non-empty')
  t.is(typeof result.waitForPeer, 'function', 'waitForPeer is a function')

  // Destroy the linker to clean up the swarm and pairing
  await mgr._linker.destroy()
  await mgr.close()
  await store.close()
  rmrf(dir)
})