package tenancy import ( "context" "testing" "bookra/apps/backend/internal/db" "bookra/apps/backend/internal/domain" ) func TestBootstrapResolvesMembershipAfterIdentitySync(t *testing.T) { repo := db.NewMemoryRepository() service := NewService(repo) if err := repo.EnsureUserIdentity(context.Background(), "neon-user-123", "owner@bookra.dev", "Neon Owner"); err != nil { t.Fatalf("ensure user identity: %v", err) } bootstrap, err := service.Bootstrap(context.Background(), domain.Principal{ Subject: "neon-user-123", Email: "owner@bookra.dev", Name: "Neon Owner", Role: "authenticated", }) if err != nil { t.Fatalf("bootstrap: %v", err) } if bootstrap.TenantID == "" { t.Fatal("expected tenant id") } if bootstrap.CurrentUser.Role != "owner" { t.Fatalf("expected owner role, got %s", bootstrap.CurrentUser.Role) } if bootstrap.CurrentUser.Name != "Neon Owner" { t.Fatalf("expected synced name, got %s", bootstrap.CurrentUser.Name) } } func TestBootstrapReturnsShellWhenMembershipMissing(t *testing.T) { repo := db.NewMemoryRepository() service := NewService(repo) bootstrap, err := service.Bootstrap(context.Background(), domain.Principal{ Subject: "unassigned-user", Email: "new@bookra.dev", Name: "New User", Role: "authenticated", }) if err != nil { t.Fatalf("bootstrap without membership: %v", err) } if bootstrap.TenantID != "" { t.Fatalf("expected empty tenant id, got %s", bootstrap.TenantID) } if bootstrap.CurrentUser.Subject != "unassigned-user" { t.Fatalf("expected subject passthrough, got %s", bootstrap.CurrentUser.Subject) } } func TestOnboardCreatesTenantForAuthenticatedUser(t *testing.T) { repo := db.NewMemoryRepository() service := NewService(repo) bootstrap, err := service.Onboard(context.Background(), domain.Principal{ Subject: "fresh-user", Email: "fresh@bookra.dev", Name: "Fresh User", Role: "authenticated", }, domain.OnboardTenantRequest{ Name: "Fresh Studio", Slug: "fresh-studio", Preset: "studio", Locale: "cs", Timezone: "Europe/Prague", }) if err != nil { t.Fatalf("onboard: %v", err) } if bootstrap.TenantName != "Fresh Studio" { t.Fatalf("expected tenant name, got %s", bootstrap.TenantName) } if bootstrap.CurrentUser.Role != "owner" { t.Fatalf("expected owner role, got %s", bootstrap.CurrentUser.Role) } } func TestOnboardRejectsInvalidSlug(t *testing.T) { repo := db.NewMemoryRepository() service := NewService(repo) _, err := service.Onboard(context.Background(), domain.Principal{ Subject: "fresh-user", Email: "fresh@bookra.dev", Name: "Fresh User", Role: "authenticated", }, domain.OnboardTenantRequest{ Name: "Fresh Studio", Slug: "bad slug", Preset: "studio", Locale: "cs", Timezone: "Europe/Prague", }) if err != ErrInvalidOnboarding { t.Fatalf("expected invalid onboarding, got %v", err) } }