package httpapi import ( "strings" "testing" "calllinesystem/server/internal/model" ) func TestValidateAdminProjectRequestNormalizesProjectProfile(t *testing.T) { got, err := validateAdminProjectRequest(adminProjectRequest{Name: " 云岭漂流 ", Code: "ride-east", Timezone: "Asia/Shanghai", TicketPrefix: "q"}) if err != nil { t.Fatal(err) } if got.Name != "云岭漂流" || got.Code != "RIDE-EAST" || got.Timezone != "Asia/Shanghai" || got.TicketPrefix != "Q" { t.Fatalf("normalized project = %#v", got) } } func TestValidateAdminProjectRequestUsesDefaultTimezone(t *testing.T) { got, err := validateAdminProjectRequest(adminProjectRequest{Name: "漂流", Code: "RIDE", TicketPrefix: "A"}) if err != nil { t.Fatal(err) } if got.Timezone != "Asia/Shanghai" { t.Fatalf("default timezone = %q", got.Timezone) } } func TestValidateAdminProjectRequestRejectsInvalidProfile(t *testing.T) { tests := []adminProjectRequest{ {Name: "", Code: "RIDE", Timezone: "Asia/Shanghai", TicketPrefix: "A"}, {Name: "漂流", Code: "x", Timezone: "Asia/Shanghai", TicketPrefix: "A"}, {Name: "漂流", Code: "RIDE", Timezone: "Mars/Base", TicketPrefix: "A"}, {Name: "漂流", Code: "RIDE", Timezone: "Asia/Shanghai", TicketPrefix: "A-"}, } for _, input := range tests { if _, err := validateAdminProjectRequest(input); err == nil { t.Fatalf("expected invalid project request: %#v", input) } } } func TestRemovesLastActiveAdmin(t *testing.T) { admin := model.User{Role: model.RoleAdmin, Active: true} if !removesLastActiveAdmin(admin, model.RoleStaff, true, 0) { t.Fatal("demoting the last active admin must be rejected") } if !removesLastActiveAdmin(admin, model.RoleAdmin, false, 0) { t.Fatal("disabling the last active admin must be rejected") } if removesLastActiveAdmin(admin, model.RoleStaff, true, 1) { t.Fatal("demotion is allowed when another active admin remains") } if removesLastActiveAdmin(admin, model.RoleAdmin, true, 0) { t.Fatal("keeping the last admin active must be allowed") } } func TestAdminUserViewMarksPermanentSuperAdminProtected(t *testing.T) { view := adminUserView(model.User{Username: model.SuperAdminUsername}, nil) if view["protected"] != true { t.Fatalf("super admin view must be protected: %#v", view) } regular := adminUserView(model.User{Username: "admin02"}, nil) if regular["protected"] != false { t.Fatalf("regular admin view must remain editable: %#v", regular) } } func TestValidateProjectSettingsVisitorNotice(t *testing.T) { notice := " 请在入口附近等候。 " updates, err := validateProjectSettings(updateProjectSettingsRequest{VisitorNotice: ¬ice}) if err != nil { t.Fatal(err) } if updates["visitor_notice"] != "请在入口附近等候。" { t.Fatalf("visitor notice was not trimmed: %#v", updates) } tooLong := strings.Repeat("字", 241) if _, err := validateProjectSettings(updateProjectSettingsRequest{VisitorNotice: &tooLong}); err == nil { t.Fatal("expected visitor notice length validation") } } func TestValidateProjectSettingsETAInterval(t *testing.T) { interval := 90 updates, err := validateProjectSettings(updateProjectSettingsRequest{ETAIntervalSeconds: &interval}) if err != nil || updates["eta_interval_seconds"] != 90 { t.Fatalf("unexpected interval result: %#v, %v", updates, err) } invalid := 0 if _, err := validateProjectSettings(updateProjectSettingsRequest{ETAIntervalSeconds: &invalid}); err == nil { t.Fatal("expected interval validation") } }