Files
alkvault/tests/service_tests.rs
glm-5.2 110146870a Rebrand alknet-vault -> alkvault
Rename the crate from alknet-vault to alkvault across source and docs:
- Cargo.toml: package name and lib name (alknet_vault -> alkvault)
- src/ doc comments and doc-test use statements
- tests/ use statements and one string literal

Convert references to non-vault alknet ADRs (003, 005, 008, 010, 014,
064) that were broken local links into @alkdev/alknet: cross-repo
references, matching the alktype sibling pattern. Local ADR/OQ
references are now proper links. Rewrote monorepo path references
(crates/alknet-vault/src/...) to the flat layout (src/...). Fixed
sdd_process.md package name (@alkdev/storage -> @alkdev/alkvault).

ADR/OQ renumbering is deferred to a subsequent pass per the alknet-
origin numbering convention. Generic prose 'vault' and type names
(VaultServiceHandle, VaultServiceError, etc.) are unchanged.

Build, 108 tests, and clippy all pass clean.
2026-08-02 09:25:43 +00:00

99 lines
2.8 KiB
Rust

//! Integration tests for the VaultService lifecycle.
//!
//! These tests verify the unlock/lock lifecycle, error conditions,
//! and that the vault correctly manages state transitions.
use alkvault::derivation::PATHS;
use alkvault::service::{VaultServiceError, VaultServiceHandle};
#[test]
fn test_full_lifecycle() {
let service = VaultServiceHandle::new();
// Starts locked
assert!(!service.is_unlocked());
// Can't derive while locked
let result = service.derive_ed25519(PATHS::IDENTITY);
assert!(matches!(result, Err(VaultServiceError::VaultLocked)));
// Unlock
let phrase = service.unlock_new(24).unwrap();
assert!(service.is_unlocked());
assert!(!phrase.is_empty());
// Can derive while unlocked
let key = service.derive_ed25519(PATHS::IDENTITY).unwrap();
assert!(!key.private_key.is_empty());
// Lock
service.lock();
assert!(!service.is_unlocked());
// Can't derive again
let result = service.derive_ed25519(PATHS::IDENTITY);
assert!(matches!(result, Err(VaultServiceError::VaultLocked)));
}
#[test]
fn test_unlock_with_known_phrase() {
let service = VaultServiceHandle::new();
// Generate a phrase
let phrase = service.unlock_new(24).unwrap();
service.lock();
// Re-unlock with the same phrase
service.unlock(&phrase, None).unwrap();
assert!(service.is_unlocked());
// Different passphrase produces different seed
// (tested by deriving keys with different passphrases)
}
#[test]
fn test_double_unlock_fails() {
let service = VaultServiceHandle::new();
service.unlock_new(24).unwrap();
let result = service.unlock_new(12);
assert!(matches!(result, Err(VaultServiceError::AlreadyUnlocked)));
}
#[test]
fn test_lock_when_already_locked_is_noop() {
let service = VaultServiceHandle::new();
assert!(!service.is_unlocked());
// Lock on already-locked service is a no-op
service.lock();
assert!(!service.is_unlocked());
}
#[test]
fn test_encrypt_decrypt_lifecycle() {
let service = VaultServiceHandle::new();
service.unlock_new(24).unwrap();
let plaintext = "my-api-key-12345";
let encrypted = service.encrypt(plaintext, 2).unwrap();
let decrypted = service.decrypt(&encrypted).unwrap();
assert_eq!(decrypted, plaintext);
// After lock, can't decrypt
service.lock();
let result = service.decrypt(&encrypted);
assert!(matches!(result, Err(VaultServiceError::VaultLocked)));
}
#[test]
fn test_multiple_derive_paths_succeed() {
let service = VaultServiceHandle::new();
service.unlock_new(24).unwrap();
// All standard paths should work
let _identity = service.derive_ed25519(PATHS::IDENTITY).unwrap();
let _ssh = service.derive_ed25519(PATHS::SSH_HOST).unwrap();
let _enc = service.derive_encryption_key(PATHS::ENCRYPTION).unwrap();
}