Files
plebeian-signer/projects/common/src/lib/domain/value-objects/nostr-keypair.spec.ts
woikos d98a0ef76e Implement DDD refactoring phases 1-4 with domain layer and ubiquitous language
Phase 1-3: Domain Layer Foundation
- Add value objects: IdentityId, PermissionId, RelayId, WalletId, Nickname, NostrKeyPair
- Add rich domain entities: Identity, Permission, Relay with behavior
- Add domain events: IdentityCreated, IdentityRenamed, IdentitySelected, etc.
- Add repository interfaces for Identity, Permission, Relay
- Add infrastructure layer with repository implementations
- Add EncryptionService abstraction

Phase 4: Ubiquitous Language Cleanup
- Rename BrowserSyncData → EncryptedVault (encrypted vault storage)
- Rename BrowserSessionData → VaultSession (decrypted session state)
- Rename SignerMetaData → ExtensionSettings (extension configuration)
- Rename Identity_ENCRYPTED → StoredIdentity (storage DTO)
- Rename Identity_DECRYPTED → IdentityData (session DTO)
- Similar renames for Permission, Relay, NwcConnection, CashuMint
- Add backwards compatibility aliases with @deprecated markers

Test Coverage
- Add comprehensive tests for all value objects
- Add tests for domain entities and their behavior
- Add tests for domain events
- Fix PermissionChecker to prioritize kind-specific rules over blanket rules
- Fix pre-existing component test issues (IconButton, Pubkey)

All 113 tests pass. Both Chrome and Firefox builds succeed.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-25 05:21:44 +01:00

92 lines
3.0 KiB
TypeScript

import { NostrKeyPair, InvalidNostrKeyError } from './nostr-keypair';
describe('NostrKeyPair Value Object', () => {
// Known test vectors
const TEST_PRIVATE_KEY_HEX = '0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef';
describe('generate', () => {
it('should generate a valid keypair', () => {
const keyPair = NostrKeyPair.generate();
expect(keyPair.publicKeyHex).toBeTruthy();
expect(keyPair.publicKeyHex.length).toBe(64);
});
it('should generate unique keypairs each time', () => {
const keyPair1 = NostrKeyPair.generate();
const keyPair2 = NostrKeyPair.generate();
expect(keyPair1.publicKeyHex).not.toEqual(keyPair2.publicKeyHex);
});
});
describe('fromPrivateKey', () => {
it('should create keypair from valid hex private key', () => {
const keyPair = NostrKeyPair.fromPrivateKey(TEST_PRIVATE_KEY_HEX);
expect(keyPair.publicKeyHex).toBeTruthy();
expect(keyPair.publicKeyHex.length).toBe(64);
});
it('should throw InvalidNostrKeyError for empty string', () => {
expect(() => NostrKeyPair.fromPrivateKey('')).toThrowError(InvalidNostrKeyError);
});
it('should throw InvalidNostrKeyError for invalid hex', () => {
expect(() => NostrKeyPair.fromPrivateKey('not-valid-hex')).toThrowError(InvalidNostrKeyError);
});
it('should throw InvalidNostrKeyError for hex that is too short', () => {
const shortHex = '0123456789abcdef';
expect(() => NostrKeyPair.fromPrivateKey(shortHex)).toThrowError(InvalidNostrKeyError);
});
});
describe('public key formats', () => {
it('should return hex public key', () => {
const keyPair = NostrKeyPair.fromPrivateKey(TEST_PRIVATE_KEY_HEX);
expect(keyPair.publicKeyHex).toMatch(/^[0-9a-f]{64}$/);
});
it('should return npub format', () => {
const keyPair = NostrKeyPair.fromPrivateKey(TEST_PRIVATE_KEY_HEX);
expect(keyPair.npub).toMatch(/^npub1[a-z0-9]+$/);
});
it('should return nsec format', () => {
const keyPair = NostrKeyPair.fromPrivateKey(TEST_PRIVATE_KEY_HEX);
expect(keyPair.nsec).toMatch(/^nsec1[a-z0-9]+$/);
});
});
describe('getPrivateKeyBytes', () => {
it('should return 32-byte Uint8Array', () => {
const keyPair = NostrKeyPair.fromPrivateKey(TEST_PRIVATE_KEY_HEX);
const bytes = keyPair.getPrivateKeyBytes();
expect(bytes).toBeInstanceOf(Uint8Array);
expect(bytes.length).toBe(32);
});
});
describe('toStorageHex', () => {
it('should return the hex private key for storage', () => {
const keyPair = NostrKeyPair.fromPrivateKey(TEST_PRIVATE_KEY_HEX);
expect(keyPair.toStorageHex()).toEqual(TEST_PRIVATE_KEY_HEX);
});
});
describe('deterministic derivation', () => {
it('should derive the same public key from the same private key', () => {
const keyPair1 = NostrKeyPair.fromPrivateKey(TEST_PRIVATE_KEY_HEX);
const keyPair2 = NostrKeyPair.fromPrivateKey(TEST_PRIVATE_KEY_HEX);
expect(keyPair1.publicKeyHex).toEqual(keyPair2.publicKeyHex);
});
});
});