bitspire/.claude/skills/test.md
Padreug 53b0d382e8 docs: finish the LNbits-era doc sweep across docs/ + .claude/skills/
Second + final batch of the doc refresh. README + CLAUDE went out in
8c9ae29; deploy/nixos/README + obsolete-flow flags in 924844f. This
commit covers everything left.

docs/machine-installation.md
  Was describing a manual AppImage scp deploy + a `lamassu-kiosk`
  systemd unit that hasn't been the deployment path for months.
  Replaced with a high-level "what the pipeline does and why"
  overview that points at deploy/nixos/README.md for the full
  command-by-command walkthrough. Includes the BATM3 chassis-mod
  note (custom Dell OptiPlex retrofit, not a stock Dell).

docs/architecture-comparison.md
  Rewrote the comparison to be lamassu-server (≤ v8.1.5) vs bitSpire
  (LNbits-backed) instead of the original lamassu-server vs LP-backed
  lamassu-next framing. Updated the cash-out + cash-in flow diagrams
  to show the actual nostr-transport path (LNbits-bundled nostrrelay
  extension at ws://<host>:5001/nostrrelay/test, no separate strfry
  container). Replaced the migration-path section with a softer
  "when to choose what" framing that includes Lamassu's current
  commercial offering as a legitimate third option. Added a header
  pointer to the Acknowledgements section.

docs/business-model.md
  Light touch-ups: Lightning.Pub → LNbits where it appeared, swapped
  the [[ndebit-cash-in-flow]] link for [[architecture-comparison]],
  noted the kind-30078 service beacon for availability broadcasts.

