Files
worker/app/models/notification_credential_test.go
Gleb Tv 2c884c5612
Некоторые проверки не удались
CI / test (push) Successful in 2m5s
Docker / Build and publish worker image (push) Failing after 31s
refactor: adopt worker module path
2026-07-13 17:56:12 +03:00

187 строки
6.2 KiB
Go

package models_test
import (
"strings"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"rocketgit.ru/rsmon/worker/app/models"
"rocketgit.ru/rsmon/worker/config/database"
)
func init() {
database.Init()
}
// TestNotificationCredential_EncryptDecryptRoundTrip verifies that SetSecret
// followed by GetSecret returns the original plaintext regardless of which
// encryption mode (AES-GCM or plain: fallback) is active.
func TestNotificationCredential_EncryptDecryptRoundTrip(t *testing.T) {
c := &models.NotificationCredential{}
plaintext := "super-secret-smtp-password"
require.NoError(t, c.SetSecret(plaintext))
got, err := c.GetSecret()
require.NoError(t, err)
assert.Equal(t, plaintext, got)
}
// TestNotificationCredential_EncryptDecryptWithKey verifies that when
// RSMON_CRED_KEY is configured the stored value is prefixed with "enc:" and
// can still be decrypted back to the original plaintext.
func TestNotificationCredential_EncryptDecryptWithKey(t *testing.T) {
t.Setenv("RSMON_CRED_KEY", "test-key-rotate-me-1234567890")
c := &models.NotificationCredential{}
plaintext := "bot-token-9876543210:ABCDEFG"
require.NoError(t, c.SetSecret(plaintext))
assert.True(t, strings.HasPrefix(c.SecretEnc, "enc:"),
"expected SecretEnc to start with 'enc:' prefix, got %q", c.SecretEnc)
assert.NotEqual(t, plaintext, c.SecretEnc, "encrypted value must not equal plaintext")
got, err := c.GetSecret()
require.NoError(t, err)
assert.Equal(t, plaintext, got)
}
// TestNotificationCredential_CRUD exercises create / find-by-id / find-by-name
// / delete against the test database.
func TestNotificationCredential_CRUD(t *testing.T) {
models.Drop()
models.Migrate()
server := "smtp.example.com"
port := 587
login := "alerts@example.com"
enabled := true
c := &models.NotificationCredential{
Kind: models.CredentialKindSMTP,
Name: "primary",
Server: &server,
Port: &port,
Login: &login,
Enabled: &enabled,
}
require.NoError(t, c.SetSecret("smtp-password-xyz"))
require.NoError(t, models.DB().Create(c).Error)
require.NotZero(t, c.ID, "expected ID to be assigned after Create")
found, err := models.FindCredential(c.ID)
require.NoError(t, err)
assert.Equal(t, "primary", found.Name)
assert.Equal(t, models.CredentialKindSMTP, found.Kind)
require.NotNil(t, found.Server)
assert.Equal(t, "smtp.example.com", *found.Server)
gotSecret, err := found.GetSecret()
require.NoError(t, err)
assert.Equal(t, "smtp-password-xyz", gotSecret)
assert.Equal(t, "s***z", found.SecretMasked)
byName, err := models.FindCredentialByName(models.CredentialKindSMTP, "primary")
require.NoError(t, err)
assert.Equal(t, c.ID, byName.ID)
require.NoError(t, models.DeleteCredential(c.ID))
_, err = models.FindCredential(c.ID)
assert.Error(t, err, "FindCredential should fail after delete")
}
// TestNotificationCredential_UniqueKindName verifies that two credentials with
// the same (kind, name) pair violate the unique index.
func TestNotificationCredential_UniqueKindName(t *testing.T) {
models.Drop()
models.Migrate()
enTrue := true
first := &models.NotificationCredential{
Kind: models.CredentialKindTelegram,
Name: "main-bot",
Enabled: &enTrue,
}
require.NoError(t, first.SetSecret("token-a"))
require.NoError(t, models.DB().Create(first).Error)
second := &models.NotificationCredential{
Kind: models.CredentialKindTelegram,
Name: "main-bot",
Enabled: &enTrue,
}
require.NoError(t, second.SetSecret("token-b"))
err := models.DB().Create(second).Error
require.Error(t, err, "expected unique constraint violation for duplicate (kind, name)")
assert.True(t,
strings.Contains(strings.ToLower(err.Error()), "unique") ||
strings.Contains(strings.ToLower(err.Error()), "duplicate"),
"expected error mentioning unique/duplicate, got: %v", err)
}
// TestEnabledCredentialsByKind verifies the kind+enabled filter.
func TestEnabledCredentialsByKind(t *testing.T) {
models.Drop()
models.Migrate()
enTrue := true
enFalse := false
enabled := &models.NotificationCredential{Kind: models.CredentialKindSMTP, Name: "enabled-1", Enabled: &enTrue}
disabled := &models.NotificationCredential{Kind: models.CredentialKindSMTP, Name: "disabled-1", Enabled: &enFalse}
require.NoError(t, models.DB().Create(enabled).Error)
require.NoError(t, models.DB().Create(disabled).Error)
got, err := models.EnabledCredentialsByKind(models.CredentialKindSMTP)
require.NoError(t, err)
var names []string
for _, c := range got {
names = append(names, c.Name)
}
assert.Contains(t, names, "enabled-1")
assert.NotContains(t, names, "disabled-1")
}
func TestNotificationCredentialsAreScopedToSystemOrAccount(t *testing.T) {
models.Drop()
models.Migrate()
accountA := &models.Account{Name: "credential-a"}
accountB := &models.Account{Name: "credential-b"}
require.NoError(t, models.DB().Create(accountA).Error)
require.NoError(t, models.DB().Create(accountB).Error)
enabled := true
system := &models.NotificationCredential{Kind: models.CredentialKindSMTP, Name: "system", Enabled: &enabled}
ownedA := &models.NotificationCredential{AccountID: &accountA.ID, Kind: models.CredentialKindSMTP, Name: "owned", Enabled: &enabled}
ownedB := &models.NotificationCredential{AccountID: &accountB.ID, Kind: models.CredentialKindSMTP, Name: "owned", Enabled: &enabled}
require.NoError(t, models.DB().Create(system).Error)
require.NoError(t, models.DB().Create(ownedA).Error)
require.NoError(t, models.DB().Create(ownedB).Error)
systemCreds, err := models.EnabledCredentialsByKind(models.CredentialKindSMTP)
require.NoError(t, err)
require.Len(t, systemCreds, 1)
assert.Equal(t, system.ID, systemCreds[0].ID)
accountCreds, err := models.EnabledCredentialsByAccountAndKind(accountA.ID, models.CredentialKindSMTP)
require.NoError(t, err)
require.Len(t, accountCreds, 1)
assert.Equal(t, ownedA.ID, accountCreds[0].ID)
}
func TestNotificationCredentialSecretMasked(t *testing.T) {
models.Drop()
models.Migrate()
cred := models.NotificationCredential{Kind: models.CredentialKindSMTP, Name: "smtp"}
require.NoError(t, cred.SetSecret("password"))
require.NoError(t, models.DB().Create(&cred).Error)
loaded, err := models.FindCredential(cred.ID)
require.NoError(t, err)
assert.Equal(t, "p***d", loaded.SecretMasked)
}