package services // Live-DB tests for FirmDashboardDefaultService — gated on // TEST_DATABASE_URL like the rest of the integration suite. // // These cover the round-trip (Set → Get → Clear → Get) and the // SanitizeForRead behavior on read. Pure-function validation lives in // dashboard_layout_spec_test.go. import ( "context" "encoding/json" "os" "testing" "github.com/google/uuid" "github.com/jmoiron/sqlx" _ "github.com/lib/pq" ) func openTestDBForFirmDefault(t *testing.T) *sqlx.DB { t.Helper() url := os.Getenv("TEST_DATABASE_URL") if url == "" { t.Skip("TEST_DATABASE_URL not set — skipping firm-dashboard-default live test") } db, err := sqlx.Connect("postgres", url) if err != nil { t.Fatalf("connect: %v", err) } return db } func TestFirmDashboardDefault_RoundTrip(t *testing.T) { db := openTestDBForFirmDefault(t) defer db.Close() svc := NewFirmDashboardDefaultService(db) ctx := context.Background() // Start clean — prior tests may have left a row. if err := svc.Clear(ctx); err != nil { t.Fatalf("pre-clear: %v", err) } if _, ok, err := svc.Get(ctx); err != nil || ok { t.Fatalf("Get after Clear: ok=%v err=%v; want ok=false err=nil", ok, err) } spec := FactoryDefaultLayout() if _, err := svc.Set(ctx, spec, uuid.Nil); err != nil { t.Fatalf("Set factory: %v", err) } got, ok, err := svc.Get(ctx) if err != nil { t.Fatalf("Get: %v", err) } if !ok { t.Fatal("Get: ok=false after Set; want true") } if len(got.Widgets) != len(spec.Widgets) { t.Errorf("widget count mismatch: %d vs %d", len(got.Widgets), len(spec.Widgets)) } if got.Version != spec.Version { t.Errorf("version mismatch: %d vs %d", got.Version, spec.Version) } // Clear is idempotent. if err := svc.Clear(ctx); err != nil { t.Fatalf("clear after set: %v", err) } if err := svc.Clear(ctx); err != nil { t.Fatalf("second clear: %v", err) } if _, ok, err := svc.Get(ctx); err != nil || ok { t.Fatalf("Get after Clear: ok=%v err=%v; want false/nil", ok, err) } } func TestFirmDashboardDefault_RejectsInvalid(t *testing.T) { db := openTestDBForFirmDefault(t) defer db.Close() svc := NewFirmDashboardDefaultService(db) ctx := context.Background() bad := DashboardLayoutSpec{Version: 1, Widgets: []DashboardWidgetRef{ {Key: WidgetUpcomingDeadlines, Visible: true, Settings: json.RawMessage(`{"count": 7}`)}, }} _, err := svc.Set(ctx, bad, uuid.Nil) if err == nil { t.Fatal("Set with invalid count: err=nil; want ErrInvalidInput") } }