- Add new test files for handlers (storage, payment, settings) - Add new test files for services (chat, email, storage, settings, admin) - Add integration tests for services - Update handler implementations with bug fixes - Add coverage reports and test documentation
153 lines
3.9 KiB
Go
153 lines
3.9 KiB
Go
package services_test
|
|
|
|
import (
|
|
"context"
|
|
"crypto/rand"
|
|
"crypto/rsa"
|
|
"crypto/sha256"
|
|
"crypto/x509"
|
|
"encoding/base64"
|
|
"encoding/pem"
|
|
"os"
|
|
"regexp"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/DATA-DOG/go-sqlmock"
|
|
"github.com/rede5/gohorsejobs/backend/internal/services"
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
// Helper to generate a valid RSA private key for testing
|
|
func generateTestRSAKey() (string, *rsa.PublicKey, error) {
|
|
key, err := rsa.GenerateKey(rand.Reader, 2048)
|
|
if err != nil {
|
|
return "", nil, err
|
|
}
|
|
|
|
keyBytes := x509.MarshalPKCS1PrivateKey(key)
|
|
pemBlock := &pem.Block{
|
|
Type: "RSA PRIVATE KEY",
|
|
Bytes: keyBytes,
|
|
}
|
|
pemBytes := pem.EncodeToMemory(pemBlock)
|
|
|
|
return base64.StdEncoding.EncodeToString(pemBytes), &key.PublicKey, nil
|
|
}
|
|
|
|
func TestSaveCredentials(t *testing.T) {
|
|
db, mock, err := sqlmock.New()
|
|
assert.NoError(t, err)
|
|
defer db.Close()
|
|
|
|
service := services.NewCredentialsService(db)
|
|
ctx := context.Background()
|
|
|
|
mock.ExpectExec(regexp.QuoteMeta(`INSERT INTO external_services_credentials`)).
|
|
WithArgs("stripe", "encrypted_data", "admin").
|
|
WillReturnResult(sqlmock.NewResult(1, 1))
|
|
|
|
err = service.SaveCredentials(ctx, "stripe", "encrypted_data", "admin")
|
|
assert.NoError(t, err)
|
|
}
|
|
|
|
func TestGetDecryptedKey(t *testing.T) {
|
|
// Setup RSA Key
|
|
privKeyStr, pubKey, err := generateTestRSAKey()
|
|
assert.NoError(t, err)
|
|
os.Setenv("RSA_PRIVATE_KEY_BASE64", privKeyStr)
|
|
defer os.Unsetenv("RSA_PRIVATE_KEY_BASE64")
|
|
|
|
db, mock, err := sqlmock.New()
|
|
assert.NoError(t, err)
|
|
defer db.Close()
|
|
|
|
service := services.NewCredentialsService(db)
|
|
ctx := context.Background()
|
|
|
|
// Encrypt a secret
|
|
secret := "my-secret-key"
|
|
encryptedBytes, err := rsa.EncryptOAEP(
|
|
sha256.New(),
|
|
rand.Reader,
|
|
pubKey,
|
|
[]byte(secret),
|
|
nil,
|
|
)
|
|
assert.NoError(t, err)
|
|
encryptedPayload := base64.StdEncoding.EncodeToString(encryptedBytes)
|
|
|
|
// Mock DB return
|
|
mock.ExpectQuery(regexp.QuoteMeta(`SELECT encrypted_payload FROM external_services_credentials`)).
|
|
WithArgs("stripe").
|
|
WillReturnRows(sqlmock.NewRows([]string{"encrypted_payload"}).AddRow(encryptedPayload))
|
|
|
|
// Execute
|
|
decrypted, err := service.GetDecryptedKey(ctx, "stripe")
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, secret, decrypted)
|
|
}
|
|
|
|
func TestListConfiguredServices(t *testing.T) {
|
|
db, mock, err := sqlmock.New()
|
|
assert.NoError(t, err)
|
|
defer db.Close()
|
|
|
|
service := services.NewCredentialsService(db)
|
|
ctx := context.Background()
|
|
|
|
mock.ExpectQuery(regexp.QuoteMeta(`SELECT service_name, updated_at, COALESCE(updated_by::text, '')`)).
|
|
WillReturnRows(sqlmock.NewRows([]string{"service_name", "updated_at", "updated_by"}).
|
|
AddRow("stripe", time.Now().Format(time.RFC3339), "admin").
|
|
AddRow("appwrite", time.Now().Format(time.RFC3339), "system"))
|
|
|
|
servicesList, err := service.ListConfiguredServices(ctx)
|
|
assert.NoError(t, err)
|
|
assert.NotEmpty(t, servicesList)
|
|
|
|
// Verify mapped correctly
|
|
foundStripe := false
|
|
for _, s := range servicesList {
|
|
if s.ServiceName == "stripe" {
|
|
assert.True(t, s.IsConfigured)
|
|
foundStripe = true
|
|
}
|
|
if s.ServiceName == "firebase" {
|
|
assert.False(t, s.IsConfigured)
|
|
}
|
|
}
|
|
assert.True(t, foundStripe)
|
|
}
|
|
|
|
func TestDeleteCredentials(t *testing.T) {
|
|
db, mock, err := sqlmock.New()
|
|
assert.NoError(t, err)
|
|
defer db.Close()
|
|
|
|
service := services.NewCredentialsService(db)
|
|
ctx := context.Background()
|
|
|
|
mock.ExpectExec(regexp.QuoteMeta(`DELETE FROM external_services_credentials`)).
|
|
WithArgs("stripe").
|
|
WillReturnResult(sqlmock.NewResult(1, 1))
|
|
|
|
err = service.DeleteCredentials(ctx, "stripe")
|
|
assert.NoError(t, err)
|
|
}
|
|
|
|
func TestEncryptPayload(t *testing.T) {
|
|
// Setup RSA Key
|
|
privKeyStr, _, err := generateTestRSAKey()
|
|
assert.NoError(t, err)
|
|
os.Setenv("RSA_PRIVATE_KEY_BASE64", privKeyStr)
|
|
defer os.Unsetenv("RSA_PRIVATE_KEY_BASE64")
|
|
|
|
service := services.NewCredentialsService(nil)
|
|
|
|
// Encrypt
|
|
payload := "test-payload-123"
|
|
encrypted, err := service.EncryptPayload(payload)
|
|
assert.NoError(t, err)
|
|
assert.NotEmpty(t, encrypted)
|
|
assert.NotEqual(t, payload, encrypted)
|
|
}
|