docs/device-configuration.md
  Dropped "Lamassu" branding from the machine-model headings
  (Sintra / tejo / douro / batm3 are referenced by hardware identity
  here, not by Lamassu's product line). Added the Sintra-specific
  ttyS4-vs-placeholder-ttyS1..3 gotcha we hard-learned during the
  first flash. Corrected the BATM3 entry: stock GeneralBytes chassis
  with a Dell OptiPlex 9030 AIO motherboard physically grafted in,
  NOT a Dell out of the box. Updated the example /dev/ttyJ* symlink
  output to match what a healthy Sintra actually shows.

docs/adr/001-hal-architecture.md
  ADRs are historical artifacts — kept the original decision text
  intact. Added a postscript noting:
    - The package rename @lamassu/hal → @bitSpire/hal
    - The v8.1.5 boundary on any lamassu-machine source-tree
      references (Lamassu's 2024-01-26 license transition)
    - That the "Remaining Work" list is complete and the first
      successful Sintra hardware integration ran on 2026-05-13

.claude/skills/lightning-check.md
  Rewrote end-to-end. Was Lightning.Pub-flavoured with CLINK kinds
  21001/21002 as the primary flows; now validates the LNbits nostr-
  transport surface (kind-21000 envelope, NIP-44 v2 encryption,
  subscribe_payments filter discipline, lnurlw link composition).
  Preserved a --clink mode for the still-live kind-21003 operator-
  management surface. Includes a "what to check" rubric for cash-out
  vs cash-in flows that mirrors the actual code in
  apps/machine/src/services/lightning.ts.

.claude/skills/hal-check.md
  Two pivots: (1) acknowledge ADR-001's TypeScript-not-Rust choice
  and reframe all the safety checklists in TS-flavour (type safety,
  discriminated unions, single-writer serial, bounded emitters)
  instead of Rust-flavour (unsafe, borrow checker). (2) Add explicit
  v8.1.5 provenance boundary plus a "forbidden operations" section
  that prohibits diffing or porting from v8.1.6+ lamassu-machine
  source. Updated the port-validation source-reference table to
  list TS file paths under packages/hal/ instead of Rust paths.

.claude/skills/docs.md
  @lamassu/* → @bitSpire/*. Replaced the Lightning.Pub mermaid
  diagram with a current cash-out flow showing the nostr-transport
  RPC + subscribe_payments push path. Left the createOffer noffer
  example in the API-docs template section since it's illustrative
  ("here's what a good TSDoc block looks like") rather than current
  reference documentation.

.claude/skills/test.md
  One-line: @lamassu/nostr-client → @bitSpire/nostr-client in the
  pnpm-filter example.

deploy/nixos/README.md
  Single touch-up: clarified the douro/batm3 hardware-module comments
  to reflect that BATM3 is a custom-installed Dell board in a
  GeneralBytes BATM3 chassis (not a Dell OEM).

Files NOT touched in this sweep (intentionally):
  - packages/hal/src/**/*.ts attribution comments — those reference
    "lamassu-machine" in their port-source headers. Those are
    factually accurate (the drivers ARE ported from there, up to
    v8.1.5) and constitute necessary license/attribution metadata.
    Editing them would erase the provenance trail.
  - .claude/skills/{nostr-check,security}.md — already protocol-
    neutral, no LP/lamassu references to clean up.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-01 19:08:03 +02:00

3.9 KiB

/test - Testing Agent

Purpose

Run tests, analyze coverage, generate test cases, and validate ATM transaction flows.

Invocation

/test [command] [target]

Commands:

  • run - Run tests (default)
  • coverage - Run with coverage report
  • generate - Generate test cases for a file
  • flow - Validate transaction flow
  • hardware - Run hardware mock tests

Test Categories

1. Unit Tests

Location: *.test.ts or *.spec.ts alongside source files

pnpm test                    # All tests
pnpm test --filter @bitSpire/nostr-client  # Specific package

2. Integration Tests

Location: tests/integration/

Tests cross-package interactions:

  • Nostr client + CLINK
  • State machine + Hardware mocks
  • Lightning client + Invoice handling

3. E2E Tests (Playwright)

Location: tests/e2e/

Full transaction flows:

  • Cash-in flow (bill insert → Lightning payment)
  • Cash-out flow (Lightning receive → dispense)
  • Error recovery flows

4. Hardware Mock Tests

Test against mock hardware:

pnpm test:hardware           # With mock validator/dispenser
REAL_HARDWARE=true pnpm test:hardware  # With real hardware (CI skip)

Test Generation

For a new file:

/test generate packages/lightning/src/client.ts

Generates test skeleton:

import { describe, it, expect, vi } from 'vitest'
import { LightningPubClient } from './client'

describe('LightningPubClient', () => {
  describe('createInvoice', () => {
    it('should create valid BOLT11 invoice', async () => {
      // TODO: Implement
    })

    it('should handle network errors', async () => {
      // TODO: Implement
    })

    it('should validate amount bounds', async () => {
      // TODO: Implement
    })
  })
})

Test Case Suggestions

Based on code analysis, suggest test cases for:

  • Happy path
  • Edge cases (null, empty, max values)
  • Error conditions
  • Timeout scenarios
  • Concurrent operations

Transaction Flow Validation

Cash-In Flow

/test flow cash-in

Validates:

  1. Idle → Select Cash-In
  2. Bill insertion events received
  3. Amount calculation correct
  4. CLINK offer generated
  5. Payment received event
  6. Receipt sent (optional)
  7. Return to Idle

Cash-Out Flow

/test flow cash-out

Validates:

  1. Idle → Select Cash-Out
  2. Amount selection
  3. Invoice generated
  4. Payment received
  5. Cash dispensed
  6. Bills removed detection (F56)
  7. Return to Idle

Error Flows

/test flow errors

Validates:

  • Hardware timeout recovery
  • Payment failure handling
  • Network disconnection
  • Partial dispense handling

Coverage Requirements

Minimum Coverage Targets

Package Statements Branches Functions
nostr-client 80% 75% 80%
clink 80% 75% 80%
state-machine 90% 85% 90%
lightning 80% 75% 80%
hal (mocks) 70% 65% 70%

Critical Paths (100% coverage required)

  • Payment processing
  • Cash dispensing logic
  • Key handling
  • Amount calculations

Output Format

Test Run

## Test Results: [target]

### Summary
- Total: 42
- Passed: 40
- Failed: 2
- Skipped: 0

### Failed Tests
1. `client.test.ts` > createInvoice > should validate amount
   - Expected: Error thrown
   - Received: Invoice created with negative amount

### Coverage
| File | Statements | Branches | Functions |
|------|------------|----------|-----------|
| client.ts | 85% | 78% | 90% |

Test Generation

## Generated Tests: [file]

### Test File
`packages/lightning/src/client.test.ts`

### Suggested Test Cases
1. **createInvoice**
   - ✅ Valid amount creates invoice
   - ✅ Zero amount rejected
   - ✅ Negative amount rejected
   - ✅ Network error handled

### Missing Coverage
- `payInvoice` has no tests
- Error handling branch at line 45 untested

Example Usage

/test coverage packages/state-machine/
/test generate packages/clink/src/offer.ts
/test flow cash-out