OverviewFilesCommitsIssuesDocsReleasesPeers

P2P-Hiverelay / test / unit / audit-owned-diff.test.js

209 lines · javascript ref:
import test from 'brittle'
import { execFile } from 'node:child_process'
import { mkdtemp, rm, writeFile } from 'node:fs/promises'
import { readFileSync } from 'node:fs'
import { tmpdir } from 'node:os'
import path from 'node:path'
import { buildOwnedDiffReport, parsePorcelainStatus } from '../../scripts/lib/audit-owned-diff.mjs'

function runAudit (argv) {
  return new Promise((resolve) => {
    execFile(process.execPath, ['scripts/check-audit-owned-diff.mjs', ...argv], {
      cwd: process.cwd(),
      env: { PATH: process.env.PATH || '' },
      timeout: 10000
    }, (err, stdout, stderr) => {
      resolve({
        status: err && typeof err.code === 'number' ? err.code : 0,
        stdout,
        stderr
      })
    })
  })
}

async function tempFile (t, body) {
  const dir = await mkdtemp(path.join(tmpdir(), 'hiverelay-owned-diff-'))
  t.teardown(async () => {
    await rm(dir, { recursive: true, force: true })
  })
  const file = path.join(dir, 'status.txt')
  await writeFile(file, body)
  return file
}

test('audit-owned diff command is exposed as a package command', (t) => {
  const pkg = JSON.parse(readFileSync('package.json', 'utf8'))
  t.is(pkg.scripts['audit:owned-diff'], 'node scripts/check-audit-owned-diff.mjs')
})

test('audit-owned diff parser normalizes porcelain paths and renames', (t) => {
  const parsed = parsePorcelainStatus(' M README.md\n?? "docs/space name.md"\nR  old.js -> scripts/check-audit-owned-diff.mjs\n')
  t.is(parsed.length, 3)
  t.is(parsed[0].path, 'README.md')
  t.is(parsed[1].path, 'docs/space name.md')
  t.is(parsed[2].path, 'scripts/check-audit-owned-diff.mjs')
})

