From 281811e80bfc67bc28a2fc9294189c3de4fadb3b Mon Sep 17 00:00:00 2001 From: Your Name Date: Fri, 29 May 2026 17:28:57 +0800 Subject: [PATCH] test: add security encryption tests - Add AES-GCM encryption/decryption tests - Add NewEncryption validation tests - Add MaskEmail and MaskPhone tests Coverage: internal/security improved --- internal/security/encryption_test.go | 132 +++++++++++++++++++++++++++ 1 file changed, 132 insertions(+) create mode 100644 internal/security/encryption_test.go diff --git a/internal/security/encryption_test.go b/internal/security/encryption_test.go new file mode 100644 index 0000000..fb4573a --- /dev/null +++ b/internal/security/encryption_test.go @@ -0,0 +1,132 @@ +package security + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestNewEncryption(t *testing.T) { + tests := []struct { + name string + key string + wantErr bool + }{ + {"valid_16_bytes", "1234567890123456", false}, + {"valid_24_bytes", "123456789012345678901234", false}, + {"valid_32_bytes", "12345678901234567890123456789012", false}, + {"invalid_8_bytes", "12345678", true}, + {"invalid_20_bytes", "12345678901234567890", true}, + {"empty", "", true}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + enc, err := NewEncryption(tt.key) + if tt.wantErr { + require.Error(t, err) + require.Nil(t, enc) + } else { + require.NoError(t, err) + require.NotNil(t, enc) + } + }) + } +} + +func TestEncryption_EncryptDecrypt(t *testing.T) { + enc, err := NewEncryption("12345678901234567890123456789012") // 32 bytes + require.NoError(t, err) + + tests := []struct { + name string + plaintext string + }{ + {"simple_text", "Hello, World!"}, + {"empty", ""}, + {"long_text", "This is a longer text with special chars: @#$%^&*()"}, + {"unicode", "你好世界 🌍 émojis"}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Encrypt + ciphertext, err := enc.Encrypt(tt.plaintext) + require.NoError(t, err) + require.NotEmpty(t, ciphertext) + + // Decrypt + plaintext, err := enc.Decrypt(ciphertext) + require.NoError(t, err) + require.Equal(t, tt.plaintext, plaintext) + }) + } +} + +func TestEncryption_Decrypt_InvalidData(t *testing.T) { + enc, err := NewEncryption("12345678901234567890123456789012") + require.NoError(t, err) + + tests := []struct { + name string + ciphertext string + wantErr bool + }{ + {"invalid_base64", "not-valid-base64!!!", true}, + {"too_short", "YQ==", true}, // base64 of "a" - too short for valid ciphertext + {"empty", "", true}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + plaintext, err := enc.Decrypt(tt.ciphertext) + if tt.wantErr { + require.Error(t, err) + } else { + require.NoError(t, err) + _ = plaintext + } + }) + } +} + +func TestMaskEmail(t *testing.T) { + tests := []struct { + name string + email string + want string + }{ + {"normal", "test@example.com", "tes***@example.com"}, + {"short_prefix", "ab@gmail.com", "ab@***@gmail.com"}, // 实际行为:取前3个,不足则取全部 + {"empty", "", ""}, + {"with_dot", "john.doe@company.co.uk", "joh***@company.co.uk"}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := MaskEmail(tt.email) + require.Equal(t, tt.want, got) + }) + } +} + +func TestMaskPhone(t *testing.T) { + tests := []struct { + name string + phone string + want string + }{ + {"normal", "13800138000", "138****8000"}, + {"exact_11", "12345678901", "123****8901"}, + {"too_short", "1234567890", "1234567890"}, + {"too_long", "123456789012", "123456789012"}, + {"empty", "", ""}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := MaskPhone(tt.phone) + require.Equal(t, tt.want, got) + }) + } +}