OverviewFilesCommitsIssuesDocsReleasesPeers

pgh / test / app-status-verbose.test.js

136 lines · javascript ref:
// Tests for `pgh app status -v` (verbose).
//
// The verbose-render is a pure function that takes the existing basic
// status + a snapshot of daemon RPC responses and emits an enriched
// status. Daemon RPCs each have a try/catch upstream so any one of them
// can be undefined or carry an `error` field; the renderer must not
// crash on partial input.
//
// Two test surfaces:
//   1. Pure renderer (this file) — fast, no I/O, exhaustive shape coverage.
//   2. Integration smoke against a real daemon — separate file (deferred
//      until the renderer is locked in).

import test from 'brittle'
import { renderVerboseStatus } from '../lib/commands/app.js'

const basic = {
  name: 'pear-git-v3',
  running: true,
  supervisorPid: 1234,
  childPid: 1235,
  version: '0.1.57',
  startedAt: '2026-05-05T13:42:55.728Z',
  lastExit: null,
  lastExitCode: null,
  autostart: true,
  log: '/tmp/x.log',
  sidecar: { registered: true, udsPath: '/tmp/sock', pid: 1235 }
}

test('renderVerboseStatus: full daemon state populates every section', (t) => {
  const daemonState = {
    status: {
      transport: 'uds',
      identity: 'b74708cb1fda118ff3e218d32f12ad4404509365d48910448c8a0e675d063c17',
      orgs: 4,
      issues: { total: 140, open: 140, closed: 0, repos: 97, orgs: 4 },
      users: { total: 20 },
      swarm: { topic: '5ad0cc0d77ee8c33...', connections: 1 }
    },
    swarmPeers: {
      total: 1,
      peers: [{
        remotePublicKey: 'b2dc873d877a69b724419a9dad330628a1e33d1cd264c71e4f980cf18eb14b43',
        remoteAddress: '1.2.3.4:5555',
        opened: true,
        destroyed: false
      }]
    },
    mirrorWriters: {
      identityViewLength: 125,
      identityWritable: true,
      autobaseState: {
        systemCoreLength: 229,
        systemCoreSignedLength: 229,
        viewVersion: 125,
        activeWriters: 2,
        ackTimerArmed: true,
        linearizer: { indexerCount: 1, indexers: [{ key: 'b74708cb1fda118f', length: 83, indexed: 83 }] }
      }
    },
    otaLatest: { version: '0.1.57', publishedAt: 1777986127064 },
    role: 'primary'
  }

  const out = renderVerboseStatus(basic, daemonState)

  t.is(out.name, 'pear-git-v3', 'name preserved from basic')
  t.is(out.running, true, 'running preserved')
  t.ok(out.daemon, 'daemon section present')
  t.is(out.daemon.role, 'primary', 'role surfaced')
  t.is(out.daemon.swarm.peers, 1, 'swarm peer count surfaced')
  t.is(out.daemon.swarm.topic, '5ad0cc0d77ee8c33...', 'swarm topic surfaced')
  t.is(out.daemon.users, 20, 'users count surfaced')
  t.is(out.daemon.orgs, 4, 'orgs count surfaced')
  t.is(out.daemon.issues.total, 140, 'issues total surfaced')
  t.is(out.daemon.autobase.identity.viewLength, 125, 'identity view length surfaced')
  t.is(out.daemon.autobase.identity.activeWriters, 2, 'identity active writers surfaced')
  t.is(out.daemon.autobase.identity.indexerCount, 1, 'identity indexer count surfaced')
  t.is(out.daemon.ota.upToDate, true, 'OTA up-to-date computed (current === latest)')
  t.is(out.daemon.ota.latestVersion, '0.1.57', 'OTA latest version surfaced')
})

test('renderVerboseStatus: ota.upToDate=false when current < latest', (t) => {
  const out = renderVerboseStatus(
    { ...basic, version: '0.1.55' },
    { otaLatest: { version: '0.1.57', publishedAt: 1 } }
  )
  t.is(out.daemon.ota.upToDate, false, 'detects pending OTA')
  t.is(out.daemon.ota.currentVersion, '0.1.55', 'currentVersion surfaced')
  t.is(out.daemon.ota.latestVersion, '0.1.57', 'latestVersion surfaced')
})

test('renderVerboseStatus: mirror role surfaces originServerKey', (t) => {
  const out = renderVerboseStatus(basic, {
    role: 'mirror',
    originServerKey: 'b74708cb1fda118ff3e218d32f12ad4404509365d48910448c8a0e675d063c17'
  })
  t.is(out.daemon.role, 'mirror')
  t.is(out.daemon.originServerKey, 'b74708cb1fda118f...', 'origin server key abbreviated')
})

test('renderVerboseStatus: missing/error daemonState keeps basic intact + reports unavailability', (t) => {
  const out = renderVerboseStatus(basic, null)
  t.is(out.name, 'pear-git-v3')
  t.is(out.running, true)
  t.ok(out.daemon, 'daemon section still present (so callers can detect unavailability)')
  t.is(out.daemon.available, false, 'daemon unavailable flagged')
  t.ok(out.daemon.reason, 'reason string present')
})

test('renderVerboseStatus: partial RPC failures populate what works, error the rest', (t) => {
  const out = renderVerboseStatus(basic, {
    status: {
      identity: 'abc', orgs: 4, issues: { total: 8, open: 8, closed: 0, repos: 0, orgs: 1 },
      users: { total: 20 }, swarm: { topic: 'xx', connections: 0 }
    },
    swarmPeers: { error: 'EAUTH' }, // simulated failure
    mirrorWriters: { error: 'autobase not ready' },
    otaLatest: null,
    role: 'primary'
  })
  t.is(out.daemon.users, 20, 'status data still populated')
  t.is(out.daemon.swarm.peers, 0, 'falls back to status.swarm.connections when swarmPeers errored')
  t.ok(out.daemon.errors, 'errors collected for failed RPCs')
  t.ok(out.daemon.errors.swarmPeers, 'swarmPeers error reported')
  t.ok(out.daemon.errors.mirrorWriters, 'mirrorWriters error reported')
})

test('renderVerboseStatus: empty daemonState (all undefined) does not crash', (t) => {
  const out = renderVerboseStatus(basic, {})
  t.is(out.name, 'pear-git-v3')
  t.ok(out.daemon, 'daemon section present')
  t.is(out.daemon.available, true, 'daemon dialed but returned nothing')
})