## tests/test_nippels_cli.nim ## Comprehensive tests for Nippels CLI commands import std/[unittest, os, strformat, options, tables] import ../src/nimpak/[nippels, nippels_cli, nippel_types, profile_manager] # Test setup const testRoot = "/tmp/nippels_cli_test" proc setupTest(): NippelManager = if dirExists(testRoot): removeDir(testRoot) createDir(testRoot) result = newNippelManager(testRoot) proc teardownTest() = if dirExists(testRoot): removeDir(testRoot) suite "Nippels CLI Commands": setup: var manager {.used.} = setupTest() teardown: teardownTest() # ========================================================================== # Test: nip cell create # ========================================================================== test "cmdCellCreate - basic creation": let opts = CreateOptions( name: "test-cell", profile: SecurityProfile.Homestation, isolation: IsolationLevel.Standard, overrides: ProfileOverrides(), description: "Test cell" ) let exitCode = cmdCellCreate(manager, opts) check exitCode == 0 let nippel = manager.getNippel("test-cell") check nippel.isSome check nippel.get.name == "test-cell" check nippel.get.profile == SecurityProfile.Homestation test "cmdCellCreate - with custom profile": let opts = CreateOptions( name: "workstation-cell", profile: SecurityProfile.Workstation, isolation: IsolationLevel.Strict, overrides: ProfileOverrides(), description: "Workstation test" ) let exitCode = cmdCellCreate(manager, opts) check exitCode == 0 let nippel = manager.getNippel("workstation-cell") check nippel.isSome check nippel.get.profile == SecurityProfile.Workstation check nippel.get.isolationLevel == IsolationLevel.Strict test "cmdCellCreate - with profile overrides": var overrides = ProfileOverrides() overrides.isolationLevel = some(IsolationLevel.None) overrides.networkAccess = some(NetworkAccessLevel.NoNetwork) let opts = CreateOptions( name: "custom-cell", profile: SecurityProfile.Homestation, isolation: IsolationLevel.Standard, overrides: overrides, description: "Custom overrides" ) let exitCode = cmdCellCreate(manager, opts) check exitCode == 0 let nippel = manager.getNippel("custom-cell") check nippel.isSome check nippel.get.isolationLevel == IsolationLevel.None check nippel.get.profileSettings.networkAccess == NetworkAccessLevel.NoNetwork test "cmdCellCreate - duplicate name fails": let opts1 = CreateOptions( name: "duplicate", profile: SecurityProfile.Homestation, isolation: IsolationLevel.Standard, overrides: ProfileOverrides(), description: "First" ) check cmdCellCreate(manager, opts1) == 0 let opts2 = CreateOptions( name: "duplicate", profile: SecurityProfile.Homestation, isolation: IsolationLevel.Standard, overrides: ProfileOverrides(), description: "Second" ) check cmdCellCreate(manager, opts2) != 0 # ========================================================================== # Test: nip cell list # ========================================================================== test "cmdCellList - empty list": let exitCode = cmdCellList(manager, verbose = false) check exitCode == 0 test "cmdCellList - with cells": # Create some cells discard manager.createNippel("cell1", SecurityProfile.Homestation, ProfileOverrides()) discard manager.createNippel("cell2", SecurityProfile.Workstation, ProfileOverrides()) discard manager.createNippel("cell3", SecurityProfile.Server, ProfileOverrides()) let exitCode = cmdCellList(manager, verbose = false) check exitCode == 0 let nippels = manager.listNippels() check nippels.len == 3 test "cmdCellList - verbose mode": discard manager.createNippel("verbose-cell", SecurityProfile.Homestation, ProfileOverrides()) let exitCode = cmdCellList(manager, verbose = true) check exitCode == 0 test "cmdCellList - shows active status": discard manager.createNippel("active-cell", SecurityProfile.Homestation, ProfileOverrides()) discard manager.activateNippel("active-cell") let exitCode = cmdCellList(manager, verbose = false) check exitCode == 0 check manager.isNippelActive("active-cell") # ========================================================================== # Test: nip cell activate/deactivate # ========================================================================== test "cmdCellActivate - successful activation": discard manager.createNippel("activate-test", SecurityProfile.Homestation, ProfileOverrides()) let exitCode = cmdCellActivate(manager, "activate-test") check exitCode == 0 check manager.isNippelActive("activate-test") test "cmdCellActivate - nonexistent cell fails": let exitCode = cmdCellActivate(manager, "nonexistent") check exitCode != 0 test "cmdCellDeactivate - successful deactivation": discard manager.createNippel("deactivate-test", SecurityProfile.Homestation, ProfileOverrides()) discard manager.activateNippel("deactivate-test") check manager.isNippelActive("deactivate-test") let exitCode = cmdCellDeactivate(manager, "deactivate-test") check exitCode == 0 check not manager.isNippelActive("deactivate-test") test "cmdCellDeactivate - nonexistent cell fails": let exitCode = cmdCellDeactivate(manager, "nonexistent") check exitCode != 0 test "cmdCellDeactivate - inactive cell fails": discard manager.createNippel("inactive-test", SecurityProfile.Homestation, ProfileOverrides()) let exitCode = cmdCellDeactivate(manager, "inactive-test") check exitCode != 0 # ========================================================================== # Test: nip cell profile list # ========================================================================== test "cmdCellProfileList - shows all profiles": let exitCode = cmdCellProfileList() check exitCode == 0 # ========================================================================== # Test: nip cell profile show # ========================================================================== test "cmdCellProfileShow - shows profile settings": discard manager.createNippel("profile-show-test", SecurityProfile.Workstation, ProfileOverrides()) let exitCode = cmdCellProfileShow(manager, "profile-show-test") check exitCode == 0 test "cmdCellProfileShow - nonexistent cell fails": let exitCode = cmdCellProfileShow(manager, "nonexistent") check exitCode != 0 # ========================================================================== # Test: nip cell profile set # ========================================================================== test "cmdCellProfileSet - changes profile": discard manager.createNippel("profile-set-test", SecurityProfile.Homestation, ProfileOverrides()) let exitCode = cmdCellProfileSet(manager, "profile-set-test", SecurityProfile.Server) check exitCode == 0 let nippel = manager.getNippel("profile-set-test") check nippel.isSome check nippel.get.profile == SecurityProfile.Server test "cmdCellProfileSet - nonexistent cell fails": let exitCode = cmdCellProfileSet(manager, "nonexistent", SecurityProfile.Server) check exitCode != 0 # ========================================================================== # Test: nip cell verify # ========================================================================== test "cmdCellVerify - verifies merkle tree": discard manager.createNippel("verify-test", SecurityProfile.Homestation, ProfileOverrides()) let exitCode = cmdCellVerify(manager, "verify-test") check exitCode == 0 test "cmdCellVerify - nonexistent cell fails": let exitCode = cmdCellVerify(manager, "nonexistent") check exitCode != 0 test "cmdCellVerify - no merkle tree warning": discard manager.createNippel("no-merkle-test", SecurityProfile.Homestation, ProfileOverrides()) # Remove merkle tree del(manager.merkleTrees, "no-merkle-test") let exitCode = cmdCellVerify(manager, "no-merkle-test") check exitCode == 2 # Warning code # ========================================================================== # Test: nip cell query # ========================================================================== test "cmdCellQuery - queries nippel state": discard manager.createNippel("query-test", SecurityProfile.Homestation, ProfileOverrides()) let nippel = manager.getNippel("query-test").get let address = formatUTCPAddress(nippel.utcpAddress) let exitCode = cmdCellQuery(manager, address) check exitCode == 0 test "cmdCellQuery - queries merkle tree": discard manager.createNippel("query-merkle-test", SecurityProfile.Homestation, ProfileOverrides()) let nippel = manager.getNippel("query-merkle-test").get let address = formatUTCPAddress(nippel.utcpAddress) & "/merkle" let exitCode = cmdCellQuery(manager, address) check exitCode == 0 test "cmdCellQuery - queries profile": discard manager.createNippel("query-profile-test", SecurityProfile.Workstation, ProfileOverrides()) let nippel = manager.getNippel("query-profile-test").get let address = formatUTCPAddress(nippel.utcpAddress) & "/profile" let exitCode = cmdCellQuery(manager, address) check exitCode == 0 test "cmdCellQuery - invalid address fails": let exitCode = cmdCellQuery(manager, "invalid-address") check exitCode != 0 test "cmdCellQuery - nonexistent nippel fails": let exitCode = cmdCellQuery(manager, "utcp://localhost/nippel/nonexistent") check exitCode != 0 # ========================================================================== # Test: nip cell info # ========================================================================== test "cmdCellInfo - shows detailed information": discard manager.createNippel("info-test", SecurityProfile.Workstation, ProfileOverrides()) let exitCode = cmdCellInfo(manager, "info-test") check exitCode == 0 test "cmdCellInfo - nonexistent cell fails": let exitCode = cmdCellInfo(manager, "nonexistent") check exitCode != 0 test "cmdCellInfo - shows active status": discard manager.createNippel("info-active-test", SecurityProfile.Homestation, ProfileOverrides()) discard manager.activateNippel("info-active-test") let exitCode = cmdCellInfo(manager, "info-active-test") check exitCode == 0 check manager.isNippelActive("info-active-test") # ========================================================================== # Test: nip cell delete # ========================================================================== test "cmdCellDelete - deletes inactive cell": discard manager.createNippel("delete-test", SecurityProfile.Homestation, ProfileOverrides()) let exitCode = cmdCellDelete(manager, "delete-test", force = false) check exitCode == 0 let nippel = manager.getNippel("delete-test") check nippel.isNone test "cmdCellDelete - fails on active cell without force": discard manager.createNippel("delete-active-test", SecurityProfile.Homestation, ProfileOverrides()) discard manager.activateNippel("delete-active-test") let exitCode = cmdCellDelete(manager, "delete-active-test", force = false) check exitCode != 0 # Cell should still exist let nippel = manager.getNippel("delete-active-test") check nippel.isSome test "cmdCellDelete - force deletes active cell": discard manager.createNippel("delete-force-test", SecurityProfile.Homestation, ProfileOverrides()) discard manager.activateNippel("delete-force-test") let exitCode = cmdCellDelete(manager, "delete-force-test", force = true) check exitCode == 0 let nippel = manager.getNippel("delete-force-test") check nippel.isNone test "cmdCellDelete - nonexistent cell fails": let exitCode = cmdCellDelete(manager, "nonexistent", force = false) check exitCode != 0 # ========================================================================== # Test: Integration scenarios # ========================================================================== test "Full workflow - create, activate, verify, deactivate, delete": # Create let createOpts = CreateOptions( name: "workflow-test", profile: SecurityProfile.Workstation, isolation: IsolationLevel.Strict, overrides: ProfileOverrides(), description: "Full workflow test" ) check cmdCellCreate(manager, createOpts) == 0 # Activate check cmdCellActivate(manager, "workflow-test") == 0 check manager.isNippelActive("workflow-test") # Verify check cmdCellVerify(manager, "workflow-test") == 0 # Query let nippel = manager.getNippel("workflow-test").get let address = formatUTCPAddress(nippel.utcpAddress) check cmdCellQuery(manager, address) == 0 # Info check cmdCellInfo(manager, "workflow-test") == 0 # Deactivate check cmdCellDeactivate(manager, "workflow-test") == 0 check not manager.isNippelActive("workflow-test") # Delete check cmdCellDelete(manager, "workflow-test", force = false) == 0 check manager.getNippel("workflow-test").isNone test "Multiple cells workflow": # Create multiple cells with different profiles let profiles = [ ("home", SecurityProfile.Homestation), ("work", SecurityProfile.Workstation), ("server", SecurityProfile.Server) ] for (name, profile) in profiles: let opts = CreateOptions( name: name, profile: profile, isolation: IsolationLevel.Standard, overrides: ProfileOverrides(), description: fmt"Test {name}" ) check cmdCellCreate(manager, opts) == 0 # List all check cmdCellList(manager, verbose = false) == 0 check manager.listNippels().len == 3 # Activate one check cmdCellActivate(manager, "work") == 0 # Verify all for (name, _) in profiles: check cmdCellVerify(manager, name) == 0 # Change profile check cmdCellProfileSet(manager, "home", SecurityProfile.Satellite) == 0 # Deactivate check cmdCellDeactivate(manager, "work") == 0 # Delete all for (name, _) in profiles: check cmdCellDelete(manager, name, force = false) == 0 check manager.listNippels().len == 0 echo "✓ All Nippels CLI tests completed"