OverviewFilesCommitsIssuesDocsReleasesPeers

hyper-wallet / tests / manual / test-phase5.3.cjs

203 lines · javascript ref:
#!/usr/bin/env bare

// test-phase5.3.cjs - Quick test for Phase 5.3 implementation
// Tests connection tracking, status functions, and basic flow

require('bare-node-runtime/global')

const {
  initializeStorage,
  bootstrapDevice,
  createInvite,
  getCurrentDevice,
  listDevices,
  getConnectionStatus,
  closeStorage
} = require('./lib/wallet-storage.cjs')

const IdentityKey = require('keet-identity-key')
const fs = require('bare-fs')
const path = require('bare-path')
const os = require('bare-os')

// Test uses actual .hyper-wallet directory
const TEST_DIR = path.join(os.homedir(), '.hyper-wallet')

function removeDir(dir) {
  if (!fs.existsSync(dir)) return

  const files = fs.readdirSync(dir)
  for (const file of files) {
    const filePath = path.join(dir, file)
    const stat = fs.statSync(filePath)

    if (stat.isDirectory()) {
      removeDir(filePath)
    } else {
      fs.unlinkSync(filePath)
    }
  }

  fs.rmdirSync(dir)
}

async function cleanup() {
  if (fs.existsSync(TEST_DIR)) {
    // Remove test directory
    removeDir(TEST_DIR)
  }
}

async function cleanupStorage() {
  // Close storage first
  try {
    await closeStorage()
  } catch (err) {
    // Ignore
  }

  // Wait a bit for cleanup
  await new Promise(resolve => setTimeout(resolve, 500))

  // Remove directory
  await cleanup()
}

async function runTests() {
  console.log('🧪 Testing Phase 5.3 Implementation\n')

  let testsPassed = 0
  let testsFailed = 0

  try {
    // Clean up first
    await cleanup()

    // Test 1: Identity generation
    console.log('Test 1: Generate identity')
    const mnemonic = IdentityKey.generateMnemonic()
    const identity = await IdentityKey.from({ mnemonic })
    console.log('✅ Identity generated\n')
    testsPassed++

    // Test 2: Initialize storage
    console.log('Test 2: Initialize storage with Hyperswarm')
    const { store, autobase, txHistoryDb, swarm } = await initializeStorage(identity)
    console.log('✅ Storage initialized')
    console.log(`   Store ready: ${store !== null}`)
    console.log(`   Autobase ready: ${autobase !== null}`)
    console.log(`   Swarm ready: ${swarm !== null}\n`)
    testsPassed++

    // Test 3: Bootstrap device
    console.log('Test 3: Bootstrap device')
    const device = await bootstrapDevice(identity, 'Test Device')
    console.log('✅ Device bootstrapped')
    console.log(`   Name: ${device.name}`)
    console.log(`   IsLocal: ${device.isLocal}\n`)
    testsPassed++

    // Test 4: Get current device
    console.log('Test 4: Get current device')
    const currentDevice = getCurrentDevice()
    if (currentDevice) {
      console.log('✅ Current device retrieved')
      console.log(`   Name: ${currentDevice.name}`)
      console.log(`   IsLocal: ${currentDevice.isLocal}\n`)
      testsPassed++
    } else {
      console.log('❌ Current device not found\n')
      testsFailed++
    }

    // Test 5: List devices
    console.log('Test 5: List devices')
    const devices = listDevices()
    if (devices.length === 1) {
      console.log(`✅ Found ${devices.length} device(s)`)
      console.log(`   Device: ${devices[0].name}\n`)
      testsPassed++
    } else {
      console.log(`❌ Expected 1 device, found ${devices.length}\n`)
      testsFailed++
    }

    // Test 6: Create invite
    console.log('Test 6: Create invite')
    const invite = await createInvite(identity)
    if (invite && invite.length > 100) {
      console.log('✅ Invite created')
      console.log(`   Length: ${invite.length} characters`)

      // Verify invite can be decoded
      const b4a = require('b4a')
      const inviteJson = b4a.toString(b4a.from(invite, 'base64'))
      const inviteData = JSON.parse(inviteJson)

      console.log(`   Has discoveryKey: ${!!inviteData.discoveryKey}`)
      console.log(`   Has identityKey: ${!!inviteData.identityKey}`)
      console.log(`   Has autobaseKey: ${!!inviteData.autobaseKey}\n`)
      testsPassed++
    } else {
      console.log('❌ Invite creation failed\n')
      testsFailed++
    }

    // Test 7: Get connection status
    console.log('Test 7: Get connection status')
    const status = getConnectionStatus()
    console.log('✅ Connection status retrieved')
    console.log(`   Connected: ${status.connected}`)
    console.log(`   Peer count: ${status.count}`)
    console.log(`   (Expected 0 peers since this is single-device test)\n`)
    testsPassed++

    // Clean up
    console.log('Cleaning up...')
    await cleanupStorage()
    console.log('✅ Cleanup complete\n')

    // Summary
    console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━')
    console.log(`Tests Passed: ${testsPassed}`)
    console.log(`Tests Failed: ${testsFailed}`)
    console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n')

    if (testsFailed === 0) {
      console.log('✅ All Phase 5.3 tests passed!')
      console.log('')
      console.log('Next steps:')
      console.log('  1. Test multi-device flow (tabertron + ashatron)')
      console.log('  2. Verify Hyperswarm discovery works')
      console.log('  3. Test automatic writer addition')
      console.log('')
      process.exit(0)
    } else {
      console.log('❌ Some tests failed. Review implementation.')
      console.log('')
      process.exit(1)
    }

  } catch (err) {
    console.error('')
    console.error('❌ Test error:', err.message)
    if (process.env.DEBUG) {
      console.error('')
      console.error('Stack trace:')
      console.error(err.stack)
    }
    console.error('')

    // Try to clean up
    try {
      await cleanupStorage()
    } catch (cleanupErr) {
      // Ignore cleanup errors
    }

    process.exit(1)
  }
}

runTests()