test: add core test suite for crypto, auth, and store packages

- 8 crypto tests: key derivation, encrypt/decrypt round-trip, wrong key, nonce uniqueness
- 6 auth tests: password hash/verify, JWT generate/validate, token revocation
- 14 store tests: project CRUD, user CRUD, stage/deploy lifecycle, pagination, cascade deletes
- Fix stages CREATE TABLE schema to include notification_url column
- Total: 28 tests, all passing
This commit is contained in:
2026-04-04 14:13:05 +03:00
parent 3743e7fe45
commit 205a5a36c6
4 changed files with 598 additions and 1 deletions
+136
View File
@@ -0,0 +1,136 @@
package crypto
import (
"testing"
)
func TestDeriveKey(t *testing.T) {
key := DeriveKey("test-passphrase-that-is-long-enough")
if key == [32]byte{} {
t.Fatal("DeriveKey returned zero key")
}
// Same input produces same output
key2 := DeriveKey("test-passphrase-that-is-long-enough")
if key != key2 {
t.Fatal("DeriveKey is not deterministic")
}
// Different input produces different output
key3 := DeriveKey("different-passphrase-also-long-enough")
if key == key3 {
t.Fatal("DeriveKey produced same key for different inputs")
}
}
func TestEncryptDecryptRoundTrip(t *testing.T) {
key := DeriveKey("test-key-for-encryption-testing-1234")
plaintext := "super-secret-value"
encrypted, err := Encrypt(key, plaintext)
if err != nil {
t.Fatalf("Encrypt failed: %v", err)
}
if encrypted == plaintext {
t.Fatal("Encrypt returned plaintext")
}
if encrypted == "" {
t.Fatal("Encrypt returned empty string")
}
decrypted, err := Decrypt(key, encrypted)
if err != nil {
t.Fatalf("Decrypt failed: %v", err)
}
if decrypted != plaintext {
t.Fatalf("Decrypt mismatch: got %q, want %q", decrypted, plaintext)
}
}
func TestDecryptWithWrongKey(t *testing.T) {
key1 := DeriveKey("key-one-for-testing-encryption-1234")
key2 := DeriveKey("key-two-for-testing-encryption-5678")
encrypted, err := Encrypt(key1, "secret")
if err != nil {
t.Fatalf("Encrypt failed: %v", err)
}
_, err = Decrypt(key2, encrypted)
if err == nil {
t.Fatal("Decrypt with wrong key should have failed")
}
}
func TestEncryptIfNotEmpty(t *testing.T) {
key := DeriveKey("test-key-for-encryption-testing-1234")
result, err := EncryptIfNotEmpty(key, "")
if err != nil {
t.Fatalf("EncryptIfNotEmpty with empty input failed: %v", err)
}
if result != "" {
t.Fatal("EncryptIfNotEmpty should return empty for empty input")
}
result, err = EncryptIfNotEmpty(key, "value")
if err != nil {
t.Fatalf("EncryptIfNotEmpty failed: %v", err)
}
if result == "" || result == "value" {
t.Fatal("EncryptIfNotEmpty should encrypt non-empty input")
}
}
func TestKeyFromEnv(t *testing.T) {
// Test with no key set
t.Setenv("ENCRYPTION_KEY", "")
_, err := KeyFromEnv()
if err == nil {
t.Fatal("KeyFromEnv should fail with empty ENCRYPTION_KEY")
}
// Test with valid key
t.Setenv("ENCRYPTION_KEY", "a-very-long-encryption-key-that-is-definitely-over-32-chars")
key, err := KeyFromEnv()
if err != nil {
t.Fatalf("KeyFromEnv failed with valid key: %v", err)
}
if key == [32]byte{} {
t.Fatal("KeyFromEnv returned zero key")
}
}
func TestEncryptProducesDifferentCiphertexts(t *testing.T) {
key := DeriveKey("test-key-for-nonce-uniqueness-1234")
enc1, err := Encrypt(key, "same-plaintext")
if err != nil {
t.Fatalf("Encrypt 1 failed: %v", err)
}
enc2, err := Encrypt(key, "same-plaintext")
if err != nil {
t.Fatalf("Encrypt 2 failed: %v", err)
}
if enc1 == enc2 {
t.Fatal("Two encryptions of the same plaintext should produce different ciphertexts (random nonce)")
}
}
func TestDecryptInvalidHex(t *testing.T) {
key := DeriveKey("test-key-for-invalid-hex-testing")
_, err := Decrypt(key, "not-valid-hex!!!")
if err == nil {
t.Fatal("Decrypt should fail with invalid hex input")
}
}
func TestDecryptTooShort(t *testing.T) {
key := DeriveKey("test-key-for-short-ciphertext-test")
_, err := Decrypt(key, "aabb")
if err == nil {
t.Fatal("Decrypt should fail with ciphertext shorter than nonce")
}
}