Files
silo-server/internal/notifications/interest_hooks_test.go
QuickandGitHub 3bdfc58512 feat(settings): sync navigation and card customization by client family (#538)
* test(web): use safe auth placeholders

* feat(settings): sync navigation and card customization

* fix(settings): address customization review feedback

* fix(settings): address customization review feedback

* fix(settings): harden customization capability handling
2026-08-04 08:20:41 -04:00

103 lines
3.3 KiB
Go

package notifications
import (
"context"
"database/sql"
"encoding/json"
"testing"
"time"
"github.com/Silo-Server/silo-server/internal/settingscontract"
"github.com/Silo-Server/silo-server/internal/userdb"
"github.com/Silo-Server/silo-server/internal/userstore"
)
type preferenceTransactionTestProvider struct {
store userstore.UserStore
}
func (p preferenceTransactionTestProvider) ForUser(context.Context, int) (userstore.UserStore, error) {
return p.store, nil
}
func (preferenceTransactionTestProvider) Close() error { return nil }
func TestInterestTrackingStorePreservesSettingCapabilities(t *testing.T) {
db, err := sql.Open("sqlite3", ":memory:")
if err != nil {
t.Fatalf("open sqlite: %v", err)
}
t.Cleanup(func() { _ = db.Close() })
if err := userdb.InitSchema(db); err != nil {
t.Fatalf("init schema: %v", err)
}
provider := WrapUserStoreProvider(
preferenceTransactionTestProvider{store: userdb.NewSQLiteUserStore(db)},
&System{},
)
wrapped, err := provider.ForUser(context.Background(), 1)
if err != nil {
t.Fatalf("ForUser: %v", err)
}
transactioner, ok := wrapped.(userstore.PreferenceSettingsTransactioner)
if !ok {
t.Fatal("interest-tracking wrapper dropped PreferenceSettingsTransactioner")
}
called := false
if err := transactioner.WithPreferenceSettingsTransaction(context.Background(),
func(userstore.PreferenceSettingsWriter) error {
called = true
return nil
}); err != nil {
t.Fatalf("WithPreferenceSettingsTransaction: %v", err)
}
if !called {
t.Fatal("transaction callback was not invoked")
}
cas, ok := wrapped.(userstore.SettingValueCompareAndSetter)
if !ok {
t.Fatal("interest-tracking wrapper dropped SettingValueCompareAndSetter")
}
identity := userstore.SettingIdentity{Key: "ui.test", Scope: settingscontract.ScopeAccount}
first, err := cas.CompareAndSetSettingValue(
context.Background(), identity, json.RawMessage(`"first"`), 0)
if err != nil {
t.Fatalf("CompareAndSetSettingValue: %v", err)
}
mutationTx, ok := wrapped.(userstore.SettingMutationTransactioner)
if !ok {
t.Fatal("interest-tracking wrapper dropped SettingMutationTransactioner")
}
called = false
if err := mutationTx.WithSettingMutationTransaction(context.Background(), "wrapped-mutation",
func(writer userstore.SettingMutationWriter) error {
called = true
if _, err := writer.CompareAndSetSettingValue(
context.Background(), identity, json.RawMessage(`"second"`), first.Revision); err != nil {
return err
}
_, _, err := writer.PutSettingMutation(context.Background(), userstore.SettingMutationRecord{
MutationID: "wrapped-mutation", RequestHash: "hash",
Result: json.RawMessage(`{"ok":true}`), ExpiresAt: time.Now().UTC().Add(time.Hour),
})
return err
}); err != nil {
t.Fatalf("WithSettingMutationTransaction: %v", err)
}
if !called {
t.Fatal("mutation transaction callback was not invoked")
}
stored, err := wrapped.GetSettingValue(context.Background(), identity)
if err != nil || stored == nil || stored.Revision != 2 {
t.Fatalf("wrapped setting after transaction = %+v (%v), want revision 2", stored, err)
}
receipt, err := wrapped.GetSettingMutation(context.Background(), "wrapped-mutation")
if err != nil || receipt == nil || receipt.RequestHash != "hash" {
t.Fatalf("wrapped receipt = %+v (%v)", receipt, err)
}
}