package appconfig import ( "testing" "time" ) func TestH5LinkModelFromPayloadValidatesDynamicConfig(t *testing.T) { item, err := h5LinkModelFromPayload(h5LinkPayload{ Key: "host-center.v2", Label: "Host Center", URL: "https://h5.example.com/host", }) if err != nil { t.Fatalf("h5 config should be valid: %v", err) } if item.Group != h5LinkGroup || item.Key != "host-center.v2" || item.Description != "Host Center" || item.Value != "https://h5.example.com/host" { t.Fatalf("h5 config model mismatch: %+v", item) } } func TestH5LinkModelFromPayloadRejectsInvalidKey(t *testing.T) { _, err := h5LinkModelFromPayload(h5LinkPayload{ Key: "host center", Label: "Host Center", URL: "https://h5.example.com/host", }) if err == nil { t.Fatal("expected invalid key to fail") } } func TestBannerModelFromRequestRequiresRoomSmallImageForRoomScope(t *testing.T) { _, err := bannerModelFromRequest("lalu", bannerRequest{ CoverURL: "https://cdn.example.com/banner.png", BannerType: "h5", DisplayScope: bannerDisplayScopeRoom, Param: "https://h5.example.com/activity", Status: bannerStatusActive, Platform: "android", EndsAtMs: time.Now().UTC().Add(time.Hour).UnixMilli(), }) if err == nil { t.Fatal("expected room scope without room small image to fail") } } func TestBannerModelFromRequestKeepsRoomScopeScheduleFields(t *testing.T) { startsAtMs := time.Now().UTC().Add(time.Hour).UnixMilli() endsAtMs := startsAtMs + int64(time.Hour/time.Millisecond) item, err := bannerModelFromRequest("lalu", bannerRequest{ CoverURL: "https://cdn.example.com/banner.png", RoomSmallImageURL: "https://cdn.example.com/banner-small.png", BannerType: "h5", DisplayScope: bannerDisplayScopeRoom, Param: "https://h5.example.com/activity", Status: bannerStatusActive, Platform: "android", StartsAtMs: startsAtMs, EndsAtMs: endsAtMs, }) if err != nil { t.Fatalf("banner model should be valid: %v", err) } if item.DisplayScope != bannerDisplayScopeRoom || item.RoomSmallImageURL == "" { t.Fatalf("room display fields mismatch: %+v", item) } if item.StartsAtMS != startsAtMs || item.EndsAtMS != endsAtMs || item.Status != bannerStatusActive { t.Fatalf("schedule fields mismatch: %+v", item) } } func TestBannerModelFromRequestExpiresEndedActiveBanner(t *testing.T) { item, err := bannerModelFromRequest("lalu", bannerRequest{ CoverURL: "https://cdn.example.com/banner.png", RoomSmallImageURL: "https://cdn.example.com/ignored.png", BannerType: "app", DisplayScope: bannerDisplayScopeHome, Status: bannerStatusActive, Platform: "ios", EndsAtMs: 1, }) if err != nil { t.Fatalf("banner model should accept ended active banner: %v", err) } if item.Status != bannerStatusExpired { t.Fatalf("ended active banner must become expired: %+v", item) } if item.RoomSmallImageURL != "" { t.Fatalf("non-room banner must not retain room small image: %+v", item) } } func TestExploreTabModelFromRequestValidatesRequiredFields(t *testing.T) { item, err := exploreTabModelFromRequest("lalu", exploreTabRequest{ Enabled: true, H5URL: "https://h5.example.com/explore/live", SortOrder: 3, Tab: "Live", }) if err != nil { t.Fatalf("explore tab should be valid: %v", err) } if item.AppCode != "lalu" || item.Tab != "Live" || item.H5URL != "https://h5.example.com/explore/live" || !item.Enabled || item.SortOrder != 3 { t.Fatalf("explore tab model mismatch: %+v", item) } } func TestExploreTabModelFromRequestRejectsWhitespaceURL(t *testing.T) { _, err := exploreTabModelFromRequest("lalu", exploreTabRequest{ Enabled: true, H5URL: "https://h5.example.com/explore live", Tab: "Live", }) if err == nil { t.Fatal("expected whitespace h5 url to fail") } }