test('audit-owned diff accepts known audit slice paths', async (t) => {
  const fixture = await tempFile(t, [
    ' M README.md',
    ' M packages/core/core/protocol/seed-request.js',
    ' M package.json',
    ' M packages/core/core/capability-doc.js',
    ' M packages/core/core/relay-node/bare-relay.js',
    ' M packages/core/gateway/hyper-gateway.js',
    ' M docs/SERVICES.md',
    ' M packages/client/README.md',
    ' M packages/client/package.json',
    ' M packages/services/README.md',
    ' M packages/services/index.js',
    '?? docs/PUSH-NOTIFICATION-SERVICE-SPEC.md',
    '?? packages/client/notify.js',
    '?? packages/core/core/relay-node/api-notify.js',
    '?? packages/services/builtin/notify-service.js',
    '?? packages/services/builtin/outboxlog/blind-seal.js',
    '?? packages/services/builtin/outboxlog/hypercore-journal.js',
    '?? packages/services/builtin/outboxlog/http-adapter.js',
    '?? packages/services/builtin/outboxlog/outbox-log.js',
    '?? scripts/check-audit-owned-diff.mjs',
    '?? scripts/bench-outboxlog.mjs',
    '?? test/unit/api-notify.test.js',
    '?? test/unit/capability-doc.test.js',
    '?? test/unit/client-notify.test.js',
    '?? test/unit/hyper-gateway-hardening.test.js',
    '?? test/unit/notify-service.test.js',
    '?? test/unit/outboxlog-blind-seal.test.js',
    '?? test/unit/outboxlog-bench.test.js',
    '?? test/unit/outboxlog-http-adapter.test.js',
    '?? test/unit/outboxlog-seeder-runtime.test.js',
    '?? test/unit/outboxlog.test.js',
    '?? test/unit/audit-owned-diff.test.js'
  ].join('\n') + '\n')
  const res = await runAudit(['--json', '--status-file', fixture])

  t.is(res.status, 0)
  t.is(res.stderr, '')

  const report = JSON.parse(res.stdout)
  t.is(report.kind, 'hiverelay-audit-owned-diff')
  t.is(report.status, 'pass')
  t.is(report.totals.changed, 32)
  t.is(report.totals.unknown, 0)
  t.ok(report.entries.find(entry => entry.path === 'README.md').owners.length > 1)
  t.ok(report.entries
    .find(entry => entry.path === 'packages/services/builtin/outboxlog/http-adapter.js')
    .owners.some(owner => owner.id === 'outboxlog-sync-event-sse'))
  t.ok(report.entries
    .find(entry => entry.path === 'packages/services/builtin/outboxlog/outbox-log.js')
    .owners.some(owner => owner.id === 'outboxlog-append-event-replay'))
  t.ok(report.entries
    .find(entry => entry.path === 'packages/services/builtin/outboxlog/outbox-log.js')
    .owners.some(owner => owner.id === 'outboxlog-operation-journal'))
  t.ok(report.entries
    .find(entry => entry.path === 'packages/services/builtin/outboxlog/hypercore-journal.js')
    .owners.some(owner => owner.id === 'outboxlog-hypercore-journal'))
  t.ok(report.entries
    .find(entry => entry.path === 'packages/services/builtin/outboxlog/hypercore-journal.js')
    .owners.some(owner => owner.id === 'outboxlog-partitioned-hypercore-journal'))
  t.ok(report.entries
    .find(entry => entry.path === 'scripts/bench-outboxlog.mjs')
    .owners.some(owner => owner.id === 'outboxlog-release-budget-gate'))
  t.ok(report.entries
    .find(entry => entry.path === 'test/unit/outboxlog-seeder-runtime.test.js')
    .owners.some(owner => owner.id === 'outboxlog-runtime-seeder-rehearsal'))
  t.ok(report.entries
    .find(entry => entry.path === 'packages/services/builtin/outboxlog/outbox-log.js')
    .owners.some(owner => owner.id === 'outboxlog-namespace-registration'))
  t.ok(report.entries
    .find(entry => entry.path === 'test/unit/outboxlog.test.js')
    .owners.some(owner => owner.id === 'outboxlog-namespace-registration'))
  t.ok(report.entries
    .find(entry => entry.path === 'packages/services/README.md')
    .owners.some(owner => owner.id === 'outboxlog-namespace-registration'))
  t.ok(report.entries
    .find(entry => entry.path === 'packages/services/builtin/outboxlog/outbox-log.js')
    .owners.some(owner => owner.id === 'outboxlog-sealed-blind-namespace'))
  t.ok(report.entries
    .find(entry => entry.path === 'test/unit/outboxlog.test.js')
    .owners.some(owner => owner.id === 'outboxlog-sealed-blind-namespace'))
  t.ok(report.entries
    .find(entry => entry.path === 'packages/services/README.md')
    .owners.some(owner => owner.id === 'outboxlog-sealed-blind-namespace'))
  t.ok(report.entries
    .find(entry => entry.path === 'packages/services/index.js')
    .owners.some(owner => owner.id === 'outboxlog-sealed-blind-namespace'))
  t.ok(report.entries
    .find(entry => entry.path === 'packages/services/builtin/outboxlog/blind-seal.js')
    .owners.some(owner => owner.id === 'outboxlog-blind-seal-helper'))
  t.ok(report.entries
    .find(entry => entry.path === 'test/unit/outboxlog-blind-seal.test.js')
    .owners.some(owner => owner.id === 'outboxlog-blind-seal-helper'))
  t.ok(report.entries
    .find(entry => entry.path === 'packages/services/index.js')
    .owners.some(owner => owner.id === 'outboxlog-blind-seal-helper'))
  t.ok(report.entries
    .find(entry => entry.path === 'packages/services/builtin/outboxlog/blind-seal.js')
    .owners.some(owner => owner.id === 'outboxlog-blind-recipient-key-wrap'))
  t.ok(report.entries
    .find(entry => entry.path === 'test/unit/outboxlog-blind-seal.test.js')
    .owners.some(owner => owner.id === 'outboxlog-blind-recipient-key-wrap'))
  t.ok(report.entries
    .find(entry => entry.path === 'packages/services/index.js')
    .owners.some(owner => owner.id === 'outboxlog-blind-recipient-key-wrap'))
  t.ok(report.entries
    .find(entry => entry.path === 'packages/services/builtin/outboxlog/blind-seal.js')
    .owners.some(owner => owner.id === 'outboxlog-blind-aad-binding-helper'))
  t.ok(report.entries
    .find(entry => entry.path === 'test/unit/outboxlog-blind-seal.test.js')
    .owners.some(owner => owner.id === 'outboxlog-blind-aad-binding-helper'))
  t.ok(report.entries
    .find(entry => entry.path === 'packages/services/README.md')
    .owners.some(owner => owner.id === 'outboxlog-blind-aad-binding-helper'))
  t.ok(report.entries
    .find(entry => entry.path === 'packages/services/builtin/outboxlog/blind-seal.js')
    .owners.some(owner => owner.id === 'outboxlog-blind-recipient-directory-helper'))
  t.ok(report.entries
    .find(entry => entry.path === 'test/unit/outboxlog-blind-seal.test.js')
    .owners.some(owner => owner.id === 'outboxlog-blind-recipient-directory-helper'))
  t.ok(report.entries
    .find(entry => entry.path === 'packages/services/index.js')
    .owners.some(owner => owner.id === 'outboxlog-blind-recipient-directory-helper'))
  t.ok(report.entries
    .find(entry => entry.path === 'packages/services/builtin/outboxlog/blind-seal.js')
    .owners.some(owner => owner.id === 'outboxlog-blind-recipient-rotation-helper'))
  t.ok(report.entries
    .find(entry => entry.path === 'test/unit/outboxlog-blind-seal.test.js')
    .owners.some(owner => owner.id === 'outboxlog-blind-recipient-rotation-helper'))
  t.ok(report.entries
    .find(entry => entry.path === 'packages/services/README.md')
    .owners.some(owner => owner.id === 'outboxlog-blind-recipient-rotation-helper'))
  t.ok(report.entries
    .find(entry => entry.path === 'packages/services/builtin/outboxlog/blind-seal.js')
    .owners.some(owner => owner.id === 'outboxlog-blind-recipient-trust-root-helper'))
  t.ok(report.entries
    .find(entry => entry.path === 'test/unit/outboxlog-blind-seal.test.js')
    .owners.some(owner => owner.id === 'outboxlog-blind-recipient-trust-root-helper'))
  t.ok(report.entries
    .find(entry => entry.path === 'packages/services/index.js')
    .owners.some(owner => owner.id === 'outboxlog-blind-recipient-trust-root-helper'))
})

test('audit-owned diff blocks unknown development paths', async (t) => {
  const fixture = await tempFile(t, '?? stray-release-note.txt\n')
  const res = await runAudit(['--json', '--status-file', fixture])

  t.is(res.status, 1)
  const report = JSON.parse(res.stdout)
  t.is(report.status, 'blocked')
  t.is(report.totals.unknown, 1)
  t.is(report.unknown[0].path, 'stray-release-note.txt')
})

test('audit-owned diff treats a clean status as pass', (t) => {
  const report = buildOwnedDiffReport('')
  t.is(report.status, 'pass')
  t.is(report.totals.changed, 0)
  t.is(report.totals.unknown, 0)
})