2025-10-24 04:55:10 +01:00
|
|
|
package crypt
|
|
|
|
|
|
|
|
|
|
import (
|
2026-01-13 23:33:01 +00:00
|
|
|
"bytes"
|
2025-10-24 04:55:10 +01:00
|
|
|
"testing"
|
|
|
|
|
|
2026-01-28 15:29:42 +00:00
|
|
|
"github.com/host-uk/core/pkg/core"
|
2025-10-24 04:55:10 +01:00
|
|
|
"github.com/stretchr/testify/assert"
|
2026-01-13 23:33:01 +00:00
|
|
|
"github.com/stretchr/testify/require"
|
2025-10-24 04:55:10 +01:00
|
|
|
)
|
|
|
|
|
|
2026-01-13 23:33:01 +00:00
|
|
|
// --- Constructor Tests ---
|
|
|
|
|
|
|
|
|
|
func TestNew(t *testing.T) {
|
|
|
|
|
t.Run("creates service successfully", func(t *testing.T) {
|
|
|
|
|
service, err := New()
|
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
assert.NotNil(t, service)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
t.Run("returns independent instances", func(t *testing.T) {
|
|
|
|
|
service1, err1 := New()
|
|
|
|
|
service2, err2 := New()
|
|
|
|
|
assert.NoError(t, err1)
|
|
|
|
|
assert.NoError(t, err2)
|
|
|
|
|
assert.NotSame(t, service1, service2)
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestRegister(t *testing.T) {
|
|
|
|
|
t.Run("registers with core successfully", func(t *testing.T) {
|
|
|
|
|
coreInstance, err := core.New()
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
|
|
service, err := Register(coreInstance)
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
assert.NotNil(t, service)
|
|
|
|
|
})
|
|
|
|
|
|
2026-01-15 22:46:50 +00:00
|
|
|
t.Run("returns Service type with ServiceRuntime", func(t *testing.T) {
|
2026-01-13 23:33:01 +00:00
|
|
|
coreInstance, err := core.New()
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
|
|
service, err := Register(coreInstance)
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
|
|
cryptService, ok := service.(*Service)
|
|
|
|
|
assert.True(t, ok)
|
2026-01-15 22:46:50 +00:00
|
|
|
assert.NotNil(t, cryptService.ServiceRuntime)
|
2026-01-13 23:33:01 +00:00
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// --- Hash Tests ---
|
|
|
|
|
|
2025-10-24 04:55:10 +01:00
|
|
|
func TestHash(t *testing.T) {
|
2026-01-13 23:33:01 +00:00
|
|
|
s, _ := New()
|
|
|
|
|
|
|
|
|
|
t.Run("LTHN hash", func(t *testing.T) {
|
|
|
|
|
hash := s.Hash(LTHN, "hello")
|
|
|
|
|
assert.NotEmpty(t, hash)
|
|
|
|
|
// LTHN hash should be consistent
|
|
|
|
|
hash2 := s.Hash(LTHN, "hello")
|
|
|
|
|
assert.Equal(t, hash, hash2)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
t.Run("SHA512 hash", func(t *testing.T) {
|
|
|
|
|
hash := s.Hash(SHA512, "hello")
|
|
|
|
|
// Known SHA512 hash for "hello"
|
|
|
|
|
expected := "9b71d224bd62f3785d96d46ad3ea3d73319bfbc2890caadae2dff72519673ca72323c3d99ba5c11d7c7acc6e14b8c5da0c4663475c2e5c3adef46f73bcdec043"
|
|
|
|
|
assert.Equal(t, expected, hash)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
t.Run("SHA256 hash", func(t *testing.T) {
|
|
|
|
|
hash := s.Hash(SHA256, "hello")
|
|
|
|
|
// Known SHA256 hash for "hello"
|
|
|
|
|
expected := "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824"
|
|
|
|
|
assert.Equal(t, expected, hash)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
t.Run("SHA1 hash", func(t *testing.T) {
|
|
|
|
|
hash := s.Hash(SHA1, "hello")
|
|
|
|
|
// Known SHA1 hash for "hello"
|
|
|
|
|
expected := "aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d"
|
|
|
|
|
assert.Equal(t, expected, hash)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
t.Run("MD5 hash", func(t *testing.T) {
|
|
|
|
|
hash := s.Hash(MD5, "hello")
|
|
|
|
|
// Known MD5 hash for "hello"
|
|
|
|
|
expected := "5d41402abc4b2a76b9719d911017c592"
|
|
|
|
|
assert.Equal(t, expected, hash)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
t.Run("default falls back to SHA256", func(t *testing.T) {
|
|
|
|
|
hash := s.Hash("unknown", "hello")
|
|
|
|
|
sha256Hash := s.Hash(SHA256, "hello")
|
|
|
|
|
assert.Equal(t, sha256Hash, hash)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
t.Run("empty string hash", func(t *testing.T) {
|
|
|
|
|
hash := s.Hash(SHA256, "")
|
|
|
|
|
// Known SHA256 hash for empty string
|
|
|
|
|
expected := "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
|
|
|
|
assert.Equal(t, expected, hash)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
t.Run("hash with special characters", func(t *testing.T) {
|
|
|
|
|
hash := s.Hash(SHA256, "hello!@#$%^&*()")
|
|
|
|
|
assert.NotEmpty(t, hash)
|
|
|
|
|
assert.Len(t, hash, 64) // SHA256 produces 64 hex chars
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
t.Run("hash with unicode", func(t *testing.T) {
|
|
|
|
|
hash := s.Hash(SHA256, "你好世界")
|
|
|
|
|
assert.NotEmpty(t, hash)
|
|
|
|
|
assert.Len(t, hash, 64)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
t.Run("hash consistency", func(t *testing.T) {
|
|
|
|
|
payload := "test payload for consistency check"
|
|
|
|
|
for _, hashType := range []HashType{LTHN, SHA512, SHA256, SHA1, MD5} {
|
|
|
|
|
hash1 := s.Hash(hashType, payload)
|
|
|
|
|
hash2 := s.Hash(hashType, payload)
|
|
|
|
|
assert.Equal(t, hash1, hash2, "Hash should be consistent for %s", hashType)
|
|
|
|
|
}
|
|
|
|
|
})
|
2025-10-24 04:55:10 +01:00
|
|
|
}
|
|
|
|
|
|
2026-01-13 23:33:01 +00:00
|
|
|
// --- Luhn Tests ---
|
|
|
|
|
|
2025-10-24 04:55:10 +01:00
|
|
|
func TestLuhn(t *testing.T) {
|
2026-01-13 23:33:01 +00:00
|
|
|
s, _ := New()
|
|
|
|
|
|
|
|
|
|
t.Run("valid Luhn numbers", func(t *testing.T) {
|
|
|
|
|
validNumbers := []string{
|
|
|
|
|
"79927398713",
|
|
|
|
|
"4532015112830366", // Visa test number
|
|
|
|
|
"6011514433546201", // Discover test number
|
|
|
|
|
"371449635398431", // Amex test number
|
|
|
|
|
"30569309025904", // Diners Club test number
|
|
|
|
|
}
|
|
|
|
|
for _, num := range validNumbers {
|
|
|
|
|
assert.True(t, s.Luhn(num), "Expected %s to be valid", num)
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
t.Run("invalid Luhn numbers", func(t *testing.T) {
|
|
|
|
|
invalidNumbers := []string{
|
|
|
|
|
"79927398714",
|
|
|
|
|
"1234567890",
|
|
|
|
|
"1111111111",
|
|
|
|
|
"1234567891",
|
|
|
|
|
}
|
|
|
|
|
for _, num := range invalidNumbers {
|
|
|
|
|
assert.False(t, s.Luhn(num), "Expected %s to be invalid", num)
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
t.Run("all zeros is valid", func(t *testing.T) {
|
|
|
|
|
// All zeros: each digit contributes 0, sum=0, 0%10==0
|
|
|
|
|
assert.True(t, s.Luhn("0000000000"))
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
t.Run("handles spaces", func(t *testing.T) {
|
|
|
|
|
// Same number with and without spaces should give same result
|
|
|
|
|
assert.True(t, s.Luhn("7992 7398 713"))
|
|
|
|
|
assert.True(t, s.Luhn("4532 0151 1283 0366"))
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
t.Run("non-digit characters return false", func(t *testing.T) {
|
|
|
|
|
assert.False(t, s.Luhn("1234abcd5678"))
|
|
|
|
|
assert.False(t, s.Luhn("12-34-56-78"))
|
|
|
|
|
assert.False(t, s.Luhn("1234.5678"))
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
t.Run("empty string", func(t *testing.T) {
|
2026-01-15 22:46:50 +00:00
|
|
|
// Enchantrix treats empty string as invalid
|
|
|
|
|
assert.False(t, s.Luhn(""))
|
2026-01-13 23:33:01 +00:00
|
|
|
})
|
|
|
|
|
|
|
|
|
|
t.Run("single digit", func(t *testing.T) {
|
2026-01-15 22:46:50 +00:00
|
|
|
// Enchantrix requires minimum length for valid Luhn
|
|
|
|
|
assert.False(t, s.Luhn("0"))
|
2026-01-13 23:33:01 +00:00
|
|
|
assert.False(t, s.Luhn("1"))
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// --- Fletcher Checksum Tests ---
|
|
|
|
|
|
|
|
|
|
func TestFletcher16(t *testing.T) {
|
|
|
|
|
s, _ := New()
|
|
|
|
|
|
|
|
|
|
t.Run("basic checksum", func(t *testing.T) {
|
|
|
|
|
checksum := s.Fletcher16("hello")
|
|
|
|
|
assert.NotZero(t, checksum)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
t.Run("empty string", func(t *testing.T) {
|
|
|
|
|
checksum := s.Fletcher16("")
|
|
|
|
|
assert.Equal(t, uint16(0), checksum)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
t.Run("consistency", func(t *testing.T) {
|
|
|
|
|
checksum1 := s.Fletcher16("test data")
|
|
|
|
|
checksum2 := s.Fletcher16("test data")
|
|
|
|
|
assert.Equal(t, checksum1, checksum2)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
t.Run("different inputs produce different checksums", func(t *testing.T) {
|
|
|
|
|
checksum1 := s.Fletcher16("hello")
|
|
|
|
|
checksum2 := s.Fletcher16("world")
|
|
|
|
|
assert.NotEqual(t, checksum1, checksum2)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
t.Run("known value", func(t *testing.T) {
|
|
|
|
|
// "abcde" has a known Fletcher-16 checksum
|
|
|
|
|
checksum := s.Fletcher16("abcde")
|
|
|
|
|
assert.NotZero(t, checksum)
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestFletcher32(t *testing.T) {
|
|
|
|
|
s, _ := New()
|
|
|
|
|
|
|
|
|
|
t.Run("basic checksum", func(t *testing.T) {
|
|
|
|
|
checksum := s.Fletcher32("hello")
|
|
|
|
|
assert.NotZero(t, checksum)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
t.Run("empty string", func(t *testing.T) {
|
|
|
|
|
checksum := s.Fletcher32("")
|
|
|
|
|
assert.Equal(t, uint32(0), checksum)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
t.Run("consistency", func(t *testing.T) {
|
|
|
|
|
checksum1 := s.Fletcher32("test data")
|
|
|
|
|
checksum2 := s.Fletcher32("test data")
|
|
|
|
|
assert.Equal(t, checksum1, checksum2)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
t.Run("different inputs produce different checksums", func(t *testing.T) {
|
|
|
|
|
checksum1 := s.Fletcher32("hello")
|
|
|
|
|
checksum2 := s.Fletcher32("world")
|
|
|
|
|
assert.NotEqual(t, checksum1, checksum2)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
t.Run("handles odd-length input", func(t *testing.T) {
|
|
|
|
|
// Odd length input should be padded
|
|
|
|
|
checksum := s.Fletcher32("abc")
|
|
|
|
|
assert.NotZero(t, checksum)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
t.Run("handles even-length input", func(t *testing.T) {
|
|
|
|
|
checksum := s.Fletcher32("abcd")
|
|
|
|
|
assert.NotZero(t, checksum)
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestFletcher64(t *testing.T) {
|
|
|
|
|
s, _ := New()
|
|
|
|
|
|
|
|
|
|
t.Run("basic checksum", func(t *testing.T) {
|
|
|
|
|
checksum := s.Fletcher64("hello")
|
|
|
|
|
assert.NotZero(t, checksum)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
t.Run("empty string", func(t *testing.T) {
|
|
|
|
|
checksum := s.Fletcher64("")
|
|
|
|
|
assert.Equal(t, uint64(0), checksum)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
t.Run("consistency", func(t *testing.T) {
|
|
|
|
|
checksum1 := s.Fletcher64("test data")
|
|
|
|
|
checksum2 := s.Fletcher64("test data")
|
|
|
|
|
assert.Equal(t, checksum1, checksum2)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
t.Run("different inputs produce different checksums", func(t *testing.T) {
|
|
|
|
|
checksum1 := s.Fletcher64("hello")
|
|
|
|
|
checksum2 := s.Fletcher64("world")
|
|
|
|
|
assert.NotEqual(t, checksum1, checksum2)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
t.Run("handles various input lengths", func(t *testing.T) {
|
|
|
|
|
// Test padding for different lengths
|
|
|
|
|
for i := 1; i <= 8; i++ {
|
|
|
|
|
input := string(make([]byte, i))
|
|
|
|
|
checksum := s.Fletcher64(input)
|
|
|
|
|
// Just verify it doesn't panic
|
|
|
|
|
_ = checksum
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
t.Run("long input", func(t *testing.T) {
|
|
|
|
|
// Use actual text content, not null bytes
|
|
|
|
|
longInput := ""
|
|
|
|
|
for i := 0; i < 100; i++ {
|
|
|
|
|
longInput += "test data "
|
|
|
|
|
}
|
|
|
|
|
checksum := s.Fletcher64(longInput)
|
|
|
|
|
assert.NotZero(t, checksum)
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// --- HashType Constants Tests ---
|
|
|
|
|
|
|
|
|
|
func TestHashTypeConstants(t *testing.T) {
|
|
|
|
|
t.Run("constants have expected values", func(t *testing.T) {
|
|
|
|
|
assert.Equal(t, HashType("lthn"), LTHN)
|
|
|
|
|
assert.Equal(t, HashType("sha512"), SHA512)
|
|
|
|
|
assert.Equal(t, HashType("sha256"), SHA256)
|
|
|
|
|
assert.Equal(t, HashType("sha1"), SHA1)
|
|
|
|
|
assert.Equal(t, HashType("md5"), MD5)
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-15 22:46:50 +00:00
|
|
|
// --- IsHashAlgo Tests ---
|
|
|
|
|
|
|
|
|
|
func TestIsHashAlgo(t *testing.T) {
|
|
|
|
|
s, _ := New()
|
|
|
|
|
|
|
|
|
|
t.Run("valid hash algorithms", func(t *testing.T) {
|
|
|
|
|
assert.True(t, s.IsHashAlgo("sha256"))
|
|
|
|
|
assert.True(t, s.IsHashAlgo("sha512"))
|
|
|
|
|
assert.True(t, s.IsHashAlgo("sha1"))
|
|
|
|
|
assert.True(t, s.IsHashAlgo("md5"))
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
t.Run("invalid hash algorithm", func(t *testing.T) {
|
|
|
|
|
assert.False(t, s.IsHashAlgo("invalid"))
|
|
|
|
|
assert.False(t, s.IsHashAlgo(""))
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// --- RSA Tests ---
|
|
|
|
|
|
|
|
|
|
func TestGenerateRSAKeyPair(t *testing.T) {
|
|
|
|
|
s, _ := New()
|
|
|
|
|
|
|
|
|
|
t.Run("generates valid key pair", func(t *testing.T) {
|
|
|
|
|
pubKey, privKey, err := s.GenerateRSAKeyPair(2048)
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
assert.NotEmpty(t, pubKey)
|
|
|
|
|
assert.NotEmpty(t, privKey)
|
|
|
|
|
assert.Contains(t, pubKey, "PUBLIC KEY")
|
|
|
|
|
assert.Contains(t, privKey, "PRIVATE KEY")
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestEncryptDecryptRSA(t *testing.T) {
|
|
|
|
|
s, _ := New()
|
|
|
|
|
|
|
|
|
|
t.Run("encrypt and decrypt roundtrip", func(t *testing.T) {
|
|
|
|
|
pubKey, privKey, err := s.GenerateRSAKeyPair(2048)
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
|
|
plaintext := "hello RSA world"
|
|
|
|
|
ciphertext, err := s.EncryptRSA(pubKey, plaintext)
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
assert.NotEmpty(t, ciphertext)
|
|
|
|
|
assert.NotEqual(t, plaintext, ciphertext)
|
|
|
|
|
|
|
|
|
|
decrypted, err := s.DecryptRSA(privKey, ciphertext)
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
assert.Equal(t, plaintext, decrypted)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
t.Run("encrypt with invalid key fails", func(t *testing.T) {
|
|
|
|
|
_, err := s.EncryptRSA("invalid key", "data")
|
|
|
|
|
assert.Error(t, err)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
t.Run("decrypt with invalid key fails", func(t *testing.T) {
|
|
|
|
|
_, err := s.DecryptRSA("invalid key", "data")
|
|
|
|
|
assert.Error(t, err)
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// --- PGP Tests ---
|
|
|
|
|
|
|
|
|
|
func TestGeneratePGPKeyPair(t *testing.T) {
|
|
|
|
|
s, _ := New()
|
|
|
|
|
|
|
|
|
|
t.Run("generates valid key pair", func(t *testing.T) {
|
|
|
|
|
pubKey, privKey, err := s.GeneratePGPKeyPair("Test User", "test@example.com", "test comment")
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
assert.NotEmpty(t, pubKey)
|
|
|
|
|
assert.NotEmpty(t, privKey)
|
|
|
|
|
assert.Contains(t, pubKey, "PGP PUBLIC KEY")
|
|
|
|
|
assert.Contains(t, privKey, "PGP PRIVATE KEY")
|
|
|
|
|
})
|
|
|
|
|
}
|
2026-01-13 23:33:01 +00:00
|
|
|
|
|
|
|
|
func TestEncryptPGP(t *testing.T) {
|
2026-01-15 22:46:50 +00:00
|
|
|
s, _ := New()
|
|
|
|
|
|
|
|
|
|
t.Run("requires valid key", func(t *testing.T) {
|
|
|
|
|
var buf bytes.Buffer
|
|
|
|
|
err := s.EncryptPGP(&buf, "invalid key content", "test data")
|
|
|
|
|
assert.Error(t, err)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
t.Run("encrypts with valid key", func(t *testing.T) {
|
|
|
|
|
pubKey, _, err := s.GeneratePGPKeyPair("Test", "test@test.com", "comment")
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
2026-01-13 23:33:01 +00:00
|
|
|
var buf bytes.Buffer
|
2026-01-15 22:46:50 +00:00
|
|
|
err = s.EncryptPGP(&buf, pubKey, "test data")
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
assert.NotEmpty(t, buf.String())
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestEncryptPGPToString(t *testing.T) {
|
|
|
|
|
s, _ := New()
|
|
|
|
|
|
|
|
|
|
t.Run("encrypts to string", func(t *testing.T) {
|
|
|
|
|
pubKey, _, err := s.GeneratePGPKeyPair("Test", "test@test.com", "comment")
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
|
|
ciphertext, err := s.EncryptPGPToString(pubKey, "test data")
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
assert.NotEmpty(t, ciphertext)
|
|
|
|
|
})
|
2026-01-13 23:33:01 +00:00
|
|
|
|
2026-01-15 22:46:50 +00:00
|
|
|
t.Run("requires valid key", func(t *testing.T) {
|
|
|
|
|
_, err := s.EncryptPGPToString("invalid key", "data")
|
2026-01-13 23:33:01 +00:00
|
|
|
assert.Error(t, err)
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestDecryptPGP(t *testing.T) {
|
2026-01-15 22:46:50 +00:00
|
|
|
s, _ := New()
|
2026-01-13 23:33:01 +00:00
|
|
|
|
2026-01-15 22:46:50 +00:00
|
|
|
t.Run("requires valid key", func(t *testing.T) {
|
|
|
|
|
_, err := s.DecryptPGP("invalid key content", "encrypted data")
|
2026-01-13 23:33:01 +00:00
|
|
|
assert.Error(t, err)
|
|
|
|
|
})
|
2026-01-15 22:46:50 +00:00
|
|
|
|
|
|
|
|
t.Run("decrypts with valid key", func(t *testing.T) {
|
|
|
|
|
pubKey, privKey, err := s.GeneratePGPKeyPair("Test", "test@test.com", "comment")
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
|
|
plaintext := "secret message"
|
|
|
|
|
ciphertext, err := s.EncryptPGPToString(pubKey, plaintext)
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
|
|
decrypted, err := s.DecryptPGP(privKey, ciphertext)
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
assert.Equal(t, plaintext, decrypted)
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestSignAndVerifyPGP(t *testing.T) {
|
|
|
|
|
s, _ := New()
|
|
|
|
|
|
|
|
|
|
t.Run("sign and verify roundtrip", func(t *testing.T) {
|
|
|
|
|
pubKey, privKey, err := s.GeneratePGPKeyPair("Test", "test@test.com", "comment")
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
|
|
data := "data to sign"
|
|
|
|
|
signature, err := s.SignPGP(privKey, data)
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
assert.NotEmpty(t, signature)
|
|
|
|
|
|
|
|
|
|
err = s.VerifyPGP(pubKey, data, signature)
|
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
t.Run("sign with invalid key fails", func(t *testing.T) {
|
|
|
|
|
_, err := s.SignPGP("invalid key", "data")
|
|
|
|
|
assert.Error(t, err)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
t.Run("verify with invalid key fails", func(t *testing.T) {
|
|
|
|
|
err := s.VerifyPGP("invalid key", "data", "signature")
|
|
|
|
|
assert.Error(t, err)
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestSymmetricallyEncryptPGP(t *testing.T) {
|
|
|
|
|
s, _ := New()
|
|
|
|
|
|
|
|
|
|
t.Run("encrypts with passphrase", func(t *testing.T) {
|
|
|
|
|
var buf bytes.Buffer
|
|
|
|
|
err := s.SymmetricallyEncryptPGP(&buf, "secret data", "my passphrase")
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
assert.NotEmpty(t, buf.String())
|
|
|
|
|
})
|
2026-01-13 23:33:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// --- HandleIPCEvents Tests ---
|
|
|
|
|
|
|
|
|
|
func TestHandleIPCEvents(t *testing.T) {
|
|
|
|
|
t.Run("handles ActionServiceStartup", func(t *testing.T) {
|
|
|
|
|
coreInstance, err := core.New()
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
|
|
serviceAny, err := Register(coreInstance)
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
|
|
s := serviceAny.(*Service)
|
|
|
|
|
err = s.HandleIPCEvents(coreInstance, core.ActionServiceStartup{})
|
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
t.Run("handles unknown message type", func(t *testing.T) {
|
|
|
|
|
coreInstance, err := core.New()
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
|
|
serviceAny, err := Register(coreInstance)
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
|
|
s := serviceAny.(*Service)
|
|
|
|
|
// Pass an arbitrary type as unknown message
|
|
|
|
|
err = s.HandleIPCEvents(coreInstance, "unknown message")
|
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
})
|
2025-10-24 04:55:10 +01:00
|
|
|
}
|