Merge pull request #35 from Snider/feature-add-good-bad-ugly-tests

Add Good, Bad, and Ugly tests
This commit is contained in:
Snider 2025-11-13 21:31:45 +00:00 committed by GitHub
commit deff3a80c6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 246 additions and 18 deletions

View file

@ -3,6 +3,7 @@ package crypt
import (
"crypto/md5"
"crypto/sha1"
"errors"
"crypto/sha256"
"crypto/sha512"
"encoding/binary"
@ -217,5 +218,8 @@ func (s *Service) VerifyPGP(publicKey, data, signature []byte) error {
// SymmetricallyEncryptPGP encrypts data with a passphrase.
func (s *Service) SymmetricallyEncryptPGP(passphrase, data []byte) ([]byte, error) {
s.ensurePGP()
if len(passphrase) == 0 {
return nil, errors.New("passphrase cannot be empty")
}
return s.pgp.SymmetricallyEncrypt(passphrase, data)
}

View file

@ -6,8 +6,28 @@ import (
"github.com/stretchr/testify/assert"
)
func TestEnsureRSA(t *testing.T) {
// TestEnsureRSA_Good tests that the RSA service is initialized correctly.
func TestEnsureRSA_Good(t *testing.T) {
s := &Service{}
s.ensureRSA()
assert.NotNil(t, s.rsa)
}
// TestEnsureRSA_Bad tests that calling ensureRSA multiple times does not change the RSA service.
func TestEnsureRSA_Bad(t *testing.T) {
s := &Service{}
s.ensureRSA()
rsa1 := s.rsa
s.ensureRSA()
rsa2 := s.rsa
assert.Same(t, rsa1, rsa2)
}
// TestEnsureRSA_Ugly tests that ensureRSA works correctly on a service with a pre-initialized RSA service.
func TestEnsureRSA_Ugly(t *testing.T) {
s := NewService() // NewService initializes the RSA service
rsa1 := s.rsa
s.ensureRSA()
rsa2 := s.rsa
assert.Same(t, rsa1, rsa2)
}

View file

@ -155,6 +155,63 @@ func TestPGP_Good(t *testing.T) {
assert.NotNil(t, ciphertext)
}
func TestPGP_Bad(t *testing.T) {
// Generate two key pairs
pubKey1, privKey1, err := service.GeneratePGPKeyPair("test1", "test1@test.com", "")
assert.NoError(t, err)
pubKey2, privKey2, err := service.GeneratePGPKeyPair("test2", "test2@test.com", "")
assert.NoError(t, err)
message := []byte("secret message")
// Test decryption with the wrong key
ciphertext, err := service.EncryptPGP(pubKey1, message)
assert.NoError(t, err)
// This should fail because we are using the wrong private key.
_, err = service.DecryptPGP(privKey2, ciphertext) // Intentionally using wrong key
assert.Error(t, err)
// Test verification with the wrong key
signature, err := service.SignPGP(privKey1, message)
assert.NoError(t, err)
err = service.VerifyPGP(pubKey2, message, signature)
assert.Error(t, err)
// Test verification with a tampered message
tamperedMessage := []byte("tampered message")
err = service.VerifyPGP(pubKey1, tamperedMessage, signature)
assert.Error(t, err)
}
func TestPGP_Ugly(t *testing.T) {
// Test with malformed keys
_, err := service.EncryptPGP([]byte("not a real key"), []byte("message"))
assert.Error(t, err)
_, err = service.DecryptPGP([]byte("not a real key"), []byte("message"))
assert.Error(t, err)
_, err = service.SignPGP([]byte("not a real key"), []byte("message"))
assert.Error(t, err)
err = service.VerifyPGP([]byte("not a real key"), []byte("message"), []byte("not a real signature"))
assert.Error(t, err)
// Test with empty message
pubKey, privKey, err := service.GeneratePGPKeyPair("test", "test@test.com", "")
assert.NoError(t, err)
message := []byte("")
ciphertext, err := service.EncryptPGP(pubKey, message)
assert.NoError(t, err)
plaintext, err := service.DecryptPGP(privKey, ciphertext, )
assert.NoError(t, err)
assert.Equal(t, message, plaintext)
// Test symmetric encryption with empty passphrase
_, err = service.SymmetricallyEncryptPGP([]byte(""), message)
assert.Error(t, err)
}
// --- IsHashAlgo Tests ---
func TestIsHashAlgo_Good(t *testing.T) {

View file

@ -40,6 +40,21 @@ func TestTransmute_Bad(t *testing.T) {
assert.Error(t, err)
}
func TestTransmute_Ugly(t *testing.T) {
// Test with nil data
_, err := enchantrix.Transmute(nil, []enchantrix.Sigil{&enchantrix.ReverseSigil{}})
assert.NoError(t, err)
// Test with nil sigils
_, err = enchantrix.Transmute([]byte("hello"), nil)
assert.NoError(t, err)
// Test with no sigils
result, err := enchantrix.Transmute([]byte("hello"), []enchantrix.Sigil{})
assert.NoError(t, err)
assert.Equal(t, "hello", string(result))
}
// --- Factory Tests ---
func TestNewSigil_Good(t *testing.T) {
@ -63,3 +78,20 @@ func TestNewSigil_Bad(t *testing.T) {
assert.Nil(t, sigil)
assert.Contains(t, err.Error(), "unknown sigil name")
}
func TestNewSigil_Ugly(t *testing.T) {
// Test with empty string
sigil, err := enchantrix.NewSigil("")
assert.Error(t, err)
assert.Nil(t, sigil)
// Test with whitespace
sigil, err = enchantrix.NewSigil(" ")
assert.Error(t, err)
assert.Nil(t, sigil)
// Test with non-printable characters
sigil, err = enchantrix.NewSigil("\x00\x01\x02")
assert.Error(t, err)
assert.Nil(t, sigil)
}

View file

@ -26,6 +26,9 @@ type ReverseSigil struct{}
// In reverses the bytes of the data.
func (s *ReverseSigil) In(data []byte) ([]byte, error) {
if data == nil {
return nil, nil
}
reversed := make([]byte, len(data))
for i, j := 0, len(data)-1; i < len(data); i, j = i+1, j-1 {
reversed[i] = data[j]
@ -43,6 +46,9 @@ type HexSigil struct{}
// In encodes the data to hexadecimal.
func (s *HexSigil) In(data []byte) ([]byte, error) {
if data == nil {
return nil, nil
}
dst := make([]byte, hex.EncodedLen(len(data)))
hex.Encode(dst, data)
return dst, nil
@ -50,6 +56,9 @@ func (s *HexSigil) In(data []byte) ([]byte, error) {
// Out decodes the data from hexadecimal.
func (s *HexSigil) Out(data []byte) ([]byte, error) {
if data == nil {
return nil, nil
}
dst := make([]byte, hex.DecodedLen(len(data)))
_, err := hex.Decode(dst, data)
return dst, err
@ -60,6 +69,9 @@ type Base64Sigil struct{}
// In encodes the data to base64.
func (s *Base64Sigil) In(data []byte) ([]byte, error) {
if data == nil {
return nil, nil
}
dst := make([]byte, base64.StdEncoding.EncodedLen(len(data)))
base64.StdEncoding.Encode(dst, data)
return dst, nil
@ -67,6 +79,9 @@ func (s *Base64Sigil) In(data []byte) ([]byte, error) {
// Out decodes the data from base64.
func (s *Base64Sigil) Out(data []byte) ([]byte, error) {
if data == nil {
return nil, nil
}
dst := make([]byte, base64.StdEncoding.DecodedLen(len(data)))
n, err := base64.StdEncoding.Decode(dst, data)
return dst[:n], err
@ -79,6 +94,9 @@ type GzipSigil struct {
// In compresses the data using gzip.
func (s *GzipSigil) In(data []byte) ([]byte, error) {
if data == nil {
return nil, nil
}
var b bytes.Buffer
w := s.writer
if w == nil {
@ -96,6 +114,9 @@ func (s *GzipSigil) In(data []byte) ([]byte, error) {
// Out decompresses the data using gzip.
func (s *GzipSigil) Out(data []byte) ([]byte, error) {
if data == nil {
return nil, nil
}
r, err := gzip.NewReader(bytes.NewReader(data))
if err != nil {
return nil, err

View file

@ -28,7 +28,7 @@ func (m *failOnSecondWrite) Write(p []byte) (n int, err error) {
return len(p), nil
}
func TestReverseSigil(t *testing.T) {
func TestReverseSigil_Good(t *testing.T) {
s := &ReverseSigil{}
data := []byte("hello")
reversed, err := s.In(data)
@ -37,15 +37,23 @@ func TestReverseSigil(t *testing.T) {
original, err := s.Out(reversed)
assert.NoError(t, err)
assert.Equal(t, "hello", string(original))
}
// Ugly - empty string
func TestReverseSigil_Ugly(t *testing.T) {
s := &ReverseSigil{}
// Test with empty string
empty := []byte("")
reversedEmpty, err := s.In(empty)
assert.NoError(t, err)
assert.Equal(t, "", string(reversedEmpty))
// Test with nil
reversedNil, err := s.In(nil)
assert.NoError(t, err)
assert.Nil(t, reversedNil)
}
func TestHexSigil(t *testing.T) {
func TestHexSigil_Good(t *testing.T) {
s := &HexSigil{}
data := []byte("hello")
encoded, err := s.In(data)
@ -54,13 +62,29 @@ func TestHexSigil(t *testing.T) {
decoded, err := s.Out(encoded)
assert.NoError(t, err)
assert.Equal(t, "hello", string(decoded))
}
// Bad - invalid hex string
_, err = s.Out([]byte("not hex"))
func TestHexSigil_Bad(t *testing.T) {
s := &HexSigil{}
_, err := s.Out([]byte("not hex"))
assert.Error(t, err)
}
func TestBase64Sigil(t *testing.T) {
func TestHexSigil_Ugly(t *testing.T) {
s := &HexSigil{}
// Test with empty string
empty := []byte("")
encodedEmpty, err := s.In(empty)
assert.NoError(t, err)
assert.Equal(t, "", string(encodedEmpty))
// Test with nil
encodedNil, err := s.In(nil)
assert.NoError(t, err)
assert.Nil(t, encodedNil)
}
func TestBase64Sigil_Good(t *testing.T) {
s := &Base64Sigil{}
data := []byte("hello")
encoded, err := s.In(data)
@ -69,13 +93,29 @@ func TestBase64Sigil(t *testing.T) {
decoded, err := s.Out(encoded)
assert.NoError(t, err)
assert.Equal(t, "hello", string(decoded))
}
// Bad - invalid base64 string
_, err = s.Out([]byte("not base64"))
func TestBase64Sigil_Bad(t *testing.T) {
s := &Base64Sigil{}
_, err := s.Out([]byte("not base64"))
assert.Error(t, err)
}
func TestGzipSigil(t *testing.T) {
func TestBase64Sigil_Ugly(t *testing.T) {
s := &Base64Sigil{}
// Test with empty string
empty := []byte("")
encodedEmpty, err := s.In(empty)
assert.NoError(t, err)
assert.Equal(t, "", string(encodedEmpty))
// Test with nil
encodedNil, err := s.In(nil)
assert.NoError(t, err)
assert.Nil(t, encodedNil)
}
func TestGzipSigil_Good(t *testing.T) {
s := &GzipSigil{}
data := []byte("hello")
compressed, err := s.In(data)
@ -84,9 +124,14 @@ func TestGzipSigil(t *testing.T) {
decompressed, err := s.Out(compressed)
assert.NoError(t, err)
assert.Equal(t, "hello", string(decompressed))
}
// Bad - invalid gzip data
_, err = s.Out([]byte("not gzip"))
func TestGzipSigil_Bad(t *testing.T) {
s := &GzipSigil{}
data := []byte("hello")
// Test with invalid gzip data
_, err := s.Out([]byte("not gzip"))
assert.Error(t, err)
// Test writer error
@ -100,27 +145,60 @@ func TestGzipSigil(t *testing.T) {
assert.Error(t, err)
}
func TestJSONSigil(t *testing.T) {
func TestGzipSigil_Ugly(t *testing.T) {
s := &GzipSigil{}
// Test with empty string
empty := []byte("")
compressedEmpty, err := s.In(empty)
assert.NoError(t, err)
decompressedEmpty, err := s.Out(compressedEmpty)
assert.NoError(t, err)
assert.Equal(t, "", string(decompressedEmpty))
// Test with nil
compressedNil, err := s.In(nil)
assert.NoError(t, err)
decompressedNil, err := s.Out(compressedNil)
assert.NoError(t, err)
assert.Nil(t, decompressedNil)
}
func TestJSONSigil_Good(t *testing.T) {
s := &JSONSigil{Indent: true}
data := []byte(`{"hello":"world"}`)
indented, err := s.In(data)
assert.NoError(t, err)
assert.Equal(t, "{\n \"hello\": \"world\"\n}", string(indented))
s.Indent = false
compacted, err := s.In(indented)
assert.NoError(t, err)
assert.Equal(t, `{"hello":"world"}`, string(compacted))
// Bad - invalid json
_, err = s.In([]byte("not json"))
assert.Error(t, err)
// Out is a no-op, so it should return the data as-is
// Out is a no-op
outData, err := s.Out(data)
assert.NoError(t, err)
assert.Equal(t, data, outData)
}
func TestJSONSigil_Bad(t *testing.T) {
s := &JSONSigil{}
_, err := s.In([]byte("not json"))
assert.Error(t, err)
}
func TestJSONSigil_Ugly(t *testing.T) {
s := &JSONSigil{}
// Test with empty string
empty := []byte("")
_, err := s.In(empty)
assert.Error(t, err)
// Test with nil
_, err = s.In(nil)
assert.Error(t, err)
}
func TestHashSigils_Good(t *testing.T) {
// Using the input "hello" for all hash tests
data := []byte("hello")
@ -172,3 +250,19 @@ func TestHashSigil_Bad(t *testing.T) {
assert.Error(t, err)
assert.Contains(t, err.Error(), "hash algorithm not available")
}
func TestHashSigil_Ugly(t *testing.T) {
s, err := NewSigil("sha256")
assert.NoError(t, err)
// Test with empty string
empty := []byte("")
hashedEmpty, err := s.In(empty)
assert.NoError(t, err)
assert.NotEmpty(t, hashedEmpty)
// Test with nil
hashedNil, err := s.In(nil)
assert.NoError(t, err)
assert.NotEmpty(t, hashedNil)
}