OverviewFilesCommitsIssuesDocsReleasesPeers

hyper-orgs / test / resource-keys.test.js

89 lines · javascript ref:
// Phase B: org records carry each grouped repo's tracker bootstrap key
// (resourceKeys) so a peer that joins the org can mount exactly those
// repos (scoped). These tests cover the schema apply + addResource API:
// store-with-key, name-only, backfill, remove, and cross-org reassignment.

import test from 'brittle'
import Corestore from 'corestore'
import { mkdtempSync } from 'fs'
import { join } from 'path'
import { tmpdir } from 'os'
import { HyperOrgs } from '../index.js'

function tmpStore () {
  return new Corestore(mkdtempSync(join(tmpdir(), 'hyperorgs-rk-')))
}

async function makeOrgs (t, namespace = 'rk') {
  const store = tmpStore()
  const orgs = new HyperOrgs(store, { namespace })
  await orgs.ready()
  t.teardown(async () => {
    try { await orgs.close() } catch {}
    try { await store.close() } catch {}
  })
  return orgs
}

const KEY_A = 'a'.repeat(64)
const KEY_B = 'b'.repeat(64)

test('new org record initialises resourceKeys to {}', async (t) => {
  const orgs = await makeOrgs(t, 'rk-1')
  const org = await orgs.create('team', 'group')
  t.alike(org.resourceKeys, {}, 'resourceKeys present and empty')
})

test('addResource with a bootstrapKey records it under resourceKeys', async (t) => {
  const orgs = await makeOrgs(t, 'rk-2')
  await orgs.create('team', 'group')
  const org = await orgs.addResource('team', 'repo-1', { bootstrapKey: KEY_A })
  t.alike(org.resources, ['repo-1'])
  t.is(org.resourceKeys['repo-1'], KEY_A, 'key stored')
})

test('addResource without a key adds the name only (no key)', async (t) => {
  const orgs = await makeOrgs(t, 'rk-3')
  await orgs.create('team', 'group')
  const org = await orgs.addResource('team', 'repo-1')
  t.alike(org.resources, ['repo-1'])
  t.absent(org.resourceKeys['repo-1'], 'no key for a name-only add')
})

test('re-adding with a key backfills a name-only entry', async (t) => {
  const orgs = await makeOrgs(t, 'rk-4')
  await orgs.create('team', 'group')
  await orgs.addResource('team', 'repo-1') // name only (repo not created yet)
  const org = await orgs.addResource('team', 'repo-1', { bootstrapKey: KEY_A })
  t.alike(org.resources, ['repo-1'], 'no duplicate name')
  t.is(org.resourceKeys['repo-1'], KEY_A, 'key backfilled')
})

test('removeResource drops both the name and the key', async (t) => {
  const orgs = await makeOrgs(t, 'rk-5')
  await orgs.create('team', 'group')
  await orgs.addResource('team', 'repo-1', { bootstrapKey: KEY_A })
  const org = await orgs.removeResource('team', 'repo-1')
  t.alike(org.resources, [])
  t.absent(org.resourceKeys['repo-1'], 'key removed with the name')
})

test('each org keeps its own key — no cross-org uniqueness in the per-org model', async (t) => {
  // Under #37 each org is its OWN autobase, so the cross-org "remove from
  // other orgs" scan in add-resource only sees the current org's view. A
  // repo can therefore belong to two orgs independently, each carrying its
  // own resourceKeys entry. (Cross-org uniqueness was a property of the old
  // single-orgs-autobase model; it does not hold here, and that's fine for
  // the grouped-repos feature — each org lists + keys its own repos.)
  const orgs = await makeOrgs(t, 'rk-6')
  await orgs.create('team-a', 'group')
  await orgs.create('team-b', 'group')
  await orgs.addResource('team-a', 'repo-1', { bootstrapKey: KEY_A })
  await orgs.addResource('team-b', 'repo-1', { bootstrapKey: KEY_B })

  const a = await orgs.get('team-a')
  const b = await orgs.get('team-b')
  t.is(a.resourceKeys['repo-1'], KEY_A, 'team-a keeps its own key')
  t.is(b.resourceKeys['repo-1'], KEY_B, 'team-b keeps its own key')
})